@bufbuild/protobuf 2.0.0-alpha.2 → 2.0.0-alpha.4

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.
Files changed (145) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/clone.d.ts +1 -1
  3. package/dist/cjs/clone.js +9 -6
  4. package/dist/cjs/codegenv1/boot.d.ts +1 -1
  5. package/dist/cjs/codegenv1/boot.js +3 -5
  6. package/dist/cjs/codegenv1/embed.d.ts +1 -1
  7. package/dist/cjs/codegenv1/embed.js +39 -34
  8. package/dist/cjs/codegenv1/enum.d.ts +1 -1
  9. package/dist/cjs/codegenv1/extension.d.ts +1 -1
  10. package/dist/cjs/codegenv1/file.d.ts +1 -1
  11. package/dist/cjs/codegenv1/file.js +5 -7
  12. package/dist/cjs/codegenv1/index.d.ts +1 -0
  13. package/dist/cjs/codegenv1/index.js +1 -0
  14. package/dist/cjs/codegenv1/message.d.ts +1 -1
  15. package/dist/cjs/codegenv1/scalar.d.ts +5 -0
  16. package/dist/cjs/codegenv1/scalar.js +39 -0
  17. package/dist/cjs/codegenv1/service.d.ts +3 -3
  18. package/dist/cjs/codegenv1/types.d.ts +7 -9
  19. package/dist/cjs/create.d.ts +1 -1
  20. package/dist/cjs/create.js +6 -5
  21. package/dist/cjs/{desc-types.d.ts → descriptors.d.ts} +39 -7
  22. package/dist/cjs/descriptors.js +53 -0
  23. package/dist/cjs/equals.d.ts +1 -1
  24. package/dist/cjs/extensions.d.ts +1 -1
  25. package/dist/cjs/extensions.js +4 -3
  26. package/dist/cjs/fields.d.ts +1 -1
  27. package/dist/cjs/from-binary.d.ts +1 -1
  28. package/dist/cjs/from-binary.js +32 -29
  29. package/dist/cjs/from-json.d.ts +2 -2
  30. package/dist/cjs/from-json.js +201 -188
  31. package/dist/cjs/index.d.ts +2 -1
  32. package/dist/cjs/index.js +2 -1
  33. package/dist/cjs/is-message.d.ts +1 -1
  34. package/dist/cjs/proto-int64.d.ts +4 -1
  35. package/dist/cjs/proto-int64.js +16 -6
  36. package/dist/cjs/reflect/error.d.ts +1 -1
  37. package/dist/cjs/reflect/guard.d.ts +1 -1
  38. package/dist/cjs/reflect/guard.js +4 -4
  39. package/dist/cjs/reflect/index.d.ts +0 -1
  40. package/dist/cjs/reflect/index.js +0 -1
  41. package/dist/cjs/reflect/names.d.ts +1 -1
  42. package/dist/cjs/reflect/names.js +1 -1
  43. package/dist/cjs/reflect/nested-types.d.ts +1 -1
  44. package/dist/cjs/reflect/reflect-check.d.ts +10 -1
  45. package/dist/cjs/reflect/reflect-check.js +126 -9
  46. package/dist/cjs/reflect/reflect-types.d.ts +3 -41
  47. package/dist/cjs/reflect/reflect.d.ts +1 -1
  48. package/dist/cjs/reflect/reflect.js +42 -60
  49. package/dist/cjs/reflect/scalar.d.ts +3 -55
  50. package/dist/cjs/reflect/scalar.js +26 -220
  51. package/dist/cjs/reflect/unsafe.d.ts +1 -17
  52. package/dist/cjs/reflect/unsafe.js +2 -20
  53. package/dist/cjs/{reflect/registry.d.ts → registry.d.ts} +2 -2
  54. package/dist/cjs/{reflect/registry.js → registry.js} +54 -36
  55. package/dist/cjs/to-binary.d.ts +1 -1
  56. package/dist/cjs/to-binary.js +27 -27
  57. package/dist/cjs/to-json.d.ts +7 -6
  58. package/dist/cjs/to-json.js +57 -44
  59. package/dist/cjs/types.d.ts +1 -1
  60. package/dist/cjs/wire/base64-encoding.js +2 -2
  61. package/dist/cjs/wire/binary-encoding.d.ts +20 -0
  62. package/dist/cjs/wire/binary-encoding.js +75 -8
  63. package/dist/cjs/wire/size-delimited.d.ts +1 -1
  64. package/dist/cjs/wire/text-format.d.ts +1 -2
  65. package/dist/cjs/wire/text-format.js +21 -19
  66. package/dist/cjs/wkt/any.d.ts +2 -2
  67. package/dist/cjs/wkt/gen/google/protobuf/descriptor_pb.d.ts +6 -0
  68. package/dist/cjs/wkt/gen/google/protobuf/descriptor_pb.js +1 -1
  69. package/dist/cjs/wkt/wrappers.d.ts +1 -1
  70. package/dist/esm/clone.d.ts +1 -1
  71. package/dist/esm/clone.js +8 -5
  72. package/dist/esm/codegenv1/boot.d.ts +1 -1
  73. package/dist/esm/codegenv1/boot.js +3 -5
  74. package/dist/esm/codegenv1/embed.d.ts +1 -1
  75. package/dist/esm/codegenv1/embed.js +9 -4
  76. package/dist/esm/codegenv1/enum.d.ts +1 -1
  77. package/dist/esm/codegenv1/extension.d.ts +1 -1
  78. package/dist/esm/codegenv1/file.d.ts +1 -1
  79. package/dist/esm/codegenv1/file.js +4 -6
  80. package/dist/esm/codegenv1/index.d.ts +1 -0
  81. package/dist/esm/codegenv1/index.js +1 -0
  82. package/dist/esm/codegenv1/message.d.ts +1 -1
  83. package/dist/esm/codegenv1/scalar.d.ts +5 -0
  84. package/dist/esm/codegenv1/scalar.js +35 -0
  85. package/dist/esm/codegenv1/service.d.ts +3 -3
  86. package/dist/esm/codegenv1/types.d.ts +7 -9
  87. package/dist/esm/create.d.ts +1 -1
  88. package/dist/esm/create.js +4 -3
  89. package/dist/esm/{desc-types.d.ts → descriptors.d.ts} +39 -7
  90. package/dist/esm/descriptors.js +50 -0
  91. package/dist/esm/equals.d.ts +1 -1
  92. package/dist/esm/extensions.d.ts +1 -1
  93. package/dist/esm/extensions.js +4 -3
  94. package/dist/esm/fields.d.ts +1 -1
  95. package/dist/esm/from-binary.d.ts +1 -1
  96. package/dist/esm/from-binary.js +14 -11
  97. package/dist/esm/from-json.d.ts +2 -2
  98. package/dist/esm/from-json.js +194 -181
  99. package/dist/esm/index.d.ts +2 -1
  100. package/dist/esm/index.js +2 -1
  101. package/dist/esm/is-message.d.ts +1 -1
  102. package/dist/esm/proto-int64.d.ts +4 -1
  103. package/dist/esm/proto-int64.js +16 -6
  104. package/dist/esm/reflect/error.d.ts +1 -1
  105. package/dist/esm/reflect/guard.d.ts +1 -1
  106. package/dist/esm/reflect/guard.js +4 -4
  107. package/dist/esm/reflect/index.d.ts +0 -1
  108. package/dist/esm/reflect/index.js +0 -1
  109. package/dist/esm/reflect/names.d.ts +1 -1
  110. package/dist/esm/reflect/names.js +1 -1
  111. package/dist/esm/reflect/nested-types.d.ts +1 -1
  112. package/dist/esm/reflect/reflect-check.d.ts +10 -1
  113. package/dist/esm/reflect/reflect-check.js +119 -2
  114. package/dist/esm/reflect/reflect-types.d.ts +3 -41
  115. package/dist/esm/reflect/reflect-types.js +1 -0
  116. package/dist/esm/reflect/reflect.d.ts +1 -1
  117. package/dist/esm/reflect/reflect.js +25 -43
  118. package/dist/esm/reflect/scalar.d.ts +3 -55
  119. package/dist/esm/reflect/scalar.js +14 -205
  120. package/dist/esm/reflect/unsafe.d.ts +1 -17
  121. package/dist/esm/reflect/unsafe.js +1 -17
  122. package/dist/esm/{reflect/registry.d.ts → registry.d.ts} +2 -2
  123. package/dist/esm/{reflect/registry.js → registry.js} +44 -26
  124. package/dist/esm/to-binary.d.ts +1 -1
  125. package/dist/esm/to-binary.js +1 -1
  126. package/dist/esm/to-json.d.ts +7 -6
  127. package/dist/esm/to-json.js +42 -29
  128. package/dist/esm/types.d.ts +1 -1
  129. package/dist/esm/wire/base64-encoding.js +2 -2
  130. package/dist/esm/wire/binary-encoding.d.ts +20 -0
  131. package/dist/esm/wire/binary-encoding.js +68 -1
  132. package/dist/esm/wire/size-delimited.d.ts +1 -1
  133. package/dist/esm/wire/text-format.d.ts +1 -2
  134. package/dist/esm/wire/text-format.js +5 -3
  135. package/dist/esm/wkt/any.d.ts +2 -2
  136. package/dist/esm/wkt/gen/google/protobuf/descriptor_pb.d.ts +6 -0
  137. package/dist/esm/wkt/gen/google/protobuf/descriptor_pb.js +1 -1
  138. package/dist/esm/wkt/wrappers.d.ts +1 -1
  139. package/package.json +1 -1
  140. package/dist/cjs/desc-types.js +0 -15
  141. package/dist/cjs/reflect/assert.d.ts +0 -16
  142. package/dist/cjs/reflect/assert.js +0 -59
  143. package/dist/esm/desc-types.js +0 -14
  144. package/dist/esm/reflect/assert.d.ts +0 -16
  145. package/dist/esm/reflect/assert.js +0 -52
@@ -14,16 +14,16 @@
14
14
  // limitations under the License.
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.mergeFromJson = exports.fromJson = exports.mergeFromJsonString = exports.fromJsonString = void 0;
17
- const assert_js_1 = require("./reflect/assert.js");
17
+ /* eslint-disable no-case-declarations,@typescript-eslint/restrict-template-expressions */
18
+ const descriptors_js_1 = require("./descriptors.js");
18
19
  const proto_int64_js_1 = require("./proto-int64.js");
19
20
  const create_js_1 = require("./create.js");
20
21
  const reflect_js_1 = require("./reflect/reflect.js");
22
+ const error_js_1 = require("./reflect/error.js");
21
23
  const reflect_check_js_1 = require("./reflect/reflect-check.js");
22
24
  const scalar_js_1 = require("./reflect/scalar.js");
23
25
  const base64_encoding_js_1 = require("./wire/base64-encoding.js");
24
- const text_encoding_js_1 = require("./wire/text-encoding.js");
25
26
  const index_js_1 = require("./wkt/index.js");
26
- const wrappers_js_1 = require("./wkt/wrappers.js");
27
27
  const extensions_js_1 = require("./extensions.js");
28
28
  // Default options for parsing JSON.
29
29
  const jsonReadDefaults = {
@@ -57,7 +57,18 @@ exports.mergeFromJsonString = mergeFromJsonString;
57
57
  */
58
58
  function fromJson(messageDesc, json, options) {
59
59
  const msg = (0, reflect_js_1.reflect)(messageDesc);
60
- readMessage(msg, json, makeReadOptions(options));
60
+ try {
61
+ readMessage(msg, json, makeReadOptions(options));
62
+ }
63
+ catch (e) {
64
+ if ((0, error_js_1.isFieldError)(e)) {
65
+ // @ts-expect-error we use the ES2022 error CTOR option "cause" for better stack traces
66
+ throw new Error(`cannot decode ${e.field()} from JSON: ${e.message}`, {
67
+ cause: e,
68
+ });
69
+ }
70
+ throw e;
71
+ }
61
72
  return msg.message;
62
73
  }
63
74
  exports.fromJson = fromJson;
@@ -71,7 +82,18 @@ exports.fromJson = fromJson;
71
82
  * new data.
72
83
  */
73
84
  function mergeFromJson(messageDesc, target, json, options) {
74
- readMessage((0, reflect_js_1.reflect)(messageDesc, target), json, makeReadOptions(options));
85
+ try {
86
+ readMessage((0, reflect_js_1.reflect)(messageDesc, target), json, makeReadOptions(options));
87
+ }
88
+ catch (e) {
89
+ if ((0, error_js_1.isFieldError)(e)) {
90
+ // @ts-expect-error we use the ES2022 error CTOR option "cause" for better stack traces
91
+ throw new Error(`cannot decode ${e.field()} from JSON: ${e.message}`, {
92
+ cause: e,
93
+ });
94
+ }
95
+ throw e;
96
+ }
75
97
  return target;
76
98
  }
77
99
  exports.mergeFromJson = mergeFromJson;
@@ -81,7 +103,7 @@ function readMessage(msg, json, opts) {
81
103
  return;
82
104
  }
83
105
  if (json == null || Array.isArray(json) || typeof json != "object") {
84
- throw new Error(`cannot decode message ${msg.desc.typeName} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
106
+ throw new Error(`cannot decode ${msg.desc} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
85
107
  }
86
108
  const oneofSeen = new Map();
87
109
  const jsonNames = new Map();
@@ -98,9 +120,9 @@ function readMessage(msg, json, opts) {
98
120
  }
99
121
  const seen = oneofSeen.get(field.oneof);
100
122
  if (seen !== undefined) {
101
- throw new Error(`cannot decode message ${msg.desc.typeName} from JSON: multiple keys for oneof "${field.oneof.name}" present: "${seen}", "${jsonKey}"`);
123
+ throw new error_js_1.FieldError(field.oneof, `oneof set multiple times by ${seen.name} and ${field.name}`);
102
124
  }
103
- oneofSeen.set(field.oneof, jsonKey);
125
+ oneofSeen.set(field.oneof, field);
104
126
  }
105
127
  readField(msg, field, jsonValue, opts);
106
128
  }
@@ -115,7 +137,7 @@ function readMessage(msg, json, opts) {
115
137
  (0, extensions_js_1.setExtension)(msg.message, extension, get());
116
138
  }
117
139
  if (!extension && !opts.ignoreUnknownFields) {
118
- throw new Error(`cannot decode message ${msg.desc.typeName} from JSON: key "${jsonKey}" is unknown`);
140
+ throw new Error(`cannot decode ${msg.desc} from JSON: key "${jsonKey}" is unknown`);
119
141
  }
120
142
  }
121
143
  }
@@ -132,95 +154,79 @@ function readField(msg, field, json, opts) {
132
154
  readMessageField(msg, field, json, opts);
133
155
  break;
134
156
  case "list":
135
- readListField(msg, field, json, opts);
157
+ readListField(msg.get(field), json, opts);
136
158
  break;
137
159
  case "map":
138
- readMapField(msg, field, json, opts);
160
+ readMapField(msg.get(field), json, opts);
139
161
  break;
140
162
  }
141
163
  }
142
- function readMapField(msg, field, json, opts) {
164
+ function readMapField(map, json, opts) {
143
165
  if (json === null) {
144
166
  return;
145
167
  }
168
+ const field = map.field();
146
169
  if (typeof json != "object" || Array.isArray(json)) {
147
- throw new Error(`cannot decode field ${msg.desc.typeName}.${field.name} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
170
+ throw new error_js_1.FieldError(field, "expected object, got " + (0, reflect_check_js_1.formatVal)(json));
148
171
  }
149
172
  for (const [jsonMapKey, jsonMapValue] of Object.entries(json)) {
150
173
  if (jsonMapValue === null) {
151
- throw new Error(`cannot decode field ${msg.desc.typeName}.${field.name} from JSON: map value null`);
152
- }
153
- let key;
154
- try {
155
- key = readMapKey(field.mapKey, jsonMapKey);
156
- }
157
- catch (e) {
158
- let m = `cannot decode map key for field ${msg.desc.typeName}.${field.name} from JSON: ${(0, reflect_check_js_1.formatVal)(jsonMapKey)}`;
159
- if (e instanceof Error && e.message.length > 0) {
160
- m += `: ${e.message}`;
161
- }
162
- throw new Error(m);
174
+ throw new error_js_1.FieldError(field, "map value must not be null");
163
175
  }
176
+ let value;
164
177
  switch (field.mapKind) {
165
178
  case "message":
166
179
  const msgValue = (0, reflect_js_1.reflect)(field.message);
167
180
  readMessage(msgValue, jsonMapValue, opts);
168
- msg.setMapEntry(field, key, msgValue);
181
+ value = msgValue;
169
182
  break;
170
183
  case "enum":
171
- const enumValue = readEnum(field.enum, jsonMapValue, opts.ignoreUnknownFields, true);
172
- if (enumValue !== tokenIgnoredUnknownEnum) {
173
- msg.setMapEntry(field, key, enumValue);
184
+ value = readEnum(field.enum, jsonMapValue, opts.ignoreUnknownFields, true);
185
+ if (value === tokenIgnoredUnknownEnum) {
186
+ return;
174
187
  }
175
188
  break;
176
189
  case "scalar":
177
- try {
178
- msg.setMapEntry(field, key, readScalar(field.scalar, jsonMapValue, true));
179
- }
180
- catch (e) {
181
- let m = `cannot decode map value for field ${msg.desc.typeName}.${field.name} from JSON: ${(0, reflect_check_js_1.formatVal)(jsonMapValue)}`;
182
- if (e instanceof Error && e.message.length > 0) {
183
- m += `: ${e.message}`;
184
- }
185
- throw new Error(m);
186
- }
190
+ value = scalarFromJson(field, jsonMapValue, true);
187
191
  break;
188
192
  }
193
+ const key = mapKeyFromJson(field.mapKey, jsonMapKey);
194
+ // TODO fix types
195
+ // @ts-expect-error TODO
196
+ const err = map.set(key, value);
197
+ if (err) {
198
+ throw err;
199
+ }
189
200
  }
190
201
  }
191
- function readListField(msg, field, json, opts) {
202
+ function readListField(list, json, opts) {
192
203
  if (json === null) {
193
204
  return;
194
205
  }
206
+ const field = list.field();
195
207
  if (!Array.isArray(json)) {
196
- throw new Error(`cannot decode field ${msg.desc.typeName}.${field.name} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
208
+ throw new error_js_1.FieldError(field, "expected Array, got " + (0, reflect_check_js_1.formatVal)(json));
197
209
  }
198
210
  for (const jsonItem of json) {
199
211
  if (jsonItem === null) {
200
- throw new Error(`cannot decode field ${msg.desc.typeName}.${field.name} from JSON: ${(0, reflect_check_js_1.formatVal)(jsonItem)}`);
212
+ throw new error_js_1.FieldError(field, "list item must not be null");
201
213
  }
202
214
  switch (field.listKind) {
203
215
  case "message":
204
216
  const msgValue = (0, reflect_js_1.reflect)(field.message);
205
217
  readMessage(msgValue, jsonItem, opts);
206
- msg.addListItem(field, msgValue);
218
+ list.add(msgValue);
207
219
  break;
208
220
  case "enum":
209
221
  const enumValue = readEnum(field.enum, jsonItem, opts.ignoreUnknownFields, true);
210
222
  if (enumValue !== tokenIgnoredUnknownEnum) {
211
- msg.addListItem(field, enumValue);
223
+ list.add(enumValue);
212
224
  }
213
225
  break;
214
226
  case "scalar":
215
- try {
216
- msg.addListItem(field, readScalar(field.scalar, jsonItem, true));
217
- }
218
- catch (e) {
219
- let m = `cannot decode field ${msg.desc.typeName}.${field.name} from JSON: ${(0, reflect_check_js_1.formatVal)(jsonItem)}`;
220
- if (e instanceof Error && e.message.length > 0) {
221
- m += `: ${e.message}`;
222
- }
223
- throw new Error(m);
227
+ const err = list.add(scalarFromJson(field, jsonItem, true));
228
+ if (err) {
229
+ throw err;
224
230
  }
225
231
  break;
226
232
  }
@@ -245,36 +251,18 @@ function readEnumField(msg, field, json, opts) {
245
251
  }
246
252
  }
247
253
  function readScalarField(msg, field, json) {
248
- try {
249
- const scalarValue = readScalar(field.scalar, json, false);
250
- if (scalarValue === tokenNull) {
251
- msg.clear(field);
252
- }
253
- else {
254
- msg.set(field, scalarValue);
255
- }
256
- }
257
- catch (e) {
258
- let m = `cannot decode field ${msg.desc.typeName}.${field.name} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`;
259
- if (e instanceof Error && e.message.length > 0) {
260
- m += `: ${e.message}`;
261
- }
262
- throw new Error(m);
254
+ const scalarValue = scalarFromJson(field, json, false);
255
+ if (scalarValue === tokenNull) {
256
+ msg.clear(field);
263
257
  }
264
- }
265
- function readMapKey(type, json) {
266
- if (type === scalar_js_1.ScalarType.BOOL) {
267
- // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
268
- switch (json) {
269
- case "true":
270
- json = true;
271
- break;
272
- case "false":
273
- json = false;
274
- break;
258
+ else {
259
+ // TODO fix type error
260
+ // @ts-expect-error TODO
261
+ const err = msg.set(field, scalarValue);
262
+ if (err) {
263
+ throw err;
275
264
  }
276
265
  }
277
- return readScalar(type, json, true);
278
266
  }
279
267
  const tokenIgnoredUnknownEnum = Symbol();
280
268
  function readEnum(desc, json, ignoreUnknownFields, nullAsZeroValue) {
@@ -301,116 +289,143 @@ function readEnum(desc, json, ignoreUnknownFields, nullAsZeroValue) {
301
289
  }
302
290
  break;
303
291
  }
304
- throw new Error(`cannot decode enum ${desc.typeName} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
292
+ throw new Error(`cannot decode ${desc} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
305
293
  }
306
294
  const tokenNull = Symbol();
307
- function readScalar(type, json, nullAsZeroValue) {
295
+ function scalarFromJson(field, json, nullAsZeroValue) {
308
296
  if (json === null) {
309
297
  if (nullAsZeroValue) {
310
- return (0, scalar_js_1.scalarZeroValue)(type, scalar_js_1.LongType.BIGINT);
298
+ return (0, scalar_js_1.scalarZeroValue)(field.scalar, false);
311
299
  }
312
300
  return tokenNull;
313
301
  }
314
- // every valid case in the switch below returns, and every fall
315
- // through is regarded as a failure.
316
- switch (type) {
302
+ // int64, sfixed64, sint64, fixed64, uint64: Reflect supports string and number.
303
+ // string, bool: Supported by reflect.
304
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
305
+ switch (field.scalar) {
317
306
  // float, double: JSON value will be a number or one of the special string values "NaN", "Infinity", and "-Infinity".
318
307
  // Either numbers or strings are accepted. Exponent notation is also accepted.
319
- case scalar_js_1.ScalarType.DOUBLE:
320
- case scalar_js_1.ScalarType.FLOAT:
308
+ case descriptors_js_1.ScalarType.DOUBLE:
309
+ case descriptors_js_1.ScalarType.FLOAT:
321
310
  if (json === "NaN")
322
- return Number.NaN;
311
+ return NaN;
323
312
  if (json === "Infinity")
324
313
  return Number.POSITIVE_INFINITY;
325
314
  if (json === "-Infinity")
326
315
  return Number.NEGATIVE_INFINITY;
327
- if (json === "") {
328
- // empty string is not a number
329
- break;
330
- }
331
- if (typeof json == "string" && json.trim().length !== json.length) {
332
- // extra whitespace
333
- break;
334
- }
335
- if (typeof json != "string" && typeof json != "number") {
336
- break;
337
- }
338
- const float = Number(json);
339
- if (Number.isNaN(float)) {
340
- // not a number
316
+ if (typeof json == "number") {
317
+ if (isNaN(json)) {
318
+ // NaN must be encoded with string constants
319
+ throw new error_js_1.FieldError(field, "unexpected NaN number");
320
+ }
321
+ if (!isFinite(json)) {
322
+ // Infinity must be encoded with string constants
323
+ throw new error_js_1.FieldError(field, "unexpected infinite number");
324
+ }
341
325
  break;
342
326
  }
343
- if (!Number.isFinite(float)) {
344
- // infinity and -infinity are handled by string representation above, so this is an error
345
- break;
327
+ if (typeof json == "string") {
328
+ if (json === "") {
329
+ // empty string is not a number
330
+ break;
331
+ }
332
+ if (json.trim().length !== json.length) {
333
+ // extra whitespace
334
+ break;
335
+ }
336
+ const float = Number(json);
337
+ if (!isFinite(float)) {
338
+ // Infinity and NaN must be encoded with string constants
339
+ break;
340
+ }
341
+ return float;
346
342
  }
347
- if (type == scalar_js_1.ScalarType.FLOAT)
348
- (0, assert_js_1.assertFloat32)(float);
349
- return float;
343
+ break;
350
344
  // int32, fixed32, uint32: JSON value will be a decimal number. Either numbers or strings are accepted.
351
- case scalar_js_1.ScalarType.INT32:
352
- case scalar_js_1.ScalarType.FIXED32:
353
- case scalar_js_1.ScalarType.SFIXED32:
354
- case scalar_js_1.ScalarType.SINT32:
355
- case scalar_js_1.ScalarType.UINT32:
356
- let int32;
357
- if (typeof json == "number")
358
- int32 = json;
359
- else if (typeof json == "string" && json.length > 0) {
360
- if (json.trim().length === json.length)
361
- int32 = Number(json);
362
- }
363
- if (int32 === undefined)
364
- break;
365
- if (type == scalar_js_1.ScalarType.UINT32 || type == scalar_js_1.ScalarType.FIXED32)
366
- (0, assert_js_1.assertUInt32)(int32);
367
- else
368
- (0, assert_js_1.assertInt32)(int32);
369
- return int32;
370
- // int64, fixed64, uint64: JSON value will be a decimal string. Either numbers or strings are accepted.
371
- case scalar_js_1.ScalarType.INT64:
372
- case scalar_js_1.ScalarType.SFIXED64:
373
- case scalar_js_1.ScalarType.SINT64:
374
- if (typeof json != "number" && typeof json != "string")
375
- break;
376
- return proto_int64_js_1.protoInt64.parse(json);
377
- case scalar_js_1.ScalarType.FIXED64:
378
- case scalar_js_1.ScalarType.UINT64:
379
- if (typeof json != "number" && typeof json != "string")
380
- break;
381
- return proto_int64_js_1.protoInt64.uParse(json);
382
- // bool:
383
- case scalar_js_1.ScalarType.BOOL:
384
- if (typeof json !== "boolean")
385
- break;
386
- return json;
387
- // string:
388
- case scalar_js_1.ScalarType.STRING:
389
- if (typeof json !== "string") {
390
- break;
345
+ case descriptors_js_1.ScalarType.INT32:
346
+ case descriptors_js_1.ScalarType.FIXED32:
347
+ case descriptors_js_1.ScalarType.SFIXED32:
348
+ case descriptors_js_1.ScalarType.SINT32:
349
+ case descriptors_js_1.ScalarType.UINT32:
350
+ return int32FromJson(json);
351
+ // bytes: JSON value will be the data encoded as a string using standard base64 encoding with paddings.
352
+ // Either standard or URL-safe base64 encoding with/without paddings are accepted.
353
+ case descriptors_js_1.ScalarType.BYTES:
354
+ if (typeof json == "string") {
355
+ if (json === "") {
356
+ return new Uint8Array(0);
357
+ }
358
+ try {
359
+ return (0, base64_encoding_js_1.base64Decode)(json);
360
+ }
361
+ catch (e) {
362
+ const message = e instanceof Error ? e.message : String(e);
363
+ throw new error_js_1.FieldError(field, message);
364
+ }
391
365
  }
392
- // A string must always contain UTF-8 encoded or 7-bit ASCII.
393
- if (!(0, text_encoding_js_1.getTextEncoding)().checkUtf8(json)) {
394
- throw new Error("invalid UTF8");
366
+ break;
367
+ }
368
+ return json;
369
+ }
370
+ /**
371
+ * Try to parse a JSON value to a map key for the reflect API.
372
+ *
373
+ * Returns the input if the JSON value cannot be converted.
374
+ */
375
+ function mapKeyFromJson(type, json) {
376
+ switch (type) {
377
+ case descriptors_js_1.ScalarType.BOOL:
378
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
379
+ switch (json) {
380
+ case "true":
381
+ return true;
382
+ case "false":
383
+ return false;
395
384
  }
396
385
  return json;
397
- // bytes: JSON value will be the data encoded as a string using standard base64 encoding with paddings.
398
- // Either standard or URL-safe base64 encoding with/without paddings are accepted.
399
- case scalar_js_1.ScalarType.BYTES:
400
- if (json === "")
401
- return new Uint8Array(0);
402
- if (typeof json !== "string")
403
- break;
404
- return (0, base64_encoding_js_1.base64Decode)(json);
386
+ case descriptors_js_1.ScalarType.INT32:
387
+ case descriptors_js_1.ScalarType.FIXED32:
388
+ case descriptors_js_1.ScalarType.UINT32:
389
+ case descriptors_js_1.ScalarType.SFIXED32:
390
+ case descriptors_js_1.ScalarType.SINT32:
391
+ return int32FromJson(json);
392
+ default:
393
+ return json;
405
394
  }
406
- throw new Error();
395
+ }
396
+ /**
397
+ * Try to parse a JSON value to a 32-bit integer for the reflect API.
398
+ *
399
+ * Returns the input if the JSON value cannot be converted.
400
+ */
401
+ function int32FromJson(json) {
402
+ if (typeof json == "string") {
403
+ if (json === "") {
404
+ // empty string is not a number
405
+ return json;
406
+ }
407
+ if (json.trim().length !== json.length) {
408
+ // extra whitespace
409
+ return json;
410
+ }
411
+ const num = Number(json);
412
+ if (Number.isNaN(num)) {
413
+ // not a number
414
+ return json;
415
+ }
416
+ return num;
417
+ }
418
+ return json;
407
419
  }
408
420
  function parseJsonString(jsonString, typeName) {
409
421
  try {
410
422
  return JSON.parse(jsonString);
411
423
  }
412
424
  catch (e) {
413
- throw new Error(`cannot decode ${typeName} from JSON: ${e instanceof Error ? e.message : String(e)}`);
425
+ const message = e instanceof Error ? e.message : String(e);
426
+ throw new Error(`cannot decode message ${typeName} from JSON: ${message}`,
427
+ // @ts-expect-error we use the ES2022 error CTOR option "cause" for better stack traces
428
+ { cause: e });
414
429
  }
415
430
  }
416
431
  function tryWktFromJson(msg, jsonValue, opts) {
@@ -440,13 +455,16 @@ function tryWktFromJson(msg, jsonValue, opts) {
440
455
  listValueFromJson(msg.message, jsonValue);
441
456
  return true;
442
457
  default:
443
- if ((0, wrappers_js_1.isWrapperDesc)(msg.desc)) {
458
+ if ((0, index_js_1.isWrapperDesc)(msg.desc)) {
444
459
  const valueField = msg.desc.fields[0];
445
460
  if (jsonValue === null) {
446
461
  msg.clear(valueField);
447
462
  }
448
463
  else {
449
- msg.set(valueField, readScalar(valueField.scalar, jsonValue, true));
464
+ const err = msg.set(valueField, scalarFromJson(valueField, jsonValue, true));
465
+ if (err) {
466
+ throw err;
467
+ }
450
468
  }
451
469
  return true;
452
470
  }
@@ -456,7 +474,7 @@ function tryWktFromJson(msg, jsonValue, opts) {
456
474
  function anyFromJson(any, json, opts) {
457
475
  var _a;
458
476
  if (json === null || Array.isArray(json) || typeof json != "object") {
459
- throw new Error(`cannot decode message ${any.$typeName} from JSON: expected object but got ${json === null ? "null" : Array.isArray(json) ? "array" : typeof json}`);
477
+ throw new Error(`cannot decode message ${any.$typeName} from JSON: expected object but got ${(0, reflect_check_js_1.formatVal)(json)}`);
460
478
  }
461
479
  if (Object.keys(json).length == 0) {
462
480
  return;
@@ -465,7 +483,13 @@ function anyFromJson(any, json, opts) {
465
483
  if (typeof typeUrl != "string" || typeUrl == "") {
466
484
  throw new Error(`cannot decode message ${any.$typeName} from JSON: "@type" is empty`);
467
485
  }
468
- const typeName = typeUrlToName(typeUrl), desc = (_a = opts.registry) === null || _a === void 0 ? void 0 : _a.getMessage(typeName);
486
+ const typeName = typeUrl.includes("/")
487
+ ? typeUrl.substring(typeUrl.lastIndexOf("/") + 1)
488
+ : typeUrl;
489
+ if (!typeName.length) {
490
+ throw new Error(`cannot decode message ${any.$typeName} from JSON: "@type" is invalid`);
491
+ }
492
+ const desc = (_a = opts.registry) === null || _a === void 0 ? void 0 : _a.getMessage(typeName);
469
493
  if (!desc) {
470
494
  throw new Error(`cannot decode message ${any.$typeName} from JSON: ${typeUrl} is not in the type registry`);
471
495
  }
@@ -484,17 +508,17 @@ function anyFromJson(any, json, opts) {
484
508
  }
485
509
  function timestampFromJson(timestamp, json) {
486
510
  if (typeof json !== "string") {
487
- throw new Error(`cannot decode ${timestamp.$typeName} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
511
+ throw new Error(`cannot decode message ${timestamp.$typeName} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
488
512
  }
489
513
  const matches = json.match(/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(?:Z|\.([0-9]{3,9})Z|([+-][0-9][0-9]:[0-9][0-9]))$/);
490
514
  if (!matches) {
491
- throw new Error(`cannot decode ${timestamp.$typeName} from JSON: invalid RFC 3339 string`);
515
+ throw new Error(`cannot decode message ${timestamp.$typeName} from JSON: invalid RFC 3339 string`);
492
516
  }
493
517
  const ms = Date.parse(
494
518
  //prettier-ignore
495
519
  matches[1] + "-" + matches[2] + "-" + matches[3] + "T" + matches[4] + ":" + matches[5] + ":" + matches[6] + (matches[8] ? matches[8] : "Z"));
496
520
  if (Number.isNaN(ms)) {
497
- throw new Error(`cannot decode ${timestamp.$typeName} from JSON: invalid RFC 3339 string`);
521
+ throw new Error(`cannot decode message ${timestamp.$typeName} from JSON: invalid RFC 3339 string`);
498
522
  }
499
523
  if (ms < Date.parse("0001-01-01T00:00:00Z") ||
500
524
  ms > Date.parse("9999-12-31T23:59:59Z")) {
@@ -510,15 +534,15 @@ function timestampFromJson(timestamp, json) {
510
534
  }
511
535
  function durationFromJson(duration, json) {
512
536
  if (typeof json !== "string") {
513
- throw new Error(`cannot decode ${duration.$typeName} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
537
+ throw new Error(`cannot decode message ${duration.$typeName} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
514
538
  }
515
539
  const match = json.match(/^(-?[0-9]+)(?:\.([0-9]+))?s/);
516
540
  if (match === null) {
517
- throw new Error(`cannot decode ${duration.$typeName} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
541
+ throw new Error(`cannot decode message ${duration.$typeName} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
518
542
  }
519
543
  const longSeconds = Number(match[1]);
520
544
  if (longSeconds > 315576000000 || longSeconds < -315576000000) {
521
- throw new Error(`cannot decode ${duration.$typeName} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
545
+ throw new Error(`cannot decode message ${duration.$typeName} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
522
546
  }
523
547
  duration.seconds = proto_int64_js_1.protoInt64.parse(longSeconds);
524
548
  if (typeof match[2] !== "string") {
@@ -532,14 +556,14 @@ function durationFromJson(duration, json) {
532
556
  }
533
557
  function fieldMaskFromJson(fieldMask, json) {
534
558
  if (typeof json !== "string") {
535
- throw new Error(`cannot decode ${fieldMask.$typeName} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
559
+ throw new Error(`cannot decode message ${fieldMask.$typeName} from JSON: ${(0, reflect_check_js_1.formatVal)(json)}`);
536
560
  }
537
561
  if (json === "") {
538
562
  return;
539
563
  }
540
564
  function camelToSnake(str) {
541
565
  if (str.includes("_")) {
542
- throw new Error(`cannot decode ${fieldMask.$typeName} from JSON: path names must be lowerCamelCase`);
566
+ throw new Error(`cannot decode message ${fieldMask.$typeName} from JSON: path names must be lowerCamelCase`);
543
567
  }
544
568
  const sc = str.replace(/[A-Z]/g, (letter) => "_" + letter.toLowerCase());
545
569
  return sc[0] === "_" ? sc.substring(1) : sc;
@@ -548,7 +572,7 @@ function fieldMaskFromJson(fieldMask, json) {
548
572
  }
549
573
  function structFromJson(struct, json) {
550
574
  if (typeof json != "object" || json == null || Array.isArray(json)) {
551
- throw new Error(`cannot decode ${struct.$typeName} from JSON ${(0, reflect_check_js_1.formatVal)(json)}`);
575
+ throw new Error(`cannot decode message ${struct.$typeName} from JSON ${(0, reflect_check_js_1.formatVal)(json)}`);
552
576
  }
553
577
  for (const [k, v] of Object.entries(json)) {
554
578
  const parsedV = (0, create_js_1.create)(index_js_1.ValueDesc);
@@ -583,13 +607,13 @@ function valueFromJson(value, json) {
583
607
  }
584
608
  break;
585
609
  default:
586
- throw new Error(`cannot decode ${value.$typeName} from JSON ${(0, reflect_check_js_1.formatVal)(json)}`);
610
+ throw new Error(`cannot decode message ${value.$typeName} from JSON ${(0, reflect_check_js_1.formatVal)(json)}`);
587
611
  }
588
612
  return value;
589
613
  }
590
614
  function listValueFromJson(listValue, json) {
591
615
  if (!Array.isArray(json)) {
592
- throw new Error(`cannot decode ${listValue.$typeName} from JSON ${(0, reflect_check_js_1.formatVal)(json)}`);
616
+ throw new Error(`cannot decode message ${listValue.$typeName} from JSON ${(0, reflect_check_js_1.formatVal)(json)}`);
593
617
  }
594
618
  for (const e of json) {
595
619
  const value = (0, create_js_1.create)(index_js_1.ValueDesc);
@@ -597,14 +621,3 @@ function listValueFromJson(listValue, json) {
597
621
  listValue.values.push(value);
598
622
  }
599
623
  }
600
- function typeUrlToName(url) {
601
- if (!url.length) {
602
- throw new Error(`invalid type url: ${url}`);
603
- }
604
- const slash = url.lastIndexOf("/");
605
- const name = slash >= 0 ? url.substring(slash + 1) : url;
606
- if (!name.length) {
607
- throw new Error(`invalid type url: ${url}`);
608
- }
609
- return name;
610
- }
@@ -2,9 +2,10 @@ export * from "./types.js";
2
2
  export * from "./is-message.js";
3
3
  export * from "./create.js";
4
4
  export * from "./clone.js";
5
- export * from "./desc-types.js";
5
+ export * from "./descriptors.js";
6
6
  export * from "./equals.js";
7
7
  export * from "./fields.js";
8
+ export * from "./registry.js";
8
9
  export type { JsonValue, JsonObject } from "./json-value.js";
9
10
  export { toBinary } from "./to-binary.js";
10
11
  export type { BinaryWriteOptions } from "./to-binary.js";
package/dist/cjs/index.js CHANGED
@@ -32,9 +32,10 @@ __exportStar(require("./types.js"), exports);
32
32
  __exportStar(require("./is-message.js"), exports);
33
33
  __exportStar(require("./create.js"), exports);
34
34
  __exportStar(require("./clone.js"), exports);
35
- __exportStar(require("./desc-types.js"), exports);
35
+ __exportStar(require("./descriptors.js"), exports);
36
36
  __exportStar(require("./equals.js"), exports);
37
37
  __exportStar(require("./fields.js"), exports);
38
+ __exportStar(require("./registry.js"), exports);
38
39
  var to_binary_js_1 = require("./to-binary.js");
39
40
  Object.defineProperty(exports, "toBinary", { enumerable: true, get: function () { return to_binary_js_1.toBinary; } });
40
41
  var from_binary_js_1 = require("./from-binary.js");
@@ -1,5 +1,5 @@
1
1
  import type { MessageShape } from "./types.js";
2
- import type { DescMessage } from "./desc-types.js";
2
+ import type { DescMessage } from "./descriptors.js";
3
3
  /**
4
4
  * Determine whether the given `arg` is a message.
5
5
  * If `desc` is set, determine whether `arg` is this specific message.