@bufbuild/protobuf 2.10.2 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/dist/cjs/clone.js +1 -1
  2. package/dist/cjs/codegenv1/enum.js +1 -1
  3. package/dist/cjs/codegenv1/extension.js +1 -1
  4. package/dist/cjs/codegenv1/file.js +1 -1
  5. package/dist/cjs/codegenv1/index.js +1 -1
  6. package/dist/cjs/codegenv1/message.js +1 -1
  7. package/dist/cjs/codegenv1/service.js +1 -1
  8. package/dist/cjs/codegenv1/symbols.js +1 -1
  9. package/dist/cjs/codegenv1/types.js +1 -1
  10. package/dist/cjs/codegenv2/boot.js +1 -1
  11. package/dist/cjs/codegenv2/embed.js +1 -1
  12. package/dist/cjs/codegenv2/enum.js +1 -1
  13. package/dist/cjs/codegenv2/extension.js +1 -1
  14. package/dist/cjs/codegenv2/file.js +1 -1
  15. package/dist/cjs/codegenv2/index.js +1 -1
  16. package/dist/cjs/codegenv2/message.js +1 -1
  17. package/dist/cjs/codegenv2/restore-json-names.js +1 -1
  18. package/dist/cjs/codegenv2/scalar.js +1 -1
  19. package/dist/cjs/codegenv2/service.js +1 -1
  20. package/dist/cjs/codegenv2/symbols.js +1 -1
  21. package/dist/cjs/codegenv2/types.js +1 -1
  22. package/dist/cjs/create.js +1 -1
  23. package/dist/cjs/descriptors.js +1 -1
  24. package/dist/cjs/equals.js +1 -1
  25. package/dist/cjs/extensions.js +1 -1
  26. package/dist/cjs/fields.js +1 -1
  27. package/dist/cjs/from-binary.js +1 -1
  28. package/dist/cjs/from-json.js +80 -88
  29. package/dist/cjs/index.js +1 -1
  30. package/dist/cjs/is-message.js +1 -1
  31. package/dist/cjs/json-value.js +1 -1
  32. package/dist/cjs/merge.js +1 -1
  33. package/dist/cjs/proto-int64.js +1 -1
  34. package/dist/cjs/reflect/error.js +1 -1
  35. package/dist/cjs/reflect/guard.js +1 -1
  36. package/dist/cjs/reflect/index.js +1 -1
  37. package/dist/cjs/reflect/names.d.ts +11 -0
  38. package/dist/cjs/reflect/names.js +15 -1
  39. package/dist/cjs/reflect/nested-types.js +1 -1
  40. package/dist/cjs/reflect/path.js +1 -1
  41. package/dist/cjs/reflect/reflect-check.js +1 -1
  42. package/dist/cjs/reflect/reflect-types.js +1 -1
  43. package/dist/cjs/reflect/reflect.js +1 -1
  44. package/dist/cjs/reflect/scalar.js +1 -1
  45. package/dist/cjs/reflect/unsafe.js +1 -1
  46. package/dist/cjs/registry.js +1 -1
  47. package/dist/cjs/to-binary.js +1 -1
  48. package/dist/cjs/to-json.js +3 -5
  49. package/dist/cjs/types.js +1 -1
  50. package/dist/cjs/wire/base64-encoding.js +1 -1
  51. package/dist/cjs/wire/binary-encoding.js +1 -1
  52. package/dist/cjs/wire/index.js +1 -1
  53. package/dist/cjs/wire/size-delimited.js +1 -1
  54. package/dist/cjs/wire/text-encoding.js +1 -1
  55. package/dist/cjs/wire/text-format.js +1 -1
  56. package/dist/cjs/wkt/any.js +1 -1
  57. package/dist/cjs/wkt/duration.js +1 -1
  58. package/dist/cjs/wkt/gen/google/protobuf/any_pb.js +1 -1
  59. package/dist/cjs/wkt/gen/google/protobuf/api_pb.js +1 -1
  60. package/dist/cjs/wkt/gen/google/protobuf/compiler/plugin_pb.js +1 -1
  61. package/dist/cjs/wkt/gen/google/protobuf/cpp_features_pb.js +1 -1
  62. package/dist/cjs/wkt/gen/google/protobuf/descriptor_pb.js +1 -1
  63. package/dist/cjs/wkt/gen/google/protobuf/duration_pb.js +1 -1
  64. package/dist/cjs/wkt/gen/google/protobuf/empty_pb.js +1 -1
  65. package/dist/cjs/wkt/gen/google/protobuf/field_mask_pb.js +1 -1
  66. package/dist/cjs/wkt/gen/google/protobuf/go_features_pb.js +1 -1
  67. package/dist/cjs/wkt/gen/google/protobuf/java_features_pb.js +1 -1
  68. package/dist/cjs/wkt/gen/google/protobuf/source_context_pb.js +1 -1
  69. package/dist/cjs/wkt/gen/google/protobuf/struct_pb.js +1 -1
  70. package/dist/cjs/wkt/gen/google/protobuf/timestamp_pb.js +1 -1
  71. package/dist/cjs/wkt/gen/google/protobuf/type_pb.js +1 -1
  72. package/dist/cjs/wkt/gen/google/protobuf/wrappers_pb.js +1 -1
  73. package/dist/cjs/wkt/index.js +1 -1
  74. package/dist/cjs/wkt/timestamp.js +1 -1
  75. package/dist/cjs/wkt/wrappers.js +1 -1
  76. package/dist/esm/clone.js +1 -1
  77. package/dist/esm/codegenv1/enum.js +1 -1
  78. package/dist/esm/codegenv1/extension.js +1 -1
  79. package/dist/esm/codegenv1/file.js +1 -1
  80. package/dist/esm/codegenv1/index.js +1 -1
  81. package/dist/esm/codegenv1/message.js +1 -1
  82. package/dist/esm/codegenv1/service.js +1 -1
  83. package/dist/esm/codegenv1/symbols.js +1 -1
  84. package/dist/esm/codegenv1/types.js +1 -1
  85. package/dist/esm/codegenv2/boot.js +1 -1
  86. package/dist/esm/codegenv2/embed.js +1 -1
  87. package/dist/esm/codegenv2/enum.js +1 -1
  88. package/dist/esm/codegenv2/extension.js +1 -1
  89. package/dist/esm/codegenv2/file.js +1 -1
  90. package/dist/esm/codegenv2/index.js +1 -1
  91. package/dist/esm/codegenv2/message.js +1 -1
  92. package/dist/esm/codegenv2/restore-json-names.js +1 -1
  93. package/dist/esm/codegenv2/scalar.js +1 -1
  94. package/dist/esm/codegenv2/service.js +1 -1
  95. package/dist/esm/codegenv2/symbols.js +1 -1
  96. package/dist/esm/codegenv2/types.js +1 -1
  97. package/dist/esm/create.js +1 -1
  98. package/dist/esm/descriptors.js +1 -1
  99. package/dist/esm/equals.js +1 -1
  100. package/dist/esm/extensions.js +1 -1
  101. package/dist/esm/fields.js +1 -1
  102. package/dist/esm/from-binary.js +1 -1
  103. package/dist/esm/from-json.js +80 -88
  104. package/dist/esm/index.js +1 -1
  105. package/dist/esm/is-message.js +1 -1
  106. package/dist/esm/json-value.js +1 -1
  107. package/dist/esm/merge.js +1 -1
  108. package/dist/esm/proto-int64.js +1 -1
  109. package/dist/esm/reflect/error.js +1 -1
  110. package/dist/esm/reflect/guard.js +1 -1
  111. package/dist/esm/reflect/index.js +1 -1
  112. package/dist/esm/reflect/names.d.ts +11 -0
  113. package/dist/esm/reflect/names.js +14 -1
  114. package/dist/esm/reflect/nested-types.js +1 -1
  115. package/dist/esm/reflect/path.js +1 -1
  116. package/dist/esm/reflect/reflect-check.js +1 -1
  117. package/dist/esm/reflect/reflect-types.js +1 -1
  118. package/dist/esm/reflect/reflect.js +1 -1
  119. package/dist/esm/reflect/scalar.js +1 -1
  120. package/dist/esm/reflect/unsafe.js +1 -1
  121. package/dist/esm/registry.js +1 -1
  122. package/dist/esm/to-binary.js +1 -1
  123. package/dist/esm/to-json.js +4 -6
  124. package/dist/esm/types.js +1 -1
  125. package/dist/esm/wire/base64-encoding.js +1 -1
  126. package/dist/esm/wire/binary-encoding.js +1 -1
  127. package/dist/esm/wire/index.js +1 -1
  128. package/dist/esm/wire/size-delimited.js +1 -1
  129. package/dist/esm/wire/text-encoding.js +1 -1
  130. package/dist/esm/wire/text-format.js +1 -1
  131. package/dist/esm/wkt/any.js +1 -1
  132. package/dist/esm/wkt/duration.js +1 -1
  133. package/dist/esm/wkt/gen/google/protobuf/any_pb.js +1 -1
  134. package/dist/esm/wkt/gen/google/protobuf/api_pb.js +1 -1
  135. package/dist/esm/wkt/gen/google/protobuf/compiler/plugin_pb.js +1 -1
  136. package/dist/esm/wkt/gen/google/protobuf/cpp_features_pb.js +1 -1
  137. package/dist/esm/wkt/gen/google/protobuf/descriptor_pb.js +1 -1
  138. package/dist/esm/wkt/gen/google/protobuf/duration_pb.js +1 -1
  139. package/dist/esm/wkt/gen/google/protobuf/empty_pb.js +1 -1
  140. package/dist/esm/wkt/gen/google/protobuf/field_mask_pb.js +1 -1
  141. package/dist/esm/wkt/gen/google/protobuf/go_features_pb.js +1 -1
  142. package/dist/esm/wkt/gen/google/protobuf/java_features_pb.js +1 -1
  143. package/dist/esm/wkt/gen/google/protobuf/source_context_pb.js +1 -1
  144. package/dist/esm/wkt/gen/google/protobuf/struct_pb.js +1 -1
  145. package/dist/esm/wkt/gen/google/protobuf/timestamp_pb.js +1 -1
  146. package/dist/esm/wkt/gen/google/protobuf/type_pb.js +1 -1
  147. package/dist/esm/wkt/gen/google/protobuf/wrappers_pb.js +1 -1
  148. package/dist/esm/wkt/index.js +1 -1
  149. package/dist/esm/wkt/timestamp.js +1 -1
  150. package/dist/esm/wkt/wrappers.js +1 -1
  151. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@ import { create } from "./create.js";
17
17
  import { reflect } from "./reflect/reflect.js";
18
18
  import { FieldError, isFieldError } from "./reflect/error.js";
19
19
  import { formatVal } from "./reflect/reflect-check.js";
20
- import { scalarZeroValue } from "./reflect/scalar.js";
20
+ import { protoSnakeCase } from "./reflect/names.js";
21
21
  import { base64Decode } from "./wire/base64-encoding.js";
22
22
  import { isWrapperDesc, anyPack, ListValueSchema, NullValue, StructSchema, ValueSchema, } from "./wkt/index.js";
23
23
  import { createExtensionContainer, setExtension } from "./extensions.js";
@@ -93,11 +93,7 @@ export function mergeFromJson(schema, target, json, options) {
93
93
  * Parses an enum value from JSON.
94
94
  */
95
95
  export function enumFromJson(descEnum, json) {
96
- const val = readEnum(descEnum, json, false, false);
97
- if (val === tokenIgnoredUnknownEnum) {
98
- throw new Error(`cannot decode ${descEnum} from JSON: ${formatVal(json)}`);
99
- }
100
- return val;
96
+ return readEnum(descEnum, json, false);
101
97
  }
102
98
  /**
103
99
  * Is the given value a JSON enum value?
@@ -105,6 +101,18 @@ export function enumFromJson(descEnum, json) {
105
101
  export function isEnumJson(descEnum, value) {
106
102
  return undefined !== descEnum.values.find((v) => v.name === value);
107
103
  }
104
+ const messageJsonFields = new WeakMap();
105
+ function getJsonField(desc, jsonKey) {
106
+ var _a;
107
+ if (!messageJsonFields.has(desc)) {
108
+ const jsonNames = new Map();
109
+ for (const field of desc.fields) {
110
+ jsonNames.set(field.name, field).set(field.jsonName, field);
111
+ }
112
+ messageJsonFields.set(desc, jsonNames);
113
+ }
114
+ return (_a = messageJsonFields.get(desc)) === null || _a === void 0 ? void 0 : _a.get(jsonKey);
115
+ }
108
116
  function readMessage(msg, json, opts) {
109
117
  var _a;
110
118
  if (tryWktFromJson(msg, json, opts)) {
@@ -114,12 +122,8 @@ function readMessage(msg, json, opts) {
114
122
  throw new Error(`cannot decode ${msg.desc} from JSON: ${formatVal(json)}`);
115
123
  }
116
124
  const oneofSeen = new Map();
117
- const jsonNames = new Map();
118
- for (const field of msg.desc.fields) {
119
- jsonNames.set(field.name, field).set(field.jsonName, field);
120
- }
121
125
  for (const [jsonKey, jsonValue] of Object.entries(json)) {
122
- const field = jsonNames.get(jsonKey);
126
+ const field = getJsonField(msg.desc, jsonKey);
123
127
  if (field) {
124
128
  if (field.oneof) {
125
129
  if (jsonValue === null && field.fieldKind == "scalar") {
@@ -170,6 +174,20 @@ function readField(msg, field, json, opts) {
170
174
  break;
171
175
  }
172
176
  }
177
+ function readListOrMapItem(field, json, opts) {
178
+ if (field.scalar && json !== null) {
179
+ return scalarFromJson(field, json);
180
+ }
181
+ if (field.message && !isResetSentinelNullValue(field, json)) {
182
+ const msgValue = reflect(field.message);
183
+ readMessage(msgValue, json, opts);
184
+ return msgValue;
185
+ }
186
+ if (field.enum && !isResetSentinelNullValue(field, json)) {
187
+ return readEnum(field.enum, json, opts.ignoreUnknownFields);
188
+ }
189
+ throw new FieldError(field, `${field.fieldKind === "list" ? "list item" : "map value"} must not be null`);
190
+ }
173
191
  function readMapField(map, json, opts) {
174
192
  if (json === null) {
175
193
  return;
@@ -179,28 +197,11 @@ function readMapField(map, json, opts) {
179
197
  throw new FieldError(field, "expected object, got " + formatVal(json));
180
198
  }
181
199
  for (const [jsonMapKey, jsonMapValue] of Object.entries(json)) {
182
- if (jsonMapValue === null && !isSafeNullValueInListOrMap(field)) {
183
- throw new FieldError(field, "map value must not be null");
184
- }
185
- let value;
186
- switch (field.mapKind) {
187
- case "message":
188
- const msgValue = reflect(field.message);
189
- readMessage(msgValue, jsonMapValue, opts);
190
- value = msgValue;
191
- break;
192
- case "enum":
193
- value = readEnum(field.enum, jsonMapValue, opts.ignoreUnknownFields, true);
194
- if (value === tokenIgnoredUnknownEnum) {
195
- return;
196
- }
197
- break;
198
- case "scalar":
199
- value = scalarFromJson(field, jsonMapValue, true);
200
- break;
201
- }
202
200
  const key = mapKeyFromJson(field.mapKey, jsonMapKey);
203
- map.set(key, value);
201
+ const value = readListOrMapItem(field, jsonMapValue, opts);
202
+ if (value !== tokenIgnoredUnknownEnum) {
203
+ map.set(key, value);
204
+ }
204
205
  }
205
206
  }
206
207
  function readListField(list, json, opts) {
@@ -212,34 +213,14 @@ function readListField(list, json, opts) {
212
213
  throw new FieldError(field, "expected Array, got " + formatVal(json));
213
214
  }
214
215
  for (const jsonItem of json) {
215
- if (jsonItem === null && !isSafeNullValueInListOrMap(field)) {
216
- throw new FieldError(field, "list item must not be null");
217
- }
218
- switch (field.listKind) {
219
- case "message":
220
- const msgValue = reflect(field.message);
221
- readMessage(msgValue, jsonItem, opts);
222
- list.add(msgValue);
223
- break;
224
- case "enum":
225
- const enumValue = readEnum(field.enum, jsonItem, opts.ignoreUnknownFields, true);
226
- if (enumValue !== tokenIgnoredUnknownEnum) {
227
- list.add(enumValue);
228
- }
229
- break;
230
- case "scalar":
231
- list.add(scalarFromJson(field, jsonItem, true));
232
- break;
216
+ const value = readListOrMapItem(field, jsonItem, opts);
217
+ if (value !== tokenIgnoredUnknownEnum) {
218
+ list.add(value);
233
219
  }
234
220
  }
235
221
  }
236
- function isSafeNullValueInListOrMap(field) {
237
- var _a, _b;
238
- return (((_a = field.message) === null || _a === void 0 ? void 0 : _a.typeName) == "google.protobuf.Value" ||
239
- ((_b = field.enum) === null || _b === void 0 ? void 0 : _b.typeName) == "google.protobuf.NullValue");
240
- }
241
222
  function readMessageField(msg, field, json, opts) {
242
- if (json === null && field.message.typeName != "google.protobuf.Value") {
223
+ if (isResetSentinelNullValue(field, json)) {
243
224
  msg.clear(field);
244
225
  return;
245
226
  }
@@ -248,30 +229,44 @@ function readMessageField(msg, field, json, opts) {
248
229
  msg.set(field, msgValue);
249
230
  }
250
231
  function readEnumField(msg, field, json, opts) {
251
- const enumValue = readEnum(field.enum, json, opts.ignoreUnknownFields, false);
252
- if (enumValue === tokenNull) {
232
+ if (isResetSentinelNullValue(field, json)) {
253
233
  msg.clear(field);
234
+ return;
254
235
  }
255
- else if (enumValue !== tokenIgnoredUnknownEnum) {
236
+ const enumValue = readEnum(field.enum, json, opts.ignoreUnknownFields);
237
+ if (enumValue !== tokenIgnoredUnknownEnum) {
256
238
  msg.set(field, enumValue);
257
239
  }
258
240
  }
259
241
  function readScalarField(msg, field, json) {
260
- const scalarValue = scalarFromJson(field, json, false);
261
- if (scalarValue === tokenNull) {
242
+ if (json === null) {
262
243
  msg.clear(field);
263
244
  }
264
245
  else {
265
- msg.set(field, scalarValue);
246
+ msg.set(field, scalarFromJson(field, json));
266
247
  }
267
248
  }
249
+ /**
250
+ * Indicates whether a value is a sentinel for reseting a field.
251
+ *
252
+ * For this to be true, the value must be a JSON null and the field must not
253
+ * permit a present, Protobuf-serializable null.
254
+ *
255
+ * Only message google.protobuf.Value and enum google.protobuf.NullValue fields
256
+ * permit Protobuf-serializable nulls.
257
+ *
258
+ * Note that field-resetting sentinel nulls are not permitted in lists and maps.
259
+ */
260
+ function isResetSentinelNullValue(field, json) {
261
+ var _a, _b;
262
+ return (json === null &&
263
+ ((_a = field.message) === null || _a === void 0 ? void 0 : _a.typeName) != "google.protobuf.Value" &&
264
+ ((_b = field.enum) === null || _b === void 0 ? void 0 : _b.typeName) != "google.protobuf.NullValue");
265
+ }
268
266
  const tokenIgnoredUnknownEnum = Symbol();
269
- function readEnum(desc, json, ignoreUnknownFields, nullAsZeroValue) {
267
+ function readEnum(desc, json, ignoreUnknownFields) {
270
268
  if (json === null) {
271
- if (desc.typeName == "google.protobuf.NullValue") {
272
- return 0; // google.protobuf.NullValue.NULL_VALUE = 0
273
- }
274
- return nullAsZeroValue ? desc.values[0].number : tokenNull;
269
+ return desc.values[0].number;
275
270
  }
276
271
  switch (typeof json) {
277
272
  case "number":
@@ -291,14 +286,13 @@ function readEnum(desc, json, ignoreUnknownFields, nullAsZeroValue) {
291
286
  }
292
287
  throw new Error(`cannot decode ${desc} from JSON: ${formatVal(json)}`);
293
288
  }
294
- const tokenNull = Symbol();
295
- function scalarFromJson(field, json, nullAsZeroValue) {
296
- if (json === null) {
297
- if (nullAsZeroValue) {
298
- return scalarZeroValue(field.scalar, false);
299
- }
300
- return tokenNull;
301
- }
289
+ /**
290
+ * Try to parse a JSON value to a scalar value for the reflect API.
291
+ *
292
+ * Returns the input if the JSON value cannot be converted. Raises a FieldError
293
+ * if conversion would be ambiguous.
294
+ */
295
+ function scalarFromJson(field, json) {
302
296
  // int64, sfixed64, sint64, fixed64, uint64: Reflect supports string and number.
303
297
  // string, bool: Supported by reflect.
304
298
  switch (field.scalar) {
@@ -371,24 +365,24 @@ function scalarFromJson(field, json, nullAsZeroValue) {
371
365
  *
372
366
  * Returns the input if the JSON value cannot be converted.
373
367
  */
374
- function mapKeyFromJson(type, json) {
368
+ function mapKeyFromJson(type, jsonString) {
375
369
  switch (type) {
376
370
  case ScalarType.BOOL:
377
- switch (json) {
371
+ switch (jsonString) {
378
372
  case "true":
379
373
  return true;
380
374
  case "false":
381
375
  return false;
382
376
  }
383
- return json;
377
+ return jsonString;
384
378
  case ScalarType.INT32:
385
379
  case ScalarType.FIXED32:
386
380
  case ScalarType.UINT32:
387
381
  case ScalarType.SFIXED32:
388
382
  case ScalarType.SINT32:
389
- return int32FromJson(json);
383
+ return int32FromJson(jsonString);
390
384
  default:
391
- return json;
385
+ return jsonString;
392
386
  }
393
387
  }
394
388
  /**
@@ -459,7 +453,7 @@ function tryWktFromJson(msg, jsonValue, opts) {
459
453
  msg.clear(valueField);
460
454
  }
461
455
  else {
462
- msg.set(valueField, scalarFromJson(valueField, jsonValue, true));
456
+ msg.set(valueField, scalarFromJson(valueField, jsonValue));
463
457
  }
464
458
  return true;
465
459
  }
@@ -557,14 +551,12 @@ function fieldMaskFromJson(fieldMask, json) {
557
551
  if (json === "") {
558
552
  return;
559
553
  }
560
- function camelToSnake(str) {
561
- if (str.includes("_")) {
554
+ fieldMask.paths = json.split(",").map((path) => {
555
+ if (path.includes("_")) {
562
556
  throw new Error(`cannot decode message ${fieldMask.$typeName} from JSON: path names must be lowerCamelCase`);
563
557
  }
564
- const sc = str.replace(/[A-Z]/g, (letter) => "_" + letter.toLowerCase());
565
- return sc[0] === "_" ? sc.substring(1) : sc;
566
- }
567
- fieldMask.paths = json.split(",").map(camelToSnake);
558
+ return protoSnakeCase(path);
559
+ });
568
560
  }
569
561
  function structFromJson(struct, json) {
570
562
  if (typeof json != "object" || json == null || Array.isArray(json)) {
package/dist/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
package/dist/esm/merge.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -9,8 +9,19 @@ export declare function qualifiedName(desc: AnyDesc): string;
9
9
  /**
10
10
  * Converts snake_case to protoCamelCase according to the convention
11
11
  * used by protoc to convert a field name to a JSON name.
12
+ *
13
+ * See https://protobuf.com/docs/language-spec#default-json-names
14
+ *
15
+ * The function protoSnakeCase provides the reverse.
12
16
  */
13
17
  export declare function protoCamelCase(snakeCase: string): string;
18
+ /**
19
+ * Converts protoCamelCase to snake_case.
20
+ *
21
+ * This function is the reverse of function protoCamelCase. Note that some names
22
+ * are not reversible - for example, "foo__bar" -> "fooBar" -> "foo_bar".
23
+ */
24
+ export declare function protoSnakeCase(lowerCamelCase: string): string;
14
25
  /**
15
26
  * Escapes names that are reserved for ECMAScript built-in object properties.
16
27
  *
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -41,6 +41,10 @@ export function qualifiedName(desc) {
41
41
  /**
42
42
  * Converts snake_case to protoCamelCase according to the convention
43
43
  * used by protoc to convert a field name to a JSON name.
44
+ *
45
+ * See https://protobuf.com/docs/language-spec#default-json-names
46
+ *
47
+ * The function protoSnakeCase provides the reverse.
44
48
  */
45
49
  export function protoCamelCase(snakeCase) {
46
50
  let capNext = false;
@@ -75,6 +79,15 @@ export function protoCamelCase(snakeCase) {
75
79
  }
76
80
  return b.join("");
77
81
  }
82
+ /**
83
+ * Converts protoCamelCase to snake_case.
84
+ *
85
+ * This function is the reverse of function protoCamelCase. Note that some names
86
+ * are not reversible - for example, "foo__bar" -> "fooBar" -> "foo_bar".
87
+ */
88
+ export function protoSnakeCase(lowerCamelCase) {
89
+ return lowerCamelCase.replace(/[A-Z]/g, (letter) => "_" + letter.toLowerCase());
90
+ }
78
91
  /**
79
92
  * Names that cannot be used for object properties because they are reserved
80
93
  * by built-in JavaScript properties.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
14
  import { ScalarType, } from "./descriptors.js";
15
- import { protoCamelCase } from "./reflect/names.js";
15
+ import { protoCamelCase, protoSnakeCase } from "./reflect/names.js";
16
16
  import { reflect } from "./reflect/reflect.js";
17
17
  import { anyUnpack } from "./wkt/index.js";
18
18
  import { isWrapperDesc } from "./wkt/wrappers.js";
@@ -320,10 +320,8 @@ function durationToJson(val) {
320
320
  function fieldMaskToJson(val) {
321
321
  return val.paths
322
322
  .map((p) => {
323
- if (p.match(/_[0-9]?_/g) || p.match(/[A-Z]/g)) {
324
- throw new Error(`cannot encode message ${val.$typeName} to JSON: lowerCamelCase of path name "` +
325
- p +
326
- '" is irreversible');
323
+ if (protoSnakeCase(protoCamelCase(p)) !== p) {
324
+ throw new Error(`cannot encode message ${val.$typeName} to JSON: lowerCamelCase of path name "${p}" is irreversible`);
327
325
  }
328
326
  return protoCamelCase(p);
329
327
  })
package/dist/esm/types.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Buf Technologies, Inc.
1
+ // Copyright 2021-2026 Buf Technologies, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.