ts-proto 1.90.1 → 1.92.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 +33 -0
- package/README.markdown +81 -14
- package/build/generate-type-registry.js +1 -1
- package/build/main.js +25 -14
- package/package.json +12 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
## [1.92.2](https://github.com/stephenh/ts-proto/compare/v1.92.1...v1.92.2) (2021-12-08)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* noImplicitReturns error in Value.unwrap ([#436](https://github.com/stephenh/ts-proto/issues/436)) ([2d7a5d0](https://github.com/stephenh/ts-proto/commit/2d7a5d04c72ace58fa3a6745c3857f6cc0468543)), closes [#432](https://github.com/stephenh/ts-proto/issues/432)
|
|
7
|
+
|
|
8
|
+
## [1.92.1](https://github.com/stephenh/ts-proto/compare/v1.92.0...v1.92.1) (2021-12-02)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* Respect stringEnums option in wrap function ([#420](https://github.com/stephenh/ts-proto/issues/420)) ([7adf90c](https://github.com/stephenh/ts-proto/commit/7adf90c23c46950bcf457b317764393ff4af2bf2))
|
|
14
|
+
|
|
15
|
+
# [1.92.0](https://github.com/stephenh/ts-proto/compare/v1.91.0...v1.92.0) (2021-11-28)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* Use exact types for fromPartial ([#412](https://github.com/stephenh/ts-proto/issues/412)) ([808f8a7](https://github.com/stephenh/ts-proto/commit/808f8a7a77d56f65dd4a4643dd66158f106ab755)), closes [#156](https://github.com/stephenh/ts-proto/issues/156)
|
|
21
|
+
|
|
22
|
+
# [1.91.0](https://github.com/stephenh/ts-proto/compare/v1.90.1...v1.91.0) (2021-11-27)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* use Long.fromValue instead of Long.fromString for improved robustness regarding already parsed objects ([#405](https://github.com/stephenh/ts-proto/issues/405)) ([7bdc3ee](https://github.com/stephenh/ts-proto/commit/7bdc3eee05ed1318e18e27aa7d5bb2680060f8b6))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Features
|
|
31
|
+
|
|
32
|
+
* Include dockerized protoc ([#404](https://github.com/stephenh/ts-proto/issues/404)) ([7564a78](https://github.com/stephenh/ts-proto/commit/7564a7887ccd0bb80cac19d313ee9bd8daae778d))
|
|
33
|
+
|
|
1
34
|
## [1.90.1](https://github.com/stephenh/ts-proto/compare/v1.90.0...v1.90.1) (2021-11-27)
|
|
2
35
|
|
|
3
36
|
|
package/README.markdown
CHANGED
|
@@ -9,25 +9,29 @@
|
|
|
9
9
|
|
|
10
10
|
## Table of contents
|
|
11
11
|
|
|
12
|
+
- [ts-proto](#ts-proto)
|
|
13
|
+
- [Table of contents](#table-of-contents)
|
|
14
|
+
- [Overview](#overview)
|
|
12
15
|
- [QuickStart](#quickstart)
|
|
13
16
|
- [Goals](#goals)
|
|
14
17
|
- [Example Types](#example-types)
|
|
15
18
|
- [Highlights](#highlights)
|
|
16
19
|
- [Auto-Batching / N+1 Prevention](#auto-batching--n1-prevention)
|
|
17
20
|
- [Usage](#usage)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
- [
|
|
21
|
+
- [Supported options](#supported-options)
|
|
22
|
+
- [Only Types](#only-types)
|
|
23
|
+
- [NestJS Support](#nestjs-support)
|
|
24
|
+
- [Watch Mode](#watch-mode)
|
|
25
|
+
- [Sponsors](#sponsors)
|
|
26
|
+
- [Development](#development)
|
|
22
27
|
- [Assumptions](#assumptions)
|
|
23
28
|
- [Todo](#todo)
|
|
24
29
|
- [OneOf Handling](#oneof-handling)
|
|
25
|
-
- [Default
|
|
30
|
+
- [Default values and unset fields](#default-values-and-unset-fields)
|
|
26
31
|
- [Well-Known Types](#well-known-types)
|
|
27
32
|
- [Wrapper Types](#wrapper-types)
|
|
28
33
|
- [JSON Types (Struct Types)](#json-types-struct-types)
|
|
29
|
-
- [
|
|
30
|
-
- [Wrapper Types](#wrapper-types)
|
|
34
|
+
- [Timestamp](#timestamp)
|
|
31
35
|
- [Number Types](#number-types)
|
|
32
36
|
- [Current Status of Optional Values](#current-status-of-optional-values)
|
|
33
37
|
|
|
@@ -329,7 +333,7 @@ Generated code will be placed in the Gradle build directory.
|
|
|
329
333
|
|
|
330
334
|
Note that `addGrpcMetadata`, `addNestjsRestParameter` and `returnObservable` will still be false.
|
|
331
335
|
|
|
332
|
-
- With `--ts_proto_opt=useDate=false`, fields of type `google.protobuf.Timestamp` will not be mapped to type `Date` in the generated types. See [
|
|
336
|
+
- With `--ts_proto_opt=useDate=false`, fields of type `google.protobuf.Timestamp` will not be mapped to type `Date` in the generated types. See [Timestamp](#timestamp) for more details.
|
|
333
337
|
|
|
334
338
|
- With `--ts_proto_opt=outputSchema=true`, meta typings will be generated that can later be used in other code generators.
|
|
335
339
|
|
|
@@ -337,7 +341,7 @@ Generated code will be placed in the Gradle build directory.
|
|
|
337
341
|
|
|
338
342
|
- With `--ts_proto_opt=outputServices=grpc-js`, ts-proto will output service definitions and server / client stubs in [grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) format.
|
|
339
343
|
|
|
340
|
-
- With `--ts_proto_opt=outputServices=generic-definitions`, ts-proto will output generic (framework-agnostic) service definitions.
|
|
344
|
+
- With `--ts_proto_opt=outputServices=generic-definitions`, ts-proto will output generic (framework-agnostic) service definitions. These definitions contain descriptors for each method with links to request and response types, which allows to generate server and client stubs at runtime, and also generate strong types for them at compile time. An example of a library that uses this approach is [nice-grpc](https://github.com/deeplay-io/nice-grpc).
|
|
341
345
|
|
|
342
346
|
- With `--ts_proto_opt=outputServices=false`, or `=none`, ts-proto will output NO service definitions.
|
|
343
347
|
|
|
@@ -354,6 +358,15 @@ If you're looking for `ts-proto` to generate only types for your Protobuf types
|
|
|
354
358
|
|
|
355
359
|
We have a great way of working together with [nestjs](https://docs.nestjs.com/microservices/grpc). `ts-proto` generates `interfaces` and `decorators` for you controller, client. For more information see the [nestjs readme](NESTJS.markdown).
|
|
356
360
|
|
|
361
|
+
### Watch Mode
|
|
362
|
+
|
|
363
|
+
If you want to run `ts-proto` on every change of a proto file, you'll need to use a tool like [chokidar-cli](https://www.npmjs.com/package/chokidar-cli) and use it as a script in `package.json`:
|
|
364
|
+
|
|
365
|
+
```json
|
|
366
|
+
"proto:generate": "protoc --ts_proto_out=. ./<proto_path>/<proto_name>.proto --ts_proto_opt=esModuleInterop=true",
|
|
367
|
+
"proto:watch": "chokidar \"**/*.proto\" -c \"npm run proto:generate\""
|
|
368
|
+
```
|
|
369
|
+
|
|
357
370
|
# Sponsors
|
|
358
371
|
|
|
359
372
|
Kudos to our sponsors:
|
|
@@ -362,15 +375,69 @@ Kudos to our sponsors:
|
|
|
362
375
|
|
|
363
376
|
If you need ts-proto customizations or priority support for your company, you can ping me at [via email](mailto:stephen.haberman@gmail.com).
|
|
364
377
|
|
|
365
|
-
#
|
|
378
|
+
# Development
|
|
379
|
+
|
|
380
|
+
**Requirements**
|
|
381
|
+
|
|
382
|
+
- [Docker](https://www.docker.com) or [protoc](https://github.com/protocolbuffers/protobuf/releases) v3.19.1
|
|
383
|
+
- `yarn` — `npm install -g yarn`
|
|
384
|
+
|
|
385
|
+
**Setup**
|
|
386
|
+
|
|
387
|
+
The commands below assume you have **Docker** installed. To use a **local** copy of `protoc` without docker, use commands suffixed with `:local`
|
|
388
|
+
|
|
389
|
+
- Check out the [repository]() for the latest code.
|
|
390
|
+
- Run `yarn install` to install the dependencies.
|
|
391
|
+
- Run `yarn build:test` or `yarn build:test:local` to generate the test files.
|
|
392
|
+
> _This runs the following commands:_
|
|
393
|
+
> - `proto2bin` — Converts integration test `.proto` files to `.bin`.
|
|
394
|
+
> - `bin2ts` — Runs `ts-proto` on the `.bin` files to generate `.ts` files.
|
|
395
|
+
> - `proto2pbjs` — Generates a reference implementation using `pbjs` for testing compatibility.
|
|
396
|
+
- Run `yarn test`
|
|
397
|
+
|
|
398
|
+
**Workflow**
|
|
366
399
|
|
|
367
|
-
|
|
400
|
+
- Modifying the plugin implementation:
|
|
401
|
+
- Run `yarn bin2ts` or `yarn bin2ts:local`.
|
|
402
|
+
_Since the proto files were not changed, you only need to regenerate the typescript files._
|
|
403
|
+
- Run `yarn test` to verify the typescript files are compatible with the reference implementation, and pass other tests.
|
|
404
|
+
- Updating or adding `.proto` files in the integration directory:
|
|
405
|
+
- Run `yarn build:test` to regenerate the integration test files.
|
|
406
|
+
- Run `yarn test` to retest.
|
|
368
407
|
|
|
369
|
-
|
|
408
|
+
**Contributing**
|
|
370
409
|
|
|
371
|
-
|
|
410
|
+
- Run `yarn build:test` and `yarn test` to make sure everything works.
|
|
411
|
+
- Run `yarn prettier` to format the typescript files.
|
|
412
|
+
- Commit the changes:
|
|
413
|
+
- Also include the generated `.bin` files for the tests where you added or modified `.proto` files.
|
|
414
|
+
> These are checked into git so that the test suite can run without having to invoke the `protoc` build chain.
|
|
415
|
+
- Also include the generated `.ts` files.
|
|
416
|
+
- Create a pull request
|
|
417
|
+
|
|
418
|
+
**Dockerized Protoc**
|
|
419
|
+
|
|
420
|
+
The repository includes a dockerized version of `protoc`, which is configured in [docker-compose.yml](docker-compose.yml).
|
|
421
|
+
|
|
422
|
+
It can be useful in case you want to manually invoke the plugin with a known version of `protoc`.
|
|
423
|
+
|
|
424
|
+
Usage:
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
# Include the protoc alias in your shell.
|
|
428
|
+
. aliases.sh
|
|
429
|
+
|
|
430
|
+
# Run protoc as usual. The ts-proto directory is available in /ts-proto.
|
|
431
|
+
protoc --plugin=/ts-proto/protoc-gen-ts_proto --ts_proto_out=./output -I=./protos ./protoc/*.proto
|
|
432
|
+
|
|
433
|
+
# Or use the ts-protoc alias which specifies the plugin path for you.
|
|
434
|
+
ts-protoc --ts_proto_out=./output -I=./protos ./protoc/*.proto
|
|
435
|
+
```
|
|
372
436
|
|
|
373
|
-
|
|
437
|
+
- All paths must be relative paths _within_ the current working directory of the host. `../` is not allowed
|
|
438
|
+
- Within the docker container, the absolute path to the project root is `/ts-proto`
|
|
439
|
+
- The container mounts the current working directory in `/host`, and sets it as its working directory.
|
|
440
|
+
- Once `aliases.sh` is sourced, you can use the `protoc` command in any folder.
|
|
374
441
|
|
|
375
442
|
# Assumptions
|
|
376
443
|
|
|
@@ -13,7 +13,7 @@ function generateTypeRegistry(ctx) {
|
|
|
13
13
|
chunks.push(ts_poet_1.code `
|
|
14
14
|
export const messageTypeRegistry = new Map<string, MessageType>();
|
|
15
15
|
`);
|
|
16
|
-
chunks.push(ts_poet_1.code
|
|
16
|
+
chunks.push(ts_poet_1.code ` ${ctx.utils.Builtin.ifUsed} ${ctx.utils.DeepPartial.ifUsed}`);
|
|
17
17
|
return ts_poet_1.joinCode(chunks, { on: '\n\n' });
|
|
18
18
|
}
|
|
19
19
|
exports.generateTypeRegistry = generateTypeRegistry;
|
package/build/main.js
CHANGED
|
@@ -289,11 +289,20 @@ function makeDeepPartial(options, longs) {
|
|
|
289
289
|
const maybeExport = options.exportCommonSymbols ? 'export' : '';
|
|
290
290
|
// Allow passing longs as numbers or strings, nad we'll convert them
|
|
291
291
|
const maybeLong = options.forceLong === options_1.LongOption.LONG ? ts_poet_1.code ` : T extends ${longs.Long} ? string | number | Long ` : '';
|
|
292
|
-
const
|
|
292
|
+
const Builtin = ts_poet_1.conditionalOutput('Builtin', ts_poet_1.code `type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;`);
|
|
293
|
+
// Based on https://github.com/sindresorhus/type-fest/pull/259
|
|
294
|
+
const maybeExcludeType = options.outputTypeRegistry ? `| '$type'` : '';
|
|
295
|
+
const Exact = ts_poet_1.conditionalOutput('Exact', ts_poet_1.code `
|
|
296
|
+
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
|
297
|
+
${maybeExport} type Exact<P, I extends P> = P extends ${Builtin}
|
|
298
|
+
? P
|
|
299
|
+
: P &
|
|
300
|
+
{ [K in keyof P]: Exact<P[K], I[K]> } & Record<Exclude<keyof I, KeysOfUnion<P> ${maybeExcludeType}>, never>;
|
|
301
|
+
`);
|
|
293
302
|
// Based on the type from ts-essentials
|
|
303
|
+
const keys = options.outputTypeRegistry ? ts_poet_1.code `Exclude<keyof T, '$type'>` : ts_poet_1.code `keyof T`;
|
|
294
304
|
const DeepPartial = ts_poet_1.conditionalOutput('DeepPartial', ts_poet_1.code `
|
|
295
|
-
type
|
|
296
|
-
${maybeExport} type DeepPartial<T> = T extends Builtin
|
|
305
|
+
${maybeExport} type DeepPartial<T> = T extends ${Builtin}
|
|
297
306
|
? T
|
|
298
307
|
${maybeLong}
|
|
299
308
|
: T extends Array<infer U>
|
|
@@ -304,7 +313,7 @@ function makeDeepPartial(options, longs) {
|
|
|
304
313
|
? { [K in ${keys}]?: DeepPartial<T[K]> }
|
|
305
314
|
: Partial<T>;
|
|
306
315
|
`);
|
|
307
|
-
return { DeepPartial };
|
|
316
|
+
return { Builtin, DeepPartial, Exact };
|
|
308
317
|
}
|
|
309
318
|
function makeTimestampMethods(options, longs) {
|
|
310
319
|
const Timestamp = ts_poet_1.imp('Timestamp@./google/protobuf/timestamp');
|
|
@@ -823,7 +832,7 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
823
832
|
}
|
|
824
833
|
}
|
|
825
834
|
else if (types_1.isLong(valueType) && options.forceLong === options_1.LongOption.LONG) {
|
|
826
|
-
return ts_poet_1.code `Long.
|
|
835
|
+
return ts_poet_1.code `Long.fromValue(${from} as Long | string)`;
|
|
827
836
|
}
|
|
828
837
|
else if (types_1.isEnum(valueType)) {
|
|
829
838
|
return ts_poet_1.code `${from} as number`;
|
|
@@ -1045,8 +1054,9 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1045
1054
|
const chunks = [];
|
|
1046
1055
|
const Timestamp = ts_poet_1.imp('Timestamp@./google/protobuf/timestamp');
|
|
1047
1056
|
// create the basic function declaration
|
|
1057
|
+
const paramName = messageDesc.field.length > 0 ? 'object' : '_';
|
|
1048
1058
|
chunks.push(ts_poet_1.code `
|
|
1049
|
-
fromPartial
|
|
1059
|
+
fromPartial<I extends ${utils.Exact}<${utils.DeepPartial}<${fullName}>, I>>(${paramName}: I): ${fullName} {
|
|
1050
1060
|
const message = { ...base${fullName} } as ${fullName};
|
|
1051
1061
|
`);
|
|
1052
1062
|
// add a check for each incoming field
|
|
@@ -1122,7 +1132,7 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1122
1132
|
}
|
|
1123
1133
|
else {
|
|
1124
1134
|
chunks.push(ts_poet_1.code `
|
|
1125
|
-
message.${fieldName} =
|
|
1135
|
+
message.${fieldName} = object.${fieldName}?.map((e) => ${readSnippet('e')}) || [];
|
|
1126
1136
|
`);
|
|
1127
1137
|
}
|
|
1128
1138
|
}
|
|
@@ -1174,7 +1184,7 @@ function generateWrap(fullProtoTypeName) {
|
|
|
1174
1184
|
if (types_1.isAnyValueTypeName(fullProtoTypeName)) {
|
|
1175
1185
|
chunks.push(ts_poet_1.code `wrap(value: any): Value {
|
|
1176
1186
|
if (value === null) {
|
|
1177
|
-
return {nullValue:
|
|
1187
|
+
return {nullValue: NullValue.NULL_VALUE} as Value;
|
|
1178
1188
|
} else if (typeof value === 'boolean') {
|
|
1179
1189
|
return {boolValue: value} as Value;
|
|
1180
1190
|
} else if (typeof value === 'number') {
|
|
@@ -1212,19 +1222,20 @@ function generateUnwrap(fullProtoTypeName) {
|
|
|
1212
1222
|
}
|
|
1213
1223
|
if (types_1.isAnyValueTypeName(fullProtoTypeName)) {
|
|
1214
1224
|
chunks.push(ts_poet_1.code `unwrap(message: Value): string | number | boolean | Object | null | Array<any> | undefined {
|
|
1215
|
-
if (message
|
|
1225
|
+
if (message?.stringValue !== undefined) {
|
|
1216
1226
|
return message.stringValue;
|
|
1217
|
-
} else if (message
|
|
1227
|
+
} else if (message?.numberValue !== undefined) {
|
|
1218
1228
|
return message.numberValue;
|
|
1219
|
-
} else if (message
|
|
1229
|
+
} else if (message?.boolValue !== undefined) {
|
|
1220
1230
|
return message.boolValue;
|
|
1221
|
-
} else if (message
|
|
1231
|
+
} else if (message?.structValue !== undefined) {
|
|
1222
1232
|
return message.structValue;
|
|
1223
|
-
} else if (message
|
|
1233
|
+
} else if (message?.listValue !== undefined) {
|
|
1224
1234
|
return message.listValue;
|
|
1225
|
-
} else if (message
|
|
1235
|
+
} else if (message?.nullValue !== undefined) {
|
|
1226
1236
|
return null;
|
|
1227
1237
|
}
|
|
1238
|
+
return undefined;
|
|
1228
1239
|
}`);
|
|
1229
1240
|
}
|
|
1230
1241
|
if (types_1.isListValueTypeName(fullProtoTypeName)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-proto",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.92.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/plugin.js",
|
|
6
6
|
"repository": "github:stephenh/ts-proto",
|
|
@@ -9,10 +9,19 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "yarn tsc",
|
|
12
|
-
"
|
|
12
|
+
"build:test": "yarn proto2bin && yarn proto2pbjs && yarn bin2ts",
|
|
13
|
+
"build:test:local": "yarn proto2bin:local && yarn proto2pbjs:local && yarn bin2ts:local",
|
|
14
|
+
"proto2bin": "docker-compose run --rm protoc update-bins.sh",
|
|
15
|
+
"proto2bin-node": "docker-compose run --rm node update-bins.sh",
|
|
16
|
+
"proto2pbjs": "docker-compose run --rm protoc pbjs.sh",
|
|
17
|
+
"bin2ts": "docker-compose run --rm protoc codegen.sh",
|
|
18
|
+
"proto2bin:local": "integration/update-bins.sh",
|
|
19
|
+
"proto2pbjs:local": "integration/pbjs.sh",
|
|
20
|
+
"bin2ts:local": "integration/codegen.sh",
|
|
13
21
|
"test": "yarn jest -c jest.config.js --maxWorkers=2",
|
|
14
22
|
"prettier": "prettier --write {src,tests}/**/*.ts",
|
|
15
|
-
"prettier:check": "prettier --list-different {src,tests}/**/*.ts"
|
|
23
|
+
"prettier:check": "prettier --list-different {src,tests}/**/*.ts",
|
|
24
|
+
"setup:docker": "docker-compose build"
|
|
16
25
|
},
|
|
17
26
|
"files": [
|
|
18
27
|
"build"
|