@bufbuild/protobuf 2.0.0-alpha.1 → 2.0.0-alpha.3

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