ts-proto 1.87.0 → 1.90.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 +28 -0
- package/README.markdown +190 -24
- package/build/encode.js +2 -0
- package/build/main.js +154 -40
- package/build/types.js +24 -1
- package/build/utils.js +10 -1
- package/package.json +5 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
# [1.90.0](https://github.com/stephenh/ts-proto/compare/v1.89.0...v1.90.0) (2021-11-24)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* Add support for 'json_name' annotation ([#408](https://github.com/stephenh/ts-proto/issues/408)) ([b519717](https://github.com/stephenh/ts-proto/commit/b5197174bcaacb8f163cd197d52ab9c645d21d4c))
|
|
7
|
+
|
|
8
|
+
# [1.89.0](https://github.com/stephenh/ts-proto/compare/v1.88.0...v1.89.0) (2021-11-24)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* Improve map reading (fromJSON/fromPartial) ([#410](https://github.com/stephenh/ts-proto/issues/410)) ([057d438](https://github.com/stephenh/ts-proto/commit/057d438548d95c354331f7d2d767ccff952ad5c6))
|
|
14
|
+
|
|
15
|
+
# [1.88.0](https://github.com/stephenh/ts-proto/compare/v1.87.1...v1.88.0) (2021-11-22)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* Support for Google.Protobuf.Value, ListValue and Struct ([#396](https://github.com/stephenh/ts-proto/issues/396)) ([7dd9c16](https://github.com/stephenh/ts-proto/commit/7dd9c16ffdec4d9ea296fbdc30d390fe44192c42))
|
|
21
|
+
|
|
22
|
+
## [1.87.1](https://github.com/stephenh/ts-proto/compare/v1.87.0...v1.87.1) (2021-11-21)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* code generation for int64 map values in fromPartial and fromJson ([#395](https://github.com/stephenh/ts-proto/issues/395)) ([d3ea8eb](https://github.com/stephenh/ts-proto/commit/d3ea8eb69e19a5e45fcc1766c4af1194b17e48fc))
|
|
28
|
+
|
|
1
29
|
# [1.87.0](https://github.com/stephenh/ts-proto/compare/v1.86.0...v1.87.0) (2021-11-16)
|
|
2
30
|
|
|
3
31
|
|
package/README.markdown
CHANGED
|
@@ -22,10 +22,13 @@
|
|
|
22
22
|
- [Assumptions](#assumptions)
|
|
23
23
|
- [Todo](#todo)
|
|
24
24
|
- [OneOf Handling](#oneof-handling)
|
|
25
|
-
- [
|
|
25
|
+
- [Default Values and Unset Fields](#default-values-and-unset-fields)
|
|
26
|
+
- [Well-Known Types](#well-known-types)
|
|
27
|
+
- [Wrapper Types](#wrapper-types)
|
|
28
|
+
- [JSON Types (Struct Types)](#json-types-struct-types)
|
|
29
|
+
- [Timestamps](#timestamp)
|
|
26
30
|
- [Wrapper Types](#wrapper-types)
|
|
27
31
|
- [Number Types](#number-types)
|
|
28
|
-
- [Timestamps](#timestamps)
|
|
29
32
|
- [Current Status of Optional Values](#current-status-of-optional-values)
|
|
30
33
|
|
|
31
34
|
# Overview
|
|
@@ -70,7 +73,7 @@ It will also generate client implementations of `PingService`; currently [Twirp]
|
|
|
70
73
|
- `npm install ts-proto`
|
|
71
74
|
- `protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=. ./simple.proto`
|
|
72
75
|
- (Note that the output parameter name, `ts_proto_out`, is named based on the suffix of the plugin's name, i.e. "ts_proto" suffix in the `--plugin=./node_modules/.bin/protoc-gen-ts_proto` parameter becomes the `_out` prefix, per `protoc`'s CLI conventions.)
|
|
73
|
-
- On Windows, use `protoc --plugin=protoc-gen-ts_proto=.\node_modules\.bin\protoc-gen-ts_proto.cmd --ts_proto_out=. ./simple.proto`
|
|
76
|
+
- On Windows, use `protoc --plugin=protoc-gen-ts_proto=.\node_modules\.bin\protoc-gen-ts_proto.cmd --ts_proto_out=. ./simple.proto` (see [#93](https://github.com/stephenh/ts-proto/issues/93))
|
|
74
77
|
- Ensure you're using a modern `protoc`, i.e. the original `protoc` `3.0.0` doesn't support the `_opt` flag
|
|
75
78
|
|
|
76
79
|
This will generate `*.ts` source files for the given `*.proto` types.
|
|
@@ -376,7 +379,6 @@ The test suite's proto files (i.e. `simple.proto`, `batching.proto`, etc.) curre
|
|
|
376
379
|
# Todo
|
|
377
380
|
|
|
378
381
|
- Support the string-based encoding of duration in `fromJSON`/`toJSON`
|
|
379
|
-
- Support the `json_name` annotation
|
|
380
382
|
- Make `oneof=unions` the default behavior in 2.0
|
|
381
383
|
- Probably change `forceLong` default in 2.0, should default to `forceLong=long`
|
|
382
384
|
- Make `esModuleInterop=true` the default in 2.0
|
|
@@ -399,29 +401,201 @@ As this will automatically enforce only one of `field_a` or `field_b` "being set
|
|
|
399
401
|
|
|
400
402
|
In ts-proto's currently-unscheduled 2.x release, `oneof=unions` will become the default behavior.
|
|
401
403
|
|
|
402
|
-
#
|
|
404
|
+
# Default values and unset fields
|
|
403
405
|
|
|
404
|
-
|
|
406
|
+
In core Protobuf, values that are _unset_ or equal to the default value are not sent over the wire.
|
|
407
|
+
The default value of a message is `undefined`. Primitive types take their natural default value, i.e. `string` is `''`, `number` is `0`, etc.
|
|
408
|
+
This behavior enables forward compatibility, as primitive fields will always have a value, even when omitted by outdated agents, but it also means _default_ and _unset_ values cannot be distinguished.
|
|
405
409
|
|
|
406
|
-
|
|
410
|
+
If you need primitive fields where you can detect set/unset, see [Wrapper Types](#wrapper-types).
|
|
407
411
|
|
|
408
|
-
|
|
412
|
+
**Encode / Decode**
|
|
409
413
|
|
|
410
|
-
|
|
414
|
+
`ts-proto` follows the Protobuf rules, and always returns default values for unsets fields when decoding, while omitting them from the output when serialized in binary format.
|
|
411
415
|
|
|
412
|
-
|
|
416
|
+
```protobuf
|
|
417
|
+
syntax = "proto3";
|
|
418
|
+
message Foo {
|
|
419
|
+
string bar = 1;
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
```typescript
|
|
424
|
+
protobufBytes; // assume this is an empty Foo object, in protobuf binary format
|
|
425
|
+
Foo.decode(protobufBytes); // => { bar: '' }
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
Foo.encode({ bar: '' }); // => { }, writes an empty Foo object, in protobuf binary format
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**fromJSON / toJSON**
|
|
433
|
+
|
|
434
|
+
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.
|
|
435
|
+
|
|
436
|
+
```typescript
|
|
437
|
+
Foo.fromJSON({ }); // => { bar: '' }
|
|
438
|
+
Foo.fromJSON({ bar: '' }); // => { bar: '' }
|
|
439
|
+
Foo.fromJSON({ bar: 'baz' }); // => { bar: 'baz' }
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
When writing JSON, `ts-proto` currently does **not** normalize message when converting to JSON, other than omitting unset fields, but it may do so in the future.
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// Current ts-proto behavior
|
|
446
|
+
Foo.toJSON({ }); // => { }
|
|
447
|
+
Foo.toJSON({ bar: undefined }); // => { }
|
|
448
|
+
Foo.toJSON({ bar: '' }); // => { bar: '' } - note: this is the default value, but it's not omitted
|
|
449
|
+
Foo.toJSON({ bar: 'baz' }); // => { bar: 'baz' }
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
// Possible future behavior, where ts-proto would normalize message
|
|
454
|
+
Foo.toJSON({ }); // => { }
|
|
455
|
+
Foo.toJSON({ bar: undefined }); // => { }
|
|
456
|
+
Foo.toJSON({ bar: '' }); // => { } - note: omitting the default value, as expected
|
|
457
|
+
Foo.toJSON({ bar: 'baz' }); // => { bar: 'baz' }
|
|
458
|
+
```
|
|
413
459
|
|
|
414
|
-
|
|
460
|
+
- Please open an issue if you need this behavior.
|
|
415
461
|
|
|
416
|
-
|
|
462
|
+
# Well-Known Types
|
|
417
463
|
|
|
418
|
-
|
|
464
|
+
Protobuf comes with several predefined message definitions, called "[Well-Known Types](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf)".
|
|
465
|
+
Their interpretation is defined by the Protobuf specification, and libraries are expected to convert these messages to corresponding native types in the target language.
|
|
419
466
|
|
|
420
|
-
|
|
467
|
+
`ts-proto` currently automatically converts these messages to their corresponding native types.
|
|
421
468
|
|
|
422
|
-
|
|
469
|
+
- Wrapper Types:
|
|
470
|
+
|
|
471
|
+
* [google.protobuf.DoubleValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#DoubleValue) ⇆ `number | undefined`
|
|
472
|
+
* [google.protobuf.FloatValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#FloatValue) ⇆ `number | undefined`
|
|
473
|
+
* [google.protobuf.Int64Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Int64Value) ⇆ `number | undefined`
|
|
474
|
+
* [google.protobuf.UInt64Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#UInt64Value) ⇆ `number | undefined`
|
|
475
|
+
* [google.protobuf.Int32Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Int32Value) ⇆ `number | undefined`
|
|
476
|
+
* [google.protobuf.UInt32Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#UInt32Value) ⇆ `number | undefined`
|
|
477
|
+
* [google.protobuf.BoolValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#BoolValue) ⇆ `boolean | undefined`
|
|
478
|
+
* [google.protobuf.StringValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#StringValue) ⇆ `string | undefined`
|
|
479
|
+
* [google.protobuf.BytesValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.BytesValue) ⇆ `Uint8Array | undefined`
|
|
480
|
+
|
|
481
|
+
- JSON Types (Struct Types):
|
|
482
|
+
|
|
483
|
+
* [google.protobuf.Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Value) ⇆ `any | undefined` (i.e. `number | string | boolean | null | array | object`)
|
|
484
|
+
* [google.protobuf.ListValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#ListValue) ⇆ `any[]`
|
|
485
|
+
* [google.protobuf.Struct](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Struct) ⇆ `{ [key: string]: any } | undefined`
|
|
486
|
+
|
|
487
|
+
## Wrapper Types
|
|
488
|
+
|
|
489
|
+
Wrapper Types are messages containing a single primitive field, and can be imported in `.proto` files with `import "google/protobuf/wrappers.proto"`.
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
Since these are _messages_, their default value is `undefined`, allowing you to distinguish unset primitives from their default values, when using Wrapper Types.
|
|
493
|
+
`ts-proto` generates these fields as `<primitive> | undefined`.
|
|
494
|
+
|
|
495
|
+
For example:
|
|
496
|
+
|
|
497
|
+
```protobuf
|
|
498
|
+
// Protobuf
|
|
499
|
+
syntax = "proto3";
|
|
500
|
+
|
|
501
|
+
import "google/protobuf/wrappers.proto";
|
|
502
|
+
|
|
503
|
+
message ExampleMessage {
|
|
504
|
+
google.protobuf.StringValue name = 1;
|
|
505
|
+
}
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
```typescript
|
|
509
|
+
// TypeScript
|
|
510
|
+
interface ExampleMessage {
|
|
511
|
+
name: string | undefined;
|
|
512
|
+
}
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
When encoding a message the primitive value is converted back to its corresponding wrapper type:
|
|
516
|
+
|
|
517
|
+
```typescript
|
|
518
|
+
ExampleMessage.encode({ name: 'foo' }) // => { name: { value: 'foo' } }, in binary
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
When calling toJSON, the value is not converted, because wrapper types are idiomatic in JSON.
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
ExampleMessage.toJSON({ name: 'foo' }) // => { name: 'foo' }
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
## JSON Types (Struct Types)
|
|
528
|
+
|
|
529
|
+
Protobuf's language and types are not sufficient to represent all possible JSON values, since JSON may contain values whose type is unknown in advance.
|
|
530
|
+
For this reason, Protobuf offers several additional types to represent arbitrary JSON values.
|
|
531
|
+
|
|
532
|
+
These are called Struct Types, and can be imported in `.proto` files with `import "google/protobuf/struct.proto"`.
|
|
533
|
+
|
|
534
|
+
- [google.protobuf.Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Value) ⇆ `any`
|
|
535
|
+
- This is the most general type, and can represent any JSON value (i.e. `number | string | boolean | null | array | object`).
|
|
536
|
+
- [google.protobuf.ListValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#ListValue) ⇆ `any[]`
|
|
537
|
+
- To represent a JSON array
|
|
538
|
+
- [google.protobuf.Struct](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Struct) ⇆ `{ [key: string]: any }`
|
|
539
|
+
- To represent a JSON object
|
|
540
|
+
|
|
541
|
+
`ts-proto` automatically converts back and forth between these Struct Types and their corresponding JSON types.
|
|
542
|
+
|
|
543
|
+
Example:
|
|
544
|
+
|
|
545
|
+
```protobuf
|
|
546
|
+
// Protobuf
|
|
547
|
+
syntax = "proto3";
|
|
548
|
+
|
|
549
|
+
import "google/protobuf/struct.proto";
|
|
550
|
+
|
|
551
|
+
message ExampleMessage {
|
|
552
|
+
google.protobuf.Value anything = 1;
|
|
553
|
+
}
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
```typescript
|
|
557
|
+
// TypeScript
|
|
558
|
+
interface ExampleMessage {
|
|
559
|
+
anything: any | undefined;
|
|
560
|
+
}
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
Encoding a JSON value embedded in a message, converts it to a Struct Type:
|
|
564
|
+
```typescript
|
|
565
|
+
ExampleMessage.encode({ anything: { "name": "hello" } })
|
|
566
|
+
/* Outputs the following structure, encoded in protobuf binary format:
|
|
567
|
+
{
|
|
568
|
+
anything: Value {
|
|
569
|
+
structValue = Struct {
|
|
570
|
+
fields = [
|
|
571
|
+
MapEntry {
|
|
572
|
+
key = "name",
|
|
573
|
+
value = Value {
|
|
574
|
+
stringValue = "hello"
|
|
575
|
+
}
|
|
576
|
+
]
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}*/
|
|
581
|
+
|
|
582
|
+
ExampleMessage.encode({ anything: true })
|
|
583
|
+
/* Outputs the following structure encoded in protobuf binary format:
|
|
584
|
+
{
|
|
585
|
+
anything: Value {
|
|
586
|
+
boolValue = true
|
|
587
|
+
}
|
|
588
|
+
}*/
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
## Timestamp
|
|
592
|
+
|
|
593
|
+
The representation of `google.protobuf.Timestamp` is configurable by the `useDate` flag.
|
|
594
|
+
|
|
595
|
+
| Protobuf well-known type | Default/`useDate=true` | `useDate=false` | `useDate=string` |
|
|
596
|
+
| --------------------------- | ---------------------- | ------------------------------------ | ---------------- |
|
|
597
|
+
| `google.protobuf.Timestamp` | `Date` | `{ seconds: number, nanos: number }` | `string` |
|
|
423
598
|
|
|
424
|
-
This makes dealing with `string | unset` in your code much nicer, albeit it's unfortunate that, in Protobuf core, this is not as simple as marking a `string name = 1` field as `optional`, i.e. you have to "dirty" your proto files a bit by knowing to use the `StringValue` convention.
|
|
425
599
|
|
|
426
600
|
# Number Types
|
|
427
601
|
|
|
@@ -452,14 +626,6 @@ The protobuf number types map to JavaScript types based on the `forceLong` confi
|
|
|
452
626
|
|
|
453
627
|
Where (\*) indicates they might throw an error at runtime.
|
|
454
628
|
|
|
455
|
-
# Timestamps
|
|
456
|
-
|
|
457
|
-
The representation of `google.protobuf.Timestamp` is configurable by the `useDate` flag.
|
|
458
|
-
|
|
459
|
-
| Protobuf well-known type | Default/`useDate=true` | `useDate=false` | `useDate=string` |
|
|
460
|
-
| --------------------------- | ---------------------- | ------------------------------------ | ---------------- |
|
|
461
|
-
| `google.protobuf.Timestamp` | `Date` | `{ seconds: number, nanos: number }` | `string` |
|
|
462
|
-
|
|
463
629
|
# Current Status of Optional Values
|
|
464
630
|
|
|
465
631
|
- Required primitives: use as-is, i.e. `string name = 1`.
|
package/build/encode.js
CHANGED
|
@@ -32,6 +32,8 @@ function generateEncoder(ctx, typeName) {
|
|
|
32
32
|
return ts_poet_1.code `${TypeValue}.encode({value: value ?? false}).finish()`;
|
|
33
33
|
case 'BytesValue':
|
|
34
34
|
return ts_poet_1.code `${TypeValue}.encode({value: value ?? new Uint8Array()}).finish()`;
|
|
35
|
+
case 'ListValue':
|
|
36
|
+
return ts_poet_1.code `${TypeValue}.encode({value: value ?? []]}).finish()`;
|
|
35
37
|
}
|
|
36
38
|
throw new Error(`unknown wrapper type: ${name}`);
|
|
37
39
|
}
|
package/build/main.js
CHANGED
|
@@ -184,6 +184,7 @@ function makeUtils(options) {
|
|
|
184
184
|
...makeDeepPartial(options, longs),
|
|
185
185
|
...makeTimestampMethods(options, longs),
|
|
186
186
|
...longs,
|
|
187
|
+
...makeWrappingUtils(),
|
|
187
188
|
};
|
|
188
189
|
}
|
|
189
190
|
exports.makeUtils = makeUtils;
|
|
@@ -240,6 +241,57 @@ function makeLongUtils(options, bytes) {
|
|
|
240
241
|
`);
|
|
241
242
|
return { numberToLong, longToNumber, longToString, longInit, Long };
|
|
242
243
|
}
|
|
244
|
+
function makeWrappingUtils() {
|
|
245
|
+
const wrapAnyValue = ts_poet_1.conditionalOutput('wrapAnyValue', ts_poet_1.code `function wrapAnyValue(value: any): Value {
|
|
246
|
+
if (value === null) {
|
|
247
|
+
return {nullValue: 0} as Value;
|
|
248
|
+
} else if (typeof value === 'boolean') {
|
|
249
|
+
return {boolValue: value} as Value;
|
|
250
|
+
} else if (typeof value === 'number') {
|
|
251
|
+
return {numberValue: value} as Value;
|
|
252
|
+
} else if (typeof value === 'string') {
|
|
253
|
+
return {stringValue: value} as Value;
|
|
254
|
+
} else if (Array.isArray(value)) {
|
|
255
|
+
return {listValue: value} as Value;
|
|
256
|
+
} else if (typeof value === 'object') {
|
|
257
|
+
return {structValue: value} as Value;
|
|
258
|
+
} else if (typeof value === 'undefined') {
|
|
259
|
+
return {} as Value;
|
|
260
|
+
} else {
|
|
261
|
+
throw new Error('Unsupported any value type: ' + typeof value);
|
|
262
|
+
}
|
|
263
|
+
}`);
|
|
264
|
+
const unwrapAnyValue = ts_poet_1.conditionalOutput('unwrapAnyValue', ts_poet_1.code `function unwrapAnyValue(value: Value): string | number | boolean | Object | null | Array<any> | undefined {
|
|
265
|
+
if (value.stringValue !== undefined) {
|
|
266
|
+
return value.stringValue;
|
|
267
|
+
} else if (value.numberValue !== undefined) {
|
|
268
|
+
return value.numberValue;
|
|
269
|
+
} else if (value.boolValue !== undefined) {
|
|
270
|
+
return value.boolValue;
|
|
271
|
+
} else if (value.structValue !== undefined) {
|
|
272
|
+
return value.structValue;
|
|
273
|
+
} else if (value.listValue !== undefined) {
|
|
274
|
+
return value.listValue;
|
|
275
|
+
} else if (value.nullValue !== undefined) {
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
}`);
|
|
279
|
+
const wrapStruct = ts_poet_1.conditionalOutput('wrapStruct', ts_poet_1.code `function wrapStruct(object: {[key: string]: any}): Struct {
|
|
280
|
+
const struct = Struct.fromPartial({});
|
|
281
|
+
Object.keys(object).forEach(key => {
|
|
282
|
+
struct.fields[key] = object[key];
|
|
283
|
+
});
|
|
284
|
+
return struct;
|
|
285
|
+
}`);
|
|
286
|
+
const unwrapStruct = ts_poet_1.conditionalOutput('unwrapStruct', ts_poet_1.code `function unwrapStruct(struct: Struct): {[key: string]: any} {
|
|
287
|
+
const object: { [key: string]: any } = {};
|
|
288
|
+
Object.keys(struct.fields).forEach(key => {
|
|
289
|
+
object[key] = struct.fields[key];
|
|
290
|
+
});
|
|
291
|
+
return object;
|
|
292
|
+
}`);
|
|
293
|
+
return { wrapAnyValue, unwrapAnyValue, wrapStruct, unwrapStruct };
|
|
294
|
+
}
|
|
243
295
|
function makeByteUtils() {
|
|
244
296
|
const globalThis = ts_poet_1.conditionalOutput('globalThis', ts_poet_1.code `
|
|
245
297
|
declare var self: any | undefined;
|
|
@@ -285,13 +337,15 @@ function makeDeepPartial(options, longs) {
|
|
|
285
337
|
`;
|
|
286
338
|
}
|
|
287
339
|
const maybeExport = options.exportCommonSymbols ? 'export' : '';
|
|
288
|
-
|
|
340
|
+
// Allow passing longs as numbers or strings, nad we'll convert them
|
|
341
|
+
const maybeLong = options.forceLong === options_1.LongOption.LONG ? ts_poet_1.code ` : T extends ${longs.Long} ? string | number | Long ` : '';
|
|
289
342
|
const keys = options.outputTypeRegistry ? ts_poet_1.code `Exclude<keyof T, '$type'>` : ts_poet_1.code `keyof T`;
|
|
290
343
|
// Based on the type from ts-essentials
|
|
291
344
|
const DeepPartial = ts_poet_1.conditionalOutput('DeepPartial', ts_poet_1.code `
|
|
292
|
-
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined
|
|
293
|
-
${maybeExport} type DeepPartial<T> =
|
|
345
|
+
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
346
|
+
${maybeExport} type DeepPartial<T> = T extends Builtin
|
|
294
347
|
? T
|
|
348
|
+
${maybeLong}
|
|
295
349
|
: T extends Array<infer U>
|
|
296
350
|
? Array<DeepPartial<U>>
|
|
297
351
|
: T extends ReadonlyArray<infer U>
|
|
@@ -526,8 +580,18 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
526
580
|
}
|
|
527
581
|
}
|
|
528
582
|
else if (types_1.isValueType(ctx, field)) {
|
|
583
|
+
const unwrap = (decodedValue) => {
|
|
584
|
+
if (types_1.isAnyValueType(field))
|
|
585
|
+
return ts_poet_1.code `${ctx.utils.unwrapAnyValue}(${decodedValue})`;
|
|
586
|
+
if (types_1.isStructType(field))
|
|
587
|
+
return ts_poet_1.code `${ctx.utils.unwrapStruct}(${decodedValue})`;
|
|
588
|
+
if (types_1.isListValueType(field))
|
|
589
|
+
return ts_poet_1.code `${decodedValue}.values`;
|
|
590
|
+
return ts_poet_1.code `${decodedValue}.value`;
|
|
591
|
+
};
|
|
529
592
|
const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
|
|
530
|
-
|
|
593
|
+
const decoder = ts_poet_1.code `${type}.decode(reader, reader.uint32())`;
|
|
594
|
+
readSnippet = ts_poet_1.code `${unwrap(decoder)}`;
|
|
531
595
|
}
|
|
532
596
|
else if (types_1.isTimestamp(field) && (options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) {
|
|
533
597
|
const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
|
|
@@ -622,10 +686,19 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
622
686
|
writeSnippet = (place) => ts_poet_1.code `${type}.encode(${utils.toTimestamp}(${place}), writer.uint32(${tag}).fork()).ldelim()`;
|
|
623
687
|
}
|
|
624
688
|
else if (types_1.isValueType(ctx, field)) {
|
|
689
|
+
const maybeTypeField = options.outputTypeRegistry ? `$type: '${field.typeName.slice(1)}',` : '';
|
|
690
|
+
const wrappedValue = (place) => {
|
|
691
|
+
if (types_1.isAnyValueType(field))
|
|
692
|
+
return ts_poet_1.code `${ctx.utils.wrapAnyValue}(${place})`;
|
|
693
|
+
if (types_1.isListValueType(field))
|
|
694
|
+
return ts_poet_1.code `{values: ${place}}`;
|
|
695
|
+
if (types_1.isStructType(field))
|
|
696
|
+
return ts_poet_1.code `${ctx.utils.wrapStruct}(${place})`;
|
|
697
|
+
return ts_poet_1.code `{${maybeTypeField} value: ${place}!}`;
|
|
698
|
+
};
|
|
625
699
|
const tag = ((field.number << 3) | 2) >>> 0;
|
|
626
700
|
const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
|
|
627
|
-
|
|
628
|
-
writeSnippet = (place) => ts_poet_1.code `${type}.encode({ ${maybeTypeField} value: ${place}! }, writer.uint32(${tag}).fork()).ldelim()`;
|
|
701
|
+
writeSnippet = (place) => ts_poet_1.code `${type}.encode(${wrappedValue(place)}, writer.uint32(${tag}).fork()).ldelim()`;
|
|
629
702
|
}
|
|
630
703
|
else if (types_1.isMessage(field)) {
|
|
631
704
|
const tag = ((field.number << 3) | 2) >>> 0;
|
|
@@ -741,6 +814,7 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
741
814
|
// add a check for each incoming field
|
|
742
815
|
messageDesc.field.forEach((field) => {
|
|
743
816
|
const fieldName = case_1.maybeSnakeToCamel(field.name, options);
|
|
817
|
+
const jsonName = utils_1.determineFieldJsonName(field, options);
|
|
744
818
|
// get a generic 'reader.doSomething' bit that is specific to the basic type
|
|
745
819
|
const readSnippet = (from) => {
|
|
746
820
|
if (types_1.isEnum(field)) {
|
|
@@ -773,6 +847,9 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
773
847
|
(options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.TIMESTAMP)) {
|
|
774
848
|
return ts_poet_1.code `${utils.fromJsonTimestamp}(${from})`;
|
|
775
849
|
}
|
|
850
|
+
else if (types_1.isAnyValueType(field) || types_1.isStructType(field)) {
|
|
851
|
+
return ts_poet_1.code `${from}`;
|
|
852
|
+
}
|
|
776
853
|
else if (types_1.isValueType(ctx, field)) {
|
|
777
854
|
const valueType = types_1.valueTypeName(ctx, field.typeName);
|
|
778
855
|
if (types_1.isLongValueType(field) && options.forceLong === options_1.LongOption.LONG) {
|
|
@@ -781,6 +858,9 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
781
858
|
else if (types_1.isBytesValueType(field)) {
|
|
782
859
|
return ts_poet_1.code `new ${case_1.capitalize(valueType.toCodeString())}(${from})`;
|
|
783
860
|
}
|
|
861
|
+
else if (types_1.isListValueType(field)) {
|
|
862
|
+
return ts_poet_1.code `[...${from}]`;
|
|
863
|
+
}
|
|
784
864
|
else {
|
|
785
865
|
return ts_poet_1.code `${case_1.capitalize(valueType.toCodeString())}(${from})`;
|
|
786
866
|
}
|
|
@@ -798,6 +878,9 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
798
878
|
return ts_poet_1.code `${utils.bytesFromBase64}(${from} as string)`;
|
|
799
879
|
}
|
|
800
880
|
}
|
|
881
|
+
else if (types_1.isLong(valueType) && options.forceLong === options_1.LongOption.LONG) {
|
|
882
|
+
return ts_poet_1.code `Long.fromString(${from} as string)`;
|
|
883
|
+
}
|
|
801
884
|
else if (types_1.isEnum(valueType)) {
|
|
802
885
|
return ts_poet_1.code `${from} as number`;
|
|
803
886
|
}
|
|
@@ -817,6 +900,9 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
817
900
|
const type = types_1.basicTypeName(ctx, valueType);
|
|
818
901
|
return ts_poet_1.code `${from} as ${type}`;
|
|
819
902
|
}
|
|
903
|
+
else if (types_1.isAnyValueType(valueType)) {
|
|
904
|
+
return ts_poet_1.code `${from}`;
|
|
905
|
+
}
|
|
820
906
|
else {
|
|
821
907
|
const type = types_1.basicTypeName(ctx, valueType);
|
|
822
908
|
return ts_poet_1.code `${type}.fromJSON(${from})`;
|
|
@@ -834,36 +920,53 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
834
920
|
// and then use the snippet to handle repeated fields if necessary
|
|
835
921
|
if (types_1.isRepeated(field)) {
|
|
836
922
|
if (types_1.isMapType(ctx, messageDesc, field)) {
|
|
837
|
-
|
|
838
|
-
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
923
|
+
const fieldType = types_1.toTypeName(ctx, messageDesc, field);
|
|
839
924
|
const i = maybeCastToNumber(ctx, messageDesc, field, 'key');
|
|
840
925
|
chunks.push(ts_poet_1.code `
|
|
841
|
-
Object.entries(object.${
|
|
842
|
-
|
|
843
|
-
|
|
926
|
+
message.${fieldName} = Object.entries(object.${jsonName} ?? {}).reduce<${fieldType}>((acc, [key, value]) => {
|
|
927
|
+
acc[${i}] = ${readSnippet('value')};
|
|
928
|
+
return acc;
|
|
929
|
+
}, {});
|
|
930
|
+
`);
|
|
931
|
+
}
|
|
932
|
+
else if (types_1.isAnyValueType(field)) {
|
|
933
|
+
chunks.push(ts_poet_1.code `
|
|
934
|
+
message.${fieldName} = Array.isArray(object?.${jsonName}) ? [...object.${jsonName}] : [];
|
|
844
935
|
`);
|
|
845
|
-
chunks.push(ts_poet_1.code `}`);
|
|
846
936
|
}
|
|
847
937
|
else {
|
|
848
938
|
// Explicit `any` type required to make TS with noImplicitAny happy. `object` is also `any` here.
|
|
849
939
|
chunks.push(ts_poet_1.code `
|
|
850
|
-
message.${fieldName} = (object.${
|
|
940
|
+
message.${fieldName} = (object.${jsonName} ?? []).map((e: any) => ${readSnippet('e')});
|
|
851
941
|
`);
|
|
852
942
|
}
|
|
853
943
|
}
|
|
854
944
|
else if (types_1.isWithinOneOfThatShouldBeUnion(options, field)) {
|
|
855
|
-
chunks.push(ts_poet_1.code `if (object.${
|
|
945
|
+
chunks.push(ts_poet_1.code `if (object.${jsonName} !== undefined && object.${jsonName} !== null) {`);
|
|
856
946
|
const oneofName = case_1.maybeSnakeToCamel(messageDesc.oneofDecl[field.oneofIndex].name, options);
|
|
857
947
|
chunks.push(ts_poet_1.code `
|
|
858
|
-
message.${oneofName} = { $case: '${fieldName}', ${fieldName}: ${readSnippet(`object.${
|
|
948
|
+
message.${oneofName} = { $case: '${fieldName}', ${fieldName}: ${readSnippet(`object.${jsonName}`)} }
|
|
859
949
|
`);
|
|
860
950
|
chunks.push(ts_poet_1.code `}`);
|
|
861
951
|
}
|
|
952
|
+
else if (types_1.isAnyValueType(field)) {
|
|
953
|
+
chunks.push(ts_poet_1.code `message.${fieldName} = object.${fieldName};`);
|
|
954
|
+
}
|
|
955
|
+
else if (types_1.isStructType(field)) {
|
|
956
|
+
chunks.push(ts_poet_1.code `message.${fieldName} = typeof(object.${fieldName}) === 'object' ? object.${fieldName} : undefined;`);
|
|
957
|
+
}
|
|
958
|
+
else if (types_1.isListValueType(field)) {
|
|
959
|
+
chunks.push(ts_poet_1.code `
|
|
960
|
+
message.${fieldName} = Array.isArray(object?.${fieldName})
|
|
961
|
+
? ${readSnippet(`object.${fieldName}`)}
|
|
962
|
+
: ${'undefined'};
|
|
963
|
+
`);
|
|
964
|
+
}
|
|
862
965
|
else {
|
|
863
966
|
const fallback = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
|
864
967
|
chunks.push(ts_poet_1.code `
|
|
865
|
-
message.${fieldName} = (object.${
|
|
866
|
-
? ${readSnippet(`object.${
|
|
968
|
+
message.${fieldName} = (object.${jsonName} !== undefined && object.${jsonName} !== null)
|
|
969
|
+
? ${readSnippet(`object.${jsonName}`)}
|
|
867
970
|
: ${fallback};
|
|
868
971
|
`);
|
|
869
972
|
}
|
|
@@ -884,6 +987,7 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
884
987
|
// then add a case for each field
|
|
885
988
|
messageDesc.field.forEach((field) => {
|
|
886
989
|
const fieldName = case_1.maybeSnakeToCamel(field.name, options);
|
|
990
|
+
const jsonName = utils_1.determineFieldJsonName(field, options);
|
|
887
991
|
const readSnippet = (from) => {
|
|
888
992
|
if (types_1.isEnum(field)) {
|
|
889
993
|
const toJson = types_1.getEnumMethod(typeMap, field.typeName, 'ToJSON');
|
|
@@ -919,14 +1023,23 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
919
1023
|
else if (types_1.isTimestamp(valueType) && options.useDate === options_1.DateOption.TIMESTAMP) {
|
|
920
1024
|
return ts_poet_1.code `${utils.fromTimestamp}(${from}).toISOString()`;
|
|
921
1025
|
}
|
|
1026
|
+
else if (types_1.isLong(valueType) && options.forceLong === options_1.LongOption.LONG) {
|
|
1027
|
+
return ts_poet_1.code `${from}.toString()`;
|
|
1028
|
+
}
|
|
922
1029
|
else if (types_1.isScalar(valueType) || types_1.isValueType(ctx, valueType)) {
|
|
923
1030
|
return ts_poet_1.code `${from}`;
|
|
924
1031
|
}
|
|
1032
|
+
else if (types_1.isAnyValueType(valueType)) {
|
|
1033
|
+
return ts_poet_1.code `${from}`;
|
|
1034
|
+
}
|
|
925
1035
|
else {
|
|
926
1036
|
const type = types_1.basicTypeName(ctx, valueType);
|
|
927
1037
|
return ts_poet_1.code `${type}.toJSON(${from})`;
|
|
928
1038
|
}
|
|
929
1039
|
}
|
|
1040
|
+
else if (types_1.isAnyValueType(field)) {
|
|
1041
|
+
return ts_poet_1.code `${from}`;
|
|
1042
|
+
}
|
|
930
1043
|
else if (types_1.isMessage(field) && !types_1.isValueType(ctx, field) && !types_1.isMapType(ctx, messageDesc, field)) {
|
|
931
1044
|
const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
|
|
932
1045
|
return ts_poet_1.code `${from} ? ${type}.toJSON(${from}) : ${types_1.defaultValue(ctx, field)}`;
|
|
@@ -950,10 +1063,10 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
950
1063
|
if (types_1.isMapType(ctx, messageDesc, field)) {
|
|
951
1064
|
// Maps might need their values transformed, i.e. bytes --> base64
|
|
952
1065
|
chunks.push(ts_poet_1.code `
|
|
953
|
-
obj.${
|
|
1066
|
+
obj.${jsonName} = {};
|
|
954
1067
|
if (message.${fieldName}) {
|
|
955
1068
|
Object.entries(message.${fieldName}).forEach(([k, v]) => {
|
|
956
|
-
obj.${
|
|
1069
|
+
obj.${jsonName}[k] = ${readSnippet('v')};
|
|
957
1070
|
});
|
|
958
1071
|
}
|
|
959
1072
|
`);
|
|
@@ -962,9 +1075,9 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
962
1075
|
// Arrays might need their elements transformed
|
|
963
1076
|
chunks.push(ts_poet_1.code `
|
|
964
1077
|
if (message.${fieldName}) {
|
|
965
|
-
obj.${
|
|
1078
|
+
obj.${jsonName} = message.${fieldName}.map(e => ${readSnippet('e')});
|
|
966
1079
|
} else {
|
|
967
|
-
obj.${
|
|
1080
|
+
obj.${jsonName} = [];
|
|
968
1081
|
}
|
|
969
1082
|
`);
|
|
970
1083
|
}
|
|
@@ -972,11 +1085,11 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
972
1085
|
// oneofs in a union are only output as `oneof name = ...`
|
|
973
1086
|
const oneofName = case_1.maybeSnakeToCamel(messageDesc.oneofDecl[field.oneofIndex].name, options);
|
|
974
1087
|
const v = readSnippet(`message.${oneofName}?.${fieldName}`);
|
|
975
|
-
chunks.push(ts_poet_1.code `message.${oneofName}?.$case === '${fieldName}' && (obj.${
|
|
1088
|
+
chunks.push(ts_poet_1.code `message.${oneofName}?.$case === '${fieldName}' && (obj.${jsonName} = ${v});`);
|
|
976
1089
|
}
|
|
977
1090
|
else {
|
|
978
1091
|
const v = readSnippet(`message.${fieldName}`);
|
|
979
|
-
chunks.push(ts_poet_1.code `message.${fieldName} !== undefined && (obj.${
|
|
1092
|
+
chunks.push(ts_poet_1.code `message.${fieldName} !== undefined && (obj.${jsonName} = ${v});`);
|
|
980
1093
|
}
|
|
981
1094
|
});
|
|
982
1095
|
chunks.push(ts_poet_1.code `return obj;`);
|
|
@@ -996,7 +1109,10 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
996
1109
|
messageDesc.field.forEach((field) => {
|
|
997
1110
|
const fieldName = case_1.maybeSnakeToCamel(field.name, options);
|
|
998
1111
|
const readSnippet = (from) => {
|
|
999
|
-
if (types_1.
|
|
1112
|
+
if ((types_1.isLong(field) || types_1.isLongValueType(field)) && options.forceLong === options_1.LongOption.LONG) {
|
|
1113
|
+
return ts_poet_1.code `Long.fromValue(${from})`;
|
|
1114
|
+
}
|
|
1115
|
+
else if (types_1.isPrimitive(field) ||
|
|
1000
1116
|
(types_1.isTimestamp(field) && (options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) ||
|
|
1001
1117
|
types_1.isValueType(ctx, field)) {
|
|
1002
1118
|
return ts_poet_1.code `${from}`;
|
|
@@ -1011,11 +1127,17 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1011
1127
|
else if (types_1.isEnum(valueType)) {
|
|
1012
1128
|
return ts_poet_1.code `${from} as number`;
|
|
1013
1129
|
}
|
|
1130
|
+
else if (types_1.isLong(valueType) && options.forceLong === options_1.LongOption.LONG) {
|
|
1131
|
+
return ts_poet_1.code `Long.fromValue(${from})`;
|
|
1132
|
+
}
|
|
1014
1133
|
else {
|
|
1015
1134
|
const cstr = case_1.capitalize(types_1.basicTypeName(ctx, valueType).toCodeString());
|
|
1016
1135
|
return ts_poet_1.code `${cstr}(${from})`;
|
|
1017
1136
|
}
|
|
1018
1137
|
}
|
|
1138
|
+
else if (types_1.isAnyValueType(valueType)) {
|
|
1139
|
+
return ts_poet_1.code `${from}`;
|
|
1140
|
+
}
|
|
1019
1141
|
else if (types_1.isTimestamp(valueType) &&
|
|
1020
1142
|
(options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) {
|
|
1021
1143
|
return ts_poet_1.code `${from}`;
|
|
@@ -1028,6 +1150,9 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1028
1150
|
return ts_poet_1.code `${type}.fromPartial(${from})`;
|
|
1029
1151
|
}
|
|
1030
1152
|
}
|
|
1153
|
+
else if (types_1.isAnyValueType(field)) {
|
|
1154
|
+
return ts_poet_1.code `${from}`;
|
|
1155
|
+
}
|
|
1031
1156
|
else {
|
|
1032
1157
|
const type = types_1.basicTypeName(ctx, field);
|
|
1033
1158
|
return ts_poet_1.code `${type}.fromPartial(${from})`;
|
|
@@ -1040,17 +1165,16 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1040
1165
|
// and then use the snippet to handle repeated fields if necessary
|
|
1041
1166
|
if (types_1.isRepeated(field)) {
|
|
1042
1167
|
if (types_1.isMapType(ctx, messageDesc, field)) {
|
|
1043
|
-
|
|
1044
|
-
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
1168
|
+
const fieldType = types_1.toTypeName(ctx, messageDesc, field);
|
|
1045
1169
|
const i = maybeCastToNumber(ctx, messageDesc, field, 'key');
|
|
1046
1170
|
chunks.push(ts_poet_1.code `
|
|
1047
|
-
Object.entries(object.${fieldName}).
|
|
1171
|
+
message.${fieldName} = Object.entries(object.${fieldName} ?? {}).reduce<${fieldType}>((acc, [key, value]) => {
|
|
1048
1172
|
if (value !== undefined) {
|
|
1049
|
-
|
|
1173
|
+
acc[${i}] = ${readSnippet('value')};
|
|
1050
1174
|
}
|
|
1051
|
-
|
|
1175
|
+
return acc;
|
|
1176
|
+
}, {});
|
|
1052
1177
|
`);
|
|
1053
|
-
chunks.push(ts_poet_1.code `}`);
|
|
1054
1178
|
}
|
|
1055
1179
|
else {
|
|
1056
1180
|
chunks.push(ts_poet_1.code `
|
|
@@ -1071,16 +1195,6 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1071
1195
|
}
|
|
1072
1196
|
`);
|
|
1073
1197
|
}
|
|
1074
|
-
else if ((types_1.isLong(field) || types_1.isLongValueType(field)) && options.forceLong === options_1.LongOption.LONG) {
|
|
1075
|
-
const v = readSnippet(`object.${fieldName}`);
|
|
1076
|
-
const type = types_1.basicTypeName(ctx, field);
|
|
1077
|
-
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
1078
|
-
chunks.push(ts_poet_1.code `message.${fieldName} = ${v} as ${type};`);
|
|
1079
|
-
chunks.push(ts_poet_1.code `} else {`);
|
|
1080
|
-
const fallback = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
|
1081
|
-
chunks.push(ts_poet_1.code `message.${fieldName} = ${fallback}`);
|
|
1082
|
-
chunks.push(ts_poet_1.code `}`);
|
|
1083
|
-
}
|
|
1084
1198
|
else if (readSnippet(`x`).toCodeString() == 'x') {
|
|
1085
1199
|
// An optimized case of the else below that works when `readSnippet` returns the plain input
|
|
1086
1200
|
const fallback = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
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.isBytesValueType = exports.isValueType = exports.isTimestamp = exports.isMapType = exports.isLong = exports.isRepeated = exports.isWithinOneOfThatShouldBeUnion = exports.isWithinOneOf = exports.isEnum = exports.isMessage = exports.isBytes = exports.isPrimitive = 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.isStructType = exports.isListValueTypeName = exports.isListValueType = exports.isBytesValueType = exports.isAnyValueType = exports.isValueType = exports.isTimestamp = exports.isMapType = exports.isLong = exports.isRepeated = exports.isWithinOneOfThatShouldBeUnion = exports.isWithinOneOf = exports.isEnum = exports.isMessage = exports.isBytes = exports.isPrimitive = 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");
|
|
@@ -359,10 +359,26 @@ function isValueType(ctx, field) {
|
|
|
359
359
|
return valueTypeName(ctx, field.typeName) !== undefined;
|
|
360
360
|
}
|
|
361
361
|
exports.isValueType = isValueType;
|
|
362
|
+
function isAnyValueType(field) {
|
|
363
|
+
return field.typeName === '.google.protobuf.Value';
|
|
364
|
+
}
|
|
365
|
+
exports.isAnyValueType = isAnyValueType;
|
|
362
366
|
function isBytesValueType(field) {
|
|
363
367
|
return field.typeName === '.google.protobuf.BytesValue';
|
|
364
368
|
}
|
|
365
369
|
exports.isBytesValueType = isBytesValueType;
|
|
370
|
+
function isListValueType(field) {
|
|
371
|
+
return isListValueTypeName(field.typeName);
|
|
372
|
+
}
|
|
373
|
+
exports.isListValueType = isListValueType;
|
|
374
|
+
function isListValueTypeName(typeName) {
|
|
375
|
+
return typeName === 'google.protobuf.ListValue' || typeName === '.google.protobuf.ListValue';
|
|
376
|
+
}
|
|
377
|
+
exports.isListValueTypeName = isListValueTypeName;
|
|
378
|
+
function isStructType(field) {
|
|
379
|
+
return field.typeName === '.google.protobuf.Struct';
|
|
380
|
+
}
|
|
381
|
+
exports.isStructType = isStructType;
|
|
366
382
|
function isLongValueType(field) {
|
|
367
383
|
return field.typeName === '.google.protobuf.Int64Value' || field.typeName === '.google.protobuf.UInt64Value';
|
|
368
384
|
}
|
|
@@ -388,6 +404,12 @@ function valueTypeName(ctx, typeName) {
|
|
|
388
404
|
return ts_poet_1.code `boolean`;
|
|
389
405
|
case '.google.protobuf.BytesValue':
|
|
390
406
|
return ts_poet_1.code `Uint8Array`;
|
|
407
|
+
case '.google.protobuf.ListValue':
|
|
408
|
+
return ts_poet_1.code `Array<any>`;
|
|
409
|
+
case '.google.protobuf.Value':
|
|
410
|
+
return ts_poet_1.code `any`;
|
|
411
|
+
case '.google.protobuf.Struct':
|
|
412
|
+
return ts_poet_1.code `{[key: string]: any}`;
|
|
391
413
|
default:
|
|
392
414
|
return undefined;
|
|
393
415
|
}
|
|
@@ -404,6 +426,7 @@ function wrapperTypeName(typeName) {
|
|
|
404
426
|
case '.google.protobuf.UInt64Value':
|
|
405
427
|
case '.google.protobuf.BoolValue':
|
|
406
428
|
case '.google.protobuf.BytesValue':
|
|
429
|
+
case '.google.protobuf.ListValue':
|
|
407
430
|
case '.google.protobuf.Timestamp':
|
|
408
431
|
return typeName.split('.')[3];
|
|
409
432
|
default:
|
package/build/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
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;
|
|
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;
|
|
4
4
|
const ts_poet_1 = require("ts-poet");
|
|
5
5
|
const options_1 = require("./options");
|
|
6
6
|
const case_1 = require("./case");
|
|
@@ -144,3 +144,12 @@ class FormattedMethodDescriptor {
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
exports.FormattedMethodDescriptor = FormattedMethodDescriptor;
|
|
147
|
+
function determineFieldJsonName(field, options) {
|
|
148
|
+
// By default jsonName is camelCased by the protocol compilier unless the user has
|
|
149
|
+
// set a "json_name" option on this field.
|
|
150
|
+
if (field.jsonName.length > 0) {
|
|
151
|
+
return field.jsonName;
|
|
152
|
+
}
|
|
153
|
+
return case_1.maybeSnakeToCamel(field.name, options);
|
|
154
|
+
}
|
|
155
|
+
exports.determineFieldJsonName = determineFieldJsonName;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-proto",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.90.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/plugin.js",
|
|
6
6
|
"repository": "github:stephenh/ts-proto",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"@grpc/proto-loader": "^0.5.6",
|
|
26
26
|
"@improbable-eng/grpc-web": "^0.14.0",
|
|
27
27
|
"@improbable-eng/grpc-web-node-http-transport": "^0.14.0",
|
|
28
|
-
"@nestjs/common": "^
|
|
29
|
-
"@nestjs/core": "^
|
|
30
|
-
"@nestjs/microservices": "^
|
|
28
|
+
"@nestjs/common": "^8.2.2",
|
|
29
|
+
"@nestjs/core": "^8.2.2",
|
|
30
|
+
"@nestjs/microservices": "^8.2.2",
|
|
31
31
|
"@semantic-release/changelog": "^5.0.1",
|
|
32
32
|
"@semantic-release/commit-analyzer": "^8.0.1",
|
|
33
33
|
"@semantic-release/git": "^9.0.0",
|
|
@@ -36,11 +36,10 @@
|
|
|
36
36
|
"@semantic-release/release-notes-generator": "^9.0.2",
|
|
37
37
|
"@types/jest": "^26.0.22",
|
|
38
38
|
"@types/node": "^14.14.37",
|
|
39
|
-
"grpc": "^1.24.6",
|
|
40
39
|
"jest": "^26.6.3",
|
|
41
40
|
"prettier": "^2.2.1",
|
|
42
41
|
"reflect-metadata": "^0.1.13",
|
|
43
|
-
"rxjs": "^
|
|
42
|
+
"rxjs": "^7.4.0",
|
|
44
43
|
"semantic-release": "^17.4.2",
|
|
45
44
|
"ts-jest": "^26.5.4",
|
|
46
45
|
"ts-node": "^9.1.1",
|