ts-proto 1.96.0 → 1.97.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 +28 -0
- package/README.markdown +5 -1
- package/build/main.js +163 -75
- package/build/options.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
## [1.97.2](https://github.com/stephenh/ts-proto/compare/v1.97.1...v1.97.2) (2022-01-06)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Performance Improvements
|
|
5
|
+
|
|
6
|
+
* fromJSON returns object literal to allow v8 optimizations ([#463](https://github.com/stephenh/ts-proto/issues/463)) ([5fcd05b](https://github.com/stephenh/ts-proto/commit/5fcd05b79e7c02547c4b6db46fae7a7202f97629))
|
|
7
|
+
|
|
8
|
+
## [1.97.1](https://github.com/stephenh/ts-proto/compare/v1.97.0...v1.97.1) (2022-01-05)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* oneof=union breaks wrapper types [#458](https://github.com/stephenh/ts-proto/issues/458) ([#462](https://github.com/stephenh/ts-proto/issues/462)) ([dd16992](https://github.com/stephenh/ts-proto/commit/dd16992a409f24e88e3a142830cd0745f50dbd10))
|
|
14
|
+
|
|
15
|
+
# [1.97.0](https://github.com/stephenh/ts-proto/compare/v1.96.1...v1.97.0) (2021-12-30)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* add an option to disable Exact types ([#456](https://github.com/stephenh/ts-proto/issues/456)) ([9c53d7e](https://github.com/stephenh/ts-proto/commit/9c53d7efb0252c7ea0af85a5d161ff94bcd69760))
|
|
21
|
+
|
|
22
|
+
## [1.96.1](https://github.com/stephenh/ts-proto/compare/v1.96.0...v1.96.1) (2021-12-28)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Performance Improvements
|
|
26
|
+
|
|
27
|
+
* optimize object creation in `decode`, `fromJSON` and `fromPartial` ([#457](https://github.com/stephenh/ts-proto/issues/457)) ([70832d3](https://github.com/stephenh/ts-proto/commit/70832d33bae82ecb3c5f87845d14e992a13437e4))
|
|
28
|
+
|
|
1
29
|
# [1.96.0](https://github.com/stephenh/ts-proto/compare/v1.95.1...v1.96.0) (2021-12-24)
|
|
2
30
|
|
|
3
31
|
|
package/README.markdown
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
> `ts-proto` transforms your `.proto` files into strongly-typed, idiomatic TypeScript files!
|
|
7
7
|
|
|
8
|
-
(Note, if you're a new user of ts-proto and using a modern TS setup with `esModuleInterop`, you need to also pass that as a `ts_proto_opt`.)
|
|
8
|
+
(Note, if you're a new user of ts-proto and using a modern TS setup with `esModuleInterop`, or want to use ts-proto in ESM / snowpack / vite, you need to also pass that as a `ts_proto_opt`.)
|
|
9
9
|
|
|
10
10
|
## Table of contents
|
|
11
11
|
|
|
@@ -350,6 +350,10 @@ Generated code will be placed in the Gradle build directory.
|
|
|
350
350
|
|
|
351
351
|
- With `--ts_proto_opt=enumsAsLiterals=true`, the generated enum types will be enum-ish object with `as const`.
|
|
352
352
|
|
|
353
|
+
- With `--ts_proto_opt=useExactTypes=false`, the generated `fromPartial` method will not use Exact types.
|
|
354
|
+
|
|
355
|
+
The default behavior is `useExactTypes=true`, which makes `fromPartial` use Exact type for its argument to make TypeScript reject any unknown properties.
|
|
356
|
+
|
|
353
357
|
### Only Types
|
|
354
358
|
|
|
355
359
|
If you're looking for `ts-proto` to generate only types for your Protobuf types then passing all three of `outputEncodeMethods`, `outputJsonMethods`, and `outputClientImpl` as `false` is probably what you want, i.e.:
|
package/build/main.js
CHANGED
|
@@ -70,7 +70,7 @@ function generateFile(ctx, fileDesc) {
|
|
|
70
70
|
// then add the encoder/decoder/base instance
|
|
71
71
|
visit_1.visit(fileDesc, sourceInfo, (fullName, message, sInfo, fullProtoTypeName) => {
|
|
72
72
|
const fullTypeName = utils_1.maybePrefixPackage(fileDesc, fullProtoTypeName);
|
|
73
|
-
chunks.push(
|
|
73
|
+
chunks.push(generateBaseInstanceFactory(ctx, fullName, message, fullTypeName));
|
|
74
74
|
const staticMembers = [];
|
|
75
75
|
if (options.outputTypeRegistry) {
|
|
76
76
|
staticMembers.push(ts_poet_1.code `$type: '${fullTypeName}' as const`);
|
|
@@ -86,8 +86,8 @@ function generateFile(ctx, fileDesc) {
|
|
|
86
86
|
if (options.outputPartialMethods) {
|
|
87
87
|
staticMembers.push(generateFromPartial(ctx, fullName, message));
|
|
88
88
|
}
|
|
89
|
-
staticMembers.push(...generateWrap(fullTypeName));
|
|
90
|
-
staticMembers.push(...generateUnwrap(fullTypeName));
|
|
89
|
+
staticMembers.push(...generateWrap(ctx, fullTypeName));
|
|
90
|
+
staticMembers.push(...generateUnwrap(ctx, fullTypeName));
|
|
91
91
|
chunks.push(ts_poet_1.code `
|
|
92
92
|
export const ${ts_poet_1.def(fullName)} = {
|
|
93
93
|
${ts_poet_1.joinCode(staticMembers, { on: ',\n\n' })}
|
|
@@ -195,6 +195,7 @@ function makeUtils(options) {
|
|
|
195
195
|
...makeDeepPartial(options, longs),
|
|
196
196
|
...makeTimestampMethods(options, longs),
|
|
197
197
|
...longs,
|
|
198
|
+
...makeComparisonUtils(),
|
|
198
199
|
};
|
|
199
200
|
}
|
|
200
201
|
exports.makeUtils = makeUtils;
|
|
@@ -396,6 +397,17 @@ function makeTimestampMethods(options, longs) {
|
|
|
396
397
|
`);
|
|
397
398
|
return { toTimestamp, fromTimestamp, fromJsonTimestamp };
|
|
398
399
|
}
|
|
400
|
+
function makeComparisonUtils() {
|
|
401
|
+
const isObject = ts_poet_1.conditionalOutput('isObject', ts_poet_1.code `
|
|
402
|
+
function isObject(value: any): boolean {
|
|
403
|
+
return typeof value === 'object' && value !== null;
|
|
404
|
+
}`);
|
|
405
|
+
const isSet = ts_poet_1.conditionalOutput('isSet', ts_poet_1.code `
|
|
406
|
+
function isSet(value: any): boolean {
|
|
407
|
+
return value !== null && value !== undefined;
|
|
408
|
+
}`);
|
|
409
|
+
return { isObject, isSet };
|
|
410
|
+
}
|
|
399
411
|
// Create the interface with properties
|
|
400
412
|
function generateInterfaceDeclaration(ctx, fullName, messageDesc, sourceInfo, fullTypeName) {
|
|
401
413
|
var _a;
|
|
@@ -460,20 +472,39 @@ function generateOneofProperty(ctx, messageDesc, oneofIndex, sourceInfo) {
|
|
|
460
472
|
return prop;
|
|
461
473
|
*/
|
|
462
474
|
}
|
|
463
|
-
// Create a 'base' instance with default values for decode to use as a prototype
|
|
464
|
-
function
|
|
465
|
-
const fields =
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
.
|
|
475
|
+
// Create a function that constructs 'base' instance with default values for decode to use as a prototype
|
|
476
|
+
function generateBaseInstanceFactory(ctx, fullName, messageDesc, fullTypeName) {
|
|
477
|
+
const fields = [];
|
|
478
|
+
// When oneof=unions, we generate a single property with an ADT per `oneof` clause.
|
|
479
|
+
const processedOneofs = new Set();
|
|
480
|
+
for (const field of messageDesc.field) {
|
|
481
|
+
if (types_1.isWithinOneOfThatShouldBeUnion(ctx.options, field)) {
|
|
482
|
+
const { oneofIndex } = field;
|
|
483
|
+
if (!processedOneofs.has(oneofIndex)) {
|
|
484
|
+
processedOneofs.add(oneofIndex);
|
|
485
|
+
const name = case_1.maybeSnakeToCamel(messageDesc.oneofDecl[oneofIndex].name, ctx.options);
|
|
486
|
+
fields.push(ts_poet_1.code `${name}: undefined`);
|
|
487
|
+
}
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
470
490
|
const name = case_1.maybeSnakeToCamel(field.name, ctx.options);
|
|
471
|
-
|
|
472
|
-
|
|
491
|
+
const val = types_1.isWithinOneOf(field)
|
|
492
|
+
? 'undefined'
|
|
493
|
+
: types_1.isMapType(ctx, messageDesc, field)
|
|
494
|
+
? '{}'
|
|
495
|
+
: types_1.isRepeated(field)
|
|
496
|
+
? '[]'
|
|
497
|
+
: types_1.defaultValue(ctx, field);
|
|
498
|
+
fields.push(ts_poet_1.code `${name}: ${val}`);
|
|
499
|
+
}
|
|
473
500
|
if (ctx.options.outputTypeRegistry) {
|
|
474
501
|
fields.unshift(ts_poet_1.code `$type: '${fullTypeName}'`);
|
|
475
502
|
}
|
|
476
|
-
return ts_poet_1.code `
|
|
503
|
+
return ts_poet_1.code `
|
|
504
|
+
function createBase${fullName}(): ${fullName} {
|
|
505
|
+
return { ${ts_poet_1.joinCode(fields, { on: ',' })} };
|
|
506
|
+
}
|
|
507
|
+
`;
|
|
477
508
|
}
|
|
478
509
|
/** Creates a function to decode a message by loop overing the tags. */
|
|
479
510
|
function generateDecode(ctx, fullName, messageDesc) {
|
|
@@ -487,22 +518,8 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
487
518
|
): ${fullName} {
|
|
488
519
|
const reader = input instanceof ${Reader} ? input : new ${Reader}(input);
|
|
489
520
|
let end = length === undefined ? reader.len : reader.pos + length;
|
|
490
|
-
const message =
|
|
521
|
+
const message = createBase${fullName}();
|
|
491
522
|
`);
|
|
492
|
-
// initialize all lists
|
|
493
|
-
messageDesc.field.filter(types_1.isRepeated).forEach((field) => {
|
|
494
|
-
const name = case_1.maybeSnakeToCamel(field.name, options);
|
|
495
|
-
const value = types_1.isMapType(ctx, messageDesc, field) ? '{}' : '[]';
|
|
496
|
-
chunks.push(ts_poet_1.code `message.${name} = ${value};`);
|
|
497
|
-
});
|
|
498
|
-
// initialize all buffers
|
|
499
|
-
messageDesc.field
|
|
500
|
-
.filter((field) => !types_1.isRepeated(field) && !types_1.isWithinOneOf(field) && types_1.isBytes(field))
|
|
501
|
-
.forEach((field) => {
|
|
502
|
-
const value = options.env === options_1.EnvOption.NODE ? 'Buffer.alloc(0)' : 'new Uint8Array()';
|
|
503
|
-
const name = case_1.maybeSnakeToCamel(field.name, options);
|
|
504
|
-
chunks.push(ts_poet_1.code `message.${name} = ${value};`);
|
|
505
|
-
});
|
|
506
523
|
// start the tag loop
|
|
507
524
|
chunks.push(ts_poet_1.code `
|
|
508
525
|
while (reader.pos < end) {
|
|
@@ -567,28 +584,29 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
567
584
|
}
|
|
568
585
|
// and then use the snippet to handle repeated fields if necessary
|
|
569
586
|
if (types_1.isRepeated(field)) {
|
|
587
|
+
const maybeNonNullAssertion = ctx.options.useOptionals === 'all' ? '!' : '';
|
|
570
588
|
if (types_1.isMapType(ctx, messageDesc, field)) {
|
|
571
589
|
// We need a unique const within the `cast` statement
|
|
572
590
|
const varName = `entry${field.number}`;
|
|
573
591
|
chunks.push(ts_poet_1.code `
|
|
574
592
|
const ${varName} = ${readSnippet};
|
|
575
593
|
if (${varName}.value !== undefined) {
|
|
576
|
-
message.${fieldName}[${varName}.key] = ${varName}.value;
|
|
594
|
+
message.${fieldName}${maybeNonNullAssertion}[${varName}.key] = ${varName}.value;
|
|
577
595
|
}
|
|
578
596
|
`);
|
|
579
597
|
}
|
|
580
598
|
else if (types_1.packedType(field.type) === undefined) {
|
|
581
|
-
chunks.push(ts_poet_1.code `message.${fieldName}.push(${readSnippet});`);
|
|
599
|
+
chunks.push(ts_poet_1.code `message.${fieldName}${maybeNonNullAssertion}.push(${readSnippet});`);
|
|
582
600
|
}
|
|
583
601
|
else {
|
|
584
602
|
chunks.push(ts_poet_1.code `
|
|
585
603
|
if ((tag & 7) === 2) {
|
|
586
604
|
const end2 = reader.uint32() + reader.pos;
|
|
587
605
|
while (reader.pos < end2) {
|
|
588
|
-
message.${fieldName}.push(${readSnippet});
|
|
606
|
+
message.${fieldName}${maybeNonNullAssertion}.push(${readSnippet});
|
|
589
607
|
}
|
|
590
608
|
} else {
|
|
591
|
-
message.${fieldName}.push(${readSnippet});
|
|
609
|
+
message.${fieldName}${maybeNonNullAssertion}.push(${readSnippet});
|
|
592
610
|
}
|
|
593
611
|
`);
|
|
594
612
|
}
|
|
@@ -796,16 +814,21 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
796
814
|
function generateFromJson(ctx, fullName, messageDesc) {
|
|
797
815
|
const { options, utils, typeMap } = ctx;
|
|
798
816
|
const chunks = [];
|
|
817
|
+
const choiceFieldChunks = [];
|
|
799
818
|
// create the basic function declaration
|
|
800
819
|
chunks.push(ts_poet_1.code `
|
|
801
820
|
fromJSON(${messageDesc.field.length > 0 ? 'object' : '_'}: any): ${fullName} {
|
|
802
|
-
|
|
821
|
+
return {
|
|
803
822
|
`);
|
|
823
|
+
if (ctx.options.outputTypeRegistry) {
|
|
824
|
+
chunks.push(ts_poet_1.code `$type: ${fullName}.$type,`);
|
|
825
|
+
}
|
|
826
|
+
const oneofFieldsCases = messageDesc.oneofDecl.map((oneof, oneofIndex) => messageDesc.field.filter(types_1.isWithinOneOf).filter((field) => field.oneofIndex === oneofIndex));
|
|
804
827
|
// add a check for each incoming field
|
|
805
828
|
messageDesc.field.forEach((field) => {
|
|
806
829
|
const fieldName = case_1.maybeSnakeToCamel(field.name, options);
|
|
807
830
|
const jsonName = utils_1.determineFieldJsonName(field, options);
|
|
808
|
-
// get
|
|
831
|
+
// get code that extracts value from incoming object
|
|
809
832
|
const readSnippet = (from) => {
|
|
810
833
|
if (types_1.isEnum(field)) {
|
|
811
834
|
const fromJson = types_1.getEnumMethod(ctx, field.typeName, 'FromJSON');
|
|
@@ -840,6 +863,9 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
840
863
|
else if (types_1.isAnyValueType(field) || types_1.isStructType(field)) {
|
|
841
864
|
return ts_poet_1.code `${from}`;
|
|
842
865
|
}
|
|
866
|
+
else if (types_1.isListValueType(field)) {
|
|
867
|
+
return ts_poet_1.code `[...${from}]`;
|
|
868
|
+
}
|
|
843
869
|
else if (types_1.isValueType(ctx, field)) {
|
|
844
870
|
const valueType = types_1.valueTypeName(ctx, field.typeName);
|
|
845
871
|
if (types_1.isLongValueType(field) && options.forceLong === options_1.LongOption.LONG) {
|
|
@@ -848,9 +874,6 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
848
874
|
else if (types_1.isBytesValueType(field)) {
|
|
849
875
|
return ts_poet_1.code `new ${case_1.capitalize(valueType.toCodeString())}(${from})`;
|
|
850
876
|
}
|
|
851
|
-
else if (types_1.isListValueType(field)) {
|
|
852
|
-
return ts_poet_1.code `[...${from}]`;
|
|
853
|
-
}
|
|
854
877
|
else {
|
|
855
878
|
return ts_poet_1.code `${case_1.capitalize(valueType.toCodeString())}(${from})`;
|
|
856
879
|
}
|
|
@@ -913,56 +936,71 @@ function generateFromJson(ctx, fullName, messageDesc) {
|
|
|
913
936
|
const fieldType = types_1.toTypeName(ctx, messageDesc, field);
|
|
914
937
|
const i = maybeCastToNumber(ctx, messageDesc, field, 'key');
|
|
915
938
|
chunks.push(ts_poet_1.code `
|
|
916
|
-
|
|
917
|
-
acc[
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
}
|
|
922
|
-
else if (types_1.isAnyValueType(field)) {
|
|
923
|
-
chunks.push(ts_poet_1.code `
|
|
924
|
-
message.${fieldName} = Array.isArray(object?.${jsonName}) ? [...object.${jsonName}] : [];
|
|
939
|
+
${fieldName}: ${ctx.utils.isObject}(object.${jsonName})
|
|
940
|
+
? Object.entries(object.${jsonName}).reduce<${fieldType}>((acc, [key, value]) => {
|
|
941
|
+
acc[${i}] = ${readSnippet('value')};
|
|
942
|
+
return acc;
|
|
943
|
+
}, {})
|
|
944
|
+
: {},
|
|
925
945
|
`);
|
|
926
946
|
}
|
|
927
947
|
else {
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
948
|
+
const readValueSnippet = readSnippet('e');
|
|
949
|
+
if (readValueSnippet.toString() === ts_poet_1.code `e`.toString()) {
|
|
950
|
+
chunks.push(ts_poet_1.code `${fieldName}: Array.isArray(object?.${jsonName}) ? [...object.${jsonName}] : [],`);
|
|
951
|
+
}
|
|
952
|
+
else {
|
|
953
|
+
// Explicit `any` type required to make TS with noImplicitAny happy. `object` is also `any` here.
|
|
954
|
+
chunks.push(ts_poet_1.code `
|
|
955
|
+
${fieldName}: Array.isArray(object?.${jsonName}) ? object.${jsonName}.map((e: any) => ${readValueSnippet}): [],
|
|
956
|
+
`);
|
|
957
|
+
}
|
|
932
958
|
}
|
|
933
959
|
}
|
|
934
960
|
else if (types_1.isWithinOneOfThatShouldBeUnion(options, field)) {
|
|
935
|
-
|
|
936
|
-
const
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
961
|
+
const cases = oneofFieldsCases[field.oneofIndex];
|
|
962
|
+
const firstCase = cases[0];
|
|
963
|
+
const lastCase = cases[cases.length - 1];
|
|
964
|
+
if (field === firstCase) {
|
|
965
|
+
const fieldName = case_1.maybeSnakeToCamel(messageDesc.oneofDecl[field.oneofIndex].name, options);
|
|
966
|
+
chunks.push(ts_poet_1.code `${fieldName}: `);
|
|
967
|
+
}
|
|
968
|
+
const ternaryIf = ts_poet_1.code `${ctx.utils.isSet}(object.${jsonName})`;
|
|
969
|
+
const ternaryThen = ts_poet_1.code `{ $case: '${fieldName}', ${fieldName}: ${readSnippet(`object.${jsonName}`)}`;
|
|
970
|
+
chunks.push(ts_poet_1.code `${ternaryIf} ? ${ternaryThen}} : `);
|
|
971
|
+
if (field === lastCase) {
|
|
972
|
+
chunks.push(ts_poet_1.code `undefined,`);
|
|
973
|
+
}
|
|
941
974
|
}
|
|
942
975
|
else if (types_1.isAnyValueType(field)) {
|
|
943
|
-
chunks.push(ts_poet_1.code
|
|
976
|
+
chunks.push(ts_poet_1.code `${fieldName}: ${ctx.utils.isSet}(object?.${jsonName})
|
|
977
|
+
? ${readSnippet(`object.${jsonName}`)}
|
|
978
|
+
: undefined,
|
|
979
|
+
`);
|
|
944
980
|
}
|
|
945
981
|
else if (types_1.isStructType(field)) {
|
|
946
|
-
chunks.push(ts_poet_1.code
|
|
982
|
+
chunks.push(ts_poet_1.code `${fieldName}: ${ctx.utils.isObject}(object.${jsonName})
|
|
983
|
+
? ${readSnippet(`object.${jsonName}`)}
|
|
984
|
+
: undefined,`);
|
|
947
985
|
}
|
|
948
986
|
else if (types_1.isListValueType(field)) {
|
|
949
987
|
chunks.push(ts_poet_1.code `
|
|
950
|
-
|
|
951
|
-
? ${readSnippet(`object.${
|
|
952
|
-
:
|
|
988
|
+
${fieldName}: Array.isArray(object.${jsonName})
|
|
989
|
+
? ${readSnippet(`object.${jsonName}`)}
|
|
990
|
+
: undefined,
|
|
953
991
|
`);
|
|
954
992
|
}
|
|
955
993
|
else {
|
|
956
994
|
const fallback = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
|
|
957
995
|
chunks.push(ts_poet_1.code `
|
|
958
|
-
|
|
996
|
+
${fieldName}: ${ctx.utils.isSet}(object.${jsonName})
|
|
959
997
|
? ${readSnippet(`object.${jsonName}`)}
|
|
960
|
-
: ${fallback}
|
|
998
|
+
: ${fallback},
|
|
961
999
|
`);
|
|
962
1000
|
}
|
|
963
1001
|
});
|
|
964
1002
|
// and then wrap up the switch/while/return
|
|
965
|
-
chunks.push(ts_poet_1.code `
|
|
1003
|
+
chunks.push(ts_poet_1.code `};`);
|
|
966
1004
|
chunks.push(ts_poet_1.code `}`);
|
|
967
1005
|
return ts_poet_1.joinCode(chunks, { on: '\n' });
|
|
968
1006
|
}
|
|
@@ -1095,13 +1133,19 @@ function generateToJson(ctx, fullName, messageDesc) {
|
|
|
1095
1133
|
function generateFromPartial(ctx, fullName, messageDesc) {
|
|
1096
1134
|
const { options, utils, typeMap } = ctx;
|
|
1097
1135
|
const chunks = [];
|
|
1098
|
-
const Timestamp = utils_1.impProto(options, 'google/protobuf/timestamp', 'Timestamp');
|
|
1099
1136
|
// create the basic function declaration
|
|
1100
1137
|
const paramName = messageDesc.field.length > 0 ? 'object' : '_';
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1138
|
+
if (ctx.options.useExactTypes) {
|
|
1139
|
+
chunks.push(ts_poet_1.code `
|
|
1140
|
+
fromPartial<I extends ${utils.Exact}<${utils.DeepPartial}<${fullName}>, I>>(${paramName}: I): ${fullName} {
|
|
1141
|
+
`);
|
|
1142
|
+
}
|
|
1143
|
+
else {
|
|
1144
|
+
chunks.push(ts_poet_1.code `
|
|
1145
|
+
fromPartial(${paramName}: ${utils.DeepPartial}<${fullName}>): ${fullName} {
|
|
1146
|
+
`);
|
|
1147
|
+
}
|
|
1148
|
+
chunks.push(ts_poet_1.code `const message = createBase${fullName}();`);
|
|
1105
1149
|
// add a check for each incoming field
|
|
1106
1150
|
messageDesc.field.forEach((field) => {
|
|
1107
1151
|
const fieldName = case_1.maybeSnakeToCamel(field.name, options);
|
|
@@ -1211,7 +1255,7 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1211
1255
|
chunks.push(ts_poet_1.code `}`);
|
|
1212
1256
|
return ts_poet_1.joinCode(chunks, { on: '\n' });
|
|
1213
1257
|
}
|
|
1214
|
-
function generateWrap(fullProtoTypeName) {
|
|
1258
|
+
function generateWrap(ctx, fullProtoTypeName) {
|
|
1215
1259
|
const chunks = [];
|
|
1216
1260
|
if (types_1.isStructTypeName(fullProtoTypeName)) {
|
|
1217
1261
|
chunks.push(ts_poet_1.code `wrap(object: {[key: string]: any} | undefined): Struct {
|
|
@@ -1225,7 +1269,29 @@ function generateWrap(fullProtoTypeName) {
|
|
|
1225
1269
|
}`);
|
|
1226
1270
|
}
|
|
1227
1271
|
if (types_1.isAnyValueTypeName(fullProtoTypeName)) {
|
|
1228
|
-
|
|
1272
|
+
if (ctx.options.oneof === options_1.OneofOption.UNIONS) {
|
|
1273
|
+
chunks.push(ts_poet_1.code `wrap(value: any): Value {
|
|
1274
|
+
if (value === null) {
|
|
1275
|
+
return {kind: {$case: 'nullValue', nullValue: NullValue.NULL_VALUE}};
|
|
1276
|
+
} else if (typeof value === 'boolean') {
|
|
1277
|
+
return {kind: {$case: 'boolValue', boolValue: value}};
|
|
1278
|
+
} else if (typeof value === 'number') {
|
|
1279
|
+
return {kind: {$case: 'numberValue', numberValue: value}};
|
|
1280
|
+
} else if (typeof value === 'string') {
|
|
1281
|
+
return {kind: {$case: 'stringValue', stringValue: value}};
|
|
1282
|
+
} else if (Array.isArray(value)) {
|
|
1283
|
+
return {kind: {$case: 'listValue', listValue: value}};
|
|
1284
|
+
} else if (typeof value === 'object') {
|
|
1285
|
+
return {kind: {$case: 'structValue', structValue: value}};
|
|
1286
|
+
} else if (typeof value === 'undefined') {
|
|
1287
|
+
return {} as Value;
|
|
1288
|
+
} else {
|
|
1289
|
+
throw new Error('Unsupported any value type: ' + typeof value);
|
|
1290
|
+
}
|
|
1291
|
+
}`);
|
|
1292
|
+
}
|
|
1293
|
+
else {
|
|
1294
|
+
chunks.push(ts_poet_1.code `wrap(value: any): Value {
|
|
1229
1295
|
if (value === null) {
|
|
1230
1296
|
return {nullValue: NullValue.NULL_VALUE} as Value;
|
|
1231
1297
|
} else if (typeof value === 'boolean') {
|
|
@@ -1244,15 +1310,16 @@ function generateWrap(fullProtoTypeName) {
|
|
|
1244
1310
|
throw new Error('Unsupported any value type: ' + typeof value);
|
|
1245
1311
|
}
|
|
1246
1312
|
}`);
|
|
1313
|
+
}
|
|
1247
1314
|
}
|
|
1248
1315
|
if (types_1.isListValueTypeName(fullProtoTypeName)) {
|
|
1249
|
-
chunks.push(ts_poet_1.code `wrap(value: Array<any>): ListValue {
|
|
1250
|
-
return {values: value};
|
|
1316
|
+
chunks.push(ts_poet_1.code `wrap(value: Array<any> | undefined): ListValue {
|
|
1317
|
+
return {values: value ?? []};
|
|
1251
1318
|
}`);
|
|
1252
1319
|
}
|
|
1253
1320
|
return chunks;
|
|
1254
1321
|
}
|
|
1255
|
-
function generateUnwrap(fullProtoTypeName) {
|
|
1322
|
+
function generateUnwrap(ctx, fullProtoTypeName) {
|
|
1256
1323
|
const chunks = [];
|
|
1257
1324
|
if (types_1.isStructTypeName(fullProtoTypeName)) {
|
|
1258
1325
|
chunks.push(ts_poet_1.code `unwrap(message: Struct): {[key: string]: any} {
|
|
@@ -1264,7 +1331,27 @@ function generateUnwrap(fullProtoTypeName) {
|
|
|
1264
1331
|
}`);
|
|
1265
1332
|
}
|
|
1266
1333
|
if (types_1.isAnyValueTypeName(fullProtoTypeName)) {
|
|
1267
|
-
|
|
1334
|
+
if (ctx.options.oneof === options_1.OneofOption.UNIONS) {
|
|
1335
|
+
chunks.push(ts_poet_1.code `unwrap(message: Value): string | number | boolean | Object | null | Array<any> | undefined {
|
|
1336
|
+
if (message.kind?.$case === 'nullValue') {
|
|
1337
|
+
return null;
|
|
1338
|
+
} else if (message.kind?.$case === 'numberValue') {
|
|
1339
|
+
return message.kind?.numberValue;
|
|
1340
|
+
} else if (message.kind?.$case === 'stringValue') {
|
|
1341
|
+
return message.kind?.stringValue;
|
|
1342
|
+
} else if (message.kind?.$case === 'boolValue') {
|
|
1343
|
+
return message.kind?.boolValue;
|
|
1344
|
+
} else if (message.kind?.$case === 'structValue') {
|
|
1345
|
+
return message.kind?.structValue;
|
|
1346
|
+
} else if (message.kind?.$case === 'listValue') {
|
|
1347
|
+
return message.kind?.listValue;
|
|
1348
|
+
} else {
|
|
1349
|
+
return undefined;
|
|
1350
|
+
}
|
|
1351
|
+
}`);
|
|
1352
|
+
}
|
|
1353
|
+
else {
|
|
1354
|
+
chunks.push(ts_poet_1.code `unwrap(message: Value): string | number | boolean | Object | null | Array<any> | undefined {
|
|
1268
1355
|
if (message?.stringValue !== undefined) {
|
|
1269
1356
|
return message.stringValue;
|
|
1270
1357
|
} else if (message?.numberValue !== undefined) {
|
|
@@ -1280,6 +1367,7 @@ function generateUnwrap(fullProtoTypeName) {
|
|
|
1280
1367
|
}
|
|
1281
1368
|
return undefined;
|
|
1282
1369
|
}`);
|
|
1370
|
+
}
|
|
1283
1371
|
}
|
|
1284
1372
|
if (types_1.isListValueTypeName(fullProtoTypeName)) {
|
|
1285
1373
|
chunks.push(ts_poet_1.code `unwrap(message: ListValue): Array<any> {
|
package/build/options.js
CHANGED