@aptre/protobuf-es-lite 0.3.0 → 0.4.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/dist/enum.d.ts +11 -1
- package/dist/enum.js +56 -7
- package/dist/field-wrapper.d.ts +2 -2
- package/dist/field.d.ts +37 -11
- package/dist/google/protobuf/any.pb.js +17 -6
- package/dist/google/protobuf/api.pb.js +21 -3
- package/dist/google/protobuf/descriptor.pb.js +990 -138
- package/dist/google/protobuf/duration.pb.js +1 -1
- package/dist/google/protobuf/struct.pb.js +67 -13
- package/dist/google/protobuf/timestamp.pb.js +19 -5
- package/dist/google/protobuf/type.pb.js +43 -7
- package/dist/google/protobuf/wrappers.pb.js +100 -10
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/message.d.ts +7 -3
- package/dist/message.js +9 -4
- package/dist/names.d.ts +2 -0
- package/dist/names.js +13 -20
- package/dist/partial.d.ts +2 -1
- package/dist/partial.js +161 -66
- package/dist/protoc-gen-es-lite/typescript.js +25 -0
- package/dist/scalar.d.ts +8 -0
- package/dist/scalar.js +23 -0
- package/dist/util.d.ts +1 -1
- package/dist/util.js +2 -2
- package/dist/zero-value.d.ts +23 -0
- package/dist/zero-value.js +88 -0
- package/example/example.pb.ts +53 -28
- package/package.json +1 -1
package/dist/partial.js
CHANGED
|
@@ -1,99 +1,194 @@
|
|
|
1
|
+
import { normalizeEnumValue } from "./enum.js";
|
|
1
2
|
import { resolveMessageType } from "./field.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
3
|
+
import { createCompleteMessage } from "./message.js";
|
|
4
|
+
import { throwSanitizeKey } from "./names.js";
|
|
5
|
+
import { normalizeScalarValue } from "./scalar.js";
|
|
6
|
+
// applyPartialMessage applies a partial source message to a target message.
|
|
4
7
|
export function applyPartialMessage(source, target, fields) {
|
|
5
|
-
if (source
|
|
8
|
+
if (source == null || target == null) {
|
|
6
9
|
return;
|
|
7
10
|
}
|
|
11
|
+
const t = target, s = source;
|
|
8
12
|
for (const member of fields.byMember()) {
|
|
9
|
-
const localName = member.localName
|
|
10
|
-
|
|
13
|
+
const localName = member.localName;
|
|
14
|
+
throwSanitizeKey(localName);
|
|
15
|
+
if (!(localName in s) || s[localName] === undefined) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
const sourceValue = s[localName];
|
|
19
|
+
if (sourceValue === null) {
|
|
20
|
+
delete t[localName];
|
|
11
21
|
continue;
|
|
12
22
|
}
|
|
13
23
|
switch (member.kind) {
|
|
14
24
|
case "oneof":
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
if (typeof sourceValue !== "object") {
|
|
26
|
+
throw new Error(`field ${localName}: invalid oneof: must be an object with case and value`);
|
|
27
|
+
}
|
|
28
|
+
// sk, sk are the source case and value
|
|
29
|
+
const { case: sk, value: sv } = sourceValue;
|
|
30
|
+
// sourceField is the field set by the source case, if any.
|
|
31
|
+
const sourceField = sk != null ? member.findField(sk) : null;
|
|
32
|
+
// dv is the destination oneof object
|
|
33
|
+
let dv = localName in t ? t[localName] : undefined;
|
|
34
|
+
if (typeof dv !== "object") {
|
|
35
|
+
dv = Object.create(null);
|
|
36
|
+
}
|
|
37
|
+
// check the case is valid and throw if not
|
|
38
|
+
if (sk != null && sourceField == null) {
|
|
39
|
+
throw new Error(`field ${localName}: invalid oneof case: ${sk}`);
|
|
40
|
+
}
|
|
41
|
+
// update the case
|
|
42
|
+
dv.case = sk;
|
|
43
|
+
// if the case was different or null, clear the value.
|
|
44
|
+
if (dv.case !== sk || sk == null) {
|
|
45
|
+
delete dv.value;
|
|
18
46
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (sourceField
|
|
22
|
-
|
|
23
|
-
|
|
47
|
+
t[localName] = dv;
|
|
48
|
+
// stop here if there was no valid case selected
|
|
49
|
+
if (!sourceField) {
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
if (sourceField.kind === "message") {
|
|
53
|
+
// apply the partial to the value
|
|
54
|
+
let dest = dv.value;
|
|
55
|
+
if (typeof dest !== "object") {
|
|
56
|
+
dest = dv.value = Object.create(null);
|
|
57
|
+
}
|
|
58
|
+
// skip zero or null value
|
|
59
|
+
if (sv != null) {
|
|
60
|
+
const sourceFieldMt = resolveMessageType(sourceField.T);
|
|
61
|
+
applyPartialMessage(sv, dest, sourceFieldMt.fields);
|
|
24
62
|
}
|
|
25
63
|
}
|
|
26
|
-
else if (sourceField
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
64
|
+
else if (sourceField.kind === "scalar") {
|
|
65
|
+
dv.value = normalizeScalarValue(sourceField.T, sv);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
dv.value = sv;
|
|
30
69
|
}
|
|
31
|
-
t[localName] = { case: sk, value: val };
|
|
32
70
|
break;
|
|
33
71
|
case "scalar":
|
|
72
|
+
if (member.repeated) {
|
|
73
|
+
if (!Array.isArray(sourceValue)) {
|
|
74
|
+
throw new Error(`field ${localName}: invalid value: must be array`);
|
|
75
|
+
}
|
|
76
|
+
let dst = localName in t ? t[localName] : null;
|
|
77
|
+
if (dst == null || !Array.isArray(dst)) {
|
|
78
|
+
dst = t[localName] = [];
|
|
79
|
+
}
|
|
80
|
+
dst.push(...sourceValue.map((v) => normalizeScalarValue(member.T, v)));
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
t[localName] = normalizeScalarValue(member.T, sourceValue);
|
|
84
|
+
break;
|
|
34
85
|
case "enum":
|
|
35
|
-
|
|
36
|
-
if (member.T === ScalarType.BYTES) {
|
|
37
|
-
copy =
|
|
38
|
-
member.repeated ?
|
|
39
|
-
copy.map(toU8Arr)
|
|
40
|
-
: toU8Arr(copy);
|
|
41
|
-
}
|
|
42
|
-
t[localName] = copy;
|
|
86
|
+
t[localName] = normalizeEnumValue(member.T, sourceValue);
|
|
43
87
|
break;
|
|
44
88
|
case "map":
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
Object.assign(t[localName], s[localName]);
|
|
55
|
-
}
|
|
56
|
-
break;
|
|
57
|
-
case "message":
|
|
58
|
-
const messageType = resolveMessageType(member.V.T);
|
|
59
|
-
for (const k of Object.keys(s[localName])) {
|
|
60
|
-
let val = s[localName][k];
|
|
61
|
-
if (!messageType.fieldWrapper) {
|
|
62
|
-
if (val === undefined) {
|
|
63
|
-
val = {};
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
t[localName][k] = val;
|
|
67
|
-
}
|
|
68
|
-
break;
|
|
89
|
+
if (typeof sourceValue !== "object") {
|
|
90
|
+
throw new Error(`field ${member.localName}: invalid value: must be object`);
|
|
91
|
+
}
|
|
92
|
+
let tMap = t[localName];
|
|
93
|
+
if (typeof tMap !== "object") {
|
|
94
|
+
tMap = t[localName] = Object.create(null);
|
|
69
95
|
}
|
|
96
|
+
applyPartialMap(sourceValue, tMap, member.V);
|
|
70
97
|
break;
|
|
71
98
|
case "message":
|
|
72
99
|
const mt = resolveMessageType(member.T);
|
|
73
100
|
if (member.repeated) {
|
|
74
|
-
|
|
101
|
+
// skip null or undefined values
|
|
102
|
+
if (!Array.isArray(sourceValue)) {
|
|
103
|
+
throw new Error(`field ${localName}: invalid value: must be array`);
|
|
104
|
+
}
|
|
105
|
+
let tArr = t[localName];
|
|
106
|
+
if (!Array.isArray(tArr)) {
|
|
107
|
+
tArr = t[localName] = [];
|
|
108
|
+
}
|
|
109
|
+
for (const v of sourceValue) {
|
|
110
|
+
// skip null or undefined values
|
|
111
|
+
if (v != null) {
|
|
112
|
+
if (mt.fieldWrapper) {
|
|
113
|
+
tArr.push(mt.fieldWrapper.unwrapField(mt.fieldWrapper.wrapField(v)));
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
tArr.push(mt.create(v));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
if (mt.fieldWrapper) {
|
|
123
|
+
t[localName] = mt.fieldWrapper.unwrapField(mt.fieldWrapper.wrapField(sourceValue));
|
|
75
124
|
}
|
|
76
125
|
else {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
// We can't use BytesValue.typeName as that will create a circular import
|
|
81
|
-
mt.typeName === "google.protobuf.BytesValue") {
|
|
82
|
-
t[localName] = toU8Arr(val);
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
t[localName] = val;
|
|
86
|
-
}
|
|
126
|
+
if (typeof sourceValue !== "object") {
|
|
127
|
+
throw new Error(`field ${member.localName}: invalid value: must be object`);
|
|
87
128
|
}
|
|
88
|
-
|
|
89
|
-
|
|
129
|
+
let destMsg = t[localName];
|
|
130
|
+
if (typeof destMsg !== "object") {
|
|
131
|
+
destMsg = t[localName] = Object.create(null);
|
|
90
132
|
}
|
|
133
|
+
applyPartialMessage(sourceValue, destMsg, mt.fields);
|
|
91
134
|
}
|
|
92
135
|
break;
|
|
93
136
|
}
|
|
94
137
|
}
|
|
95
138
|
}
|
|
96
|
-
//
|
|
97
|
-
function
|
|
98
|
-
|
|
139
|
+
// applyPartialMap applies a partial source map to a target map.
|
|
140
|
+
export function applyPartialMap(sourceMap, targetMap, value) {
|
|
141
|
+
if (sourceMap == null) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (typeof sourceMap !== "object") {
|
|
145
|
+
throw new Error(`invalid map: must be object`);
|
|
146
|
+
}
|
|
147
|
+
switch (value.kind) {
|
|
148
|
+
case "scalar":
|
|
149
|
+
for (const [k, v] of Object.entries(sourceMap)) {
|
|
150
|
+
throwSanitizeKey(k);
|
|
151
|
+
if (v !== undefined) {
|
|
152
|
+
targetMap[k] = normalizeScalarValue(value.T, v);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
delete targetMap[k];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
break;
|
|
159
|
+
case "enum":
|
|
160
|
+
for (const [k, v] of Object.entries(sourceMap)) {
|
|
161
|
+
throwSanitizeKey(k);
|
|
162
|
+
if (v !== undefined) {
|
|
163
|
+
targetMap[k] = normalizeEnumValue(value.T, v);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
delete targetMap[k];
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
break;
|
|
170
|
+
case "message":
|
|
171
|
+
const messageType = resolveMessageType(value.T);
|
|
172
|
+
for (const [k, v] of Object.entries(sourceMap)) {
|
|
173
|
+
throwSanitizeKey(k);
|
|
174
|
+
if (v === undefined) {
|
|
175
|
+
delete targetMap[k];
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (typeof v !== "object") {
|
|
179
|
+
throw new Error(`invalid value: must be object`);
|
|
180
|
+
}
|
|
181
|
+
let val = targetMap[k];
|
|
182
|
+
if (!!messageType.fieldWrapper) {
|
|
183
|
+
// For wrapper type messages, call createCompleteMessage.
|
|
184
|
+
val = targetMap[k] = createCompleteMessage(messageType.fields);
|
|
185
|
+
}
|
|
186
|
+
else if (typeof val !== "object") {
|
|
187
|
+
// Otherwise apply the partial to the existing value, if any.
|
|
188
|
+
val = targetMap[k] = Object.create(null);
|
|
189
|
+
}
|
|
190
|
+
applyPartialMessage(v, val, messageType.fields);
|
|
191
|
+
}
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
99
194
|
}
|
|
@@ -146,6 +146,7 @@ function generateMessage(schema, f, message) {
|
|
|
146
146
|
f.print("});");
|
|
147
147
|
}
|
|
148
148
|
else {
|
|
149
|
+
generateWktFieldWrapper(f, message, reWkt);
|
|
149
150
|
f.print("}, ", message, "_Wkt);");
|
|
150
151
|
}
|
|
151
152
|
f.print();
|
|
@@ -549,3 +550,27 @@ function generateWktMethods(schema, f, message, ref) {
|
|
|
549
550
|
break;
|
|
550
551
|
}
|
|
551
552
|
}
|
|
553
|
+
function generateWktFieldWrapper(f, message, ref) {
|
|
554
|
+
switch (ref?.typeName) {
|
|
555
|
+
case "google.protobuf.DoubleValue":
|
|
556
|
+
case "google.protobuf.FloatValue":
|
|
557
|
+
case "google.protobuf.Int64Value":
|
|
558
|
+
case "google.protobuf.UInt64Value":
|
|
559
|
+
case "google.protobuf.Int32Value":
|
|
560
|
+
case "google.protobuf.UInt32Value":
|
|
561
|
+
case "google.protobuf.BoolValue":
|
|
562
|
+
case "google.protobuf.StringValue":
|
|
563
|
+
case "google.protobuf.BytesValue": {
|
|
564
|
+
const { typing } = getFieldTypeInfo(ref.value);
|
|
565
|
+
f.print(" fieldWrapper: {");
|
|
566
|
+
f.print(" wrapField(value: ", typing, " | null | undefined): ", message, " {");
|
|
567
|
+
f.print(" return ", message, ".createComplete({ value: value ?? undefined });");
|
|
568
|
+
f.print(" },");
|
|
569
|
+
f.print(" unwrapField(msg: ", message, "): ", typing, " | null | undefined {");
|
|
570
|
+
f.print(" return msg.", localName(ref.value), ";");
|
|
571
|
+
f.print(" }");
|
|
572
|
+
f.print(" } as const,");
|
|
573
|
+
break;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
package/dist/scalar.d.ts
CHANGED
|
@@ -67,3 +67,11 @@ export declare function scalarZeroValue<T extends ScalarType, L extends LongType
|
|
|
67
67
|
* optional or repeated.
|
|
68
68
|
*/
|
|
69
69
|
export declare function isScalarZeroValue(type: ScalarType, value: unknown): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Returns the normalized version of the scalar value.
|
|
72
|
+
* Zero or null is cast to the zero value.
|
|
73
|
+
* Bytes is cast to a Uint8Array.
|
|
74
|
+
* The BigInt long type is used.
|
|
75
|
+
*/
|
|
76
|
+
export declare function normalizeScalarValue<T>(type: ScalarType, value: T | null | undefined, longType?: LongType): T;
|
|
77
|
+
export declare function toU8Arr(input: ArrayLike<number>): Uint8Array;
|
package/dist/scalar.js
CHANGED
|
@@ -161,3 +161,26 @@ export function isScalarZeroValue(type, value) {
|
|
|
161
161
|
return value == 0; // Loose comparison matches 0n, 0 and "0"
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* Returns the normalized version of the scalar value.
|
|
166
|
+
* Zero or null is cast to the zero value.
|
|
167
|
+
* Bytes is cast to a Uint8Array.
|
|
168
|
+
* The BigInt long type is used.
|
|
169
|
+
*/
|
|
170
|
+
export function normalizeScalarValue(type, value, longType = LongType.BIGINT) {
|
|
171
|
+
if (value == null) {
|
|
172
|
+
return scalarZeroValue(type, longType);
|
|
173
|
+
}
|
|
174
|
+
if (type === ScalarType.BYTES) {
|
|
175
|
+
return toU8Arr(value);
|
|
176
|
+
}
|
|
177
|
+
if (isScalarZeroValue(type, value)) {
|
|
178
|
+
return scalarZeroValue(type, longType);
|
|
179
|
+
}
|
|
180
|
+
// TODO: enforce correct type for other values as well.
|
|
181
|
+
return value;
|
|
182
|
+
}
|
|
183
|
+
// converts any ArrayLike<number> to Uint8Array if necessary.
|
|
184
|
+
export function toU8Arr(input) {
|
|
185
|
+
return input instanceof Uint8Array ? input : new Uint8Array(input);
|
|
186
|
+
}
|
package/dist/util.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export declare function getFieldDefaultValueExpression(field: DescField | DescEx
|
|
|
15
15
|
*
|
|
16
16
|
* Returns either:
|
|
17
17
|
* - empty array literal for repeated fields
|
|
18
|
-
* -
|
|
18
|
+
* - Object.create(null) for maps
|
|
19
19
|
* - undefined for message fields
|
|
20
20
|
* - an enums first value
|
|
21
21
|
* - scalar zero value
|
package/dist/util.js
CHANGED
|
@@ -134,7 +134,7 @@ export function getFieldDefaultValueExpression(field, enumAs = "enum_value_as_is
|
|
|
134
134
|
*
|
|
135
135
|
* Returns either:
|
|
136
136
|
* - empty array literal for repeated fields
|
|
137
|
-
* -
|
|
137
|
+
* - Object.create(null) for maps
|
|
138
138
|
* - undefined for message fields
|
|
139
139
|
* - an enums first value
|
|
140
140
|
* - scalar zero value
|
|
@@ -147,7 +147,7 @@ export function getFieldZeroValueExpression(field, enumAs = "enum_value_as_is")
|
|
|
147
147
|
case "message":
|
|
148
148
|
return undefined;
|
|
149
149
|
case "map":
|
|
150
|
-
return "
|
|
150
|
+
return "Object.create(null)";
|
|
151
151
|
case "enum": {
|
|
152
152
|
// In proto3, the first enum value must be zero.
|
|
153
153
|
// In proto2, protobuf-go returns the first value as the default.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DescExtension, DescField } from "./descriptor-set.js";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the zero value for a field.
|
|
4
|
+
*
|
|
5
|
+
* Returns either:
|
|
6
|
+
* - empty array literal for repeated fields
|
|
7
|
+
* - Object.create(null) for maps
|
|
8
|
+
* - undefined for message fields
|
|
9
|
+
* - an enums first value
|
|
10
|
+
* - scalar zero value
|
|
11
|
+
*/
|
|
12
|
+
export declare function getFieldZeroValue(field: DescField | DescExtension): any;
|
|
13
|
+
/**
|
|
14
|
+
* Returns true for a zero-value (all fields are zero).
|
|
15
|
+
*
|
|
16
|
+
* In proto3, zero-values are not written to the wire, unless the field is
|
|
17
|
+
* optional or repeated.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isMessageZeroValue<T extends Record<string, any>>(value: T | null | undefined, fields: (DescField | DescExtension)[]): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Compares if the value is considered a zero value for the field.
|
|
22
|
+
*/
|
|
23
|
+
export declare function compareFieldZeroValue<T>(field: DescField | DescExtension, value: T | null | undefined): boolean;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { enumDescZeroValue } from "./enum.js";
|
|
2
|
+
import { localName } from "./names.js";
|
|
3
|
+
import { scalarZeroValue } from "./scalar.js";
|
|
4
|
+
/**
|
|
5
|
+
* Returns the zero value for a field.
|
|
6
|
+
*
|
|
7
|
+
* Returns either:
|
|
8
|
+
* - empty array literal for repeated fields
|
|
9
|
+
* - Object.create(null) for maps
|
|
10
|
+
* - undefined for message fields
|
|
11
|
+
* - an enums first value
|
|
12
|
+
* - scalar zero value
|
|
13
|
+
*/
|
|
14
|
+
export function getFieldZeroValue(field) {
|
|
15
|
+
if (field.repeated) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
switch (field.fieldKind) {
|
|
19
|
+
case "message":
|
|
20
|
+
return undefined;
|
|
21
|
+
case "map":
|
|
22
|
+
return Object.create(null);
|
|
23
|
+
case "enum": {
|
|
24
|
+
return enumDescZeroValue(field.enum);
|
|
25
|
+
}
|
|
26
|
+
case "scalar": {
|
|
27
|
+
return scalarZeroValue(field.scalar, field.longType);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Returns true for a zero-value (all fields are zero).
|
|
33
|
+
*
|
|
34
|
+
* In proto3, zero-values are not written to the wire, unless the field is
|
|
35
|
+
* optional or repeated.
|
|
36
|
+
*/
|
|
37
|
+
export function isMessageZeroValue(value, fields) {
|
|
38
|
+
if (value == null) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
if (typeof value !== "object") {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
for (const field of fields) {
|
|
45
|
+
const fieldLocalName = localName(field);
|
|
46
|
+
if (fieldLocalName in value &&
|
|
47
|
+
!compareFieldZeroValue(field, value[fieldLocalName])) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Compares if the value is considered a zero value for the field.
|
|
55
|
+
*/
|
|
56
|
+
export function compareFieldZeroValue(field, value) {
|
|
57
|
+
if (value == null || value == 0) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
if (field.repeated) {
|
|
61
|
+
if (!Array.isArray(value) || typeof value.length !== "number") {
|
|
62
|
+
throw new Error("invalid repeated field: must be an array");
|
|
63
|
+
}
|
|
64
|
+
return value.length === 0;
|
|
65
|
+
}
|
|
66
|
+
switch (field.fieldKind) {
|
|
67
|
+
case "message":
|
|
68
|
+
if (typeof value !== "object") {
|
|
69
|
+
throw new Error("invalid message: must be an object");
|
|
70
|
+
}
|
|
71
|
+
// We need to check if all the fields are empty.
|
|
72
|
+
return isMessageZeroValue(value, field.message.fields);
|
|
73
|
+
case "map":
|
|
74
|
+
return Object.create(null);
|
|
75
|
+
case "enum": {
|
|
76
|
+
// In proto3, the first enum value must be zero.
|
|
77
|
+
// In proto2, protobuf-go returns the first value as the default.
|
|
78
|
+
if (field.enum.values.length < 1) {
|
|
79
|
+
throw new Error("invalid enum: missing at least one value");
|
|
80
|
+
}
|
|
81
|
+
const zeroValue = field.enum.values[0];
|
|
82
|
+
return zeroValue.number === value;
|
|
83
|
+
}
|
|
84
|
+
case "scalar": {
|
|
85
|
+
return scalarZeroValue(field.scalar, field.longType) === value;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
package/example/example.pb.ts
CHANGED
|
@@ -3,7 +3,13 @@
|
|
|
3
3
|
/* eslint-disable */
|
|
4
4
|
|
|
5
5
|
import type { MessageType, PartialFieldInfo } from "@aptre/protobuf-es-lite";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
createEnumType,
|
|
8
|
+
createMessageType,
|
|
9
|
+
Message,
|
|
10
|
+
ScalarType,
|
|
11
|
+
Timestamp,
|
|
12
|
+
} from "@aptre/protobuf-es-lite";
|
|
7
13
|
|
|
8
14
|
export const protobufPackage = "example";
|
|
9
15
|
|
|
@@ -58,35 +64,54 @@ export type EchoMsg = Message<{
|
|
|
58
64
|
/**
|
|
59
65
|
* @generated from oneof example.EchoMsg.demo
|
|
60
66
|
*/
|
|
61
|
-
demo?:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
67
|
+
demo?:
|
|
68
|
+
| {
|
|
69
|
+
value?: undefined;
|
|
70
|
+
case: undefined;
|
|
71
|
+
}
|
|
72
|
+
| {
|
|
73
|
+
/**
|
|
74
|
+
* @generated from field: example.ExampleEnum example_enum = 3;
|
|
75
|
+
*/
|
|
76
|
+
value: ExampleEnum;
|
|
77
|
+
case: "exampleEnum";
|
|
78
|
+
}
|
|
79
|
+
| {
|
|
80
|
+
/**
|
|
81
|
+
* @generated from field: string example_string = 4;
|
|
82
|
+
*/
|
|
83
|
+
value: string;
|
|
84
|
+
case: "exampleString";
|
|
85
|
+
};
|
|
78
86
|
}>;
|
|
79
87
|
|
|
80
88
|
// EchoMsg contains the message type declaration for EchoMsg.
|
|
81
89
|
export const EchoMsg: MessageType<EchoMsg> = createMessageType({
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
typeName: "example.EchoMsg",
|
|
91
|
+
fields: [
|
|
92
|
+
{ no: 1, name: "body", kind: "scalar", T: ScalarType.STRING },
|
|
93
|
+
{ no: 2, name: "ts", kind: "message", T: () => Timestamp },
|
|
94
|
+
{
|
|
95
|
+
no: 3,
|
|
96
|
+
name: "example_enum",
|
|
97
|
+
kind: "enum",
|
|
98
|
+
T: ExampleEnum_Enum,
|
|
99
|
+
oneof: "demo",
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
no: 4,
|
|
103
|
+
name: "example_string",
|
|
104
|
+
kind: "scalar",
|
|
105
|
+
T: ScalarType.STRING,
|
|
106
|
+
oneof: "demo",
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
no: 5,
|
|
110
|
+
name: "timestamps",
|
|
111
|
+
kind: "message",
|
|
112
|
+
T: () => Timestamp,
|
|
113
|
+
repeated: true,
|
|
114
|
+
},
|
|
115
|
+
] as readonly PartialFieldInfo[],
|
|
116
|
+
packedByDefault: true,
|
|
91
117
|
});
|
|
92
|
-
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aptre/protobuf-es-lite",
|
|
3
3
|
"description": "Lightweight Protobuf codegen for TypeScript and JavaScript.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"url": "git+ssh://git@github.com/aperturerobotics/protobuf-es-lite.git"
|