@aptre/protobuf-es-lite 0.1.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/.ignore +4 -0
- package/LICENSE +203 -0
- package/README.md +226 -0
- package/bin/protoc-gen-es-lite +6 -0
- package/dist/assert.js +59 -0
- package/dist/binary.js +389 -0
- package/dist/editions.js +26 -0
- package/dist/field-wrapper.js +14 -0
- package/dist/field.js +309 -0
- package/dist/index.js +16 -0
- package/dist/is-message.js +61 -0
- package/dist/json.js +624 -0
- package/dist/message.js +247 -0
- package/dist/partial.js +105 -0
- package/dist/protoc-gen-es-lite-plugin.js +25 -0
- package/dist/scalar.js +104 -0
- package/dist/typescript.js +177 -0
- package/dist/unknown.js +21 -0
- package/dist/util.js +261 -0
- package/example/example.proto +30 -0
- package/package.json +58 -0
- package/tsconfig.base.json +23 -0
- package/tsconfig.json +10 -0
package/dist/field.js
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeFieldInfos = exports.InternalOneofInfo = exports.localOneofName = exports.safeObjectProperty = exports.localFieldName = exports.fieldJsonName = exports.isFieldSet = exports.protoCamelCase = exports.newFieldList = exports.FieldList = void 0;
|
|
4
|
+
const protobuf_1 = require("@bufbuild/protobuf");
|
|
5
|
+
const assert_js_1 = require("./assert.js");
|
|
6
|
+
const scalar_js_1 = require("./scalar.js");
|
|
7
|
+
/**
|
|
8
|
+
* Provides convenient access to field information of a message type.
|
|
9
|
+
*/
|
|
10
|
+
class FieldList {
|
|
11
|
+
constructor(fields, normalizer) {
|
|
12
|
+
this._fields = fields;
|
|
13
|
+
this._normalizer = normalizer;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Find field information by field name or json_name.
|
|
17
|
+
*/
|
|
18
|
+
findJsonName(jsonName) {
|
|
19
|
+
if (!this.jsonNames) {
|
|
20
|
+
const t = {};
|
|
21
|
+
for (const f of this.list()) {
|
|
22
|
+
t[f.jsonName] = t[f.name] = f;
|
|
23
|
+
}
|
|
24
|
+
this.jsonNames = t;
|
|
25
|
+
}
|
|
26
|
+
return this.jsonNames[jsonName];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Find field information by proto field number.
|
|
30
|
+
*/
|
|
31
|
+
find(fieldNo) {
|
|
32
|
+
if (!this.numbers) {
|
|
33
|
+
const t = {};
|
|
34
|
+
for (const f of this.list()) {
|
|
35
|
+
t[f.no] = f;
|
|
36
|
+
}
|
|
37
|
+
this.numbers = t;
|
|
38
|
+
}
|
|
39
|
+
return this.numbers[fieldNo];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Return field information in the order they appear in the source.
|
|
43
|
+
*/
|
|
44
|
+
list() {
|
|
45
|
+
if (!this.all) {
|
|
46
|
+
this.all = this._normalizer(this._fields);
|
|
47
|
+
}
|
|
48
|
+
return this.all;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Return field information ordered by field number ascending.
|
|
52
|
+
*/
|
|
53
|
+
byNumber() {
|
|
54
|
+
if (!this.numbersAsc) {
|
|
55
|
+
this.numbersAsc = this.list()
|
|
56
|
+
.concat()
|
|
57
|
+
.sort((a, b) => a.no - b.no);
|
|
58
|
+
}
|
|
59
|
+
return this.numbersAsc;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* In order of appearance in the source, list fields and
|
|
63
|
+
* oneof groups.
|
|
64
|
+
*/
|
|
65
|
+
byMember() {
|
|
66
|
+
if (!this.members) {
|
|
67
|
+
this.members = [];
|
|
68
|
+
const a = this.members;
|
|
69
|
+
let o;
|
|
70
|
+
for (const f of this.list()) {
|
|
71
|
+
if (f.oneof) {
|
|
72
|
+
if (f.oneof !== o) {
|
|
73
|
+
o = f.oneof;
|
|
74
|
+
a.push(o);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
a.push(f);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return this.members;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.FieldList = FieldList;
|
|
86
|
+
// newFieldList constructs a new field list.
|
|
87
|
+
function newFieldList(fields, packedByDefault) {
|
|
88
|
+
return new FieldList(fields, (source) => normalizeFieldInfos(source, packedByDefault));
|
|
89
|
+
}
|
|
90
|
+
exports.newFieldList = newFieldList;
|
|
91
|
+
/*
|
|
92
|
+
* Converts snake_case to protoCamelCase according to the convention
|
|
93
|
+
* used by protoc to convert a field name to a JSON name.
|
|
94
|
+
*/
|
|
95
|
+
function protoCamelCase(snakeCase) {
|
|
96
|
+
let capNext = false;
|
|
97
|
+
const b = [];
|
|
98
|
+
for (let i = 0; i < snakeCase.length; i++) {
|
|
99
|
+
let c = snakeCase.charAt(i);
|
|
100
|
+
switch (c) {
|
|
101
|
+
case "_":
|
|
102
|
+
capNext = true;
|
|
103
|
+
break;
|
|
104
|
+
case "0":
|
|
105
|
+
case "1":
|
|
106
|
+
case "2":
|
|
107
|
+
case "3":
|
|
108
|
+
case "4":
|
|
109
|
+
case "5":
|
|
110
|
+
case "6":
|
|
111
|
+
case "7":
|
|
112
|
+
case "8":
|
|
113
|
+
case "9":
|
|
114
|
+
b.push(c);
|
|
115
|
+
capNext = false;
|
|
116
|
+
break;
|
|
117
|
+
default:
|
|
118
|
+
if (capNext) {
|
|
119
|
+
capNext = false;
|
|
120
|
+
c = c.toUpperCase();
|
|
121
|
+
}
|
|
122
|
+
b.push(c);
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return b.join("");
|
|
127
|
+
}
|
|
128
|
+
exports.protoCamelCase = protoCamelCase;
|
|
129
|
+
/**
|
|
130
|
+
* Returns true if the field is set.
|
|
131
|
+
*/
|
|
132
|
+
function isFieldSet(field, target) {
|
|
133
|
+
const localName = field.localName;
|
|
134
|
+
if (field.repeated) {
|
|
135
|
+
return target[localName].length > 0;
|
|
136
|
+
}
|
|
137
|
+
if (field.oneof) {
|
|
138
|
+
return target[field.oneof.localName].case === localName; // eslint-disable-line @typescript-eslint/no-unsafe-member-access
|
|
139
|
+
}
|
|
140
|
+
switch (field.kind) {
|
|
141
|
+
case "enum":
|
|
142
|
+
case "scalar":
|
|
143
|
+
if (field.opt || field.req) {
|
|
144
|
+
// explicit presence
|
|
145
|
+
return target[localName] !== undefined;
|
|
146
|
+
}
|
|
147
|
+
// implicit presence
|
|
148
|
+
if (field.kind == "enum") {
|
|
149
|
+
return target[localName] !== field.T.values[0].no;
|
|
150
|
+
}
|
|
151
|
+
return !(0, scalar_js_1.isScalarZeroValue)(field.T, target[localName]);
|
|
152
|
+
case "message":
|
|
153
|
+
return target[localName] !== undefined;
|
|
154
|
+
case "map":
|
|
155
|
+
return Object.keys(target[localName]).length > 0; // eslint-disable-line @typescript-eslint/no-unsafe-argument
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.isFieldSet = isFieldSet;
|
|
159
|
+
/**
|
|
160
|
+
* Returns the JSON name for a protobuf field, exactly like protoc does.
|
|
161
|
+
*/
|
|
162
|
+
exports.fieldJsonName = protoCamelCase;
|
|
163
|
+
/**
|
|
164
|
+
* Returns the name of a field in generated code.
|
|
165
|
+
*/
|
|
166
|
+
function localFieldName(protoName, inOneof) {
|
|
167
|
+
const name = protoCamelCase(protoName);
|
|
168
|
+
if (inOneof) {
|
|
169
|
+
// oneof member names are not properties, but values of the `case` property.
|
|
170
|
+
return name;
|
|
171
|
+
}
|
|
172
|
+
return (0, exports.safeObjectProperty)(safeMessageProperty(name));
|
|
173
|
+
}
|
|
174
|
+
exports.localFieldName = localFieldName;
|
|
175
|
+
/**
|
|
176
|
+
* Names that cannot be used for object properties because they are reserved
|
|
177
|
+
* by built-in JavaScript properties.
|
|
178
|
+
*/
|
|
179
|
+
const reservedObjectProperties = new Set([
|
|
180
|
+
// names reserved by JavaScript
|
|
181
|
+
"constructor",
|
|
182
|
+
"toString",
|
|
183
|
+
"toJSON",
|
|
184
|
+
"valueOf",
|
|
185
|
+
]);
|
|
186
|
+
/*
|
|
187
|
+
* Names that cannot be used for object properties because they are reserved
|
|
188
|
+
* by the runtime.
|
|
189
|
+
*/
|
|
190
|
+
const reservedMessageProperties = new Set([
|
|
191
|
+
// names reserved by the runtime
|
|
192
|
+
"getType",
|
|
193
|
+
"clone",
|
|
194
|
+
"equals",
|
|
195
|
+
"fromBinary",
|
|
196
|
+
"fromJson",
|
|
197
|
+
"fromJsonString",
|
|
198
|
+
"toBinary",
|
|
199
|
+
"toJson",
|
|
200
|
+
"toJsonString",
|
|
201
|
+
// names reserved by the runtime for the future
|
|
202
|
+
"toObject",
|
|
203
|
+
]);
|
|
204
|
+
const fallback = (name) => `${name}$`;
|
|
205
|
+
/**
|
|
206
|
+
* Will wrap names that are Object prototype properties or names reserved
|
|
207
|
+
* for `Message`s.
|
|
208
|
+
*/
|
|
209
|
+
const safeMessageProperty = (name) => {
|
|
210
|
+
if (reservedMessageProperties.has(name)) {
|
|
211
|
+
return fallback(name);
|
|
212
|
+
}
|
|
213
|
+
return name;
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* Names that cannot be used for object properties because they are reserved
|
|
217
|
+
* by built-in JavaScript properties.
|
|
218
|
+
*/
|
|
219
|
+
const safeObjectProperty = (name) => {
|
|
220
|
+
if (reservedObjectProperties.has(name)) {
|
|
221
|
+
return fallback(name);
|
|
222
|
+
}
|
|
223
|
+
return name;
|
|
224
|
+
};
|
|
225
|
+
exports.safeObjectProperty = safeObjectProperty;
|
|
226
|
+
/**
|
|
227
|
+
* Returns the name of a oneof group in generated code.
|
|
228
|
+
*/
|
|
229
|
+
function localOneofName(protoName) {
|
|
230
|
+
return localFieldName(protoName, false);
|
|
231
|
+
}
|
|
232
|
+
exports.localOneofName = localOneofName;
|
|
233
|
+
// InternarlOneofInfo implements OneofInfo.
|
|
234
|
+
class InternalOneofInfo {
|
|
235
|
+
constructor(name) {
|
|
236
|
+
this.kind = "oneof";
|
|
237
|
+
this.repeated = false;
|
|
238
|
+
this.packed = false;
|
|
239
|
+
this.opt = false;
|
|
240
|
+
this.req = false;
|
|
241
|
+
this.default = undefined;
|
|
242
|
+
this.fields = [];
|
|
243
|
+
this.name = name;
|
|
244
|
+
this.localName = localOneofName(name);
|
|
245
|
+
}
|
|
246
|
+
addField(field) {
|
|
247
|
+
(0, assert_js_1.assert)(field.oneof === this, `field ${field.name} not one of ${this.name}`);
|
|
248
|
+
this.fields.push(field);
|
|
249
|
+
}
|
|
250
|
+
findField(localName) {
|
|
251
|
+
if (!this._lookup) {
|
|
252
|
+
this._lookup = Object.create(null);
|
|
253
|
+
for (let i = 0; i < this.fields.length; i++) {
|
|
254
|
+
this._lookup[this.fields[i].localName] = this.fields[i];
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return this._lookup[localName];
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
exports.InternalOneofInfo = InternalOneofInfo;
|
|
261
|
+
/**
|
|
262
|
+
* Convert a collection of field info to an array of normalized FieldInfo.
|
|
263
|
+
*
|
|
264
|
+
* The argument `packedByDefault` specifies whether fields that do not specify
|
|
265
|
+
* `packed` should be packed (proto3) or unpacked (proto2).
|
|
266
|
+
*/
|
|
267
|
+
function normalizeFieldInfos(fieldInfos, packedByDefault) {
|
|
268
|
+
const r = [];
|
|
269
|
+
let o;
|
|
270
|
+
for (const field of typeof fieldInfos == "function"
|
|
271
|
+
? fieldInfos()
|
|
272
|
+
: fieldInfos) {
|
|
273
|
+
const f = field;
|
|
274
|
+
f.localName = localFieldName(field.name, field.oneof !== undefined);
|
|
275
|
+
f.jsonName = field.jsonName ?? (0, exports.fieldJsonName)(field.name);
|
|
276
|
+
f.repeated = field.repeated ?? false;
|
|
277
|
+
if (field.kind == "scalar") {
|
|
278
|
+
f.L = field.L ?? protobuf_1.LongType.BIGINT;
|
|
279
|
+
}
|
|
280
|
+
f.delimited = field.delimited ?? false;
|
|
281
|
+
f.req = field.req ?? false;
|
|
282
|
+
f.opt = field.opt ?? false;
|
|
283
|
+
if (field.packed === undefined) {
|
|
284
|
+
if (packedByDefault) {
|
|
285
|
+
f.packed =
|
|
286
|
+
field.kind == "enum" ||
|
|
287
|
+
(field.kind == "scalar" &&
|
|
288
|
+
field.T != protobuf_1.ScalarType.BYTES &&
|
|
289
|
+
field.T != protobuf_1.ScalarType.STRING);
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
f.packed = false;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
// We do not surface options at this time
|
|
296
|
+
// f.options = field.options ?? emptyReadonlyObject;
|
|
297
|
+
if (field.oneof !== undefined) {
|
|
298
|
+
const ooname = typeof field.oneof == "string" ? field.oneof : field.oneof.name;
|
|
299
|
+
if (!o || o.name != ooname) {
|
|
300
|
+
o = new InternalOneofInfo(ooname);
|
|
301
|
+
}
|
|
302
|
+
f.oneof = o;
|
|
303
|
+
o.addField(f);
|
|
304
|
+
}
|
|
305
|
+
r.push(f);
|
|
306
|
+
}
|
|
307
|
+
return r;
|
|
308
|
+
}
|
|
309
|
+
exports.normalizeFieldInfos = normalizeFieldInfos;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isScalarZeroValue = exports.scalarZeroValue = exports.scalarEquals = exports.localOneofName = exports.localFieldName = exports.fieldJsonName = exports.FieldList = exports.newFieldList = exports.createMessageType = exports.compareMessages = void 0;
|
|
4
|
+
var message_js_1 = require("./message.js");
|
|
5
|
+
Object.defineProperty(exports, "compareMessages", { enumerable: true, get: function () { return message_js_1.compareMessages; } });
|
|
6
|
+
Object.defineProperty(exports, "createMessageType", { enumerable: true, get: function () { return message_js_1.createMessageType; } });
|
|
7
|
+
var field_js_1 = require("./field.js");
|
|
8
|
+
Object.defineProperty(exports, "newFieldList", { enumerable: true, get: function () { return field_js_1.newFieldList; } });
|
|
9
|
+
Object.defineProperty(exports, "FieldList", { enumerable: true, get: function () { return field_js_1.FieldList; } });
|
|
10
|
+
Object.defineProperty(exports, "fieldJsonName", { enumerable: true, get: function () { return field_js_1.fieldJsonName; } });
|
|
11
|
+
Object.defineProperty(exports, "localFieldName", { enumerable: true, get: function () { return field_js_1.localFieldName; } });
|
|
12
|
+
Object.defineProperty(exports, "localOneofName", { enumerable: true, get: function () { return field_js_1.localOneofName; } });
|
|
13
|
+
var scalar_js_1 = require("./scalar.js");
|
|
14
|
+
Object.defineProperty(exports, "scalarEquals", { enumerable: true, get: function () { return scalar_js_1.scalarEquals; } });
|
|
15
|
+
Object.defineProperty(exports, "scalarZeroValue", { enumerable: true, get: function () { return scalar_js_1.scalarZeroValue; } });
|
|
16
|
+
Object.defineProperty(exports, "isScalarZeroValue", { enumerable: true, get: function () { return scalar_js_1.isScalarZeroValue; } });
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isCompleteMessage = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Check whether the given partial has all fields present recursively.
|
|
6
|
+
*/
|
|
7
|
+
function isCompleteMessage(arg, fields) {
|
|
8
|
+
if (arg == null || typeof arg !== "object") {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
return fields.every((fi) => {
|
|
12
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any -- `any` is the best choice for dynamic access
|
|
13
|
+
const value = arg[fi.localName];
|
|
14
|
+
if (fi.repeated) {
|
|
15
|
+
return (Array.isArray(value) && value.every((item) => isCompleteField(item, fi)));
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
return isCompleteField(value, fi);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
exports.isCompleteMessage = isCompleteMessage;
|
|
23
|
+
/**
|
|
24
|
+
* Check whether the given partial field has a full value present recursively.
|
|
25
|
+
*/
|
|
26
|
+
function isCompleteField(value, field) {
|
|
27
|
+
if (field.oneof) {
|
|
28
|
+
// For oneof fields, only one field should be set
|
|
29
|
+
const oneofFields = field.oneof.fields;
|
|
30
|
+
const setField = oneofFields.find((f) => value[f.localName] !== undefined);
|
|
31
|
+
return setField === field;
|
|
32
|
+
}
|
|
33
|
+
if (value === undefined) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const fieldKind = field.kind;
|
|
37
|
+
switch (fieldKind) {
|
|
38
|
+
case "scalar":
|
|
39
|
+
return true;
|
|
40
|
+
case "message":
|
|
41
|
+
return isCompleteMessage(value, field.T.fields.list());
|
|
42
|
+
case "enum":
|
|
43
|
+
return typeof value === "number";
|
|
44
|
+
case "map":
|
|
45
|
+
return Object.values(value).every((val) => {
|
|
46
|
+
const valueKind = field.V.kind;
|
|
47
|
+
switch (valueKind) {
|
|
48
|
+
case "scalar":
|
|
49
|
+
return true;
|
|
50
|
+
case "enum":
|
|
51
|
+
return typeof val === "number";
|
|
52
|
+
case "message":
|
|
53
|
+
return isCompleteMessage(val, field.V.T.fields.list());
|
|
54
|
+
default:
|
|
55
|
+
return valueKind;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
default:
|
|
59
|
+
return fieldKind;
|
|
60
|
+
}
|
|
61
|
+
}
|