@bufbuild/protobuf 2.11.0 → 2.12.1
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.md +3 -3
- package/dist/commonjs/codegenv1/boot.d.ts +1 -0
- package/dist/{cjs/codegenv1/types.js → commonjs/codegenv1/boot.js} +3 -7
- package/dist/{cjs → commonjs}/codegenv1/types.d.ts +9 -5
- package/dist/{cjs → commonjs}/codegenv2/types.d.ts +9 -5
- package/dist/{cjs → commonjs}/descriptors.d.ts +12 -5
- package/dist/{cjs → commonjs}/equals.d.ts +8 -3
- package/dist/{cjs → commonjs}/equals.js +8 -3
- package/dist/{cjs → commonjs}/extensions.d.ts +2 -1
- package/dist/{cjs → commonjs}/extensions.js +3 -4
- package/dist/{cjs → commonjs}/from-binary.d.ts +16 -2
- package/dist/{cjs → commonjs}/from-binary.js +37 -31
- package/dist/{cjs → commonjs}/from-json.d.ts +20 -3
- package/dist/{cjs → commonjs}/from-json.js +175 -55
- package/dist/commonjs/json-value.js +15 -0
- package/dist/commonjs/package.json +4 -0
- package/dist/{cjs → commonjs}/proto-int64.js +1 -0
- package/dist/{cjs → commonjs}/reflect/path.d.ts +1 -1
- package/dist/{cjs → commonjs}/reflect/reflect-check.js +3 -1
- package/dist/commonjs/reflect/scalar.d.ts +43 -0
- package/dist/{cjs → commonjs}/reflect/scalar.js +33 -6
- package/dist/{cjs → commonjs}/registry.js +24 -1
- package/dist/{cjs → commonjs}/to-json.d.ts +1 -1
- package/dist/{cjs → commonjs}/to-json.js +9 -10
- package/dist/{cjs → commonjs}/types.d.ts +1 -1
- package/dist/{cjs/codegenv2 → commonjs}/types.js +0 -7
- package/dist/{cjs → commonjs}/wire/binary-encoding.d.ts +13 -9
- package/dist/{cjs → commonjs}/wire/binary-encoding.js +26 -11
- package/dist/{cjs → commonjs}/wire/size-delimited.d.ts +1 -1
- package/dist/{cjs → commonjs}/wire/text-encoding.d.ts +4 -2
- package/dist/{cjs → commonjs}/wire/text-encoding.js +8 -1
- package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/api_pb.d.ts +1 -1
- package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/compiler/plugin_pb.d.ts +2 -2
- package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/descriptor_pb.d.ts +37 -23
- package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/descriptor_pb.js +1 -1
- package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/field_mask_pb.d.ts +32 -36
- package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/go_features_pb.d.ts +65 -0
- package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/go_features_pb.js +38 -2
- package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/timestamp_pb.d.ts +5 -5
- package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/type_pb.d.ts +3 -3
- package/dist/{cjs → commonjs}/wkt/wrappers.d.ts +10 -0
- package/dist/{cjs → commonjs}/wkt/wrappers.js +24 -0
- package/dist/esm/codegenv1/boot.d.ts +1 -0
- package/dist/esm/codegenv1/boot.js +14 -0
- package/dist/esm/codegenv1/types.d.ts +9 -5
- package/dist/esm/codegenv1/types.js +0 -7
- package/dist/esm/codegenv2/types.d.ts +9 -5
- package/dist/esm/codegenv2/types.js +0 -7
- package/dist/esm/descriptors.d.ts +12 -5
- package/dist/esm/equals.d.ts +8 -3
- package/dist/esm/equals.js +8 -3
- package/dist/esm/extensions.d.ts +2 -1
- package/dist/esm/extensions.js +4 -5
- package/dist/esm/from-binary.d.ts +16 -2
- package/dist/esm/from-binary.js +36 -31
- package/dist/esm/from-json.d.ts +20 -3
- package/dist/esm/from-json.js +176 -56
- package/dist/esm/package.json +4 -0
- package/dist/esm/proto-int64.js +1 -0
- package/dist/esm/reflect/path.d.ts +1 -1
- package/dist/esm/reflect/reflect-check.js +3 -1
- package/dist/esm/reflect/scalar.d.ts +27 -5
- package/dist/esm/reflect/scalar.js +33 -6
- package/dist/esm/registry.js +24 -1
- package/dist/esm/to-json.d.ts +1 -1
- package/dist/esm/to-json.js +10 -11
- package/dist/esm/types.d.ts +1 -1
- package/dist/esm/wire/binary-encoding.d.ts +13 -9
- package/dist/esm/wire/binary-encoding.js +26 -11
- package/dist/esm/wire/size-delimited.d.ts +1 -1
- package/dist/esm/wire/text-encoding.d.ts +4 -2
- package/dist/esm/wire/text-encoding.js +8 -1
- package/dist/esm/wkt/gen/google/protobuf/api_pb.d.ts +1 -1
- package/dist/esm/wkt/gen/google/protobuf/compiler/plugin_pb.d.ts +2 -2
- package/dist/esm/wkt/gen/google/protobuf/descriptor_pb.d.ts +37 -23
- package/dist/esm/wkt/gen/google/protobuf/descriptor_pb.js +1 -1
- package/dist/esm/wkt/gen/google/protobuf/field_mask_pb.d.ts +32 -36
- package/dist/esm/wkt/gen/google/protobuf/go_features_pb.d.ts +65 -0
- package/dist/esm/wkt/gen/google/protobuf/go_features_pb.js +37 -1
- package/dist/esm/wkt/gen/google/protobuf/timestamp_pb.d.ts +5 -5
- package/dist/esm/wkt/gen/google/protobuf/type_pb.d.ts +3 -3
- package/dist/esm/wkt/wrappers.d.ts +10 -0
- package/dist/esm/wkt/wrappers.js +23 -0
- package/package.json +97 -31
- package/dist/cjs/package.json +0 -1
- package/dist/cjs/reflect/scalar.d.ts +0 -21
- /package/dist/{cjs → commonjs}/clone.d.ts +0 -0
- /package/dist/{cjs → commonjs}/clone.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/enum.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/enum.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/extension.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/extension.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/file.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/file.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/index.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/index.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/message.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/message.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/service.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/service.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/symbols.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv1/symbols.js +0 -0
- /package/dist/{cjs → commonjs/codegenv1}/types.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/boot.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/boot.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/embed.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/embed.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/enum.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/enum.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/extension.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/extension.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/file.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/file.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/index.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/index.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/message.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/message.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/restore-json-names.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/restore-json-names.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/scalar.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/scalar.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/service.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/service.js +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/symbols.d.ts +0 -0
- /package/dist/{cjs → commonjs}/codegenv2/symbols.js +0 -0
- /package/dist/{cjs/json-value.js → commonjs/codegenv2/types.js} +0 -0
- /package/dist/{cjs → commonjs}/create.d.ts +0 -0
- /package/dist/{cjs → commonjs}/create.js +0 -0
- /package/dist/{cjs → commonjs}/descriptors.js +0 -0
- /package/dist/{cjs → commonjs}/fields.d.ts +0 -0
- /package/dist/{cjs → commonjs}/fields.js +0 -0
- /package/dist/{cjs → commonjs}/index.d.ts +0 -0
- /package/dist/{cjs → commonjs}/index.js +0 -0
- /package/dist/{cjs → commonjs}/is-message.d.ts +0 -0
- /package/dist/{cjs → commonjs}/is-message.js +0 -0
- /package/dist/{cjs → commonjs}/json-value.d.ts +0 -0
- /package/dist/{cjs → commonjs}/merge.d.ts +0 -0
- /package/dist/{cjs → commonjs}/merge.js +0 -0
- /package/dist/{cjs → commonjs}/proto-int64.d.ts +0 -0
- /package/dist/{cjs → commonjs}/reflect/error.d.ts +0 -0
- /package/dist/{cjs → commonjs}/reflect/error.js +0 -0
- /package/dist/{cjs → commonjs}/reflect/guard.d.ts +0 -0
- /package/dist/{cjs → commonjs}/reflect/guard.js +0 -0
- /package/dist/{cjs → commonjs}/reflect/index.d.ts +0 -0
- /package/dist/{cjs → commonjs}/reflect/index.js +0 -0
- /package/dist/{cjs → commonjs}/reflect/names.d.ts +0 -0
- /package/dist/{cjs → commonjs}/reflect/names.js +0 -0
- /package/dist/{cjs → commonjs}/reflect/nested-types.d.ts +0 -0
- /package/dist/{cjs → commonjs}/reflect/nested-types.js +0 -0
- /package/dist/{cjs → commonjs}/reflect/path.js +0 -0
- /package/dist/{cjs → commonjs}/reflect/reflect-check.d.ts +0 -0
- /package/dist/{cjs → commonjs}/reflect/reflect-types.d.ts +0 -0
- /package/dist/{cjs → commonjs}/reflect/reflect-types.js +0 -0
- /package/dist/{cjs → commonjs}/reflect/reflect.d.ts +0 -0
- /package/dist/{cjs → commonjs}/reflect/reflect.js +0 -0
- /package/dist/{cjs → commonjs}/reflect/unsafe.d.ts +0 -0
- /package/dist/{cjs → commonjs}/reflect/unsafe.js +0 -0
- /package/dist/{cjs → commonjs}/registry.d.ts +0 -0
- /package/dist/{cjs → commonjs}/to-binary.d.ts +0 -0
- /package/dist/{cjs → commonjs}/to-binary.js +0 -0
- /package/dist/{cjs → commonjs}/wire/base64-encoding.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wire/base64-encoding.js +0 -0
- /package/dist/{cjs → commonjs}/wire/index.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wire/index.js +0 -0
- /package/dist/{cjs → commonjs}/wire/size-delimited.js +0 -0
- /package/dist/{cjs → commonjs}/wire/text-format.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wire/text-format.js +0 -0
- /package/dist/{cjs → commonjs}/wire/varint.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wire/varint.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/any.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wkt/any.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/duration.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wkt/duration.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/any_pb.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/any_pb.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/api_pb.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/compiler/plugin_pb.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/cpp_features_pb.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/cpp_features_pb.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/duration_pb.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/duration_pb.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/empty_pb.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/empty_pb.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/field_mask_pb.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/java_features_pb.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/java_features_pb.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/source_context_pb.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/source_context_pb.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/struct_pb.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/struct_pb.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/timestamp_pb.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/type_pb.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/wrappers_pb.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/wrappers_pb.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/index.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wkt/index.js +0 -0
- /package/dist/{cjs → commonjs}/wkt/timestamp.d.ts +0 -0
- /package/dist/{cjs → commonjs}/wkt/timestamp.js +0 -0
|
@@ -29,38 +29,42 @@ const names_js_1 = require("./reflect/names.js");
|
|
|
29
29
|
const base64_encoding_js_1 = require("./wire/base64-encoding.js");
|
|
30
30
|
const index_js_1 = require("./wkt/index.js");
|
|
31
31
|
const extensions_js_1 = require("./extensions.js");
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
ignoreUnknownFields: false,
|
|
35
|
-
};
|
|
36
|
-
function makeReadOptions(options) {
|
|
37
|
-
return options ? Object.assign(Object.assign({}, jsonReadDefaults), options) : jsonReadDefaults;
|
|
32
|
+
function makeReadContext(options) {
|
|
33
|
+
return Object.assign(Object.assign({ ignoreUnknownFields: false, recursionLimit: 100 }, options), { depth: 0 });
|
|
38
34
|
}
|
|
39
35
|
/**
|
|
40
36
|
* Parse a message from a JSON string.
|
|
37
|
+
*
|
|
38
|
+
* Duplicate keys are rejected.
|
|
41
39
|
*/
|
|
42
40
|
function fromJsonString(schema, json, options) {
|
|
43
41
|
return fromJson(schema, parseJsonString(json, schema.typeName), options);
|
|
44
42
|
}
|
|
45
43
|
/**
|
|
46
|
-
* Parse a message from a JSON string, merging fields.
|
|
44
|
+
* Parse a message from a JSON string, merging fields into the target.
|
|
47
45
|
*
|
|
48
46
|
* Repeated fields are appended. Map entries are added, overwriting
|
|
49
47
|
* existing keys.
|
|
50
48
|
*
|
|
51
49
|
* If a message field is already present, it will be merged with the
|
|
52
50
|
* new data.
|
|
51
|
+
*
|
|
52
|
+
* Duplicate keys in the JSON are rejected, as in `fromJsonString`.
|
|
53
53
|
*/
|
|
54
54
|
function mergeFromJsonString(schema, target, json, options) {
|
|
55
55
|
return mergeFromJson(schema, target, parseJsonString(json, schema.typeName), options);
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
58
|
* Parse a message from a JSON value.
|
|
59
|
+
*
|
|
60
|
+
* Duplicate keys are rejected, but a value parsed by JSON.parse has already
|
|
61
|
+
* dropped duplicates (the last one wins). Use `fromJsonString` for strict
|
|
62
|
+
* duplicate-key checking.
|
|
59
63
|
*/
|
|
60
64
|
function fromJson(schema, json, options) {
|
|
61
65
|
const msg = (0, reflect_js_1.reflect)(schema);
|
|
62
66
|
try {
|
|
63
|
-
readMessage(msg, json,
|
|
67
|
+
readMessage(msg, json, makeReadContext(options));
|
|
64
68
|
}
|
|
65
69
|
catch (e) {
|
|
66
70
|
if ((0, error_js_1.isFieldError)(e)) {
|
|
@@ -74,17 +78,20 @@ function fromJson(schema, json, options) {
|
|
|
74
78
|
return msg.message;
|
|
75
79
|
}
|
|
76
80
|
/**
|
|
77
|
-
* Parse a message from a JSON value, merging fields.
|
|
81
|
+
* Parse a message from a JSON value, merging fields into the target.
|
|
78
82
|
*
|
|
79
83
|
* Repeated fields are appended. Map entries are added, overwriting
|
|
80
84
|
* existing keys.
|
|
81
85
|
*
|
|
82
86
|
* If a message field is already present, it will be merged with the
|
|
83
87
|
* new data.
|
|
88
|
+
*
|
|
89
|
+
* Duplicate keys are rejected as in `fromJson`; use `mergeFromJsonString`
|
|
90
|
+
* for strict checking.
|
|
84
91
|
*/
|
|
85
92
|
function mergeFromJson(schema, target, json, options) {
|
|
86
93
|
try {
|
|
87
|
-
readMessage((0, reflect_js_1.reflect)(schema, target), json,
|
|
94
|
+
readMessage((0, reflect_js_1.reflect)(schema, target), json, makeReadContext(options));
|
|
88
95
|
}
|
|
89
96
|
catch (e) {
|
|
90
97
|
if ((0, error_js_1.isFieldError)(e)) {
|
|
@@ -121,82 +128,95 @@ function getJsonField(desc, jsonKey) {
|
|
|
121
128
|
}
|
|
122
129
|
return (_a = messageJsonFields.get(desc)) === null || _a === void 0 ? void 0 : _a.get(jsonKey);
|
|
123
130
|
}
|
|
124
|
-
function readMessage(msg, json,
|
|
131
|
+
function readMessage(msg, json, ctx) {
|
|
125
132
|
var _a;
|
|
126
|
-
if (
|
|
133
|
+
if (++ctx.depth > ctx.recursionLimit) {
|
|
134
|
+
throw new Error(`cannot decode ${msg.desc} from JSON: maximum recursion depth of ${ctx.recursionLimit} reached`);
|
|
135
|
+
}
|
|
136
|
+
if (tryWktFromJson(msg, json, ctx)) {
|
|
137
|
+
ctx.depth--;
|
|
127
138
|
return;
|
|
128
139
|
}
|
|
129
140
|
if (json == null || Array.isArray(json) || typeof json != "object") {
|
|
130
141
|
throw new Error(`cannot decode ${msg.desc} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
|
|
131
142
|
}
|
|
132
143
|
const oneofSeen = new Map();
|
|
144
|
+
const fieldSeen = new Set();
|
|
133
145
|
for (const [jsonKey, jsonValue] of Object.entries(json)) {
|
|
134
146
|
const field = getJsonField(msg.desc, jsonKey);
|
|
135
147
|
if (field) {
|
|
148
|
+
if (fieldSeen.has(field)) {
|
|
149
|
+
// The same field may be set by its proto name and its JSON name, or by
|
|
150
|
+
// a duplicate or unicode-escaped key that JSON.parse already collapsed.
|
|
151
|
+
// Checked before the null-skip below so that a null entry still counts.
|
|
152
|
+
throw new error_js_1.FieldError(field, "set multiple times");
|
|
153
|
+
}
|
|
154
|
+
fieldSeen.add(field);
|
|
155
|
+
if (field.oneof && jsonValue === null && field.fieldKind == "scalar") {
|
|
156
|
+
// see conformance test Required.Proto3.JsonInput.OneofFieldNull{First,Second}
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
136
159
|
if (field.oneof) {
|
|
137
|
-
if (jsonValue === null && field.fieldKind == "scalar") {
|
|
138
|
-
// see conformance test Required.Proto3.JsonInput.OneofFieldNull{First,Second}
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
160
|
const seen = oneofSeen.get(field.oneof);
|
|
142
161
|
if (seen !== undefined) {
|
|
143
162
|
throw new error_js_1.FieldError(field.oneof, `oneof set multiple times by ${seen.name} and ${field.name}`);
|
|
144
163
|
}
|
|
145
164
|
oneofSeen.set(field.oneof, field);
|
|
146
165
|
}
|
|
147
|
-
readField(msg, field, jsonValue,
|
|
166
|
+
readField(msg, field, jsonValue, ctx);
|
|
148
167
|
}
|
|
149
168
|
else {
|
|
150
169
|
let extension = undefined;
|
|
151
170
|
if (jsonKey.startsWith("[") &&
|
|
152
171
|
jsonKey.endsWith("]") &&
|
|
153
172
|
// biome-ignore lint/suspicious/noAssignInExpressions: no
|
|
154
|
-
(extension = (_a =
|
|
173
|
+
(extension = (_a = ctx.registry) === null || _a === void 0 ? void 0 : _a.getExtension(jsonKey.substring(1, jsonKey.length - 1))) &&
|
|
155
174
|
extension.extendee.typeName === msg.desc.typeName) {
|
|
156
175
|
const [container, field, get] = (0, extensions_js_1.createExtensionContainer)(extension);
|
|
157
|
-
readField(container, field, jsonValue,
|
|
176
|
+
readField(container, field, jsonValue, ctx);
|
|
158
177
|
(0, extensions_js_1.setExtension)(msg.message, extension, get());
|
|
159
178
|
}
|
|
160
|
-
if (!extension && !
|
|
179
|
+
if (!extension && !ctx.ignoreUnknownFields) {
|
|
161
180
|
throw new Error(`cannot decode ${msg.desc} from JSON: key "${jsonKey}" is unknown`);
|
|
162
181
|
}
|
|
163
182
|
}
|
|
164
183
|
}
|
|
184
|
+
ctx.depth--;
|
|
165
185
|
}
|
|
166
|
-
function readField(msg, field, json,
|
|
186
|
+
function readField(msg, field, json, ctx) {
|
|
167
187
|
switch (field.fieldKind) {
|
|
168
188
|
case "scalar":
|
|
169
189
|
readScalarField(msg, field, json);
|
|
170
190
|
break;
|
|
171
191
|
case "enum":
|
|
172
|
-
readEnumField(msg, field, json,
|
|
192
|
+
readEnumField(msg, field, json, ctx);
|
|
173
193
|
break;
|
|
174
194
|
case "message":
|
|
175
|
-
readMessageField(msg, field, json,
|
|
195
|
+
readMessageField(msg, field, json, ctx);
|
|
176
196
|
break;
|
|
177
197
|
case "list":
|
|
178
|
-
readListField(msg.get(field), json,
|
|
198
|
+
readListField(msg.get(field), json, ctx);
|
|
179
199
|
break;
|
|
180
200
|
case "map":
|
|
181
|
-
readMapField(msg.get(field), json,
|
|
201
|
+
readMapField(msg.get(field), json, ctx);
|
|
182
202
|
break;
|
|
183
203
|
}
|
|
184
204
|
}
|
|
185
|
-
function readListOrMapItem(field, json,
|
|
205
|
+
function readListOrMapItem(field, json, ctx) {
|
|
186
206
|
if (field.scalar && json !== null) {
|
|
187
207
|
return scalarFromJson(field, json);
|
|
188
208
|
}
|
|
189
209
|
if (field.message && !isResetSentinelNullValue(field, json)) {
|
|
190
210
|
const msgValue = (0, reflect_js_1.reflect)(field.message);
|
|
191
|
-
readMessage(msgValue, json,
|
|
211
|
+
readMessage(msgValue, json, ctx);
|
|
192
212
|
return msgValue;
|
|
193
213
|
}
|
|
194
214
|
if (field.enum && !isResetSentinelNullValue(field, json)) {
|
|
195
|
-
return readEnum(field.enum, json,
|
|
215
|
+
return readEnum(field.enum, json, ctx.ignoreUnknownFields);
|
|
196
216
|
}
|
|
197
217
|
throw new error_js_1.FieldError(field, `${field.fieldKind === "list" ? "list item" : "map value"} must not be null`);
|
|
198
218
|
}
|
|
199
|
-
function readMapField(map, json,
|
|
219
|
+
function readMapField(map, json, ctx) {
|
|
200
220
|
if (json === null) {
|
|
201
221
|
return;
|
|
202
222
|
}
|
|
@@ -204,15 +224,20 @@ function readMapField(map, json, opts) {
|
|
|
204
224
|
if (typeof json != "object" || Array.isArray(json)) {
|
|
205
225
|
throw new error_js_1.FieldError(field, "expected object, got " + (0, reflect_check_js_1.formatVal)(json));
|
|
206
226
|
}
|
|
227
|
+
const seen = new Set();
|
|
207
228
|
for (const [jsonMapKey, jsonMapValue] of Object.entries(json)) {
|
|
208
229
|
const key = mapKeyFromJson(field.mapKey, jsonMapKey);
|
|
209
|
-
|
|
230
|
+
if (seen.has(key)) {
|
|
231
|
+
throw new error_js_1.FieldError(field, `duplicate map key "${jsonMapKey}"`);
|
|
232
|
+
}
|
|
233
|
+
seen.add(key);
|
|
234
|
+
const value = readListOrMapItem(field, jsonMapValue, ctx);
|
|
210
235
|
if (value !== tokenIgnoredUnknownEnum) {
|
|
211
236
|
map.set(key, value);
|
|
212
237
|
}
|
|
213
238
|
}
|
|
214
239
|
}
|
|
215
|
-
function readListField(list, json,
|
|
240
|
+
function readListField(list, json, ctx) {
|
|
216
241
|
if (json === null) {
|
|
217
242
|
return;
|
|
218
243
|
}
|
|
@@ -221,27 +246,27 @@ function readListField(list, json, opts) {
|
|
|
221
246
|
throw new error_js_1.FieldError(field, "expected Array, got " + (0, reflect_check_js_1.formatVal)(json));
|
|
222
247
|
}
|
|
223
248
|
for (const jsonItem of json) {
|
|
224
|
-
const value = readListOrMapItem(field, jsonItem,
|
|
249
|
+
const value = readListOrMapItem(field, jsonItem, ctx);
|
|
225
250
|
if (value !== tokenIgnoredUnknownEnum) {
|
|
226
251
|
list.add(value);
|
|
227
252
|
}
|
|
228
253
|
}
|
|
229
254
|
}
|
|
230
|
-
function readMessageField(msg, field, json,
|
|
255
|
+
function readMessageField(msg, field, json, ctx) {
|
|
231
256
|
if (isResetSentinelNullValue(field, json)) {
|
|
232
257
|
msg.clear(field);
|
|
233
258
|
return;
|
|
234
259
|
}
|
|
235
260
|
const msgValue = msg.isSet(field) ? msg.get(field) : (0, reflect_js_1.reflect)(field.message);
|
|
236
|
-
readMessage(msgValue, json,
|
|
261
|
+
readMessage(msgValue, json, ctx);
|
|
237
262
|
msg.set(field, msgValue);
|
|
238
263
|
}
|
|
239
|
-
function readEnumField(msg, field, json,
|
|
264
|
+
function readEnumField(msg, field, json, ctx) {
|
|
240
265
|
if (isResetSentinelNullValue(field, json)) {
|
|
241
266
|
msg.clear(field);
|
|
242
267
|
return;
|
|
243
268
|
}
|
|
244
|
-
const enumValue = readEnum(field.enum, json,
|
|
269
|
+
const enumValue = readEnum(field.enum, json, ctx.ignoreUnknownFields);
|
|
245
270
|
if (enumValue !== tokenIgnoredUnknownEnum) {
|
|
246
271
|
msg.set(field, enumValue);
|
|
247
272
|
}
|
|
@@ -370,7 +395,8 @@ function scalarFromJson(field, json) {
|
|
|
370
395
|
}
|
|
371
396
|
/**
|
|
372
397
|
* Try to parse a JSON value to a map key for the reflect API.
|
|
373
|
-
*
|
|
398
|
+
* Canonicalizes 64-bit integers given as string, so that "01 and "1" are one
|
|
399
|
+
* key, and duplicates can raise an error.
|
|
374
400
|
* Returns the input if the JSON value cannot be converted.
|
|
375
401
|
*/
|
|
376
402
|
function mapKeyFromJson(type, jsonString) {
|
|
@@ -389,6 +415,14 @@ function mapKeyFromJson(type, jsonString) {
|
|
|
389
415
|
case descriptors_js_1.ScalarType.SFIXED32:
|
|
390
416
|
case descriptors_js_1.ScalarType.SINT32:
|
|
391
417
|
return int32FromJson(jsonString);
|
|
418
|
+
case descriptors_js_1.ScalarType.INT64:
|
|
419
|
+
case descriptors_js_1.ScalarType.SINT64:
|
|
420
|
+
case descriptors_js_1.ScalarType.SFIXED64:
|
|
421
|
+
case descriptors_js_1.ScalarType.UINT64:
|
|
422
|
+
case descriptors_js_1.ScalarType.FIXED64:
|
|
423
|
+
return /^-?0+$/.test(jsonString)
|
|
424
|
+
? "0"
|
|
425
|
+
: jsonString.replace(/^(-?)0+(?=\d)/, "$1");
|
|
392
426
|
default:
|
|
393
427
|
return jsonString;
|
|
394
428
|
}
|
|
@@ -417,9 +451,14 @@ function int32FromJson(json) {
|
|
|
417
451
|
}
|
|
418
452
|
return json;
|
|
419
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* Parse a JSON string, rejecting duplicate object keys (which JSON.parse would
|
|
456
|
+
* otherwise silently merge).
|
|
457
|
+
*/
|
|
420
458
|
function parseJsonString(jsonString, typeName) {
|
|
459
|
+
let json;
|
|
421
460
|
try {
|
|
422
|
-
|
|
461
|
+
json = JSON.parse(jsonString);
|
|
423
462
|
}
|
|
424
463
|
catch (e) {
|
|
425
464
|
const message = e instanceof Error ? e.message : String(e);
|
|
@@ -427,14 +466,91 @@ function parseJsonString(jsonString, typeName) {
|
|
|
427
466
|
// @ts-expect-error we use the ES2022 error CTOR option "cause" for better stack traces
|
|
428
467
|
{ cause: e });
|
|
429
468
|
}
|
|
469
|
+
checkDuplicateKeys(jsonString, typeName);
|
|
470
|
+
return json;
|
|
430
471
|
}
|
|
431
|
-
|
|
472
|
+
/**
|
|
473
|
+
* Scan a JSON string for duplicate object member names at any depth, throwing
|
|
474
|
+
* if any are found. JSON.parse() silently keeps the last of duplicate keys, so
|
|
475
|
+
* this raw-string scan is the only way to reject them. It must only be called
|
|
476
|
+
* with a string that JSON.parse() has already accepted, so it can assume the
|
|
477
|
+
* input is well-formed.
|
|
478
|
+
*/
|
|
479
|
+
function checkDuplicateKeys(jsonString, typeName) {
|
|
480
|
+
// One Set of seen member names for each open object; arrays push null.
|
|
481
|
+
const stack = [];
|
|
482
|
+
// Whether the next string token is an object member name.
|
|
483
|
+
let expectKey = false;
|
|
484
|
+
let i = 0;
|
|
485
|
+
while (i < jsonString.length) {
|
|
486
|
+
switch (jsonString[i]) {
|
|
487
|
+
case "{":
|
|
488
|
+
stack.push(new Set());
|
|
489
|
+
expectKey = true;
|
|
490
|
+
i++;
|
|
491
|
+
break;
|
|
492
|
+
case "[":
|
|
493
|
+
stack.push(null);
|
|
494
|
+
expectKey = false;
|
|
495
|
+
i++;
|
|
496
|
+
break;
|
|
497
|
+
case "}":
|
|
498
|
+
case "]":
|
|
499
|
+
stack.pop();
|
|
500
|
+
expectKey = false;
|
|
501
|
+
i++;
|
|
502
|
+
break;
|
|
503
|
+
case ",":
|
|
504
|
+
expectKey = stack[stack.length - 1] != null;
|
|
505
|
+
i++;
|
|
506
|
+
break;
|
|
507
|
+
case ":":
|
|
508
|
+
expectKey = false;
|
|
509
|
+
i++;
|
|
510
|
+
break;
|
|
511
|
+
case '"': {
|
|
512
|
+
const open = i++;
|
|
513
|
+
let escaped = false;
|
|
514
|
+
while (i < jsonString.length) {
|
|
515
|
+
if (jsonString[i] == "\\") {
|
|
516
|
+
escaped = true;
|
|
517
|
+
i += 2; // skip the backslash and the character it escapes
|
|
518
|
+
continue;
|
|
519
|
+
}
|
|
520
|
+
if (jsonString[i] == '"') {
|
|
521
|
+
break;
|
|
522
|
+
}
|
|
523
|
+
i++;
|
|
524
|
+
}
|
|
525
|
+
const close = i++;
|
|
526
|
+
const seen = stack[stack.length - 1];
|
|
527
|
+
if (expectKey && seen) {
|
|
528
|
+
// Decode escapes (rare) so that, for example, a key written with a
|
|
529
|
+
// unicode escape collides with the same key written literally.
|
|
530
|
+
const name = escaped
|
|
531
|
+
? JSON.parse(jsonString.substring(open, close + 1))
|
|
532
|
+
: jsonString.substring(open + 1, close);
|
|
533
|
+
if (seen.has(name)) {
|
|
534
|
+
throw new Error(`cannot decode message ${typeName} from JSON: duplicate object key "${name}"`);
|
|
535
|
+
}
|
|
536
|
+
seen.add(name);
|
|
537
|
+
}
|
|
538
|
+
expectKey = false;
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
default:
|
|
542
|
+
i++;
|
|
543
|
+
break;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
function tryWktFromJson(msg, jsonValue, ctx) {
|
|
432
548
|
if (!msg.desc.typeName.startsWith("google.protobuf.")) {
|
|
433
549
|
return false;
|
|
434
550
|
}
|
|
435
551
|
switch (msg.desc.typeName) {
|
|
436
552
|
case "google.protobuf.Any":
|
|
437
|
-
anyFromJson(msg.message, jsonValue,
|
|
553
|
+
anyFromJson(msg.message, jsonValue, ctx);
|
|
438
554
|
return true;
|
|
439
555
|
case "google.protobuf.Timestamp":
|
|
440
556
|
timestampFromJson(msg.message, jsonValue);
|
|
@@ -446,13 +562,13 @@ function tryWktFromJson(msg, jsonValue, opts) {
|
|
|
446
562
|
fieldMaskFromJson(msg.message, jsonValue);
|
|
447
563
|
return true;
|
|
448
564
|
case "google.protobuf.Struct":
|
|
449
|
-
structFromJson(msg.message, jsonValue);
|
|
565
|
+
structFromJson(msg.message, jsonValue, ctx);
|
|
450
566
|
return true;
|
|
451
567
|
case "google.protobuf.Value":
|
|
452
|
-
valueFromJson(msg.message, jsonValue);
|
|
568
|
+
valueFromJson(msg.message, jsonValue, ctx);
|
|
453
569
|
return true;
|
|
454
570
|
case "google.protobuf.ListValue":
|
|
455
|
-
listValueFromJson(msg.message, jsonValue);
|
|
571
|
+
listValueFromJson(msg.message, jsonValue, ctx);
|
|
456
572
|
return true;
|
|
457
573
|
default:
|
|
458
574
|
if ((0, index_js_1.isWrapperDesc)(msg.desc)) {
|
|
@@ -468,7 +584,7 @@ function tryWktFromJson(msg, jsonValue, opts) {
|
|
|
468
584
|
return false;
|
|
469
585
|
}
|
|
470
586
|
}
|
|
471
|
-
function anyFromJson(any, json,
|
|
587
|
+
function anyFromJson(any, json, ctx) {
|
|
472
588
|
var _a;
|
|
473
589
|
if (json === null || Array.isArray(json) || typeof json != "object") {
|
|
474
590
|
throw new Error(`cannot decode message ${any.$typeName} from JSON: expected object but got ${(0, reflect_check_js_1.formatVal)(json)}`);
|
|
@@ -486,21 +602,21 @@ function anyFromJson(any, json, opts) {
|
|
|
486
602
|
if (!typeName.length) {
|
|
487
603
|
throw new Error(`cannot decode message ${any.$typeName} from JSON: "@type" is invalid`);
|
|
488
604
|
}
|
|
489
|
-
const desc = (_a =
|
|
605
|
+
const desc = (_a = ctx.registry) === null || _a === void 0 ? void 0 : _a.getMessage(typeName);
|
|
490
606
|
if (!desc) {
|
|
491
607
|
throw new Error(`cannot decode message ${any.$typeName} from JSON: ${typeUrl} is not in the type registry`);
|
|
492
608
|
}
|
|
493
609
|
const msg = (0, reflect_js_1.reflect)(desc);
|
|
494
|
-
if (
|
|
610
|
+
if ((0, index_js_1.hasCustomJsonRepresentation)(desc) &&
|
|
495
611
|
Object.prototype.hasOwnProperty.call(json, "value")) {
|
|
496
612
|
const value = json.value;
|
|
497
|
-
readMessage(msg, value,
|
|
613
|
+
readMessage(msg, value, ctx);
|
|
498
614
|
}
|
|
499
615
|
else {
|
|
500
616
|
const copy = Object.assign({}, json);
|
|
501
617
|
// biome-ignore lint/performance/noDelete: <explanation>
|
|
502
618
|
delete copy["@type"];
|
|
503
|
-
readMessage(msg, copy,
|
|
619
|
+
readMessage(msg, copy, ctx);
|
|
504
620
|
}
|
|
505
621
|
(0, index_js_1.anyPack)(msg.desc, msg.message, any);
|
|
506
622
|
}
|
|
@@ -566,17 +682,20 @@ function fieldMaskFromJson(fieldMask, json) {
|
|
|
566
682
|
return (0, names_js_1.protoSnakeCase)(path);
|
|
567
683
|
});
|
|
568
684
|
}
|
|
569
|
-
function structFromJson(struct, json) {
|
|
685
|
+
function structFromJson(struct, json, ctx) {
|
|
570
686
|
if (typeof json != "object" || json == null || Array.isArray(json)) {
|
|
571
687
|
throw new Error(`cannot decode message ${struct.$typeName} from JSON ${(0, reflect_check_js_1.formatVal)(json)}`);
|
|
572
688
|
}
|
|
573
689
|
for (const [k, v] of Object.entries(json)) {
|
|
574
690
|
const parsedV = (0, create_js_1.create)(index_js_1.ValueSchema);
|
|
575
|
-
valueFromJson(parsedV, v);
|
|
691
|
+
valueFromJson(parsedV, v, ctx);
|
|
576
692
|
struct.fields[k] = parsedV;
|
|
577
693
|
}
|
|
578
694
|
}
|
|
579
|
-
function valueFromJson(value, json) {
|
|
695
|
+
function valueFromJson(value, json, ctx) {
|
|
696
|
+
if (++ctx.depth > ctx.recursionLimit) {
|
|
697
|
+
throw new Error(`cannot decode ${value.$typeName} from JSON: maximum recursion depth of ${ctx.recursionLimit} reached`);
|
|
698
|
+
}
|
|
580
699
|
switch (typeof json) {
|
|
581
700
|
case "number":
|
|
582
701
|
value.kind = { case: "numberValue", value: json };
|
|
@@ -593,27 +712,28 @@ function valueFromJson(value, json) {
|
|
|
593
712
|
}
|
|
594
713
|
else if (Array.isArray(json)) {
|
|
595
714
|
const listValue = (0, create_js_1.create)(index_js_1.ListValueSchema);
|
|
596
|
-
listValueFromJson(listValue, json);
|
|
715
|
+
listValueFromJson(listValue, json, ctx);
|
|
597
716
|
value.kind = { case: "listValue", value: listValue };
|
|
598
717
|
}
|
|
599
718
|
else {
|
|
600
719
|
const struct = (0, create_js_1.create)(index_js_1.StructSchema);
|
|
601
|
-
structFromJson(struct, json);
|
|
720
|
+
structFromJson(struct, json, ctx);
|
|
602
721
|
value.kind = { case: "structValue", value: struct };
|
|
603
722
|
}
|
|
604
723
|
break;
|
|
605
724
|
default:
|
|
606
725
|
throw new Error(`cannot decode message ${value.$typeName} from JSON ${(0, reflect_check_js_1.formatVal)(json)}`);
|
|
607
726
|
}
|
|
727
|
+
ctx.depth--;
|
|
608
728
|
return value;
|
|
609
729
|
}
|
|
610
|
-
function listValueFromJson(listValue, json) {
|
|
730
|
+
function listValueFromJson(listValue, json, ctx) {
|
|
611
731
|
if (!Array.isArray(json)) {
|
|
612
732
|
throw new Error(`cannot decode message ${listValue.$typeName} from JSON ${(0, reflect_check_js_1.formatVal)(json)}`);
|
|
613
733
|
}
|
|
614
734
|
for (const e of json) {
|
|
615
735
|
const value = (0, create_js_1.create)(index_js_1.ValueSchema);
|
|
616
|
-
valueFromJson(value, e);
|
|
736
|
+
valueFromJson(value, e, ctx);
|
|
617
737
|
listValue.values.push(value);
|
|
618
738
|
}
|
|
619
739
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2021-2026 Buf Technologies, Inc.
|
|
3
|
+
//
|
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -28,6 +28,7 @@ function makeInt64Support() {
|
|
|
28
28
|
typeof dv.setBigInt64 === "function" &&
|
|
29
29
|
typeof dv.setBigUint64 === "function" &&
|
|
30
30
|
(!!globalThis.Deno ||
|
|
31
|
+
!!globalThis.Bun ||
|
|
31
32
|
typeof process != "object" ||
|
|
32
33
|
typeof process.env != "object" ||
|
|
33
34
|
process.env.BUF_BIGINT_DISABLE !== "1");
|
|
@@ -89,7 +89,7 @@ export declare function buildPath(schema: DescMessage): PathBuilder;
|
|
|
89
89
|
* paths that refer to an extension.
|
|
90
90
|
*/
|
|
91
91
|
export declare function parsePath(schema: DescMessage, path: string, options?: {
|
|
92
|
-
registry?: Registry;
|
|
92
|
+
registry?: Registry | undefined;
|
|
93
93
|
}): Path;
|
|
94
94
|
/**
|
|
95
95
|
* Stringify a path.
|
|
@@ -80,7 +80,9 @@ function checkSingular(field, value) {
|
|
|
80
80
|
}
|
|
81
81
|
if (field.enum !== undefined) {
|
|
82
82
|
if (field.enum.open) {
|
|
83
|
-
|
|
83
|
+
// Open enums accept unrecognized values, but enum values are always
|
|
84
|
+
// int32 (see https://protobuf.dev/programming-guides/proto3/#enum).
|
|
85
|
+
return checkScalarValue(value, descriptors_js_1.ScalarType.INT32);
|
|
84
86
|
}
|
|
85
87
|
return field.enum.values.some((v) => v.number === value);
|
|
86
88
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ScalarType } from "../descriptors.js";
|
|
2
|
+
/**
|
|
3
|
+
* ScalarValue maps from a scalar field type to a TypeScript value type.
|
|
4
|
+
*/
|
|
5
|
+
export type ScalarValue<T = ScalarType, LongAsString extends boolean = false> = T extends ScalarType.STRING ? string : T extends ScalarType.INT32 ? number : T extends ScalarType.UINT32 ? number : T extends ScalarType.SINT32 ? number : T extends ScalarType.FIXED32 ? number : T extends ScalarType.SFIXED32 ? number : T extends ScalarType.FLOAT ? number : T extends ScalarType.DOUBLE ? number : T extends ScalarType.INT64 ? LongAsString extends true ? string : bigint : T extends ScalarType.SINT64 ? LongAsString extends true ? string : bigint : T extends ScalarType.SFIXED64 ? LongAsString extends true ? string : bigint : T extends ScalarType.UINT64 ? LongAsString extends true ? string : bigint : T extends ScalarType.FIXED64 ? LongAsString extends true ? string : bigint : T extends ScalarType.BOOL ? boolean : T extends ScalarType.BYTES ? Uint8Array : never;
|
|
6
|
+
/**
|
|
7
|
+
* Returns true if both scalar values are equal.
|
|
8
|
+
*
|
|
9
|
+
* For float and double, values are compared following IEEE semantics: -0
|
|
10
|
+
* equals 0, and NaN does not equal NaN. This is value equality, not identity.
|
|
11
|
+
*
|
|
12
|
+
* It deliberately differs from isScalarZeroValue, which treats -0 as distinct
|
|
13
|
+
* from 0. A value can equal the zero value without being a zero value
|
|
14
|
+
* (scalarEquals(DOUBLE, -0, 0) is true while isScalarZeroValue(DOUBLE, -0) is
|
|
15
|
+
* false) so this function must not be used to derive implicit presence.
|
|
16
|
+
*/
|
|
17
|
+
export declare function scalarEquals(type: ScalarType, a: ScalarValue | undefined, b: ScalarValue | undefined): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Returns the zero value for the given scalar type, the value a field of this
|
|
20
|
+
* type has when unset: 0 for numeric types, "" for strings, false for
|
|
21
|
+
* booleans, and an empty Uint8Array for bytes. For 64-bit integer types, the
|
|
22
|
+
* result is "0" when longAsString is true, otherwise 0n.
|
|
23
|
+
*
|
|
24
|
+
* This is the type's zero value, not a proto2 custom field default. For float
|
|
25
|
+
* and double it is +0; isScalarZeroValue treats only +0, not -0, as this value.
|
|
26
|
+
*/
|
|
27
|
+
export declare function scalarZeroValue<T extends ScalarType, LongAsString extends boolean>(type: T, longAsString: LongAsString): ScalarValue<T, LongAsString>;
|
|
28
|
+
/**
|
|
29
|
+
* Returns true if the value is the zero value for the given scalar type: `0`
|
|
30
|
+
* for numeric types, `false` for booleans, `""` for strings, and an empty
|
|
31
|
+
* Uint8Array for bytes.
|
|
32
|
+
*
|
|
33
|
+
* This is the implicit-presence default check. A singular field with implicit
|
|
34
|
+
* presence is treated as unset, and omitted from the wire, when its value is
|
|
35
|
+
* the zero value. With explicit presence, or in repeated and map fields,
|
|
36
|
+
* presence is structural and this function does not apply.
|
|
37
|
+
*
|
|
38
|
+
* Note that -0 is NOT a zero value for float and double: under implicit
|
|
39
|
+
* presence, +0 is omitted from the wire but -0 is written, following the
|
|
40
|
+
* proto3 specification. As a result this can disagree with scalarEquals, which
|
|
41
|
+
* compares by value and treats -0 as equal to 0.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isScalarZeroValue(type: ScalarType, value: unknown): boolean;
|
|
@@ -20,6 +20,14 @@ const proto_int64_js_1 = require("../proto-int64.js");
|
|
|
20
20
|
const descriptors_js_1 = require("../descriptors.js");
|
|
21
21
|
/**
|
|
22
22
|
* Returns true if both scalar values are equal.
|
|
23
|
+
*
|
|
24
|
+
* For float and double, values are compared following IEEE semantics: -0
|
|
25
|
+
* equals 0, and NaN does not equal NaN. This is value equality, not identity.
|
|
26
|
+
*
|
|
27
|
+
* It deliberately differs from isScalarZeroValue, which treats -0 as distinct
|
|
28
|
+
* from 0. A value can equal the zero value without being a zero value
|
|
29
|
+
* (scalarEquals(DOUBLE, -0, 0) is true while isScalarZeroValue(DOUBLE, -0) is
|
|
30
|
+
* false) so this function must not be used to derive implicit presence.
|
|
23
31
|
*/
|
|
24
32
|
function scalarEquals(type, a, b) {
|
|
25
33
|
if (a === b) {
|
|
@@ -56,7 +64,13 @@ function scalarEquals(type, a, b) {
|
|
|
56
64
|
return false;
|
|
57
65
|
}
|
|
58
66
|
/**
|
|
59
|
-
* Returns the zero value for the given scalar type
|
|
67
|
+
* Returns the zero value for the given scalar type, the value a field of this
|
|
68
|
+
* type has when unset: 0 for numeric types, "" for strings, false for
|
|
69
|
+
* booleans, and an empty Uint8Array for bytes. For 64-bit integer types, the
|
|
70
|
+
* result is "0" when longAsString is true, otherwise 0n.
|
|
71
|
+
*
|
|
72
|
+
* This is the type's zero value, not a proto2 custom field default. For float
|
|
73
|
+
* and double it is +0; isScalarZeroValue treats only +0, not -0, as this value.
|
|
60
74
|
*/
|
|
61
75
|
function scalarZeroValue(type, longAsString) {
|
|
62
76
|
switch (type) {
|
|
@@ -82,11 +96,19 @@ function scalarZeroValue(type, longAsString) {
|
|
|
82
96
|
}
|
|
83
97
|
}
|
|
84
98
|
/**
|
|
85
|
-
* Returns true
|
|
86
|
-
*
|
|
99
|
+
* Returns true if the value is the zero value for the given scalar type: `0`
|
|
100
|
+
* for numeric types, `false` for booleans, `""` for strings, and an empty
|
|
101
|
+
* Uint8Array for bytes.
|
|
87
102
|
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
103
|
+
* This is the implicit-presence default check. A singular field with implicit
|
|
104
|
+
* presence is treated as unset, and omitted from the wire, when its value is
|
|
105
|
+
* the zero value. With explicit presence, or in repeated and map fields,
|
|
106
|
+
* presence is structural and this function does not apply.
|
|
107
|
+
*
|
|
108
|
+
* Note that -0 is NOT a zero value for float and double: under implicit
|
|
109
|
+
* presence, +0 is omitted from the wire but -0 is written, following the
|
|
110
|
+
* proto3 specification. As a result this can disagree with scalarEquals, which
|
|
111
|
+
* compares by value and treats -0 as equal to 0.
|
|
90
112
|
*/
|
|
91
113
|
function isScalarZeroValue(type, value) {
|
|
92
114
|
switch (type) {
|
|
@@ -96,7 +118,12 @@ function isScalarZeroValue(type, value) {
|
|
|
96
118
|
return value === "";
|
|
97
119
|
case descriptors_js_1.ScalarType.BYTES:
|
|
98
120
|
return value instanceof Uint8Array && !value.byteLength;
|
|
121
|
+
case descriptors_js_1.ScalarType.DOUBLE:
|
|
122
|
+
case descriptors_js_1.ScalarType.FLOAT:
|
|
123
|
+
// Object.is distinguishes -0 from 0.
|
|
124
|
+
return Object.is(value, 0);
|
|
99
125
|
default:
|
|
100
|
-
|
|
126
|
+
// Loose comparison matches 0n, 0 and "0".
|
|
127
|
+
return value == 0;
|
|
101
128
|
}
|
|
102
129
|
}
|