ts-proto 1.137.2 → 1.139.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/README.markdown +8 -4
- package/build/generate-struct-wrappers.js +318 -0
- package/build/main.js +121 -219
- package/package.json +3 -3
package/README.markdown
CHANGED
|
@@ -167,6 +167,10 @@ Along with `encode`/`decode` factory methods:
|
|
|
167
167
|
|
|
168
168
|
```typescript
|
|
169
169
|
export const Simple = {
|
|
170
|
+
create(baseObject?: DeepPartial<Simple>): Simple {
|
|
171
|
+
...
|
|
172
|
+
},
|
|
173
|
+
|
|
170
174
|
encode(message: Simple, writer: Writer = Writer.create()): Writer {
|
|
171
175
|
...
|
|
172
176
|
},
|
|
@@ -332,7 +336,7 @@ Generated code will be placed in the Gradle build directory.
|
|
|
332
336
|
|
|
333
337
|
So, between typo-prevention, reader inconsistency, and proper initialization, ts-proto recommends using `useOptionals=none` as the "most safe" option.
|
|
334
338
|
|
|
335
|
-
All that said, this approach does require writers/creators to set every field (although `fromPartial`
|
|
339
|
+
All that said, this approach does require writers/creators to set every field (although `fromPartial` and `create` are meant to address this), so if you still want to have optional fields, you can set `useOptionals=messages` or `useOptionals=all`.
|
|
336
340
|
|
|
337
341
|
(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`.)
|
|
338
342
|
|
|
@@ -368,7 +372,7 @@ Generated code will be placed in the Gradle build directory.
|
|
|
368
372
|
|
|
369
373
|
This is also useful if you want "only types".
|
|
370
374
|
|
|
371
|
-
- With `--ts_proto_opt=outputPartialMethods=false`, the `Message.fromPartial` methods for accepting partially-formed objects/object literals will not be output.
|
|
375
|
+
- With `--ts_proto_opt=outputPartialMethods=false`, the `Message.fromPartial` and `Message.create` methods for accepting partially-formed objects/object literals will not be output.
|
|
372
376
|
|
|
373
377
|
- With `--ts_proto_opt=stringEnums=true`, the generated enum types will be string-based instead of int-based.
|
|
374
378
|
|
|
@@ -433,9 +437,9 @@ Generated code will be placed in the Gradle build directory.
|
|
|
433
437
|
|
|
434
438
|
- With `--ts_proto_opt=enumsAsLiterals=true`, the generated enum types will be enum-ish object with `as const`.
|
|
435
439
|
|
|
436
|
-
- With `--ts_proto_opt=useExactTypes=false`, the generated `fromPartial`
|
|
440
|
+
- With `--ts_proto_opt=useExactTypes=false`, the generated `fromPartial` and `create` methods will not use Exact types.
|
|
437
441
|
|
|
438
|
-
The default behavior is `useExactTypes=true`, which makes `fromPartial` use Exact type for its argument to make TypeScript reject any unknown properties.
|
|
442
|
+
The default behavior is `useExactTypes=true`, which makes `fromPartial` and `create` use Exact type for its argument to make TypeScript reject any unknown properties.
|
|
439
443
|
|
|
440
444
|
- With `--ts_proto_opt=unknownFields=true`, all unknown fields will be parsed and output as arrays of buffers.
|
|
441
445
|
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateUnwrapShallow = exports.generateWrapShallow = exports.generateUnwrapDeep = exports.generateWrapDeep = exports.isWrapperType = void 0;
|
|
4
|
+
const ts_poet_1 = require("ts-poet");
|
|
5
|
+
const types_1 = require("./types");
|
|
6
|
+
const options_1 = require("./options");
|
|
7
|
+
/** Whether we need to generate `.wrap` and `.unwrap` methods for the given type. */
|
|
8
|
+
function isWrapperType(fullProtoTypeName) {
|
|
9
|
+
return ((0, types_1.isStructTypeName)(fullProtoTypeName) ||
|
|
10
|
+
(0, types_1.isAnyValueTypeName)(fullProtoTypeName) ||
|
|
11
|
+
(0, types_1.isListValueTypeName)(fullProtoTypeName) ||
|
|
12
|
+
(0, types_1.isFieldMaskTypeName)(fullProtoTypeName));
|
|
13
|
+
}
|
|
14
|
+
exports.isWrapperType = isWrapperType;
|
|
15
|
+
/**
|
|
16
|
+
* Converts ts-proto's idiomatic Struct/Value/ListValue representation to the proto messages.
|
|
17
|
+
*
|
|
18
|
+
* We do this deeply b/c NestJS does not invoke wrappers recursively.
|
|
19
|
+
*/
|
|
20
|
+
function generateWrapDeep(ctx, fullProtoTypeName, fieldNames) {
|
|
21
|
+
const chunks = [];
|
|
22
|
+
if ((0, types_1.isStructTypeName)(fullProtoTypeName)) {
|
|
23
|
+
let setStatement = "struct.fields[key] = Value.wrap(object[key]);";
|
|
24
|
+
if (ctx.options.useMapType) {
|
|
25
|
+
setStatement = "struct.fields.set(key, Value.wrap(object[key]));";
|
|
26
|
+
}
|
|
27
|
+
chunks.push((0, ts_poet_1.code) `wrap(object: {[key: string]: any} | undefined): Struct {
|
|
28
|
+
const struct = createBaseStruct();
|
|
29
|
+
if (object !== undefined) {
|
|
30
|
+
Object.keys(object).forEach(key => {
|
|
31
|
+
${setStatement}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return struct;
|
|
35
|
+
}`);
|
|
36
|
+
}
|
|
37
|
+
if ((0, types_1.isAnyValueTypeName)(fullProtoTypeName)) {
|
|
38
|
+
// Turn ts-proto representation --> proto representation
|
|
39
|
+
chunks.push((0, ts_poet_1.code) `wrap(value: any): Value {
|
|
40
|
+
const result = {} as any;
|
|
41
|
+
if (value === null) {
|
|
42
|
+
result.${fieldNames.nullValue} = NullValue.NULL_VALUE;
|
|
43
|
+
} else if (typeof value === 'boolean') {
|
|
44
|
+
result.${fieldNames.boolValue} = value;
|
|
45
|
+
} else if (typeof value === 'number') {
|
|
46
|
+
result.${fieldNames.numberValue} = value;
|
|
47
|
+
} else if (typeof value === 'string') {
|
|
48
|
+
result.${fieldNames.stringValue} = value;
|
|
49
|
+
} else if (Array.isArray(value)) {
|
|
50
|
+
result.${fieldNames.listValue} = ListValue.wrap(value);
|
|
51
|
+
} else if (typeof value === 'object') {
|
|
52
|
+
result.${fieldNames.structValue} = Struct.wrap(value);
|
|
53
|
+
} else if (typeof value !== 'undefined') {
|
|
54
|
+
throw new Error('Unsupported any value type: ' + typeof value);
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}`);
|
|
58
|
+
}
|
|
59
|
+
if ((0, types_1.isListValueTypeName)(fullProtoTypeName)) {
|
|
60
|
+
const maybeReadyOnly = ctx.options.useReadonlyTypes ? "Readonly" : "";
|
|
61
|
+
chunks.push((0, ts_poet_1.code) `wrap(array: ${maybeReadyOnly}Array<any> | undefined): ListValue {
|
|
62
|
+
const result = createBaseListValue()${maybeAsAny(ctx.options)};
|
|
63
|
+
result.values = (array ?? []).map(Value.wrap);
|
|
64
|
+
return result;
|
|
65
|
+
}`);
|
|
66
|
+
}
|
|
67
|
+
if ((0, types_1.isFieldMaskTypeName)(fullProtoTypeName)) {
|
|
68
|
+
chunks.push((0, ts_poet_1.code) `wrap(paths: ${maybeReadonly(ctx.options)} string[]): FieldMask {
|
|
69
|
+
const result = createBaseFieldMask()${maybeAsAny(ctx.options)};
|
|
70
|
+
result.paths = paths;
|
|
71
|
+
return result;
|
|
72
|
+
}`);
|
|
73
|
+
}
|
|
74
|
+
return chunks;
|
|
75
|
+
}
|
|
76
|
+
exports.generateWrapDeep = generateWrapDeep;
|
|
77
|
+
/**
|
|
78
|
+
* Converts proto's Struct/Value?listValue messages to ts-proto's idiomatic representation.
|
|
79
|
+
*
|
|
80
|
+
* We do this deeply b/c NestJS does not invoke wrappers recursively.
|
|
81
|
+
*/
|
|
82
|
+
function generateUnwrapDeep(ctx, fullProtoTypeName, fieldNames) {
|
|
83
|
+
const chunks = [];
|
|
84
|
+
if ((0, types_1.isStructTypeName)(fullProtoTypeName)) {
|
|
85
|
+
if (ctx.options.useMapType) {
|
|
86
|
+
chunks.push((0, ts_poet_1.code) `unwrap(message: Struct): {[key: string]: any} {
|
|
87
|
+
const object: { [key: string]: any } = {};
|
|
88
|
+
[...message.fields.keys()].forEach((key) => {
|
|
89
|
+
object[key] = Value.unwrap(message.fields.get(key));
|
|
90
|
+
});
|
|
91
|
+
return object;
|
|
92
|
+
}`);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
chunks.push((0, ts_poet_1.code) `unwrap(message: Struct): {[key: string]: any} {
|
|
96
|
+
const object: { [key: string]: any } = {};
|
|
97
|
+
if (message.fields) {
|
|
98
|
+
Object.keys(message.fields).forEach(key => {
|
|
99
|
+
object[key] = Value.unwrap(message.fields[key]);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return object;
|
|
103
|
+
}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if ((0, types_1.isAnyValueTypeName)(fullProtoTypeName)) {
|
|
107
|
+
// We check hasOwnProperty because the incoming `message` has been serde-ing
|
|
108
|
+
// by the NestJS/protobufjs runtime, and so has a base class with default values
|
|
109
|
+
// that throw off the simpler checks we do in generateUnwrapShallow
|
|
110
|
+
chunks.push((0, ts_poet_1.code) `unwrap(message: any): string | number | boolean | Object | null | Array<any> | undefined {
|
|
111
|
+
if (message?.hasOwnProperty('${fieldNames.stringValue}') && message.${fieldNames.stringValue} !== undefined) {
|
|
112
|
+
return message.${fieldNames.stringValue};
|
|
113
|
+
} else if (message?.hasOwnProperty('${fieldNames.numberValue}') && message?.${fieldNames.numberValue} !== undefined) {
|
|
114
|
+
return message.${fieldNames.numberValue};
|
|
115
|
+
} else if (message?.hasOwnProperty('${fieldNames.boolValue}') && message?.${fieldNames.boolValue} !== undefined) {
|
|
116
|
+
return message.${fieldNames.boolValue};
|
|
117
|
+
} else if (message?.hasOwnProperty('${fieldNames.structValue}') && message?.${fieldNames.structValue} !== undefined) {
|
|
118
|
+
return Struct.unwrap(message.${fieldNames.structValue} as any);
|
|
119
|
+
} else if (message?.hasOwnProperty('${fieldNames.listValue}') && message?.${fieldNames.listValue} !== undefined) {
|
|
120
|
+
return ListValue.unwrap(message.${fieldNames.listValue});
|
|
121
|
+
} else if (message?.hasOwnProperty('${fieldNames.nullValue}') && message?.${fieldNames.nullValue} !== undefined) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
return undefined;
|
|
125
|
+
}`);
|
|
126
|
+
}
|
|
127
|
+
if ((0, types_1.isListValueTypeName)(fullProtoTypeName)) {
|
|
128
|
+
chunks.push((0, ts_poet_1.code) `unwrap(message: ${ctx.options.useReadonlyTypes ? "any" : "ListValue"}): Array<any> {
|
|
129
|
+
if (message?.hasOwnProperty('values') && Array.isArray(message.values)) {
|
|
130
|
+
return message.values.map(Value.unwrap);
|
|
131
|
+
} else {
|
|
132
|
+
return message as any;
|
|
133
|
+
}
|
|
134
|
+
}`);
|
|
135
|
+
}
|
|
136
|
+
if ((0, types_1.isFieldMaskTypeName)(fullProtoTypeName)) {
|
|
137
|
+
chunks.push((0, ts_poet_1.code) `unwrap(message: ${ctx.options.useReadonlyTypes ? "any" : "FieldMask"}): string[] {
|
|
138
|
+
return message.paths;
|
|
139
|
+
}`);
|
|
140
|
+
}
|
|
141
|
+
return chunks;
|
|
142
|
+
}
|
|
143
|
+
exports.generateUnwrapDeep = generateUnwrapDeep;
|
|
144
|
+
/**
|
|
145
|
+
* Converts ts-proto's idiomatic Struct/Value/ListValue representation to the proto messages.
|
|
146
|
+
*
|
|
147
|
+
* We do this shallow's b/c ts-proto's encode methods handle the recursion.
|
|
148
|
+
*/
|
|
149
|
+
function generateWrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
150
|
+
const chunks = [];
|
|
151
|
+
if ((0, types_1.isStructTypeName)(fullProtoTypeName)) {
|
|
152
|
+
let setStatement = "struct.fields[key] = object[key];";
|
|
153
|
+
if (ctx.options.useMapType) {
|
|
154
|
+
setStatement = "struct.fields.set(key, object[key]);";
|
|
155
|
+
}
|
|
156
|
+
chunks.push((0, ts_poet_1.code) `wrap(object: {[key: string]: any} | undefined): Struct {
|
|
157
|
+
const struct = createBaseStruct();
|
|
158
|
+
if (object !== undefined) {
|
|
159
|
+
Object.keys(object).forEach(key => {
|
|
160
|
+
${setStatement}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return struct;
|
|
164
|
+
}`);
|
|
165
|
+
}
|
|
166
|
+
if ((0, types_1.isAnyValueTypeName)(fullProtoTypeName)) {
|
|
167
|
+
if (ctx.options.oneof === options_1.OneofOption.UNIONS) {
|
|
168
|
+
chunks.push((0, ts_poet_1.code) `wrap(value: any): Value {
|
|
169
|
+
const result = createBaseValue()${maybeAsAny(ctx.options)};
|
|
170
|
+
if (value === null) {
|
|
171
|
+
result.kind = {$case: '${fieldNames.nullValue}', ${fieldNames.nullValue}: NullValue.NULL_VALUE};
|
|
172
|
+
} else if (typeof value === 'boolean') {
|
|
173
|
+
result.kind = {$case: '${fieldNames.boolValue}', ${fieldNames.boolValue}: value};
|
|
174
|
+
} else if (typeof value === 'number') {
|
|
175
|
+
result.kind = {$case: '${fieldNames.numberValue}', ${fieldNames.numberValue}: value};
|
|
176
|
+
} else if (typeof value === 'string') {
|
|
177
|
+
result.kind = {$case: '${fieldNames.stringValue}', ${fieldNames.stringValue}: value};
|
|
178
|
+
} else if (Array.isArray(value)) {
|
|
179
|
+
result.kind = {$case: '${fieldNames.listValue}', ${fieldNames.listValue}: value};
|
|
180
|
+
} else if (typeof value === 'object') {
|
|
181
|
+
result.kind = {$case: '${fieldNames.structValue}', ${fieldNames.structValue}: value};
|
|
182
|
+
} else if (typeof value !== 'undefined') {
|
|
183
|
+
throw new Error('Unsupported any value type: ' + typeof value);
|
|
184
|
+
}
|
|
185
|
+
return result;
|
|
186
|
+
}`);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
chunks.push((0, ts_poet_1.code) `wrap(value: any): Value {
|
|
190
|
+
const result = createBaseValue()${maybeAsAny(ctx.options)};
|
|
191
|
+
if (value === null) {
|
|
192
|
+
result.${fieldNames.nullValue} = NullValue.NULL_VALUE;
|
|
193
|
+
} else if (typeof value === 'boolean') {
|
|
194
|
+
result.${fieldNames.boolValue} = value;
|
|
195
|
+
} else if (typeof value === 'number') {
|
|
196
|
+
result.${fieldNames.numberValue} = value;
|
|
197
|
+
} else if (typeof value === 'string') {
|
|
198
|
+
result.${fieldNames.stringValue} = value;
|
|
199
|
+
} else if (Array.isArray(value)) {
|
|
200
|
+
result.${fieldNames.listValue} = value;
|
|
201
|
+
} else if (typeof value === 'object') {
|
|
202
|
+
result.${fieldNames.structValue} = value;
|
|
203
|
+
} else if (typeof value !== 'undefined') {
|
|
204
|
+
throw new Error('Unsupported any value type: ' + typeof value);
|
|
205
|
+
}
|
|
206
|
+
return result;
|
|
207
|
+
}`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if ((0, types_1.isListValueTypeName)(fullProtoTypeName)) {
|
|
211
|
+
const maybeReadyOnly = ctx.options.useReadonlyTypes ? "Readonly" : "";
|
|
212
|
+
chunks.push((0, ts_poet_1.code) `wrap(array: ${maybeReadyOnly}Array<any> | undefined): ListValue {
|
|
213
|
+
const result = createBaseListValue()${maybeAsAny(ctx.options)};
|
|
214
|
+
result.values = array ?? [];
|
|
215
|
+
return result;
|
|
216
|
+
}`);
|
|
217
|
+
}
|
|
218
|
+
if ((0, types_1.isFieldMaskTypeName)(fullProtoTypeName)) {
|
|
219
|
+
chunks.push((0, ts_poet_1.code) `wrap(paths: ${maybeReadonly(ctx.options)} string[]): FieldMask {
|
|
220
|
+
const result = createBaseFieldMask()${maybeAsAny(ctx.options)};
|
|
221
|
+
result.paths = paths;
|
|
222
|
+
return result;
|
|
223
|
+
}`);
|
|
224
|
+
}
|
|
225
|
+
return chunks;
|
|
226
|
+
}
|
|
227
|
+
exports.generateWrapShallow = generateWrapShallow;
|
|
228
|
+
/**
|
|
229
|
+
* Converts proto's Struct/Value?listValue messages to ts-proto's idiomatic representation.
|
|
230
|
+
*
|
|
231
|
+
* We do this shallowly b/c ts-proto's decode methods handle recursion.
|
|
232
|
+
*/
|
|
233
|
+
function generateUnwrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
234
|
+
const chunks = [];
|
|
235
|
+
if ((0, types_1.isStructTypeName)(fullProtoTypeName)) {
|
|
236
|
+
if (ctx.options.useMapType) {
|
|
237
|
+
chunks.push((0, ts_poet_1.code) `unwrap(message: Struct): {[key: string]: any} {
|
|
238
|
+
const object: { [key: string]: any } = {};
|
|
239
|
+
[...message.fields.keys()].forEach((key) => {
|
|
240
|
+
object[key] = message.fields.get(key);
|
|
241
|
+
});
|
|
242
|
+
return object;
|
|
243
|
+
}`);
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
chunks.push((0, ts_poet_1.code) `unwrap(message: Struct): {[key: string]: any} {
|
|
247
|
+
const object: { [key: string]: any } = {};
|
|
248
|
+
if (message.fields) {
|
|
249
|
+
Object.keys(message.fields).forEach(key => {
|
|
250
|
+
object[key] = message.fields[key];
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
return object;
|
|
254
|
+
}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if ((0, types_1.isAnyValueTypeName)(fullProtoTypeName)) {
|
|
258
|
+
if (ctx.options.oneof === options_1.OneofOption.UNIONS) {
|
|
259
|
+
chunks.push((0, ts_poet_1.code) `unwrap(message: Value): string | number | boolean | Object | null | Array<any> | undefined {
|
|
260
|
+
if (message.kind?.$case === '${fieldNames.nullValue}') {
|
|
261
|
+
return null;
|
|
262
|
+
} else if (message.kind?.$case === '${fieldNames.numberValue}') {
|
|
263
|
+
return message.kind?.${fieldNames.numberValue};
|
|
264
|
+
} else if (message.kind?.$case === '${fieldNames.stringValue}') {
|
|
265
|
+
return message.kind?.${fieldNames.stringValue};
|
|
266
|
+
} else if (message.kind?.$case === '${fieldNames.boolValue}') {
|
|
267
|
+
return message.kind?.${fieldNames.boolValue};
|
|
268
|
+
} else if (message.kind?.$case === '${fieldNames.structValue}') {
|
|
269
|
+
return message.kind?.${fieldNames.structValue};
|
|
270
|
+
} else if (message.kind?.$case === '${fieldNames.listValue}') {
|
|
271
|
+
return message.kind?.${fieldNames.listValue};
|
|
272
|
+
} else {
|
|
273
|
+
return undefined;
|
|
274
|
+
}
|
|
275
|
+
}`);
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
chunks.push((0, ts_poet_1.code) `unwrap(message: any): string | number | boolean | Object | null | Array<any> | undefined {
|
|
279
|
+
if (message.${fieldNames.stringValue} !== undefined) {
|
|
280
|
+
return message.${fieldNames.stringValue};
|
|
281
|
+
} else if (message?.${fieldNames.numberValue} !== undefined) {
|
|
282
|
+
return message.${fieldNames.numberValue};
|
|
283
|
+
} else if (message?.${fieldNames.boolValue} !== undefined) {
|
|
284
|
+
return message.${fieldNames.boolValue};
|
|
285
|
+
} else if (message?.${fieldNames.structValue} !== undefined) {
|
|
286
|
+
return message.${fieldNames.structValue} as any;
|
|
287
|
+
} else if (message?.${fieldNames.listValue} !== undefined) {
|
|
288
|
+
return message.${fieldNames.listValue};
|
|
289
|
+
} else if (message?.${fieldNames.nullValue} !== undefined) {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
return undefined;
|
|
293
|
+
}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if ((0, types_1.isListValueTypeName)(fullProtoTypeName)) {
|
|
297
|
+
chunks.push((0, ts_poet_1.code) `unwrap(message: ${ctx.options.useReadonlyTypes ? "any" : "ListValue"}): Array<any> {
|
|
298
|
+
if (message?.hasOwnProperty('values') && Array.isArray(message.values)) {
|
|
299
|
+
return message.values;
|
|
300
|
+
} else {
|
|
301
|
+
return message as any;
|
|
302
|
+
}
|
|
303
|
+
}`);
|
|
304
|
+
}
|
|
305
|
+
if ((0, types_1.isFieldMaskTypeName)(fullProtoTypeName)) {
|
|
306
|
+
chunks.push((0, ts_poet_1.code) `unwrap(message: ${ctx.options.useReadonlyTypes ? "any" : "FieldMask"}): string[] {
|
|
307
|
+
return message.paths;
|
|
308
|
+
}`);
|
|
309
|
+
}
|
|
310
|
+
return chunks;
|
|
311
|
+
}
|
|
312
|
+
exports.generateUnwrapShallow = generateUnwrapShallow;
|
|
313
|
+
function maybeReadonly(options) {
|
|
314
|
+
return options.useReadonlyTypes ? "readonly " : "";
|
|
315
|
+
}
|
|
316
|
+
function maybeAsAny(options) {
|
|
317
|
+
return options.useReadonlyTypes ? " as any" : "";
|
|
318
|
+
}
|
package/build/main.js
CHANGED
|
@@ -18,6 +18,7 @@ const ConditionalOutput_1 = require("ts-poet/build/ConditionalOutput");
|
|
|
18
18
|
const generate_grpc_js_1 = require("./generate-grpc-js");
|
|
19
19
|
const generate_generic_service_definition_1 = require("./generate-generic-service-definition");
|
|
20
20
|
const generate_nice_grpc_1 = require("./generate-nice-grpc");
|
|
21
|
+
const generate_struct_wrappers_1 = require("./generate-struct-wrappers");
|
|
21
22
|
function generateFile(ctx, fileDesc) {
|
|
22
23
|
var _a;
|
|
23
24
|
const { options, utils } = ctx;
|
|
@@ -72,11 +73,18 @@ function generateFile(ctx, fileDesc) {
|
|
|
72
73
|
chunks.push(makeProtobufTimestampWrapper());
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
|
-
|
|
76
|
+
// We add `nestJs` here because enough though it doesn't use our encode/decode methods
|
|
77
|
+
// for most/vanilla messages, we do generate static wrap/unwrap methods for the special
|
|
78
|
+
// Struct/Value/wrapper types and use the `wrappers[...]` to have NestJS know about them.
|
|
79
|
+
if (options.outputEncodeMethods || options.outputJsonMethods || options.outputTypeRegistry || options.nestJs) {
|
|
76
80
|
// then add the encoder/decoder/base instance
|
|
77
81
|
(0, visit_1.visit)(fileDesc, sourceInfo, (fullName, message, _sInfo, fullProtoTypeName) => {
|
|
78
82
|
const fullTypeName = (0, utils_1.maybePrefixPackage)(fileDesc, fullProtoTypeName);
|
|
79
|
-
|
|
83
|
+
const outputWrapAndUnwrap = (0, generate_struct_wrappers_1.isWrapperType)(fullTypeName);
|
|
84
|
+
// Only decode, fromPartial, and wrap use the createBase method
|
|
85
|
+
if (options.outputEncodeMethods || options.outputPartialMethods || outputWrapAndUnwrap) {
|
|
86
|
+
chunks.push(generateBaseInstanceFactory(ctx, fullName, message, fullTypeName));
|
|
87
|
+
}
|
|
80
88
|
const staticMembers = [];
|
|
81
89
|
if (options.outputTypeRegistry) {
|
|
82
90
|
staticMembers.push((0, ts_poet_1.code) `$type: '${fullTypeName}' as const`);
|
|
@@ -104,13 +112,21 @@ function generateFile(ctx, fileDesc) {
|
|
|
104
112
|
structValue: (0, case_1.maybeSnakeToCamel)("struct_value", ctx.options),
|
|
105
113
|
listValue: (0, case_1.maybeSnakeToCamel)("list_value", ctx.options),
|
|
106
114
|
};
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
115
|
+
if (options.nestJs) {
|
|
116
|
+
staticMembers.push(...(0, generate_struct_wrappers_1.generateWrapDeep)(ctx, fullTypeName, structFieldNames));
|
|
117
|
+
staticMembers.push(...(0, generate_struct_wrappers_1.generateUnwrapDeep)(ctx, fullTypeName, structFieldNames));
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
staticMembers.push(...(0, generate_struct_wrappers_1.generateWrapShallow)(ctx, fullTypeName, structFieldNames));
|
|
121
|
+
staticMembers.push(...(0, generate_struct_wrappers_1.generateUnwrapShallow)(ctx, fullTypeName, structFieldNames));
|
|
122
|
+
}
|
|
123
|
+
if (staticMembers.length > 0) {
|
|
124
|
+
chunks.push((0, ts_poet_1.code) `
|
|
125
|
+
export const ${(0, ts_poet_1.def)(fullName)} = {
|
|
126
|
+
${(0, ts_poet_1.joinCode)(staticMembers, { on: ",\n\n" })}
|
|
127
|
+
};
|
|
128
|
+
`);
|
|
129
|
+
}
|
|
114
130
|
if (options.outputTypeRegistry) {
|
|
115
131
|
const messageTypeRegistry = (0, utils_1.impFile)(options, "messageTypeRegistry@./typeRegistry");
|
|
116
132
|
chunks.push((0, ts_poet_1.code) `
|
|
@@ -119,6 +135,11 @@ function generateFile(ctx, fileDesc) {
|
|
|
119
135
|
}
|
|
120
136
|
}, options);
|
|
121
137
|
}
|
|
138
|
+
if (options.nestJs) {
|
|
139
|
+
if (fileDesc.messageType.find((message) => message.field.find(types_1.isStructType))) {
|
|
140
|
+
chunks.push(makeProtobufStructWrapper(options));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
122
143
|
let hasServerStreamingMethods = false;
|
|
123
144
|
let hasStreamingMethods = false;
|
|
124
145
|
(0, visit_1.visitServices)(fileDesc, sourceInfo, (serviceDesc, sInfo) => {
|
|
@@ -244,6 +265,15 @@ function makeProtobufTimestampWrapper() {
|
|
|
244
265
|
},
|
|
245
266
|
} as any;`;
|
|
246
267
|
}
|
|
268
|
+
function makeProtobufStructWrapper(options) {
|
|
269
|
+
const wrappers = (0, ts_poet_1.imp)("wrappers@protobufjs");
|
|
270
|
+
const Struct = (0, utils_1.impProto)(options, "google/protobuf/struct", "Struct");
|
|
271
|
+
return (0, ts_poet_1.code) `
|
|
272
|
+
${wrappers}['.google.protobuf.Struct'] = {
|
|
273
|
+
fromObject: ${Struct}.wrap,
|
|
274
|
+
toObject: ${Struct}.unwrap,
|
|
275
|
+
} as any;`;
|
|
276
|
+
}
|
|
247
277
|
function makeLongUtils(options, bytes) {
|
|
248
278
|
// Regardless of which `forceLong` config option we're using, we always use
|
|
249
279
|
// the `long` library to either represent or at least sanity-check 64-bit values
|
|
@@ -771,6 +801,53 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
771
801
|
chunks.push((0, ts_poet_1.code) `}`);
|
|
772
802
|
return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
|
|
773
803
|
}
|
|
804
|
+
/** Returns a generic writer.doSomething based on the basic type */
|
|
805
|
+
function getEncodeWriteSnippet(ctx, field) {
|
|
806
|
+
const { options, utils } = ctx;
|
|
807
|
+
if ((0, types_1.isEnum)(field) && options.stringEnums) {
|
|
808
|
+
const tag = ((field.number << 3) | (0, types_1.basicWireType)(field.type)) >>> 0;
|
|
809
|
+
const toNumber = (0, types_1.getEnumMethod)(ctx, field.typeName, "ToNumber");
|
|
810
|
+
return (place) => (0, ts_poet_1.code) `writer.uint32(${tag}).${(0, types_1.toReaderCall)(field)}(${toNumber}(${place}))`;
|
|
811
|
+
}
|
|
812
|
+
else if ((0, types_1.isLong)(field) && options.forceLong === options_1.LongOption.BIGINT) {
|
|
813
|
+
const tag = ((field.number << 3) | (0, types_1.basicWireType)(field.type)) >>> 0;
|
|
814
|
+
return (place) => (0, ts_poet_1.code) `writer.uint32(${tag}).${(0, types_1.toReaderCall)(field)}(${place}.toString())`;
|
|
815
|
+
}
|
|
816
|
+
else if ((0, types_1.isScalar)(field) || (0, types_1.isEnum)(field)) {
|
|
817
|
+
const tag = ((field.number << 3) | (0, types_1.basicWireType)(field.type)) >>> 0;
|
|
818
|
+
return (place) => (0, ts_poet_1.code) `writer.uint32(${tag}).${(0, types_1.toReaderCall)(field)}(${place})`;
|
|
819
|
+
}
|
|
820
|
+
else if ((0, types_1.isObjectId)(field) && options.useMongoObjectId) {
|
|
821
|
+
const tag = ((field.number << 3) | 2) >>> 0;
|
|
822
|
+
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
823
|
+
return (place) => (0, ts_poet_1.code) `${type}.encode(${utils.toProtoObjectId}(${place}), writer.uint32(${tag}).fork()).ldelim()`;
|
|
824
|
+
}
|
|
825
|
+
else if ((0, types_1.isTimestamp)(field) && (options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) {
|
|
826
|
+
const tag = ((field.number << 3) | 2) >>> 0;
|
|
827
|
+
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
828
|
+
return (place) => (0, ts_poet_1.code) `${type}.encode(${utils.toTimestamp}(${place}), writer.uint32(${tag}).fork()).ldelim()`;
|
|
829
|
+
}
|
|
830
|
+
else if ((0, types_1.isValueType)(ctx, field)) {
|
|
831
|
+
const maybeTypeField = options.outputTypeRegistry ? `$type: '${field.typeName.slice(1)}',` : "";
|
|
832
|
+
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
833
|
+
const wrappedValue = (place) => {
|
|
834
|
+
if ((0, types_1.isAnyValueType)(field) || (0, types_1.isListValueType)(field) || (0, types_1.isStructType)(field) || (0, types_1.isFieldMaskType)(field)) {
|
|
835
|
+
return (0, ts_poet_1.code) `${type}.wrap(${place})`;
|
|
836
|
+
}
|
|
837
|
+
return (0, ts_poet_1.code) `{${maybeTypeField} value: ${place}!}`;
|
|
838
|
+
};
|
|
839
|
+
const tag = ((field.number << 3) | 2) >>> 0;
|
|
840
|
+
return (place) => (0, ts_poet_1.code) `${type}.encode(${wrappedValue(place)}, writer.uint32(${tag}).fork()).ldelim()`;
|
|
841
|
+
}
|
|
842
|
+
else if ((0, types_1.isMessage)(field)) {
|
|
843
|
+
const tag = ((field.number << 3) | 2) >>> 0;
|
|
844
|
+
const type = (0, types_1.basicTypeName)(ctx, field);
|
|
845
|
+
return (place) => (0, ts_poet_1.code) `${type}.encode(${place}, writer.uint32(${tag}).fork()).ldelim()`;
|
|
846
|
+
}
|
|
847
|
+
else {
|
|
848
|
+
throw new Error(`Unhandled field ${field}`);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
774
851
|
/** Creates a function to encode a message by loop overing the tags. */
|
|
775
852
|
function generateEncode(ctx, fullName, messageDesc) {
|
|
776
853
|
const { options, utils, typeMap } = ctx;
|
|
@@ -783,54 +860,15 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
783
860
|
writer: ${Writer} = ${Writer}.create(),
|
|
784
861
|
): ${Writer} {
|
|
785
862
|
`);
|
|
863
|
+
const processedOneofs = new Set();
|
|
864
|
+
const oneOfFieldsDict = messageDesc.field
|
|
865
|
+
.filter((field) => (0, types_1.isWithinOneOfThatShouldBeUnion)(options, field))
|
|
866
|
+
.reduce((result, field) => ((result[field.oneofIndex] || (result[field.oneofIndex] = [])).push(field), result), {});
|
|
786
867
|
// then add a case for each field
|
|
787
868
|
messageDesc.field.forEach((field) => {
|
|
788
869
|
const fieldName = (0, case_1.maybeSnakeToCamel)(field.name, options);
|
|
789
870
|
// get a generic writer.doSomething based on the basic type
|
|
790
|
-
|
|
791
|
-
if ((0, types_1.isEnum)(field) && options.stringEnums) {
|
|
792
|
-
const tag = ((field.number << 3) | (0, types_1.basicWireType)(field.type)) >>> 0;
|
|
793
|
-
const toNumber = (0, types_1.getEnumMethod)(ctx, field.typeName, "ToNumber");
|
|
794
|
-
writeSnippet = (place) => (0, ts_poet_1.code) `writer.uint32(${tag}).${(0, types_1.toReaderCall)(field)}(${toNumber}(${place}))`;
|
|
795
|
-
}
|
|
796
|
-
else if ((0, types_1.isLong)(field) && options.forceLong === options_1.LongOption.BIGINT) {
|
|
797
|
-
const tag = ((field.number << 3) | (0, types_1.basicWireType)(field.type)) >>> 0;
|
|
798
|
-
writeSnippet = (place) => (0, ts_poet_1.code) `writer.uint32(${tag}).${(0, types_1.toReaderCall)(field)}(${place}.toString())`;
|
|
799
|
-
}
|
|
800
|
-
else if ((0, types_1.isScalar)(field) || (0, types_1.isEnum)(field)) {
|
|
801
|
-
const tag = ((field.number << 3) | (0, types_1.basicWireType)(field.type)) >>> 0;
|
|
802
|
-
writeSnippet = (place) => (0, ts_poet_1.code) `writer.uint32(${tag}).${(0, types_1.toReaderCall)(field)}(${place})`;
|
|
803
|
-
}
|
|
804
|
-
else if ((0, types_1.isObjectId)(field) && options.useMongoObjectId) {
|
|
805
|
-
const tag = ((field.number << 3) | 2) >>> 0;
|
|
806
|
-
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
807
|
-
writeSnippet = (place) => (0, ts_poet_1.code) `${type}.encode(${utils.toProtoObjectId}(${place}), writer.uint32(${tag}).fork()).ldelim()`;
|
|
808
|
-
}
|
|
809
|
-
else if ((0, types_1.isTimestamp)(field) && (options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) {
|
|
810
|
-
const tag = ((field.number << 3) | 2) >>> 0;
|
|
811
|
-
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
812
|
-
writeSnippet = (place) => (0, ts_poet_1.code) `${type}.encode(${utils.toTimestamp}(${place}), writer.uint32(${tag}).fork()).ldelim()`;
|
|
813
|
-
}
|
|
814
|
-
else if ((0, types_1.isValueType)(ctx, field)) {
|
|
815
|
-
const maybeTypeField = options.outputTypeRegistry ? `$type: '${field.typeName.slice(1)}',` : "";
|
|
816
|
-
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
817
|
-
const wrappedValue = (place) => {
|
|
818
|
-
if ((0, types_1.isAnyValueType)(field) || (0, types_1.isListValueType)(field) || (0, types_1.isStructType)(field) || (0, types_1.isFieldMaskType)(field)) {
|
|
819
|
-
return (0, ts_poet_1.code) `${type}.wrap(${place})`;
|
|
820
|
-
}
|
|
821
|
-
return (0, ts_poet_1.code) `{${maybeTypeField} value: ${place}!}`;
|
|
822
|
-
};
|
|
823
|
-
const tag = ((field.number << 3) | 2) >>> 0;
|
|
824
|
-
writeSnippet = (place) => (0, ts_poet_1.code) `${type}.encode(${wrappedValue(place)}, writer.uint32(${tag}).fork()).ldelim()`;
|
|
825
|
-
}
|
|
826
|
-
else if ((0, types_1.isMessage)(field)) {
|
|
827
|
-
const tag = ((field.number << 3) | 2) >>> 0;
|
|
828
|
-
const type = (0, types_1.basicTypeName)(ctx, field);
|
|
829
|
-
writeSnippet = (place) => (0, ts_poet_1.code) `${type}.encode(${place}, writer.uint32(${tag}).fork()).ldelim()`;
|
|
830
|
-
}
|
|
831
|
-
else {
|
|
832
|
-
throw new Error(`Unhandled field ${field}`);
|
|
833
|
-
}
|
|
871
|
+
const writeSnippet = getEncodeWriteSnippet(ctx, field);
|
|
834
872
|
const isOptional = (0, types_1.isOptionalProperty)(field, messageDesc.options, options);
|
|
835
873
|
if ((0, types_1.isRepeated)(field)) {
|
|
836
874
|
if ((0, types_1.isMapType)(ctx, messageDesc, field)) {
|
|
@@ -925,12 +963,19 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
925
963
|
}
|
|
926
964
|
}
|
|
927
965
|
else if ((0, types_1.isWithinOneOfThatShouldBeUnion)(options, field)) {
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
966
|
+
if (!processedOneofs.has(field.oneofIndex)) {
|
|
967
|
+
processedOneofs.add(field.oneofIndex);
|
|
968
|
+
const oneofName = (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options);
|
|
969
|
+
chunks.push((0, ts_poet_1.code) `switch (message.${oneofName}?.$case) {`);
|
|
970
|
+
for (const oneOfField of oneOfFieldsDict[field.oneofIndex]) {
|
|
971
|
+
const writeSnippet = getEncodeWriteSnippet(ctx, oneOfField);
|
|
972
|
+
const oneOfFieldName = (0, case_1.maybeSnakeToCamel)(oneOfField.name, ctx.options);
|
|
973
|
+
chunks.push((0, ts_poet_1.code) `case "${oneOfFieldName}":
|
|
974
|
+
${writeSnippet(`message.${oneofName}.${oneOfFieldName}`)};
|
|
975
|
+
break;`);
|
|
976
|
+
}
|
|
977
|
+
chunks.push((0, ts_poet_1.code) `}`);
|
|
978
|
+
}
|
|
934
979
|
}
|
|
935
980
|
else if ((0, types_1.isWithinOneOf)(field)) {
|
|
936
981
|
// Oneofs don't have a default value check b/c they need to denote which-oneof presence
|
|
@@ -1389,9 +1434,24 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1389
1434
|
return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
|
|
1390
1435
|
}
|
|
1391
1436
|
function generateFromPartial(ctx, fullName, messageDesc) {
|
|
1392
|
-
const { options, utils
|
|
1437
|
+
const { options, utils } = ctx;
|
|
1393
1438
|
const chunks = [];
|
|
1394
|
-
// create the
|
|
1439
|
+
// create the create function definition
|
|
1440
|
+
if (ctx.options.useExactTypes) {
|
|
1441
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1442
|
+
create<I extends ${utils.Exact}<${utils.DeepPartial}<${fullName}>, I>>(base?: I): ${fullName} {
|
|
1443
|
+
`);
|
|
1444
|
+
}
|
|
1445
|
+
else {
|
|
1446
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1447
|
+
create(base?: ${utils.DeepPartial}<${fullName}>): ${fullName} {
|
|
1448
|
+
`);
|
|
1449
|
+
}
|
|
1450
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1451
|
+
return ${fullName}.fromPartial(base ?? {})
|
|
1452
|
+
`);
|
|
1453
|
+
chunks.push((0, ts_poet_1.code) `},`, (0, ts_poet_1.code) ``);
|
|
1454
|
+
// create the fromPartial function declaration
|
|
1395
1455
|
const paramName = messageDesc.field.length > 0 ? "object" : "_";
|
|
1396
1456
|
if (ctx.options.useExactTypes) {
|
|
1397
1457
|
chunks.push((0, ts_poet_1.code) `
|
|
@@ -1538,164 +1598,6 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1538
1598
|
chunks.push((0, ts_poet_1.code) `}`);
|
|
1539
1599
|
return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
|
|
1540
1600
|
}
|
|
1541
|
-
function generateWrap(ctx, fullProtoTypeName, fieldNames) {
|
|
1542
|
-
const chunks = [];
|
|
1543
|
-
if ((0, types_1.isStructTypeName)(fullProtoTypeName)) {
|
|
1544
|
-
let setStatement = "struct.fields[key] = object[key];";
|
|
1545
|
-
if (ctx.options.useMapType) {
|
|
1546
|
-
setStatement = "struct.fields.set(key, object[key]);";
|
|
1547
|
-
}
|
|
1548
|
-
chunks.push((0, ts_poet_1.code) `wrap(object: {[key: string]: any} | undefined): Struct {
|
|
1549
|
-
const struct = createBaseStruct();
|
|
1550
|
-
if (object !== undefined) {
|
|
1551
|
-
Object.keys(object).forEach(key => {
|
|
1552
|
-
${setStatement}
|
|
1553
|
-
});
|
|
1554
|
-
}
|
|
1555
|
-
return struct;
|
|
1556
|
-
}`);
|
|
1557
|
-
}
|
|
1558
|
-
if ((0, types_1.isAnyValueTypeName)(fullProtoTypeName)) {
|
|
1559
|
-
if (ctx.options.oneof === options_1.OneofOption.UNIONS) {
|
|
1560
|
-
chunks.push((0, ts_poet_1.code) `wrap(value: any): Value {
|
|
1561
|
-
const result = createBaseValue()${maybeAsAny(ctx.options)};
|
|
1562
|
-
|
|
1563
|
-
if (value === null) {
|
|
1564
|
-
result.kind = {$case: '${fieldNames.nullValue}', ${fieldNames.nullValue}: NullValue.NULL_VALUE};
|
|
1565
|
-
} else if (typeof value === 'boolean') {
|
|
1566
|
-
result.kind = {$case: '${fieldNames.boolValue}', ${fieldNames.boolValue}: value};
|
|
1567
|
-
} else if (typeof value === 'number') {
|
|
1568
|
-
result.kind = {$case: '${fieldNames.numberValue}', ${fieldNames.numberValue}: value};
|
|
1569
|
-
} else if (typeof value === 'string') {
|
|
1570
|
-
result.kind = {$case: '${fieldNames.stringValue}', ${fieldNames.stringValue}: value};
|
|
1571
|
-
} else if (Array.isArray(value)) {
|
|
1572
|
-
result.kind = {$case: '${fieldNames.listValue}', ${fieldNames.listValue}: value};
|
|
1573
|
-
} else if (typeof value === 'object') {
|
|
1574
|
-
result.kind = {$case: '${fieldNames.structValue}', ${fieldNames.structValue}: value};
|
|
1575
|
-
} else if (typeof value !== 'undefined') {
|
|
1576
|
-
throw new Error('Unsupported any value type: ' + typeof value);
|
|
1577
|
-
}
|
|
1578
|
-
|
|
1579
|
-
return result;
|
|
1580
|
-
}`);
|
|
1581
|
-
}
|
|
1582
|
-
else {
|
|
1583
|
-
chunks.push((0, ts_poet_1.code) `wrap(value: any): Value {
|
|
1584
|
-
const result = createBaseValue()${maybeAsAny(ctx.options)};
|
|
1585
|
-
|
|
1586
|
-
if (value === null) {
|
|
1587
|
-
result.${fieldNames.nullValue} = NullValue.NULL_VALUE;
|
|
1588
|
-
} else if (typeof value === 'boolean') {
|
|
1589
|
-
result.${fieldNames.boolValue} = value;
|
|
1590
|
-
} else if (typeof value === 'number') {
|
|
1591
|
-
result.${fieldNames.numberValue} = value;
|
|
1592
|
-
} else if (typeof value === 'string') {
|
|
1593
|
-
result.${fieldNames.stringValue} = value;
|
|
1594
|
-
} else if (Array.isArray(value)) {
|
|
1595
|
-
result.${fieldNames.listValue} = value;
|
|
1596
|
-
} else if (typeof value === 'object') {
|
|
1597
|
-
result.${fieldNames.structValue} = value;
|
|
1598
|
-
} else if (typeof value !== 'undefined') {
|
|
1599
|
-
throw new Error('Unsupported any value type: ' + typeof value);
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1602
|
-
return result;
|
|
1603
|
-
}`);
|
|
1604
|
-
}
|
|
1605
|
-
}
|
|
1606
|
-
if ((0, types_1.isListValueTypeName)(fullProtoTypeName)) {
|
|
1607
|
-
chunks.push((0, ts_poet_1.code) `wrap(value: ${ctx.options.useReadonlyTypes ? "ReadonlyArray<any>" : "Array<any>"} | undefined): ListValue {
|
|
1608
|
-
const result = createBaseListValue()${maybeAsAny(ctx.options)};
|
|
1609
|
-
|
|
1610
|
-
result.values = value ?? [];
|
|
1611
|
-
|
|
1612
|
-
return result;
|
|
1613
|
-
}`);
|
|
1614
|
-
}
|
|
1615
|
-
if ((0, types_1.isFieldMaskTypeName)(fullProtoTypeName)) {
|
|
1616
|
-
chunks.push((0, ts_poet_1.code) `wrap(paths: ${maybeReadonly(ctx.options)} string[]): FieldMask {
|
|
1617
|
-
const result = createBaseFieldMask()${maybeAsAny(ctx.options)};
|
|
1618
|
-
|
|
1619
|
-
result.paths = paths;
|
|
1620
|
-
|
|
1621
|
-
return result;
|
|
1622
|
-
}`);
|
|
1623
|
-
}
|
|
1624
|
-
return chunks;
|
|
1625
|
-
}
|
|
1626
|
-
function generateUnwrap(ctx, fullProtoTypeName, fieldNames) {
|
|
1627
|
-
const chunks = [];
|
|
1628
|
-
if ((0, types_1.isStructTypeName)(fullProtoTypeName)) {
|
|
1629
|
-
if (ctx.options.useMapType) {
|
|
1630
|
-
chunks.push((0, ts_poet_1.code) `unwrap(message: Struct): {[key: string]: any} {
|
|
1631
|
-
const object: { [key: string]: any } = {};
|
|
1632
|
-
[...message.fields.keys()].forEach((key) => {
|
|
1633
|
-
object[key] = message.fields.get(key);
|
|
1634
|
-
});
|
|
1635
|
-
return object;
|
|
1636
|
-
}`);
|
|
1637
|
-
}
|
|
1638
|
-
else {
|
|
1639
|
-
chunks.push((0, ts_poet_1.code) `unwrap(message: Struct): {[key: string]: any} {
|
|
1640
|
-
const object: { [key: string]: any } = {};
|
|
1641
|
-
Object.keys(message.fields).forEach(key => {
|
|
1642
|
-
object[key] = message.fields[key];
|
|
1643
|
-
});
|
|
1644
|
-
return object;
|
|
1645
|
-
}`);
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
|
-
if ((0, types_1.isAnyValueTypeName)(fullProtoTypeName)) {
|
|
1649
|
-
if (ctx.options.oneof === options_1.OneofOption.UNIONS) {
|
|
1650
|
-
chunks.push((0, ts_poet_1.code) `unwrap(message: Value): string | number | boolean | Object | null | Array<any> | undefined {
|
|
1651
|
-
if (message.kind?.$case === '${fieldNames.nullValue}') {
|
|
1652
|
-
return null;
|
|
1653
|
-
} else if (message.kind?.$case === '${fieldNames.numberValue}') {
|
|
1654
|
-
return message.kind?.${fieldNames.numberValue};
|
|
1655
|
-
} else if (message.kind?.$case === '${fieldNames.stringValue}') {
|
|
1656
|
-
return message.kind?.${fieldNames.stringValue};
|
|
1657
|
-
} else if (message.kind?.$case === '${fieldNames.boolValue}') {
|
|
1658
|
-
return message.kind?.${fieldNames.boolValue};
|
|
1659
|
-
} else if (message.kind?.$case === '${fieldNames.structValue}') {
|
|
1660
|
-
return message.kind?.${fieldNames.structValue};
|
|
1661
|
-
} else if (message.kind?.$case === '${fieldNames.listValue}') {
|
|
1662
|
-
return message.kind?.${fieldNames.listValue};
|
|
1663
|
-
} else {
|
|
1664
|
-
return undefined;
|
|
1665
|
-
}
|
|
1666
|
-
}`);
|
|
1667
|
-
}
|
|
1668
|
-
else {
|
|
1669
|
-
chunks.push((0, ts_poet_1.code) `unwrap(message: Value): string | number | boolean | Object | null | Array<any> | undefined {
|
|
1670
|
-
if (message?.${fieldNames.stringValue} !== undefined) {
|
|
1671
|
-
return message.${fieldNames.stringValue};
|
|
1672
|
-
} else if (message?.${fieldNames.numberValue} !== undefined) {
|
|
1673
|
-
return message.${fieldNames.numberValue};
|
|
1674
|
-
} else if (message?.${fieldNames.boolValue} !== undefined) {
|
|
1675
|
-
return message.${fieldNames.boolValue};
|
|
1676
|
-
} else if (message?.${fieldNames.structValue} !== undefined) {
|
|
1677
|
-
return message.${fieldNames.structValue};
|
|
1678
|
-
} else if (message?.${fieldNames.listValue} !== undefined) {
|
|
1679
|
-
return message.${fieldNames.listValue};
|
|
1680
|
-
} else if (message?.${fieldNames.nullValue} !== undefined) {
|
|
1681
|
-
return null;
|
|
1682
|
-
}
|
|
1683
|
-
return undefined;
|
|
1684
|
-
}`);
|
|
1685
|
-
}
|
|
1686
|
-
}
|
|
1687
|
-
if ((0, types_1.isListValueTypeName)(fullProtoTypeName)) {
|
|
1688
|
-
chunks.push((0, ts_poet_1.code) `unwrap(message: ${ctx.options.useReadonlyTypes ? "any" : "ListValue"}): Array<any> {
|
|
1689
|
-
return message.values;
|
|
1690
|
-
}`);
|
|
1691
|
-
}
|
|
1692
|
-
if ((0, types_1.isFieldMaskTypeName)(fullProtoTypeName)) {
|
|
1693
|
-
chunks.push((0, ts_poet_1.code) `unwrap(message: ${ctx.options.useReadonlyTypes ? "any" : "FieldMask"}): string[] {
|
|
1694
|
-
return message.paths;
|
|
1695
|
-
}`);
|
|
1696
|
-
}
|
|
1697
|
-
return chunks;
|
|
1698
|
-
}
|
|
1699
1601
|
exports.contextTypeVar = "Context extends DataLoaders";
|
|
1700
1602
|
function maybeCastToNumber(ctx, messageDesc, field, variableName) {
|
|
1701
1603
|
const { keyType } = (0, types_1.detectMapType)(ctx, messageDesc, field);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-proto",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.139.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/plugin.js",
|
|
6
6
|
"repository": "github:stephenh/ts-proto",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"author": "",
|
|
29
29
|
"license": "ISC",
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@grpc/grpc-js": "^1.
|
|
32
|
-
"@grpc/proto-loader": "^0.
|
|
31
|
+
"@grpc/grpc-js": "^1.3.0",
|
|
32
|
+
"@grpc/proto-loader": "^0.6.0",
|
|
33
33
|
"@improbable-eng/grpc-web": "^0.14.0",
|
|
34
34
|
"@improbable-eng/grpc-web-node-http-transport": "^0.14.0",
|
|
35
35
|
"@nestjs/common": "^8.2.2",
|