ts-proto 1.111.0 → 1.112.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 +26 -0
- package/README.markdown +2 -0
- package/build/enums.js +34 -6
- package/build/generate-nice-grpc.js +135 -0
- package/build/main.js +14 -1
- package/build/options.js +1 -0
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
## [1.112.2](https://github.com/stephenh/ts-proto/compare/v1.112.1...v1.112.2) (2022-05-18)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* enum type returns 'UNRECOGNIZED' or '-1' in xxxToJSON/xxxToNumber ([#566](https://github.com/stephenh/ts-proto/issues/566)) ([19911a1](https://github.com/stephenh/ts-proto/commit/19911a1c62e3fe5c8a0eb0a795489340512898da))
|
|
7
|
+
|
|
8
|
+
## [1.112.1](https://github.com/stephenh/ts-proto/compare/v1.112.0...v1.112.1) (2022-05-06)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* use Long.fromValue instead of Long.fromString ([#562](https://github.com/stephenh/ts-proto/issues/562)) ([c99891e](https://github.com/stephenh/ts-proto/commit/c99891e0fec6d9b7225025eb0c5bd7393e80af36))
|
|
14
|
+
|
|
15
|
+
# [1.112.0](https://github.com/stephenh/ts-proto/compare/v1.111.0...v1.112.0) (2022-05-02)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* update codegen for `nice-grpc` ([#561](https://github.com/stephenh/ts-proto/issues/561)) ([d503f67](https://github.com/stephenh/ts-proto/commit/d503f677922402e880b5d8502b3d8bc099b7f39d))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
* add support for generating `nice-grpc` server and client stubs ([#555](https://github.com/stephenh/ts-proto/issues/555)) ([8c19361](https://github.com/stephenh/ts-proto/commit/8c19361ede9a7a039acf3a1375913d012b0fcb7d)), closes [#545](https://github.com/stephenh/ts-proto/issues/545)
|
|
26
|
+
|
|
1
27
|
# [1.111.0](https://github.com/stephenh/ts-proto/compare/v1.110.4...v1.111.0) (2022-05-01)
|
|
2
28
|
|
|
3
29
|
|
package/README.markdown
CHANGED
|
@@ -362,6 +362,8 @@ Generated code will be placed in the Gradle build directory.
|
|
|
362
362
|
|
|
363
363
|
- 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).
|
|
364
364
|
|
|
365
|
+
- With `--ts_proto_opt=outputServices=nice-grpc`, ts-proto will output server and client stubs for [nice-grpc](https://github.com/deeplay-io/nice-grpc). This should be used together with generic definitions, i.e. you should specify two options: `outputServices=nice-grpc,outputServices=generic-definitions`.
|
|
366
|
+
|
|
365
367
|
- With `--ts_proto_opt=metadataType=Foo@./some-file`, ts-proto add a generic (framework-agnostic) metadata field to the generic service definition.
|
|
366
368
|
|
|
367
369
|
- With `--ts_proto_opt=outputServices=generic-definitions,outputServices=default`, ts-proto will output both generic definitions and interfaces. This is useful if you want to rely on the interfaces, but also have some reflection capabilities at runtime.
|
package/build/enums.js
CHANGED
|
@@ -43,11 +43,11 @@ function generateEnum(ctx, fullName, enumDesc, sourceInfo) {
|
|
|
43
43
|
}
|
|
44
44
|
if (options.outputJsonMethods) {
|
|
45
45
|
chunks.push(ts_poet_1.code `\n`);
|
|
46
|
-
chunks.push(generateEnumToJson(fullName, enumDesc));
|
|
46
|
+
chunks.push(generateEnumToJson(ctx, fullName, enumDesc));
|
|
47
47
|
}
|
|
48
48
|
if (options.stringEnums && options.outputEncodeMethods) {
|
|
49
49
|
chunks.push(ts_poet_1.code `\n`);
|
|
50
|
-
chunks.push(generateEnumToNumber(fullName, enumDesc));
|
|
50
|
+
chunks.push(generateEnumToNumber(ctx, fullName, enumDesc));
|
|
51
51
|
}
|
|
52
52
|
return ts_poet_1.joinCode(chunks, { on: '\n' });
|
|
53
53
|
}
|
|
@@ -87,7 +87,8 @@ function generateEnumFromJson(ctx, fullName, enumDesc) {
|
|
|
87
87
|
}
|
|
88
88
|
exports.generateEnumFromJson = generateEnumFromJson;
|
|
89
89
|
/** Generates a function with a big switch statement to encode our enum -> JSON. */
|
|
90
|
-
function generateEnumToJson(fullName, enumDesc) {
|
|
90
|
+
function generateEnumToJson(ctx, fullName, enumDesc) {
|
|
91
|
+
const { options, utils } = ctx;
|
|
91
92
|
const chunks = [];
|
|
92
93
|
const functionName = case_1.camelCase(fullName) + 'ToJSON';
|
|
93
94
|
chunks.push(ts_poet_1.code `export function ${ts_poet_1.def(functionName)}(object: ${fullName}): string {`);
|
|
@@ -95,14 +96,28 @@ function generateEnumToJson(fullName, enumDesc) {
|
|
|
95
96
|
for (const valueDesc of enumDesc.value) {
|
|
96
97
|
chunks.push(ts_poet_1.code `case ${fullName}.${valueDesc.name}: return "${valueDesc.name}";`);
|
|
97
98
|
}
|
|
98
|
-
|
|
99
|
+
if (options.unrecognizedEnum) {
|
|
100
|
+
chunks.push(ts_poet_1.code `
|
|
101
|
+
case ${fullName}.${UNRECOGNIZED_ENUM_NAME}:
|
|
102
|
+
default:
|
|
103
|
+
return "${UNRECOGNIZED_ENUM_NAME}";
|
|
104
|
+
`);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// We use globalThis to avoid conflicts on protobuf types named `Error`.
|
|
108
|
+
chunks.push(ts_poet_1.code `
|
|
109
|
+
default:
|
|
110
|
+
throw new ${utils.globalThis}.Error("Unrecognized enum value " + object + " for enum ${fullName}");
|
|
111
|
+
`);
|
|
112
|
+
}
|
|
99
113
|
chunks.push(ts_poet_1.code `}`);
|
|
100
114
|
chunks.push(ts_poet_1.code `}`);
|
|
101
115
|
return ts_poet_1.joinCode(chunks, { on: '\n' });
|
|
102
116
|
}
|
|
103
117
|
exports.generateEnumToJson = generateEnumToJson;
|
|
104
118
|
/** Generates a function with a big switch statement to encode our string enum -> int value. */
|
|
105
|
-
function generateEnumToNumber(fullName, enumDesc) {
|
|
119
|
+
function generateEnumToNumber(ctx, fullName, enumDesc) {
|
|
120
|
+
const { options, utils } = ctx;
|
|
106
121
|
const chunks = [];
|
|
107
122
|
const functionName = case_1.camelCase(fullName) + 'ToNumber';
|
|
108
123
|
chunks.push(ts_poet_1.code `export function ${ts_poet_1.def(functionName)}(object: ${fullName}): number {`);
|
|
@@ -110,7 +125,20 @@ function generateEnumToNumber(fullName, enumDesc) {
|
|
|
110
125
|
for (const valueDesc of enumDesc.value) {
|
|
111
126
|
chunks.push(ts_poet_1.code `case ${fullName}.${valueDesc.name}: return ${valueDesc.number};`);
|
|
112
127
|
}
|
|
113
|
-
|
|
128
|
+
if (options.unrecognizedEnum) {
|
|
129
|
+
chunks.push(ts_poet_1.code `
|
|
130
|
+
case ${fullName}.${UNRECOGNIZED_ENUM_NAME}:
|
|
131
|
+
default:
|
|
132
|
+
return ${UNRECOGNIZED_ENUM_VALUE};
|
|
133
|
+
`);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// We use globalThis to avoid conflicts on protobuf types named `Error`.
|
|
137
|
+
chunks.push(ts_poet_1.code `
|
|
138
|
+
default:
|
|
139
|
+
throw new ${utils.globalThis}.Error("Unrecognized enum value " + object + " for enum ${fullName}");
|
|
140
|
+
`);
|
|
141
|
+
}
|
|
114
142
|
chunks.push(ts_poet_1.code `}`);
|
|
115
143
|
chunks.push(ts_poet_1.code `}`);
|
|
116
144
|
return ts_poet_1.joinCode(chunks, { on: '\n' });
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateNiceGrpcService = void 0;
|
|
4
|
+
const ts_poet_1 = require("ts-poet");
|
|
5
|
+
const case_1 = require("./case");
|
|
6
|
+
const sourceInfo_1 = require("./sourceInfo");
|
|
7
|
+
const types_1 = require("./types");
|
|
8
|
+
const utils_1 = require("./utils");
|
|
9
|
+
const CallOptions = ts_poet_1.imp('CallOptions@nice-grpc-common');
|
|
10
|
+
const CallContext = ts_poet_1.imp('CallContext@nice-grpc-common');
|
|
11
|
+
/**
|
|
12
|
+
* Generates server / client stubs for `nice-grpc` library.
|
|
13
|
+
*/
|
|
14
|
+
function generateNiceGrpcService(ctx, fileDesc, sourceInfo, serviceDesc) {
|
|
15
|
+
const chunks = [];
|
|
16
|
+
chunks.push(generateServerStub(ctx, sourceInfo, serviceDesc));
|
|
17
|
+
chunks.push(generateClientStub(ctx, sourceInfo, serviceDesc));
|
|
18
|
+
return ts_poet_1.joinCode(chunks, { on: '\n\n' });
|
|
19
|
+
}
|
|
20
|
+
exports.generateNiceGrpcService = generateNiceGrpcService;
|
|
21
|
+
function generateServerStub(ctx, sourceInfo, serviceDesc) {
|
|
22
|
+
var _a;
|
|
23
|
+
const chunks = [];
|
|
24
|
+
chunks.push(ts_poet_1.code `export interface ${ts_poet_1.def(`${serviceDesc.name}ServiceImplementation`)}<CallContextExt = {}> {`);
|
|
25
|
+
for (const [index, methodDesc] of serviceDesc.method.entries()) {
|
|
26
|
+
utils_1.assertInstanceOf(methodDesc, utils_1.FormattedMethodDescriptor);
|
|
27
|
+
const inputType = types_1.messageToTypeName(ctx, methodDesc.inputType, { keepValueType: true });
|
|
28
|
+
let outputType = types_1.messageToTypeName(ctx, methodDesc.outputType, { keepValueType: true });
|
|
29
|
+
if (ctx.options.outputPartialMethods) {
|
|
30
|
+
outputType = ts_poet_1.code `${ctx.utils.DeepPartial}<${outputType}>`;
|
|
31
|
+
}
|
|
32
|
+
const ServerStreamingMethodResult = ctx.utils.NiceGrpcServerStreamingMethodResult;
|
|
33
|
+
const info = sourceInfo.lookup(sourceInfo_1.Fields.service.method, index);
|
|
34
|
+
utils_1.maybeAddComment(info, chunks, (_a = methodDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
|
|
35
|
+
if (methodDesc.clientStreaming) {
|
|
36
|
+
if (methodDesc.serverStreaming) {
|
|
37
|
+
// bidi streaming
|
|
38
|
+
chunks.push(ts_poet_1.code `
|
|
39
|
+
${case_1.camelCase(methodDesc.name)}(
|
|
40
|
+
request: AsyncIterable<${inputType}>,
|
|
41
|
+
context: ${CallContext} & CallContextExt,
|
|
42
|
+
): ${ServerStreamingMethodResult}<${outputType}>;
|
|
43
|
+
`);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// client streaming
|
|
47
|
+
chunks.push(ts_poet_1.code `
|
|
48
|
+
${case_1.camelCase(methodDesc.name)}(
|
|
49
|
+
request: AsyncIterable<${inputType}>,
|
|
50
|
+
context: ${CallContext} & CallContextExt,
|
|
51
|
+
): Promise<${outputType}>;
|
|
52
|
+
`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if (methodDesc.serverStreaming) {
|
|
57
|
+
// server streaming
|
|
58
|
+
chunks.push(ts_poet_1.code `
|
|
59
|
+
${case_1.camelCase(methodDesc.name)}(
|
|
60
|
+
request: ${inputType},
|
|
61
|
+
context: ${CallContext} & CallContextExt,
|
|
62
|
+
): ${ServerStreamingMethodResult}<${outputType}>;
|
|
63
|
+
`);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// unary
|
|
67
|
+
chunks.push(ts_poet_1.code `
|
|
68
|
+
${case_1.camelCase(methodDesc.name)}(
|
|
69
|
+
request: ${inputType},
|
|
70
|
+
context: ${CallContext} & CallContextExt,
|
|
71
|
+
): Promise<${outputType}>;
|
|
72
|
+
`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
chunks.push(ts_poet_1.code `}`);
|
|
77
|
+
return ts_poet_1.joinCode(chunks, { on: '\n' });
|
|
78
|
+
}
|
|
79
|
+
function generateClientStub(ctx, sourceInfo, serviceDesc) {
|
|
80
|
+
var _a;
|
|
81
|
+
const chunks = [];
|
|
82
|
+
chunks.push(ts_poet_1.code `export interface ${ts_poet_1.def(`${serviceDesc.name}Client`)}<CallOptionsExt = {}> {`);
|
|
83
|
+
for (const [index, methodDesc] of serviceDesc.method.entries()) {
|
|
84
|
+
utils_1.assertInstanceOf(methodDesc, utils_1.FormattedMethodDescriptor);
|
|
85
|
+
let inputType = types_1.messageToTypeName(ctx, methodDesc.inputType, { keepValueType: true });
|
|
86
|
+
if (ctx.options.outputPartialMethods) {
|
|
87
|
+
inputType = ts_poet_1.code `${ctx.utils.DeepPartial}<${inputType}>`;
|
|
88
|
+
}
|
|
89
|
+
const outputType = types_1.messageToTypeName(ctx, methodDesc.outputType, { keepValueType: true });
|
|
90
|
+
const info = sourceInfo.lookup(sourceInfo_1.Fields.service.method, index);
|
|
91
|
+
utils_1.maybeAddComment(info, chunks, (_a = methodDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
|
|
92
|
+
if (methodDesc.clientStreaming) {
|
|
93
|
+
if (methodDesc.serverStreaming) {
|
|
94
|
+
// bidi streaming
|
|
95
|
+
chunks.push(ts_poet_1.code `
|
|
96
|
+
${case_1.camelCase(methodDesc.name)}(
|
|
97
|
+
request: AsyncIterable<${inputType}>,
|
|
98
|
+
options?: ${CallOptions} & CallOptionsExt,
|
|
99
|
+
): AsyncIterable<${outputType}>;
|
|
100
|
+
`);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// client streaming
|
|
104
|
+
chunks.push(ts_poet_1.code `
|
|
105
|
+
${case_1.camelCase(methodDesc.name)}(
|
|
106
|
+
request: AsyncIterable<${inputType}>,
|
|
107
|
+
options?: ${CallOptions} & CallOptionsExt,
|
|
108
|
+
): Promise<${outputType}>;
|
|
109
|
+
`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
if (methodDesc.serverStreaming) {
|
|
114
|
+
// server streaming
|
|
115
|
+
chunks.push(ts_poet_1.code `
|
|
116
|
+
${case_1.camelCase(methodDesc.name)}(
|
|
117
|
+
request: ${inputType},
|
|
118
|
+
options?: ${CallOptions} & CallOptionsExt,
|
|
119
|
+
): AsyncIterable<${outputType}>;
|
|
120
|
+
`);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// unary
|
|
124
|
+
chunks.push(ts_poet_1.code `
|
|
125
|
+
${case_1.camelCase(methodDesc.name)}(
|
|
126
|
+
request: ${inputType},
|
|
127
|
+
options?: ${CallOptions} & CallOptionsExt,
|
|
128
|
+
): Promise<${outputType}>;
|
|
129
|
+
`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
chunks.push(ts_poet_1.code `}`);
|
|
134
|
+
return ts_poet_1.joinCode(chunks, { on: '\n' });
|
|
135
|
+
}
|
package/build/main.js
CHANGED
|
@@ -16,6 +16,7 @@ const schema_1 = require("./schema");
|
|
|
16
16
|
const ConditionalOutput_1 = require("ts-poet/build/ConditionalOutput");
|
|
17
17
|
const generate_grpc_js_1 = require("./generate-grpc-js");
|
|
18
18
|
const generate_generic_service_definition_1 = require("./generate-generic-service-definition");
|
|
19
|
+
const generate_nice_grpc_1 = require("./generate-nice-grpc");
|
|
19
20
|
function generateFile(ctx, fileDesc) {
|
|
20
21
|
var _a;
|
|
21
22
|
const { options, utils } = ctx;
|
|
@@ -124,6 +125,9 @@ function generateFile(ctx, fileDesc) {
|
|
|
124
125
|
if (outputService === options_1.ServiceOption.GRPC) {
|
|
125
126
|
chunks.push(generate_grpc_js_1.generateGrpcJsService(ctx, fileDesc, sInfo, serviceDesc));
|
|
126
127
|
}
|
|
128
|
+
else if (outputService === options_1.ServiceOption.NICE_GRPC) {
|
|
129
|
+
chunks.push(generate_nice_grpc_1.generateNiceGrpcService(ctx, fileDesc, sInfo, serviceDesc));
|
|
130
|
+
}
|
|
127
131
|
else if (outputService === options_1.ServiceOption.GENERIC) {
|
|
128
132
|
chunks.push(generate_generic_service_definition_1.generateGenericServiceDefinition(ctx, fileDesc, sInfo, serviceDesc));
|
|
129
133
|
}
|
|
@@ -206,6 +210,7 @@ function makeUtils(options) {
|
|
|
206
210
|
...makeTimestampMethods(options, longs),
|
|
207
211
|
...longs,
|
|
208
212
|
...makeComparisonUtils(),
|
|
213
|
+
...makeNiceGrpcServerStreamingMethodResult(),
|
|
209
214
|
};
|
|
210
215
|
}
|
|
211
216
|
exports.makeUtils = makeUtils;
|
|
@@ -444,6 +449,14 @@ function makeComparisonUtils() {
|
|
|
444
449
|
}`);
|
|
445
450
|
return { isObject, isSet };
|
|
446
451
|
}
|
|
452
|
+
function makeNiceGrpcServerStreamingMethodResult() {
|
|
453
|
+
const NiceGrpcServerStreamingMethodResult = ts_poet_1.conditionalOutput('ServerStreamingMethodResult', ts_poet_1.code `
|
|
454
|
+
export type ServerStreamingMethodResult<Response> = {
|
|
455
|
+
[Symbol.asyncIterator](): AsyncIterator<Response, void>;
|
|
456
|
+
};
|
|
457
|
+
`);
|
|
458
|
+
return { NiceGrpcServerStreamingMethodResult };
|
|
459
|
+
}
|
|
447
460
|
// Create the interface with properties
|
|
448
461
|
function generateInterfaceDeclaration(ctx, fullName, messageDesc, sourceInfo, fullTypeName) {
|
|
449
462
|
var _a;
|
|
@@ -935,7 +948,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
935
948
|
}
|
|
936
949
|
else if (types_1.isLong(field) && options.forceLong === options_1.LongOption.LONG) {
|
|
937
950
|
const cstr = case_1.capitalize(types_1.basicTypeName(ctx, field, { keepValueType: true }).toCodeString());
|
|
938
|
-
return ts_poet_1.code `${cstr}.
|
|
951
|
+
return ts_poet_1.code `${cstr}.fromValue(${from})`;
|
|
939
952
|
}
|
|
940
953
|
else {
|
|
941
954
|
const cstr = case_1.capitalize(types_1.basicTypeName(ctx, field, { keepValueType: true }).toCodeString());
|
package/build/options.js
CHANGED
|
@@ -27,6 +27,7 @@ var OneofOption;
|
|
|
27
27
|
var ServiceOption;
|
|
28
28
|
(function (ServiceOption) {
|
|
29
29
|
ServiceOption["GRPC"] = "grpc-js";
|
|
30
|
+
ServiceOption["NICE_GRPC"] = "nice-grpc";
|
|
30
31
|
ServiceOption["GENERIC"] = "generic-definitions";
|
|
31
32
|
ServiceOption["DEFAULT"] = "default";
|
|
32
33
|
ServiceOption["NONE"] = "none";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-proto",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.112.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/plugin.js",
|
|
6
6
|
"repository": "github:stephenh/ts-proto",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"chokidar": "^3.5.2",
|
|
51
51
|
"jest": "^26.6.3",
|
|
52
52
|
"mongodb": "^4.3.0",
|
|
53
|
+
"nice-grpc": "^1.1.1",
|
|
53
54
|
"prettier": "^2.2.1",
|
|
54
55
|
"reflect-metadata": "^0.1.13",
|
|
55
56
|
"rxjs": "^7.4.0",
|