@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/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
+ }