ts-proto 1.114.7 → 1.115.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 +21 -0
- package/README.markdown +28 -27
- package/build/options.js +23 -2
- package/build/types.js +10 -2
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
## [1.115.2](https://github.com/stephenh/ts-proto/compare/v1.115.1...v1.115.2) (2022-06-03)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* simplify handling useJsonWireFormat=true and fix onlyTypes=true ([#583](https://github.com/stephenh/ts-proto/issues/583)) ([6e7f938](https://github.com/stephenh/ts-proto/commit/6e7f9387d144f506ded982604f32981ac5e327de))
|
|
7
|
+
|
|
8
|
+
## [1.115.1](https://github.com/stephenh/ts-proto/compare/v1.115.0...v1.115.1) (2022-06-02)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* Bump protobufjs. ([#585](https://github.com/stephenh/ts-proto/issues/585)) ([ba6b85d](https://github.com/stephenh/ts-proto/commit/ba6b85d9d5b7ce191dce898c462cf164a6b1e308))
|
|
14
|
+
|
|
15
|
+
# [1.115.0](https://github.com/stephenh/ts-proto/compare/v1.114.7...v1.115.0) (2022-06-02)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* added option 'useJsonWireFormat' ([#576](https://github.com/stephenh/ts-proto/issues/576)) ([a71b145](https://github.com/stephenh/ts-proto/commit/a71b145c81136b8d8e3681b6753146d3ceeff179)), closes [#571](https://github.com/stephenh/ts-proto/issues/571)
|
|
21
|
+
|
|
1
22
|
## [1.114.7](https://github.com/stephenh/ts-proto/compare/v1.114.6...v1.114.7) (2022-05-28)
|
|
2
23
|
|
|
3
24
|
|
package/README.markdown
CHANGED
|
@@ -104,7 +104,7 @@ You can also use the official plugin published to the Buf Registry.
|
|
|
104
104
|
```yaml
|
|
105
105
|
version: v1
|
|
106
106
|
plugins:
|
|
107
|
-
- remote: buf.build/
|
|
107
|
+
- remote: buf.build/stephenh/plugins/ts-proto
|
|
108
108
|
out: ../gen/ts
|
|
109
109
|
```
|
|
110
110
|
|
|
@@ -274,34 +274,36 @@ Generated code will be placed in the Gradle build directory.
|
|
|
274
274
|
|
|
275
275
|
Currently `browser` doesn't have any specific behavior other than being "not `node`". It probably will soon/at some point.
|
|
276
276
|
|
|
277
|
-
- With `--ts_proto_opt=useOptionals=
|
|
277
|
+
- With `--ts_proto_opt=useOptionals=messages` (for message fields) or `--ts_proto_opt=useOptionals=all` (for message and scalar fields), fields are declared as optional keys, e.g. `field?: Message` instead of the default `field: Message | undefined`.
|
|
278
278
|
|
|
279
|
-
ts-proto defaults to `useOptionals=
|
|
279
|
+
ts-proto defaults to `useOptionals=none` because it:
|
|
280
|
+
|
|
281
|
+
1. Prevents typos when initializing messages, and
|
|
282
|
+
2. Provides the most consistent API to readers
|
|
283
|
+
3. Ensures production messages are properly initialized with all fields.
|
|
280
284
|
|
|
281
|
-
|
|
282
|
-
interface SomeMessage {
|
|
283
|
-
firstName: string | undefined;
|
|
284
|
-
lastName: string | undefined;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const data = { firstName: 'a', lastTypo: 'b' };
|
|
285
|
+
For typo prevention, optional fields make it easy for extra fields to slip into a message (until we get [Exact Types](https://github.com/microsoft/TypeScript/issues/12936)), i.e.:
|
|
288
286
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
287
|
+
```typescript
|
|
288
|
+
interface SomeMessage {
|
|
289
|
+
firstName: string | undefined;
|
|
290
|
+
lastName: string | undefined;
|
|
291
|
+
}
|
|
292
|
+
// Declared with a typo
|
|
293
|
+
const data = { firstName: 'a', lastTypo: 'b' };
|
|
294
|
+
// With useOptionals=none, this correctly fails to compile; if `lastName` was optional, it would not
|
|
295
|
+
const message: SomeMessage = { ...data };
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
For a consistent API, if `SomeMessage.lastName` is optional `lastName?`, then readers have to check _two_ empty conditions: a) is `lastName` `undefined` (b/c it was created in-memory and left unset), or b) is `lastName` empty string (b/c we read `SomeMessage` off the wire and correctly set `lastName` to empty string)?
|
|
295
299
|
|
|
296
|
-
|
|
300
|
+
For ensuring proper initialization, if later `SomeMessage.middleInitial` is added, but it's marked as optional `middleInitial?`, you may have many call sites in production code that _should_ now be passing `middleInitial` to create a valid `SomeMessage`, but are not.
|
|
297
301
|
|
|
298
|
-
|
|
302
|
+
So, between typo-prevention, reader inconsistency, and proper initialization, ts-proto recommends using `useOptionals=none` as the "most safe" option.
|
|
299
303
|
|
|
300
|
-
|
|
304
|
+
All that said, this approach does require writers/creators to set every field (although `fromPartial` is meant to address this), so if you still want to have optional fields, you can set `useOptionals=messages` or `useOptionals=all`.
|
|
301
305
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
Note that RPC methods, like `service.ping({ key: ... })`, accept `DeepPartial` versions of the request messages, because of the same rationale that it makes it easy for the writer call-site to get default values for free, and because the "reader" is the internal ts-proto serialization code, it can apply the defaults as necessary.
|
|
306
|
+
(See [this issue](https://github.com/stephenh/ts-proto/issues/120#issuecomment-678375833) and [this issue](https://github.com/stephenh/ts-proto/issues/397#issuecomment-977259118) for discussions on `useOptional`.)
|
|
305
307
|
|
|
306
308
|
- With `--ts_proto_opt=exportCommonSymbols=false`, utility types like `DeepPartial` won't be `export`d.
|
|
307
309
|
|
|
@@ -394,7 +396,7 @@ Generated code will be placed in the Gradle build directory.
|
|
|
394
396
|
|
|
395
397
|
- With `--ts_proto_opt=onlyTypes=true`, only types will be emitted, and imports for `long` and `protobufjs/minimal` will be excluded.
|
|
396
398
|
|
|
397
|
-
|
|
399
|
+
This is the same as setting `outputJsonMethods=false,outputEncodeMethods=false,outputClientImpl=false,nestJs=false`
|
|
398
400
|
|
|
399
401
|
- With `--ts_proto_opt=usePrototypeForDefaults=true`, the generated code will wrap new objects with `Object.create`.
|
|
400
402
|
|
|
@@ -404,11 +406,10 @@ Generated code will be placed in the Gradle build directory.
|
|
|
404
406
|
|
|
405
407
|
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.
|
|
406
408
|
|
|
407
|
-
|
|
408
|
-
|
|
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.:
|
|
409
|
+
- With `--ts_proto_opt=useJsonWireFormat=true`, the generated code will reflect the JSON representation of Protobuf messages.
|
|
410
410
|
|
|
411
|
-
|
|
411
|
+
Requires `onlyTypes=true`. Implies `useDate=string` and `stringEnums=true`. This option is to generate types that can be directly used with marshalling/unmarshalling Protobuf messages serialized as JSON.
|
|
412
|
+
You may also want to set `useOptionals=all`, as gRPC gateways are not required to send default value for scalar values.
|
|
412
413
|
|
|
413
414
|
### NestJS Support
|
|
414
415
|
|
package/build/options.js
CHANGED
|
@@ -67,6 +67,7 @@ function defaultOptions() {
|
|
|
67
67
|
useExactTypes: true,
|
|
68
68
|
unknownFields: false,
|
|
69
69
|
usePrototypeForDefaults: false,
|
|
70
|
+
useJsonWireFormat: false,
|
|
70
71
|
};
|
|
71
72
|
}
|
|
72
73
|
exports.defaultOptions = defaultOptions;
|
|
@@ -87,8 +88,17 @@ function optionsFromParameter(parameter) {
|
|
|
87
88
|
}
|
|
88
89
|
Object.assign(options, parsed);
|
|
89
90
|
}
|
|
90
|
-
//
|
|
91
|
-
if (
|
|
91
|
+
// onlyTypes=true implies outputJsonMethods=false,outputEncodeMethods=false,outputClientImpl=false,nestJs=false
|
|
92
|
+
if (options.onlyTypes) {
|
|
93
|
+
options.outputJsonMethods = false;
|
|
94
|
+
options.outputEncodeMethods = false;
|
|
95
|
+
options.outputClientImpl = false;
|
|
96
|
+
options.nestJs = false;
|
|
97
|
+
}
|
|
98
|
+
else if (!options.outputJsonMethods &&
|
|
99
|
+
!options.outputEncodeMethods &&
|
|
100
|
+
!options.outputClientImpl &&
|
|
101
|
+
!options.nestJs) {
|
|
92
102
|
options.onlyTypes = true;
|
|
93
103
|
}
|
|
94
104
|
// Treat forceLong=true as LONG
|
|
@@ -123,6 +133,17 @@ function optionsFromParameter(parameter) {
|
|
|
123
133
|
else if (typeof options.snakeToCamel === 'string') {
|
|
124
134
|
options.snakeToCamel = [options.snakeToCamel];
|
|
125
135
|
}
|
|
136
|
+
if (options.useJsonWireFormat) {
|
|
137
|
+
if (!options.onlyTypes) {
|
|
138
|
+
// useJsonWireFormat requires onlyTypes=true
|
|
139
|
+
options.useJsonWireFormat = false;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
// useJsonWireFormat implies stringEnums=true and useDate=string
|
|
143
|
+
options.stringEnums = true;
|
|
144
|
+
options.useDate = DateOption.STRING;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
126
147
|
return options;
|
|
127
148
|
}
|
|
128
149
|
exports.optionsFromParameter = optionsFromParameter;
|
package/build/types.js
CHANGED
|
@@ -451,7 +451,11 @@ function valueTypeName(ctx, typeName) {
|
|
|
451
451
|
case '.google.protobuf.BoolValue':
|
|
452
452
|
return ts_poet_1.code `boolean`;
|
|
453
453
|
case '.google.protobuf.BytesValue':
|
|
454
|
-
return ctx.options.env === options_1.EnvOption.NODE
|
|
454
|
+
return ctx.options.env === options_1.EnvOption.NODE
|
|
455
|
+
? ts_poet_1.code `Buffer`
|
|
456
|
+
: ctx.options.useJsonWireFormat
|
|
457
|
+
? ts_poet_1.code `string`
|
|
458
|
+
: ts_poet_1.code `Uint8Array`;
|
|
455
459
|
case '.google.protobuf.ListValue':
|
|
456
460
|
return ts_poet_1.code `Array<any>`;
|
|
457
461
|
case '.google.protobuf.Value':
|
|
@@ -459,7 +463,11 @@ function valueTypeName(ctx, typeName) {
|
|
|
459
463
|
case '.google.protobuf.Struct':
|
|
460
464
|
return ts_poet_1.code `{[key: string]: any}`;
|
|
461
465
|
case '.google.protobuf.FieldMask':
|
|
462
|
-
return ts_poet_1.code `string[]`;
|
|
466
|
+
return ctx.options.useJsonWireFormat ? ts_poet_1.code `string` : ts_poet_1.code `string[]`;
|
|
467
|
+
case '.google.protobuf.Duration':
|
|
468
|
+
return ctx.options.useJsonWireFormat ? ts_poet_1.code `string` : undefined;
|
|
469
|
+
case '.google.protobuf.Timestamp':
|
|
470
|
+
return ctx.options.useJsonWireFormat ? ts_poet_1.code `string` : undefined;
|
|
463
471
|
default:
|
|
464
472
|
return undefined;
|
|
465
473
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-proto",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.115.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/plugin.js",
|
|
6
6
|
"repository": "github:stephenh/ts-proto",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
"@types/object-hash": "^1.3.0",
|
|
66
66
|
"dataloader": "^1.4.0",
|
|
67
67
|
"object-hash": "^1.3.1",
|
|
68
|
-
"protobufjs": "^6.
|
|
69
|
-
"ts-poet": "^4.11.0",
|
|
68
|
+
"protobufjs": "^6.11.3",
|
|
69
|
+
"ts-poet": "^t 4.11.0",
|
|
70
70
|
"ts-proto-descriptors": "1.6.0"
|
|
71
71
|
}
|
|
72
72
|
}
|