ts-proto 1.83.2 → 1.86.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/build/generate-grpc-web.js +1 -3
- package/build/generate-services.js +58 -21
- package/build/main.js +63 -55
- package/build/types.js +14 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
# [1.86.0](https://github.com/stephenh/ts-proto/compare/v1.85.0...v1.86.0) (2021-11-15)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* Initialize lists with map ([#387](https://github.com/stephenh/ts-proto/issues/387)) ([200e674](https://github.com/stephenh/ts-proto/commit/200e674e4baf2640d67720ad535fe042d291d4a0))
|
|
7
|
+
|
|
8
|
+
# [1.85.0](https://github.com/stephenh/ts-proto/compare/v1.84.0...v1.85.0) (2021-11-02)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* Streaming support ([#373](https://github.com/stephenh/ts-proto/issues/373)) ([459b94f](https://github.com/stephenh/ts-proto/commit/459b94f5b2988d58d186461332e888c3e511603a))
|
|
14
|
+
|
|
15
|
+
# [1.84.0](https://github.com/stephenh/ts-proto/compare/v1.83.3...v1.84.0) (2021-11-02)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* Reduce code size by using nullish coalescing operator in fromPartial ([#376](https://github.com/stephenh/ts-proto/issues/376)) ([19d2ded](https://github.com/stephenh/ts-proto/commit/19d2deda2cf7c47b1b56bfc65cf58653291dba4a))
|
|
21
|
+
|
|
22
|
+
## [1.83.3](https://github.com/stephenh/ts-proto/compare/v1.83.2...v1.83.3) (2021-10-28)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* fix codegen for maps with wrapper value type ([#370](https://github.com/stephenh/ts-proto/issues/370)) ([dd2481d](https://github.com/stephenh/ts-proto/commit/dd2481df0835faafc561aad4a4d0c9c2ff9d868a))
|
|
28
|
+
|
|
1
29
|
## [1.83.2](https://github.com/stephenh/ts-proto/compare/v1.83.1...v1.83.2) (2021-10-26)
|
|
2
30
|
|
|
3
31
|
|
|
@@ -43,9 +43,7 @@ function generateRpcMethod(ctx, serviceDesc, methodDesc) {
|
|
|
43
43
|
const { options, utils } = ctx;
|
|
44
44
|
const inputType = types_1.requestType(ctx, methodDesc);
|
|
45
45
|
const partialInputType = ts_poet_1.code `${utils.DeepPartial}<${inputType}>`;
|
|
46
|
-
const returns =
|
|
47
|
-
? types_1.responseObservable(ctx, methodDesc)
|
|
48
|
-
: types_1.responsePromise(ctx, methodDesc);
|
|
46
|
+
const returns = types_1.responsePromiseOrObservable(ctx, methodDesc);
|
|
49
47
|
const method = methodDesc.serverStreaming ? 'invoke' : 'unary';
|
|
50
48
|
return ts_poet_1.code `
|
|
51
49
|
${methodDesc.formattedName}(
|
|
@@ -55,15 +55,7 @@ function generateService(ctx, fileDesc, sourceInfo, serviceDesc) {
|
|
|
55
55
|
if (options.addNestjsRestParameter) {
|
|
56
56
|
params.push(ts_poet_1.code `...rest: any`);
|
|
57
57
|
}
|
|
58
|
-
|
|
59
|
-
let returnType;
|
|
60
|
-
if (options.returnObservable || methodDesc.serverStreaming) {
|
|
61
|
-
returnType = types_1.responseObservable(ctx, methodDesc);
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
returnType = types_1.responsePromise(ctx, methodDesc);
|
|
65
|
-
}
|
|
66
|
-
chunks.push(ts_poet_1.code `${methodDesc.formattedName}(${ts_poet_1.joinCode(params, { on: ',' })}): ${returnType};`);
|
|
58
|
+
chunks.push(ts_poet_1.code `${methodDesc.formattedName}(${ts_poet_1.joinCode(params, { on: ',' })}): ${types_1.responsePromiseOrObservable(ctx, methodDesc)};`);
|
|
67
59
|
// If this is a batch method, auto-generate the singular version of it
|
|
68
60
|
if (options.context) {
|
|
69
61
|
const batchMethod = types_1.detectBatchMethod(ctx, fileDesc, serviceDesc, methodDesc);
|
|
@@ -83,22 +75,50 @@ function generateRegularRpcMethod(ctx, fileDesc, serviceDesc, methodDesc) {
|
|
|
83
75
|
utils_1.assertInstanceOf(methodDesc, utils_1.FormattedMethodDescriptor);
|
|
84
76
|
const { options } = ctx;
|
|
85
77
|
const Reader = ts_poet_1.imp('Reader@protobufjs/minimal');
|
|
78
|
+
const rawInputType = types_1.rawRequestType(ctx, methodDesc);
|
|
86
79
|
const inputType = types_1.requestType(ctx, methodDesc);
|
|
87
80
|
const outputType = types_1.responseType(ctx, methodDesc);
|
|
88
81
|
const params = [...(options.context ? [ts_poet_1.code `ctx: Context`] : []), ts_poet_1.code `request: ${inputType}`];
|
|
89
82
|
const maybeCtx = options.context ? 'ctx,' : '';
|
|
83
|
+
let encode = ts_poet_1.code `${rawInputType}.encode(request).finish()`;
|
|
84
|
+
let decode = ts_poet_1.code `data => ${outputType}.decode(new ${Reader}(data))`;
|
|
85
|
+
if (methodDesc.clientStreaming) {
|
|
86
|
+
encode = ts_poet_1.code `request.pipe(${ts_poet_1.imp('map@rxjs/operators')}(request => ${encode}))`;
|
|
87
|
+
}
|
|
88
|
+
let returnVariable;
|
|
89
|
+
if (options.returnObservable || methodDesc.serverStreaming) {
|
|
90
|
+
returnVariable = 'result';
|
|
91
|
+
decode = ts_poet_1.code `result.pipe(${ts_poet_1.imp('map@rxjs/operators')}(${decode}))`;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
returnVariable = 'promise';
|
|
95
|
+
decode = ts_poet_1.code `promise.then(${decode})`;
|
|
96
|
+
}
|
|
97
|
+
let rpcMethod;
|
|
98
|
+
if (methodDesc.clientStreaming && methodDesc.serverStreaming) {
|
|
99
|
+
rpcMethod = 'bidirectionalStreamingRequest';
|
|
100
|
+
}
|
|
101
|
+
else if (methodDesc.serverStreaming) {
|
|
102
|
+
rpcMethod = 'serverStreamingRequest';
|
|
103
|
+
}
|
|
104
|
+
else if (methodDesc.clientStreaming) {
|
|
105
|
+
rpcMethod = 'clientStreamingRequest';
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
rpcMethod = 'request';
|
|
109
|
+
}
|
|
90
110
|
return ts_poet_1.code `
|
|
91
111
|
${methodDesc.formattedName}(
|
|
92
112
|
${ts_poet_1.joinCode(params, { on: ',' })}
|
|
93
|
-
): ${types_1.
|
|
94
|
-
const data = ${
|
|
95
|
-
const
|
|
113
|
+
): ${types_1.responsePromiseOrObservable(ctx, methodDesc)} {
|
|
114
|
+
const data = ${encode};
|
|
115
|
+
const ${returnVariable} = this.rpc.${rpcMethod}(
|
|
96
116
|
${maybeCtx}
|
|
97
117
|
"${utils_1.maybePrefixPackage(fileDesc, serviceDesc.name)}",
|
|
98
118
|
"${methodDesc.name}",
|
|
99
119
|
data
|
|
100
120
|
);
|
|
101
|
-
return
|
|
121
|
+
return ${decode};
|
|
102
122
|
}
|
|
103
123
|
`;
|
|
104
124
|
}
|
|
@@ -217,24 +237,41 @@ function generateCachingRpcMethod(ctx, fileDesc, serviceDesc, methodDesc) {
|
|
|
217
237
|
*
|
|
218
238
|
* This lets clients pass in their own request-promise-ish client.
|
|
219
239
|
*
|
|
240
|
+
* This also requires clientStreamingRequest, serverStreamingRequest and
|
|
241
|
+
* bidirectionalStreamingRequest methods if any of the RPCs is streaming.
|
|
242
|
+
*
|
|
220
243
|
* We don't export this because if a project uses multiple `*.proto` files,
|
|
221
244
|
* we don't want our the barrel imports in `index.ts` to have multiple `Rpc`
|
|
222
245
|
* types.
|
|
223
246
|
*/
|
|
224
|
-
function generateRpcType(ctx) {
|
|
247
|
+
function generateRpcType(ctx, hasStreamingMethods) {
|
|
225
248
|
const { options } = ctx;
|
|
226
249
|
const maybeContext = options.context ? '<Context>' : '';
|
|
227
250
|
const maybeContextParam = options.context ? 'ctx: Context,' : '';
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
251
|
+
const methods = [[ts_poet_1.code `request`, ts_poet_1.code `Uint8Array`, ts_poet_1.code `Promise<Uint8Array>`]];
|
|
252
|
+
if (hasStreamingMethods) {
|
|
253
|
+
const observable = ts_poet_1.imp('Observable@rxjs');
|
|
254
|
+
methods.push([ts_poet_1.code `clientStreamingRequest`, ts_poet_1.code `${observable}<Uint8Array>`, ts_poet_1.code `Promise<Uint8Array>`]);
|
|
255
|
+
methods.push([ts_poet_1.code `serverStreamingRequest`, ts_poet_1.code `Uint8Array`, ts_poet_1.code `${observable}<Uint8Array>`]);
|
|
256
|
+
methods.push([
|
|
257
|
+
ts_poet_1.code `bidirectionalStreamingRequest`,
|
|
258
|
+
ts_poet_1.code `${observable}<Uint8Array>`,
|
|
259
|
+
ts_poet_1.code `${observable}<Uint8Array>`,
|
|
260
|
+
]);
|
|
261
|
+
}
|
|
262
|
+
const chunks = [];
|
|
263
|
+
chunks.push(ts_poet_1.code ` interface Rpc${maybeContext} {`);
|
|
264
|
+
methods.forEach((method) => {
|
|
265
|
+
chunks.push(ts_poet_1.code `
|
|
266
|
+
${method[0]}(
|
|
231
267
|
${maybeContextParam}
|
|
232
268
|
service: string,
|
|
233
269
|
method: string,
|
|
234
|
-
data:
|
|
235
|
-
):
|
|
236
|
-
}
|
|
237
|
-
|
|
270
|
+
data: ${method[1]}
|
|
271
|
+
): ${method[2]};`);
|
|
272
|
+
});
|
|
273
|
+
chunks.push(ts_poet_1.code ` }`);
|
|
274
|
+
return ts_poet_1.joinCode(chunks, { on: '\n' });
|
|
238
275
|
}
|
|
239
276
|
exports.generateRpcType = generateRpcType;
|
|
240
277
|
function generateDataLoadersType() {
|
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");
|
|
@@ -91,6 +90,7 @@ function generateFile(ctx, fileDesc) {
|
|
|
91
90
|
}
|
|
92
91
|
}, options);
|
|
93
92
|
}
|
|
93
|
+
let hasServerStreamingMethods = false;
|
|
94
94
|
let hasStreamingMethods = false;
|
|
95
95
|
visit_1.visitServices(fileDesc, sourceInfo, (serviceDesc, sInfo) => {
|
|
96
96
|
if (options.nestJs) {
|
|
@@ -126,18 +126,23 @@ function generateFile(ctx, fileDesc) {
|
|
|
126
126
|
serviceDesc.method.forEach((method) => {
|
|
127
127
|
chunks.push(generate_grpc_web_1.generateGrpcMethodDesc(ctx, serviceDesc, method));
|
|
128
128
|
if (method.serverStreaming) {
|
|
129
|
-
|
|
129
|
+
hasServerStreamingMethods = true;
|
|
130
130
|
}
|
|
131
131
|
});
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
+
serviceDesc.method.forEach((methodDesc, index) => {
|
|
135
|
+
if (methodDesc.serverStreaming || methodDesc.clientStreaming) {
|
|
136
|
+
hasStreamingMethods = true;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
134
139
|
});
|
|
135
140
|
if (options.outputServices === options_1.ServiceOption.DEFAULT && options.outputClientImpl && fileDesc.service.length > 0) {
|
|
136
141
|
if (options.outputClientImpl === true) {
|
|
137
|
-
chunks.push(generate_services_1.generateRpcType(ctx));
|
|
142
|
+
chunks.push(generate_services_1.generateRpcType(ctx, hasStreamingMethods));
|
|
138
143
|
}
|
|
139
144
|
else if (options.outputClientImpl === 'grpc-web') {
|
|
140
|
-
chunks.push(generate_grpc_web_1.addGrpcWebMisc(ctx,
|
|
145
|
+
chunks.push(generate_grpc_web_1.addGrpcWebMisc(ctx, hasServerStreamingMethods));
|
|
141
146
|
}
|
|
142
147
|
}
|
|
143
148
|
if (options.context) {
|
|
@@ -632,10 +637,18 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
632
637
|
}
|
|
633
638
|
if (types_1.isRepeated(field)) {
|
|
634
639
|
if (types_1.isMapType(ctx, messageDesc, field)) {
|
|
640
|
+
const valueType = typeMap.get(field.typeName)[2].field[1];
|
|
635
641
|
const maybeTypeField = options.outputTypeRegistry ? `$type: '${field.typeName.slice(1)}',` : '';
|
|
642
|
+
const entryWriteSnippet = types_1.isValueType(ctx, valueType)
|
|
643
|
+
? ts_poet_1.code `
|
|
644
|
+
if (value !== undefined) {
|
|
645
|
+
${writeSnippet(`{ ${maybeTypeField} key: key as any, value }`)};
|
|
646
|
+
}
|
|
647
|
+
`
|
|
648
|
+
: writeSnippet(`{ ${maybeTypeField} key: key as any, value }`);
|
|
636
649
|
chunks.push(ts_poet_1.code `
|
|
637
650
|
Object.entries(message.${fieldName}).forEach(([key, value]) => {
|
|
638
|
-
${
|
|
651
|
+
${entryWriteSnippet}
|
|
639
652
|
});
|
|
640
653
|
`);
|
|
641
654
|
}
|
|
@@ -725,20 +738,6 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
725
738
|
fromJSON(${messageDesc.field.length > 0 ? 'object' : '_'}: any): ${fullName} {
|
|
726
739
|
const message = { ...base${fullName} } as ${fullName};
|
|
727
740
|
`);
|
|
728
|
-
// initialize all lists
|
|
729
|
-
messageDesc.field.filter(types_1.isRepeated).forEach((field) => {
|
|
730
|
-
const value = types_1.isMapType(ctx, messageDesc, field) ? '{}' : '[]';
|
|
731
|
-
const name = case_1.maybeSnakeToCamel(field.name, options);
|
|
732
|
-
chunks.push(ts_poet_1.code `message.${name} = ${value};`);
|
|
733
|
-
});
|
|
734
|
-
// initialize all buffers
|
|
735
|
-
messageDesc.field
|
|
736
|
-
.filter((field) => !types_1.isRepeated(field) && !types_1.isWithinOneOf(field) && types_1.isBytes(field))
|
|
737
|
-
.forEach((field) => {
|
|
738
|
-
const value = options.env === options_1.EnvOption.NODE ? 'Buffer.alloc(0)' : 'new Uint8Array()';
|
|
739
|
-
const name = case_1.maybeSnakeToCamel(field.name, options);
|
|
740
|
-
chunks.push(ts_poet_1.code `message.${name} = ${value};`);
|
|
741
|
-
});
|
|
742
741
|
// add a check for each incoming field
|
|
743
742
|
messageDesc.field.forEach((field) => {
|
|
744
743
|
const fieldName = case_1.maybeSnakeToCamel(field.name, options);
|
|
@@ -814,6 +813,10 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
814
813
|
(options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.TIMESTAMP)) {
|
|
815
814
|
return ts_poet_1.code `${utils.fromJsonTimestamp}(${from})`;
|
|
816
815
|
}
|
|
816
|
+
else if (types_1.isValueType(ctx, valueType)) {
|
|
817
|
+
const type = types_1.basicTypeName(ctx, valueType);
|
|
818
|
+
return ts_poet_1.code `${from} as ${type}`;
|
|
819
|
+
}
|
|
817
820
|
else {
|
|
818
821
|
const type = types_1.basicTypeName(ctx, valueType);
|
|
819
822
|
return ts_poet_1.code `${type}.fromJSON(${from})`;
|
|
@@ -829,42 +832,41 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
829
832
|
}
|
|
830
833
|
};
|
|
831
834
|
// and then use the snippet to handle repeated fields if necessary
|
|
832
|
-
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
833
835
|
if (types_1.isRepeated(field)) {
|
|
834
836
|
if (types_1.isMapType(ctx, messageDesc, field)) {
|
|
837
|
+
chunks.push(ts_poet_1.code `message.${fieldName} = {};`);
|
|
838
|
+
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
835
839
|
const i = maybeCastToNumber(ctx, messageDesc, field, 'key');
|
|
836
840
|
chunks.push(ts_poet_1.code `
|
|
837
841
|
Object.entries(object.${fieldName}).forEach(([key, value]) => {
|
|
838
842
|
message.${fieldName}[${i}] = ${readSnippet('value')};
|
|
839
843
|
});
|
|
840
844
|
`);
|
|
845
|
+
chunks.push(ts_poet_1.code `}`);
|
|
841
846
|
}
|
|
842
847
|
else {
|
|
848
|
+
// Explicit `any` type required to make TS with noImplicitAny happy. `object` is also `any` here.
|
|
843
849
|
chunks.push(ts_poet_1.code `
|
|
844
|
-
|
|
845
|
-
message.${fieldName}.push(${readSnippet('e')});
|
|
846
|
-
}
|
|
850
|
+
message.${fieldName} = (object.${fieldName} ?? []).map((e: any) => ${readSnippet('e')});
|
|
847
851
|
`);
|
|
848
852
|
}
|
|
849
853
|
}
|
|
850
854
|
else if (types_1.isWithinOneOfThatShouldBeUnion(options, field)) {
|
|
855
|
+
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
851
856
|
const oneofName = case_1.maybeSnakeToCamel(messageDesc.oneofDecl[field.oneofIndex].name, options);
|
|
852
857
|
chunks.push(ts_poet_1.code `
|
|
853
858
|
message.${oneofName} = { $case: '${fieldName}', ${fieldName}: ${readSnippet(`object.${fieldName}`)} }
|
|
854
859
|
`);
|
|
860
|
+
chunks.push(ts_poet_1.code `}`);
|
|
855
861
|
}
|
|
856
862
|
else {
|
|
863
|
+
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
857
864
|
chunks.push(ts_poet_1.code `message.${fieldName} = ${readSnippet(`object.${fieldName}`)};`);
|
|
858
|
-
}
|
|
859
|
-
// set the default value (TODO Support bytes)
|
|
860
|
-
if (!types_1.isRepeated(field) &&
|
|
861
|
-
field.type !== ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_BYTES &&
|
|
862
|
-
options.oneof !== options_1.OneofOption.UNIONS) {
|
|
863
|
-
const v = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
|
864
865
|
chunks.push(ts_poet_1.code `} else {`);
|
|
865
|
-
|
|
866
|
+
const fallback = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
|
867
|
+
chunks.push(ts_poet_1.code `message.${fieldName} = ${fallback};`);
|
|
868
|
+
chunks.push(ts_poet_1.code `}`);
|
|
866
869
|
}
|
|
867
|
-
chunks.push(ts_poet_1.code `}`);
|
|
868
870
|
});
|
|
869
871
|
// and then wrap up the switch/while/return
|
|
870
872
|
chunks.push(ts_poet_1.code `return message`);
|
|
@@ -917,7 +919,7 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
917
919
|
else if (types_1.isTimestamp(valueType) && options.useDate === options_1.DateOption.TIMESTAMP) {
|
|
918
920
|
return ts_poet_1.code `${utils.fromTimestamp}(${from}).toISOString()`;
|
|
919
921
|
}
|
|
920
|
-
else if (types_1.isScalar(valueType)) {
|
|
922
|
+
else if (types_1.isScalar(valueType) || types_1.isValueType(ctx, valueType)) {
|
|
921
923
|
return ts_poet_1.code `${from}`;
|
|
922
924
|
}
|
|
923
925
|
else {
|
|
@@ -990,12 +992,6 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
990
992
|
fromPartial(${messageDesc.field.length > 0 ? 'object' : '_'}: ${utils.DeepPartial}<${fullName}>): ${fullName} {
|
|
991
993
|
const message = { ...base${fullName} } as ${fullName};
|
|
992
994
|
`);
|
|
993
|
-
// initialize all lists
|
|
994
|
-
messageDesc.field.filter(types_1.isRepeated).forEach((field) => {
|
|
995
|
-
const value = types_1.isMapType(ctx, messageDesc, field) ? '{}' : '[]';
|
|
996
|
-
const name = case_1.maybeSnakeToCamel(field.name, options);
|
|
997
|
-
chunks.push(ts_poet_1.code `message.${name} = ${value};`);
|
|
998
|
-
});
|
|
999
995
|
// add a check for each incoming field
|
|
1000
996
|
messageDesc.field.forEach((field) => {
|
|
1001
997
|
const fieldName = case_1.maybeSnakeToCamel(field.name, options);
|
|
@@ -1024,6 +1020,9 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1024
1020
|
(options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) {
|
|
1025
1021
|
return ts_poet_1.code `${from}`;
|
|
1026
1022
|
}
|
|
1023
|
+
else if (types_1.isValueType(ctx, valueType)) {
|
|
1024
|
+
return ts_poet_1.code `${from}`;
|
|
1025
|
+
}
|
|
1027
1026
|
else {
|
|
1028
1027
|
const type = types_1.basicTypeName(ctx, valueType);
|
|
1029
1028
|
return ts_poet_1.code `${type}.fromPartial(${from})`;
|
|
@@ -1040,8 +1039,9 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1040
1039
|
};
|
|
1041
1040
|
// and then use the snippet to handle repeated fields if necessary
|
|
1042
1041
|
if (types_1.isRepeated(field)) {
|
|
1043
|
-
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
1044
1042
|
if (types_1.isMapType(ctx, messageDesc, field)) {
|
|
1043
|
+
chunks.push(ts_poet_1.code `message.${fieldName} = {};`);
|
|
1044
|
+
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
1045
1045
|
const i = maybeCastToNumber(ctx, messageDesc, field, 'key');
|
|
1046
1046
|
chunks.push(ts_poet_1.code `
|
|
1047
1047
|
Object.entries(object.${fieldName}).forEach(([key, value]) => {
|
|
@@ -1050,12 +1050,11 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1050
1050
|
}
|
|
1051
1051
|
});
|
|
1052
1052
|
`);
|
|
1053
|
+
chunks.push(ts_poet_1.code `}`);
|
|
1053
1054
|
}
|
|
1054
1055
|
else {
|
|
1055
1056
|
chunks.push(ts_poet_1.code `
|
|
1056
|
-
|
|
1057
|
-
message.${fieldName}.push(${readSnippet('e')});
|
|
1058
|
-
}
|
|
1057
|
+
message.${fieldName} = (object.${fieldName} ?? []).map((e) => ${readSnippet('e')});
|
|
1059
1058
|
`);
|
|
1060
1059
|
}
|
|
1061
1060
|
}
|
|
@@ -1069,25 +1068,34 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1069
1068
|
&& object.${oneofName}?.${fieldName} !== null
|
|
1070
1069
|
) {
|
|
1071
1070
|
message.${oneofName} = { $case: '${fieldName}', ${fieldName}: ${v} };
|
|
1071
|
+
}
|
|
1072
1072
|
`);
|
|
1073
1073
|
}
|
|
1074
|
-
else {
|
|
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);
|
|
1075
1077
|
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
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
|
+
else if (types_1.isPrimitive(field) ||
|
|
1085
|
+
(types_1.isTimestamp(field) && (options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) ||
|
|
1086
|
+
types_1.isValueType(ctx, field)) {
|
|
1087
|
+
// An optimized case of the else below that works when `readSnippet` returns the plain input
|
|
1088
|
+
const fallback = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
|
1089
|
+
chunks.push(ts_poet_1.code `message.${fieldName} = object.${fieldName} ?? ${fallback};`);
|
|
1084
1090
|
}
|
|
1085
|
-
|
|
1091
|
+
else {
|
|
1092
|
+
chunks.push(ts_poet_1.code `if (object.${fieldName} !== undefined && object.${fieldName} !== null) {`);
|
|
1093
|
+
chunks.push(ts_poet_1.code `message.${fieldName} = ${readSnippet(`object.${fieldName}`)};`);
|
|
1086
1094
|
chunks.push(ts_poet_1.code `} else {`);
|
|
1087
|
-
const
|
|
1088
|
-
chunks.push(ts_poet_1.code `message.${fieldName} = ${
|
|
1095
|
+
const fallback = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
|
1096
|
+
chunks.push(ts_poet_1.code `message.${fieldName} = ${fallback};`);
|
|
1097
|
+
chunks.push(ts_poet_1.code `}`);
|
|
1089
1098
|
}
|
|
1090
|
-
chunks.push(ts_poet_1.code `}`);
|
|
1091
1099
|
});
|
|
1092
1100
|
// and then wrap up the switch/while/return
|
|
1093
1101
|
chunks.push(ts_poet_1.code `return message;`);
|
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.responseObservable = exports.responsePromise = exports.responseType = exports.requestType = 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.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;
|
|
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");
|
|
@@ -512,8 +512,12 @@ function detectMapType(ctx, messageDesc, fieldDesc) {
|
|
|
512
512
|
return undefined;
|
|
513
513
|
}
|
|
514
514
|
exports.detectMapType = detectMapType;
|
|
515
|
+
function rawRequestType(ctx, methodDesc) {
|
|
516
|
+
return messageToTypeName(ctx, methodDesc.inputType);
|
|
517
|
+
}
|
|
518
|
+
exports.rawRequestType = rawRequestType;
|
|
515
519
|
function requestType(ctx, methodDesc) {
|
|
516
|
-
let typeName =
|
|
520
|
+
let typeName = rawRequestType(ctx, methodDesc);
|
|
517
521
|
if (methodDesc.clientStreaming) {
|
|
518
522
|
return ts_poet_1.code `${ts_poet_1.imp('Observable@rxjs')}<${typeName}>`;
|
|
519
523
|
}
|
|
@@ -532,6 +536,14 @@ function responseObservable(ctx, methodDesc) {
|
|
|
532
536
|
return ts_poet_1.code `${ts_poet_1.imp('Observable@rxjs')}<${responseType(ctx, methodDesc)}>`;
|
|
533
537
|
}
|
|
534
538
|
exports.responseObservable = responseObservable;
|
|
539
|
+
function responsePromiseOrObservable(ctx, methodDesc) {
|
|
540
|
+
const { options } = ctx;
|
|
541
|
+
if (options.returnObservable || methodDesc.serverStreaming) {
|
|
542
|
+
return responseObservable(ctx, methodDesc);
|
|
543
|
+
}
|
|
544
|
+
return responsePromise(ctx, methodDesc);
|
|
545
|
+
}
|
|
546
|
+
exports.responsePromiseOrObservable = responsePromiseOrObservable;
|
|
535
547
|
function detectBatchMethod(ctx, fileDesc, serviceDesc, methodDesc) {
|
|
536
548
|
const { typeMap } = ctx;
|
|
537
549
|
const nameMatches = methodDesc.name.startsWith('Batch');
|