ts-proto 1.85.0 → 1.88.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 -23
- package/build/encode.js +2 -0
- package/build/main.js +154 -62
- package/build/types.js +24 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
# [1.88.0](https://github.com/stephenh/ts-proto/compare/v1.87.1...v1.88.0) (2021-11-22)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* 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))
|
|
7
|
+
|
|
8
|
+
## [1.87.1](https://github.com/stephenh/ts-proto/compare/v1.87.0...v1.87.1) (2021-11-21)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* 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))
|
|
14
|
+
|
|
15
|
+
# [1.87.0](https://github.com/stephenh/ts-proto/compare/v1.86.0...v1.87.0) (2021-11-16)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* Use ternary operator for conditional assignments ([#394](https://github.com/stephenh/ts-proto/issues/394)) ([d84c084](https://github.com/stephenh/ts-proto/commit/d84c084fb56c958c184f8971479979b8bfb17ccc))
|
|
21
|
+
|
|
22
|
+
# [1.86.0](https://github.com/stephenh/ts-proto/compare/v1.85.0...v1.86.0) (2021-11-15)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* Initialize lists with map ([#387](https://github.com/stephenh/ts-proto/issues/387)) ([200e674](https://github.com/stephenh/ts-proto/commit/200e674e4baf2640d67720ad535fe042d291d4a0))
|
|
28
|
+
|
|
1
29
|
# [1.85.0](https://github.com/stephenh/ts-proto/compare/v1.84.0...v1.85.0) (2021-11-02)
|
|
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.
|
|
@@ -399,29 +402,201 @@ As this will automatically enforce only one of `field_a` or `field_b` "being set
|
|
|
399
402
|
|
|
400
403
|
In ts-proto's currently-unscheduled 2.x release, `oneof=unions` will become the default behavior.
|
|
401
404
|
|
|
402
|
-
#
|
|
405
|
+
# Default values and unset fields
|
|
403
406
|
|
|
404
|
-
|
|
407
|
+
In core Protobuf, values that are _unset_ or equal to the default value are not sent over the wire.
|
|
408
|
+
The default value of a message is `undefined`. Primitive types take their natural default value, i.e. `string` is `''`, `number` is `0`, etc.
|
|
409
|
+
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
410
|
|
|
406
|
-
|
|
411
|
+
If you need primitive fields where you can detect set/unset, see [Wrapper Types](#wrapper-types).
|
|
407
412
|
|
|
408
|
-
|
|
413
|
+
**Encode / Decode**
|
|
409
414
|
|
|
410
|
-
|
|
415
|
+
`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
416
|
|
|
412
|
-
|
|
417
|
+
```protobuf
|
|
418
|
+
syntax = "proto3";
|
|
419
|
+
message Foo {
|
|
420
|
+
string bar = 1;
|
|
421
|
+
}
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
protobufBytes; // assume this is an empty Foo object, in protobuf binary format
|
|
426
|
+
Foo.decode(protobufBytes); // => { bar: '' }
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
Foo.encode({ bar: '' }); // => { }, writes an empty Foo object, in protobuf binary format
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
**fromJSON / toJSON**
|
|
434
|
+
|
|
435
|
+
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.
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
Foo.fromJSON({ }); // => { bar: '' }
|
|
439
|
+
Foo.fromJSON({ bar: '' }); // => { bar: '' }
|
|
440
|
+
Foo.fromJSON({ bar: 'baz' }); // => { bar: 'baz' }
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
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.
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
// Current ts-proto behavior
|
|
447
|
+
Foo.toJSON({ }); // => { }
|
|
448
|
+
Foo.toJSON({ bar: undefined }); // => { }
|
|
449
|
+
Foo.toJSON({ bar: '' }); // => { bar: '' } - note: this is the default value, but it's not omitted
|
|
450
|
+
Foo.toJSON({ bar: 'baz' }); // => { bar: 'baz' }
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
```typescript
|
|
454
|
+
// Possible future behavior, where ts-proto would normalize message
|
|
455
|
+
Foo.toJSON({ }); // => { }
|
|
456
|
+
Foo.toJSON({ bar: undefined }); // => { }
|
|
457
|
+
Foo.toJSON({ bar: '' }); // => { } - note: omitting the default value, as expected
|
|
458
|
+
Foo.toJSON({ bar: 'baz' }); // => { bar: 'baz' }
|
|
459
|
+
```
|
|
413
460
|
|
|
414
|
-
|
|
461
|
+
- Please open an issue if you need this behavior.
|
|
415
462
|
|
|
416
|
-
|
|
463
|
+
# Well-Known Types
|
|
417
464
|
|
|
418
|
-
|
|
465
|
+
Protobuf comes with several predefined message definitions, called "[Well-Known Types](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf)".
|
|
466
|
+
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
467
|
|
|
420
|
-
|
|
468
|
+
`ts-proto` currently automatically converts these messages to their corresponding native types.
|
|
421
469
|
|
|
422
|
-
|
|
470
|
+
- Wrapper Types:
|
|
471
|
+
|
|
472
|
+
* [google.protobuf.DoubleValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#DoubleValue) ⇆ `number | undefined`
|
|
473
|
+
* [google.protobuf.FloatValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#FloatValue) ⇆ `number | undefined`
|
|
474
|
+
* [google.protobuf.Int64Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Int64Value) ⇆ `number | undefined`
|
|
475
|
+
* [google.protobuf.UInt64Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#UInt64Value) ⇆ `number | undefined`
|
|
476
|
+
* [google.protobuf.Int32Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Int32Value) ⇆ `number | undefined`
|
|
477
|
+
* [google.protobuf.UInt32Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#UInt32Value) ⇆ `number | undefined`
|
|
478
|
+
* [google.protobuf.BoolValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#BoolValue) ⇆ `boolean | undefined`
|
|
479
|
+
* [google.protobuf.StringValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#StringValue) ⇆ `string | undefined`
|
|
480
|
+
* [google.protobuf.BytesValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.BytesValue) ⇆ `Uint8Array | undefined`
|
|
481
|
+
|
|
482
|
+
- JSON Types (Struct Types):
|
|
483
|
+
|
|
484
|
+
* [google.protobuf.Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Value) ⇆ `any | undefined` (i.e. `number | string | boolean | null | array | object`)
|
|
485
|
+
* [google.protobuf.ListValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#ListValue) ⇆ `any[]`
|
|
486
|
+
* [google.protobuf.Struct](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Struct) ⇆ `{ [key: string]: any } | undefined`
|
|
487
|
+
|
|
488
|
+
## Wrapper Types
|
|
489
|
+
|
|
490
|
+
Wrapper Types are messages containing a single primitive field, and can be imported in `.proto` files with `import "google/protobuf/wrappers.proto"`.
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
Since these are _messages_, their default value is `undefined`, allowing you to distinguish unset primitives from their default values, when using Wrapper Types.
|
|
494
|
+
`ts-proto` generates these fields as `<primitive> | undefined`.
|
|
495
|
+
|
|
496
|
+
For example:
|
|
497
|
+
|
|
498
|
+
```protobuf
|
|
499
|
+
// Protobuf
|
|
500
|
+
syntax = "proto3";
|
|
501
|
+
|
|
502
|
+
import "google/protobuf/wrappers.proto";
|
|
503
|
+
|
|
504
|
+
message ExampleMessage {
|
|
505
|
+
google.protobuf.StringValue name = 1;
|
|
506
|
+
}
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
```typescript
|
|
510
|
+
// TypeScript
|
|
511
|
+
interface ExampleMessage {
|
|
512
|
+
name: string | undefined;
|
|
513
|
+
}
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
When encoding a message the primitive value is converted back to its corresponding wrapper type:
|
|
517
|
+
|
|
518
|
+
```typescript
|
|
519
|
+
ExampleMessage.encode({ name: 'foo' }) // => { name: { value: 'foo' } }, in binary
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
When calling toJSON, the value is not converted, because wrapper types are idiomatic in JSON.
|
|
523
|
+
|
|
524
|
+
```typescript
|
|
525
|
+
ExampleMessage.toJSON({ name: 'foo' }) // => { name: 'foo' }
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
## JSON Types (Struct Types)
|
|
529
|
+
|
|
530
|
+
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.
|
|
531
|
+
For this reason, Protobuf offers several additional types to represent arbitrary JSON values.
|
|
532
|
+
|
|
533
|
+
These are called Struct Types, and can be imported in `.proto` files with `import "google/protobuf/struct.proto"`.
|
|
534
|
+
|
|
535
|
+
- [google.protobuf.Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Value) ⇆ `any`
|
|
536
|
+
- This is the most general type, and can represent any JSON value (i.e. `number | string | boolean | null | array | object`).
|
|
537
|
+
- [google.protobuf.ListValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#ListValue) ⇆ `any[]`
|
|
538
|
+
- To represent a JSON array
|
|
539
|
+
- [google.protobuf.Struct](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Struct) ⇆ `{ [key: string]: any }`
|
|
540
|
+
- To represent a JSON object
|
|
541
|
+
|
|
542
|
+
`ts-proto` automatically converts back and forth between these Struct Types and their corresponding JSON types.
|
|
543
|
+
|
|
544
|
+
Example:
|
|
545
|
+
|
|
546
|
+
```protobuf
|
|
547
|
+
// Protobuf
|
|
548
|
+
syntax = "proto3";
|
|
549
|
+
|
|
550
|
+
import "google/protobuf/struct.proto";
|
|
551
|
+
|
|
552
|
+
message ExampleMessage {
|
|
553
|
+
google.protobuf.Value anything = 1;
|
|
554
|
+
}
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
```typescript
|
|
558
|
+
// TypeScript
|
|
559
|
+
interface ExampleMessage {
|
|
560
|
+
anything: any | undefined;
|
|
561
|
+
}
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
Encoding a JSON value embedded in a message, converts it to a Struct Type:
|
|
565
|
+
```typescript
|
|
566
|
+
ExampleMessage.encode({ anything: { "name": "hello" } })
|
|
567
|
+
/* Outputs the following structure, encoded in protobuf binary format:
|
|
568
|
+
{
|
|
569
|
+
anything: Value {
|
|
570
|
+
structValue = Struct {
|
|
571
|
+
fields = [
|
|
572
|
+
MapEntry {
|
|
573
|
+
key = "name",
|
|
574
|
+
value = Value {
|
|
575
|
+
stringValue = "hello"
|
|
576
|
+
}
|
|
577
|
+
]
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}*/
|
|
582
|
+
|
|
583
|
+
ExampleMessage.encode({ anything: true })
|
|
584
|
+
/* Outputs the following structure encoded in protobuf binary format:
|
|
585
|
+
{
|
|
586
|
+
anything: Value {
|
|
587
|
+
boolValue = true
|
|
588
|
+
}
|
|
589
|
+
}*/
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
## Timestamp
|
|
593
|
+
|
|
594
|
+
The representation of `google.protobuf.Timestamp` is configurable by the `useDate` flag.
|
|
595
|
+
|
|
596
|
+
| Protobuf well-known type | Default/`useDate=true` | `useDate=false` | `useDate=string` |
|
|
597
|
+
| --------------------------- | ---------------------- | ------------------------------------ | ---------------- |
|
|
598
|
+
| `google.protobuf.Timestamp` | `Date` | `{ seconds: number, nanos: number }` | `string` |
|
|
423
599
|
|
|
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
600
|
|
|
426
601
|
# Number Types
|
|
427
602
|
|
|
@@ -452,14 +627,6 @@ The protobuf number types map to JavaScript types based on the `forceLong` confi
|
|
|
452
627
|
|
|
453
628
|
Where (\*) indicates they might throw an error at runtime.
|
|
454
629
|
|
|
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
630
|
# Current Status of Optional Values
|
|
464
631
|
|
|
465
632
|
- 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
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.contextTypeVar = exports.makeUtils = exports.generateFile = void 0;
|
|
4
4
|
const ts_poet_1 = require("ts-poet");
|
|
5
|
-
const ts_proto_descriptors_1 = require("ts-proto-descriptors");
|
|
6
5
|
const types_1 = require("./types");
|
|
7
6
|
const sourceInfo_1 = require("./sourceInfo");
|
|
8
7
|
const utils_1 = require("./utils");
|
|
@@ -185,6 +184,7 @@ function makeUtils(options) {
|
|
|
185
184
|
...makeDeepPartial(options, longs),
|
|
186
185
|
...makeTimestampMethods(options, longs),
|
|
187
186
|
...longs,
|
|
187
|
+
...makeWrappingUtils(),
|
|
188
188
|
};
|
|
189
189
|
}
|
|
190
190
|
exports.makeUtils = makeUtils;
|
|
@@ -241,6 +241,57 @@ function makeLongUtils(options, bytes) {
|
|
|
241
241
|
`);
|
|
242
242
|
return { numberToLong, longToNumber, longToString, longInit, Long };
|
|
243
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
|
+
}
|
|
244
295
|
function makeByteUtils() {
|
|
245
296
|
const globalThis = ts_poet_1.conditionalOutput('globalThis', ts_poet_1.code `
|
|
246
297
|
declare var self: any | undefined;
|
|
@@ -286,13 +337,15 @@ function makeDeepPartial(options, longs) {
|
|
|
286
337
|
`;
|
|
287
338
|
}
|
|
288
339
|
const maybeExport = options.exportCommonSymbols ? 'export' : '';
|
|
289
|
-
|
|
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 ` : '';
|
|
290
342
|
const keys = options.outputTypeRegistry ? ts_poet_1.code `Exclude<keyof T, '$type'>` : ts_poet_1.code `keyof T`;
|
|
291
343
|
// Based on the type from ts-essentials
|
|
292
344
|
const DeepPartial = ts_poet_1.conditionalOutput('DeepPartial', ts_poet_1.code `
|
|
293
|
-
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined
|
|
294
|
-
${maybeExport} type DeepPartial<T> =
|
|
345
|
+
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
346
|
+
${maybeExport} type DeepPartial<T> = T extends Builtin
|
|
295
347
|
? T
|
|
348
|
+
${maybeLong}
|
|
296
349
|
: T extends Array<infer U>
|
|
297
350
|
? Array<DeepPartial<U>>
|
|
298
351
|
: T extends ReadonlyArray<infer U>
|
|
@@ -527,8 +580,18 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
527
580
|
}
|
|
528
581
|
}
|
|
529
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
|
+
};
|
|
530
592
|
const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
|
|
531
|
-
|
|
593
|
+
const decoder = ts_poet_1.code `${type}.decode(reader, reader.uint32())`;
|
|
594
|
+
readSnippet = ts_poet_1.code `${unwrap(decoder)}`;
|
|
532
595
|
}
|
|
533
596
|
else if (types_1.isTimestamp(field) && (options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) {
|
|
534
597
|
const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
|
|
@@ -623,10 +686,19 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
623
686
|
writeSnippet = (place) => ts_poet_1.code `${type}.encode(${utils.toTimestamp}(${place}), writer.uint32(${tag}).fork()).ldelim()`;
|
|
624
687
|
}
|
|
625
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
|
+
};
|
|
626
699
|
const tag = ((field.number << 3) | 2) >>> 0;
|
|
627
700
|
const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
|
|
628
|
-
|
|
629
|
-
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()`;
|
|
630
702
|
}
|
|
631
703
|
else if (types_1.isMessage(field)) {
|
|
632
704
|
const tag = ((field.number << 3) | 2) >>> 0;
|
|
@@ -739,20 +811,6 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
739
811
|
fromJSON(${messageDesc.field.length > 0 ? 'object' : '_'}: any): ${fullName} {
|
|
740
812
|
const message = { ...base${fullName} } as ${fullName};
|
|
741
813
|
`);
|
|
742
|
-
// initialize all lists
|
|
743
|
-
messageDesc.field.filter(types_1.isRepeated).forEach((field) => {
|
|
744
|
-
const value = types_1.isMapType(ctx, messageDesc, field) ? '{}' : '[]';
|
|
745
|
-
const name = case_1.maybeSnakeToCamel(field.name, options);
|
|
746
|
-
chunks.push(ts_poet_1.code `message.${name} = ${value};`);
|
|
747
|
-
});
|
|
748
|
-
// initialize all buffers
|
|
749
|
-
messageDesc.field
|
|
750
|
-
.filter((field) => !types_1.isRepeated(field) && !types_1.isWithinOneOf(field) && types_1.isBytes(field))
|
|
751
|
-
.forEach((field) => {
|
|
752
|
-
const value = options.env === options_1.EnvOption.NODE ? 'Buffer.alloc(0)' : 'new Uint8Array()';
|
|
753
|
-
const name = case_1.maybeSnakeToCamel(field.name, options);
|
|
754
|
-
chunks.push(ts_poet_1.code `message.${name} = ${value};`);
|
|
755
|
-
});
|
|
756
814
|
// add a check for each incoming field
|
|
757
815
|
messageDesc.field.forEach((field) => {
|
|
758
816
|
const fieldName = case_1.maybeSnakeToCamel(field.name, options);
|
|
@@ -788,6 +846,9 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
788
846
|
(options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.TIMESTAMP)) {
|
|
789
847
|
return ts_poet_1.code `${utils.fromJsonTimestamp}(${from})`;
|
|
790
848
|
}
|
|
849
|
+
else if (types_1.isAnyValueType(field) || types_1.isStructType(field)) {
|
|
850
|
+
return ts_poet_1.code `${from}`;
|
|
851
|
+
}
|
|
791
852
|
else if (types_1.isValueType(ctx, field)) {
|
|
792
853
|
const valueType = types_1.valueTypeName(ctx, field.typeName);
|
|
793
854
|
if (types_1.isLongValueType(field) && options.forceLong === options_1.LongOption.LONG) {
|
|
@@ -796,6 +857,9 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
796
857
|
else if (types_1.isBytesValueType(field)) {
|
|
797
858
|
return ts_poet_1.code `new ${case_1.capitalize(valueType.toCodeString())}(${from})`;
|
|
798
859
|
}
|
|
860
|
+
else if (types_1.isListValueType(field)) {
|
|
861
|
+
return ts_poet_1.code `[...${from}]`;
|
|
862
|
+
}
|
|
799
863
|
else {
|
|
800
864
|
return ts_poet_1.code `${case_1.capitalize(valueType.toCodeString())}(${from})`;
|
|
801
865
|
}
|
|
@@ -813,6 +877,9 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
813
877
|
return ts_poet_1.code `${utils.bytesFromBase64}(${from} as string)`;
|
|
814
878
|
}
|
|
815
879
|
}
|
|
880
|
+
else if (types_1.isLong(valueType) && options.forceLong === options_1.LongOption.LONG) {
|
|
881
|
+
return ts_poet_1.code `Long.fromString(${from} as string)`;
|
|
882
|
+
}
|
|
816
883
|
else if (types_1.isEnum(valueType)) {
|
|
817
884
|
return ts_poet_1.code `${from} as number`;
|
|
818
885
|
}
|
|
@@ -832,6 +899,9 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
832
899
|
const type = types_1.basicTypeName(ctx, valueType);
|
|
833
900
|
return ts_poet_1.code `${from} as ${type}`;
|
|
834
901
|
}
|
|
902
|
+
else if (types_1.isAnyValueType(valueType)) {
|
|
903
|
+
return ts_poet_1.code `${from}`;
|
|
904
|
+
}
|
|
835
905
|
else {
|
|
836
906
|
const type = types_1.basicTypeName(ctx, valueType);
|
|
837
907
|
return ts_poet_1.code `${type}.fromJSON(${from})`;
|
|
@@ -847,42 +917,59 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
847
917
|
}
|
|
848
918
|
};
|
|
849
919
|
// and then use the snippet to handle repeated fields if necessary
|
|
850
|
-
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
851
920
|
if (types_1.isRepeated(field)) {
|
|
852
921
|
if (types_1.isMapType(ctx, messageDesc, field)) {
|
|
922
|
+
chunks.push(ts_poet_1.code `message.${fieldName} = {};`);
|
|
923
|
+
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
853
924
|
const i = maybeCastToNumber(ctx, messageDesc, field, 'key');
|
|
854
925
|
chunks.push(ts_poet_1.code `
|
|
855
926
|
Object.entries(object.${fieldName}).forEach(([key, value]) => {
|
|
856
927
|
message.${fieldName}[${i}] = ${readSnippet('value')};
|
|
857
928
|
});
|
|
929
|
+
`);
|
|
930
|
+
chunks.push(ts_poet_1.code `}`);
|
|
931
|
+
}
|
|
932
|
+
else if (types_1.isAnyValueType(field)) {
|
|
933
|
+
chunks.push(ts_poet_1.code `
|
|
934
|
+
message.${fieldName} = Array.isArray(object?.${fieldName}) ? [...object.${fieldName}] : [];
|
|
858
935
|
`);
|
|
859
936
|
}
|
|
860
937
|
else {
|
|
938
|
+
// Explicit `any` type required to make TS with noImplicitAny happy. `object` is also `any` here.
|
|
861
939
|
chunks.push(ts_poet_1.code `
|
|
862
|
-
|
|
863
|
-
message.${fieldName}.push(${readSnippet('e')});
|
|
864
|
-
}
|
|
940
|
+
message.${fieldName} = (object.${fieldName} ?? []).map((e: any) => ${readSnippet('e')});
|
|
865
941
|
`);
|
|
866
942
|
}
|
|
867
943
|
}
|
|
868
944
|
else if (types_1.isWithinOneOfThatShouldBeUnion(options, field)) {
|
|
945
|
+
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
869
946
|
const oneofName = case_1.maybeSnakeToCamel(messageDesc.oneofDecl[field.oneofIndex].name, options);
|
|
870
947
|
chunks.push(ts_poet_1.code `
|
|
871
948
|
message.${oneofName} = { $case: '${fieldName}', ${fieldName}: ${readSnippet(`object.${fieldName}`)} }
|
|
872
949
|
`);
|
|
950
|
+
chunks.push(ts_poet_1.code `}`);
|
|
873
951
|
}
|
|
874
|
-
else {
|
|
875
|
-
chunks.push(ts_poet_1.code `message.${fieldName} =
|
|
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
|
+
`);
|
|
876
964
|
}
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
965
|
+
else {
|
|
966
|
+
const fallback = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
|
967
|
+
chunks.push(ts_poet_1.code `
|
|
968
|
+
message.${fieldName} = (object.${fieldName} !== undefined && object.${fieldName} !== null)
|
|
969
|
+
? ${readSnippet(`object.${fieldName}`)}
|
|
970
|
+
: ${fallback};
|
|
971
|
+
`);
|
|
884
972
|
}
|
|
885
|
-
chunks.push(ts_poet_1.code `}`);
|
|
886
973
|
});
|
|
887
974
|
// and then wrap up the switch/while/return
|
|
888
975
|
chunks.push(ts_poet_1.code `return message`);
|
|
@@ -935,14 +1022,23 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
935
1022
|
else if (types_1.isTimestamp(valueType) && options.useDate === options_1.DateOption.TIMESTAMP) {
|
|
936
1023
|
return ts_poet_1.code `${utils.fromTimestamp}(${from}).toISOString()`;
|
|
937
1024
|
}
|
|
1025
|
+
else if (types_1.isLong(valueType) && options.forceLong === options_1.LongOption.LONG) {
|
|
1026
|
+
return ts_poet_1.code `${from}.toString()`;
|
|
1027
|
+
}
|
|
938
1028
|
else if (types_1.isScalar(valueType) || types_1.isValueType(ctx, valueType)) {
|
|
939
1029
|
return ts_poet_1.code `${from}`;
|
|
940
1030
|
}
|
|
1031
|
+
else if (types_1.isAnyValueType(valueType)) {
|
|
1032
|
+
return ts_poet_1.code `${from}`;
|
|
1033
|
+
}
|
|
941
1034
|
else {
|
|
942
1035
|
const type = types_1.basicTypeName(ctx, valueType);
|
|
943
1036
|
return ts_poet_1.code `${type}.toJSON(${from})`;
|
|
944
1037
|
}
|
|
945
1038
|
}
|
|
1039
|
+
else if (types_1.isAnyValueType(field)) {
|
|
1040
|
+
return ts_poet_1.code `${from}`;
|
|
1041
|
+
}
|
|
946
1042
|
else if (types_1.isMessage(field) && !types_1.isValueType(ctx, field) && !types_1.isMapType(ctx, messageDesc, field)) {
|
|
947
1043
|
const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
|
|
948
1044
|
return ts_poet_1.code `${from} ? ${type}.toJSON(${from}) : ${types_1.defaultValue(ctx, field)}`;
|
|
@@ -1012,7 +1108,10 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1012
1108
|
messageDesc.field.forEach((field) => {
|
|
1013
1109
|
const fieldName = case_1.maybeSnakeToCamel(field.name, options);
|
|
1014
1110
|
const readSnippet = (from) => {
|
|
1015
|
-
if (types_1.
|
|
1111
|
+
if ((types_1.isLong(field) || types_1.isLongValueType(field)) && options.forceLong === options_1.LongOption.LONG) {
|
|
1112
|
+
return ts_poet_1.code `Long.fromValue(${from})`;
|
|
1113
|
+
}
|
|
1114
|
+
else if (types_1.isPrimitive(field) ||
|
|
1016
1115
|
(types_1.isTimestamp(field) && (options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) ||
|
|
1017
1116
|
types_1.isValueType(ctx, field)) {
|
|
1018
1117
|
return ts_poet_1.code `${from}`;
|
|
@@ -1027,11 +1126,17 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1027
1126
|
else if (types_1.isEnum(valueType)) {
|
|
1028
1127
|
return ts_poet_1.code `${from} as number`;
|
|
1029
1128
|
}
|
|
1129
|
+
else if (types_1.isLong(valueType) && options.forceLong === options_1.LongOption.LONG) {
|
|
1130
|
+
return ts_poet_1.code `Long.fromValue(${from})`;
|
|
1131
|
+
}
|
|
1030
1132
|
else {
|
|
1031
1133
|
const cstr = case_1.capitalize(types_1.basicTypeName(ctx, valueType).toCodeString());
|
|
1032
1134
|
return ts_poet_1.code `${cstr}(${from})`;
|
|
1033
1135
|
}
|
|
1034
1136
|
}
|
|
1137
|
+
else if (types_1.isAnyValueType(valueType)) {
|
|
1138
|
+
return ts_poet_1.code `${from}`;
|
|
1139
|
+
}
|
|
1035
1140
|
else if (types_1.isTimestamp(valueType) &&
|
|
1036
1141
|
(options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) {
|
|
1037
1142
|
return ts_poet_1.code `${from}`;
|
|
@@ -1044,6 +1149,9 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1044
1149
|
return ts_poet_1.code `${type}.fromPartial(${from})`;
|
|
1045
1150
|
}
|
|
1046
1151
|
}
|
|
1152
|
+
else if (types_1.isAnyValueType(field)) {
|
|
1153
|
+
return ts_poet_1.code `${from}`;
|
|
1154
|
+
}
|
|
1047
1155
|
else {
|
|
1048
1156
|
const type = types_1.basicTypeName(ctx, field);
|
|
1049
1157
|
return ts_poet_1.code `${type}.fromPartial(${from})`;
|
|
@@ -1055,11 +1163,9 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1055
1163
|
};
|
|
1056
1164
|
// and then use the snippet to handle repeated fields if necessary
|
|
1057
1165
|
if (types_1.isRepeated(field)) {
|
|
1058
|
-
const value = types_1.isMapType(ctx, messageDesc, field) ? '{}' : '[]';
|
|
1059
|
-
const name = case_1.maybeSnakeToCamel(field.name, options);
|
|
1060
|
-
chunks.push(ts_poet_1.code `message.${name} = ${value};`);
|
|
1061
|
-
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
1062
1166
|
if (types_1.isMapType(ctx, messageDesc, field)) {
|
|
1167
|
+
chunks.push(ts_poet_1.code `message.${fieldName} = {};`);
|
|
1168
|
+
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
1063
1169
|
const i = maybeCastToNumber(ctx, messageDesc, field, 'key');
|
|
1064
1170
|
chunks.push(ts_poet_1.code `
|
|
1065
1171
|
Object.entries(object.${fieldName}).forEach(([key, value]) => {
|
|
@@ -1068,15 +1174,13 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1068
1174
|
}
|
|
1069
1175
|
});
|
|
1070
1176
|
`);
|
|
1177
|
+
chunks.push(ts_poet_1.code `}`);
|
|
1071
1178
|
}
|
|
1072
1179
|
else {
|
|
1073
1180
|
chunks.push(ts_poet_1.code `
|
|
1074
|
-
|
|
1075
|
-
message.${fieldName}.push(${readSnippet('e')});
|
|
1076
|
-
}
|
|
1181
|
+
message.${fieldName} = (object.${fieldName} ?? []).map((e) => ${readSnippet('e')});
|
|
1077
1182
|
`);
|
|
1078
1183
|
}
|
|
1079
|
-
chunks.push(ts_poet_1.code `}`);
|
|
1080
1184
|
}
|
|
1081
1185
|
else if (types_1.isWithinOneOfThatShouldBeUnion(options, field)) {
|
|
1082
1186
|
let oneofName = case_1.maybeSnakeToCamel(messageDesc.oneofDecl[field.oneofIndex].name, options);
|
|
@@ -1091,30 +1195,18 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1091
1195
|
}
|
|
1092
1196
|
`);
|
|
1093
1197
|
}
|
|
1094
|
-
else if ((
|
|
1095
|
-
const v = readSnippet(`object.${fieldName}`);
|
|
1096
|
-
const type = types_1.basicTypeName(ctx, field);
|
|
1097
|
-
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
1098
|
-
chunks.push(ts_poet_1.code `message.${fieldName} = ${v} as ${type};`);
|
|
1099
|
-
chunks.push(ts_poet_1.code `} else {`);
|
|
1100
|
-
const fallback = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
|
1101
|
-
chunks.push(ts_poet_1.code `message.${fieldName} = ${fallback}`);
|
|
1102
|
-
chunks.push(ts_poet_1.code `}`);
|
|
1103
|
-
}
|
|
1104
|
-
else if (types_1.isPrimitive(field) ||
|
|
1105
|
-
(types_1.isTimestamp(field) && (options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) ||
|
|
1106
|
-
types_1.isValueType(ctx, field)) {
|
|
1198
|
+
else if (readSnippet(`x`).toCodeString() == 'x') {
|
|
1107
1199
|
// An optimized case of the else below that works when `readSnippet` returns the plain input
|
|
1108
1200
|
const fallback = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
|
1109
1201
|
chunks.push(ts_poet_1.code `message.${fieldName} = object.${fieldName} ?? ${fallback};`);
|
|
1110
1202
|
}
|
|
1111
1203
|
else {
|
|
1112
|
-
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
1113
|
-
chunks.push(ts_poet_1.code `message.${fieldName} = ${readSnippet(`object.${fieldName}`)};`);
|
|
1114
|
-
chunks.push(ts_poet_1.code `} else {`);
|
|
1115
1204
|
const fallback = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
|
1116
|
-
chunks.push(ts_poet_1.code `
|
|
1117
|
-
|
|
1205
|
+
chunks.push(ts_poet_1.code `
|
|
1206
|
+
message.${fieldName} = (object.${fieldName} !== undefined && object.${fieldName} !== null)
|
|
1207
|
+
? ${readSnippet(`object.${fieldName}`)}
|
|
1208
|
+
: ${fallback};
|
|
1209
|
+
`);
|
|
1118
1210
|
}
|
|
1119
1211
|
});
|
|
1120
1212
|
// and then wrap up the switch/while/return
|
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:
|