ts-proto 2.11.10 → 2.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.markdown +2 -2
- package/build/src/main.js +38 -11
- package/build/src/types.js +1 -1
- package/package.json +1 -1
package/README.markdown
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
## ts-proto 2.x Release Notes
|
|
9
9
|
|
|
10
|
-
The 2.x release of ts-proto migrated the low-level Protobuf serializing that its `encode` and `decode` method use from the venerable
|
|
10
|
+
The 2.x release of ts-proto migrated the low-level Protobuf serializing that its `encode` and `decode` method use from the venerable `protobufjs` package to `@bufbuild/protobuf`.
|
|
11
11
|
|
|
12
12
|
If you only used the `encode` and `decode` methods, this should largely be a non-breaking change.
|
|
13
13
|
|
|
@@ -321,7 +321,7 @@ Generated code will be placed in the Gradle build directory.
|
|
|
321
321
|
|
|
322
322
|
With `--ts_proto_opt=forceLong=string`, all 64-bit numbers will be output as strings.
|
|
323
323
|
|
|
324
|
-
With `--ts_proto_opt=forceLong=bigint`, all 64-bit numbers will be output as `BigInt`s. This option still uses the `long` library to encode/decode internally within `protobuf.js`, but then converts to/from `BigInt`s in the ts-proto-generated code.
|
|
324
|
+
With `--ts_proto_opt=forceLong=bigint`, all 64-bit numbers will be output as `BigInt`s. This option still uses the `long` library to encode/decode internally within `protobuf.js`, but then converts to/from `BigInt`s in the ts-proto-generated code. As with `forceLong=long`, `DeepPartial` widens 64-bit fields to `string | number | bigint`, and `fromPartial`/`create` coerce those inputs to `BigInt` (matching what `fromJSON` already does), so you can pass a string or number and get a `BigInt` back.
|
|
325
325
|
|
|
326
326
|
The default behavior is `forceLong=number`, which will internally still use the `long` library to encode/decode values on the wire (so you will still see a `util.Long = Long` line in your output), but will convert the `long` values to `number` automatically for you. Note that a runtime error is thrown if, while doing this conversion, a 64-bit value is larger than can be correctly stored as a `number`.
|
|
327
327
|
|
package/build/src/main.js
CHANGED
|
@@ -492,6 +492,8 @@ function makeDeepPartial(options, longs) {
|
|
|
492
492
|
const maybeExport = options.exportCommonSymbols ? "export" : "";
|
|
493
493
|
// Allow passing longs as numbers or strings, nad we'll convert them
|
|
494
494
|
const maybeLong = options.forceLong === options_1.LongOption.LONG ? (0, ts_poet_1.code) ` : T extends ${longs.Long} ? string | number | Long ` : "";
|
|
495
|
+
// Allow passing bigints as numbers or strings; fromPartial coerces them via BigInt()
|
|
496
|
+
const maybeBigInt = options.forceLong === options_1.LongOption.BIGINT ? (0, ts_poet_1.code) `T extends bigint ? string | number | bigint : ` : "";
|
|
495
497
|
const optionalBuiltins = [];
|
|
496
498
|
if (options.forceLong === options_1.LongOption.BIGINT) {
|
|
497
499
|
optionalBuiltins.push("bigint");
|
|
@@ -512,7 +514,7 @@ function makeDeepPartial(options, longs) {
|
|
|
512
514
|
// Based on the type from ts-essentials
|
|
513
515
|
const keys = (0, options_1.addTypeToMessages)(options) ? (0, ts_poet_1.code) `Exclude<keyof T, '$type'>` : (0, ts_poet_1.code) `keyof T`;
|
|
514
516
|
const DeepPartial = (0, ts_poet_1.conditionalOutput)("DeepPartial", (0, ts_poet_1.code) `
|
|
515
|
-
${maybeExport} type DeepPartial<T> =
|
|
517
|
+
${maybeExport} type DeepPartial<T> = ${maybeBigInt} T extends ${Builtin}
|
|
516
518
|
? T
|
|
517
519
|
${maybeLong}
|
|
518
520
|
: T extends globalThis.Array<infer U>
|
|
@@ -720,7 +722,7 @@ function makeTimestampMethods(options, longs, bytes) {
|
|
|
720
722
|
const seconds = ${seconds};
|
|
721
723
|
const remainder = instant.round({ smallestUnit: "seconds", roundingMode: "floor" }).until(instant);
|
|
722
724
|
const nanos = (remainder.milliseconds * 1_000_000) + (remainder.microseconds * 1_000) + remainder.nanoseconds;
|
|
723
|
-
|
|
725
|
+
|
|
724
726
|
return { ${maybeTypeField} seconds, nanos };
|
|
725
727
|
}
|
|
726
728
|
`
|
|
@@ -1087,7 +1089,13 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
1087
1089
|
length?: number,
|
|
1088
1090
|
): ${fullName} {
|
|
1089
1091
|
const reader = input instanceof ${BinaryReader} ? input : new ${BinaryReader}(input);
|
|
1090
|
-
const
|
|
1092
|
+
const previousRecursionDepth = (reader as any).__tsProtoDecodeDepth ?? 0;
|
|
1093
|
+
if (previousRecursionDepth >= 100) {
|
|
1094
|
+
throw new ${ctx.utils.globalThis}.Error("protobuf decode recursion limit exceeded");
|
|
1095
|
+
}
|
|
1096
|
+
(reader as any).__tsProtoDecodeDepth = previousRecursionDepth + 1;
|
|
1097
|
+
try {
|
|
1098
|
+
const end = length === undefined ? reader.len : reader.pos + length;
|
|
1091
1099
|
`);
|
|
1092
1100
|
chunks.push((0, ts_poet_1.code) `const message = ${createBase}${maybeAsAny(options)};`);
|
|
1093
1101
|
// start the tag loop
|
|
@@ -1253,7 +1261,12 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
1253
1261
|
// and then wrap up the while/return
|
|
1254
1262
|
chunks.push((0, ts_poet_1.code) `}`);
|
|
1255
1263
|
chunks.push((0, ts_poet_1.code) `return message;`);
|
|
1256
|
-
chunks.push((0, ts_poet_1.code) `
|
|
1264
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1265
|
+
} finally {
|
|
1266
|
+
(reader as any).__tsProtoDecodeDepth = previousRecursionDepth;
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
`);
|
|
1257
1270
|
return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
|
|
1258
1271
|
}
|
|
1259
1272
|
/** Returns a generic writer.doSomething based on the basic type */
|
|
@@ -2037,7 +2050,10 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
2037
2050
|
protoJsonComparison = (0, ts_poet_1.code) `
|
|
2038
2051
|
: ${ctx.utils.isObject}(${protoJsonProperty})
|
|
2039
2052
|
? (${ctx.utils.globalThis}.Object.entries(${protoJsonProperty}) as [string, any][]).reduce((acc: ${fieldType}, [key, value]: [string, any]) => {
|
|
2040
|
-
acc
|
|
2053
|
+
${ctx.utils.globalThis}.Object.defineProperty(acc, ${i}, {
|
|
2054
|
+
value: ${readSnippet("value")},
|
|
2055
|
+
enumerable: true, configurable: true, writable: true,
|
|
2056
|
+
});
|
|
2041
2057
|
return acc;
|
|
2042
2058
|
}, {})
|
|
2043
2059
|
`;
|
|
@@ -2045,7 +2061,10 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
2045
2061
|
chunks.push((0, ts_poet_1.code) `
|
|
2046
2062
|
${fieldKey}: ${ctx.utils.isObject}(${jsonProperty})
|
|
2047
2063
|
? (${ctx.utils.globalThis}.Object.entries(${jsonProperty}) as [string, any][]).reduce((acc: ${fieldType}, [key, value]: [string, any]) => {
|
|
2048
|
-
acc
|
|
2064
|
+
${ctx.utils.globalThis}.Object.defineProperty(acc, ${i}, {
|
|
2065
|
+
value: ${readSnippet("value")},
|
|
2066
|
+
enumerable: true, configurable: true, writable: true,
|
|
2067
|
+
});
|
|
2049
2068
|
return acc;
|
|
2050
2069
|
}, {})
|
|
2051
2070
|
${protoJsonComparison}
|
|
@@ -2219,6 +2238,9 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
2219
2238
|
const jsonName = (0, utils_1.getFieldJsonName)(field, options);
|
|
2220
2239
|
const jsonProperty = (0, utils_1.getPropertyAccessor)("obj", jsonName);
|
|
2221
2240
|
const messageProperty = (0, utils_1.getPropertyAccessor)("message", fieldName);
|
|
2241
|
+
const setJsonProperty = (value) => jsonName === "__proto__"
|
|
2242
|
+
? (0, ts_poet_1.code) `${utils.globalThis}.Object.defineProperty(obj, "__proto__", { value: ${value}, enumerable: true });`
|
|
2243
|
+
: (0, ts_poet_1.code) `${jsonProperty} = ${value};`;
|
|
2222
2244
|
const readSnippet = (from) => {
|
|
2223
2245
|
if ((0, types_1.isEnum)(field)) {
|
|
2224
2246
|
const toJson = (0, types_1.getEnumMethod)(ctx, field.typeName, "ToJSON");
|
|
@@ -2330,7 +2352,7 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
2330
2352
|
if ((0, types_1.shouldGenerateJSMapType)(ctx, messageDesc, field)) {
|
|
2331
2353
|
chunks.push((0, ts_poet_1.code) `
|
|
2332
2354
|
if (${messageProperty}?.size) {
|
|
2333
|
-
${
|
|
2355
|
+
${setJsonProperty("{}")}
|
|
2334
2356
|
${messageProperty}.forEach((v, k) => {
|
|
2335
2357
|
${jsonProperty}[${i}] = ${readSnippet("v")};
|
|
2336
2358
|
});
|
|
@@ -2343,7 +2365,7 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
2343
2365
|
if (${messageProperty}) {
|
|
2344
2366
|
const entries = ${utils.globalThis}.Object.entries(${messageProperty}) as [string, ${mapInfo.valueType}][];
|
|
2345
2367
|
if (entries.length > 0) {
|
|
2346
|
-
${
|
|
2368
|
+
${setJsonProperty("{}")}
|
|
2347
2369
|
entries.forEach(([k, v]) => {
|
|
2348
2370
|
${jsonProperty}[${i}] = ${readSnippet("v")};
|
|
2349
2371
|
});
|
|
@@ -2358,7 +2380,7 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
2358
2380
|
const maybeMap = needMap ? (0, ts_poet_1.code) `.map(e => ${readSnippet("e")})` : "";
|
|
2359
2381
|
chunks.push((0, ts_poet_1.code) `
|
|
2360
2382
|
if (${messageProperty}?.length) {
|
|
2361
|
-
${
|
|
2383
|
+
${setJsonProperty((0, ts_poet_1.code) `${messageProperty}${maybeMap}`)}
|
|
2362
2384
|
}
|
|
2363
2385
|
`);
|
|
2364
2386
|
}
|
|
@@ -2370,7 +2392,7 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
2370
2392
|
const valueName = (0, utils_1.oneofValueName)(fieldName, options);
|
|
2371
2393
|
chunks.push((0, ts_poet_1.code) `
|
|
2372
2394
|
${currentIfTarget === oneofNameWithMessage ? "else " : ""}if (${oneofNameWithMessage}?.$case === '${fieldName}') {
|
|
2373
|
-
${
|
|
2395
|
+
${setJsonProperty(readSnippet(`${oneofNameWithMessage}.${valueName}`))}
|
|
2374
2396
|
}
|
|
2375
2397
|
`);
|
|
2376
2398
|
currentIfTarget = oneofNameWithMessage;
|
|
@@ -2382,7 +2404,7 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
2382
2404
|
: `${messageProperty} !== undefined ${(0, utils_1.withAndMaybeCheckIsNotNull)(options, messageProperty)}`;
|
|
2383
2405
|
chunks.push((0, ts_poet_1.code) `
|
|
2384
2406
|
if (${check}) {
|
|
2385
|
-
${
|
|
2407
|
+
${setJsonProperty(readSnippet(`${messageProperty}`))}
|
|
2386
2408
|
}
|
|
2387
2409
|
`);
|
|
2388
2410
|
}
|
|
@@ -2443,6 +2465,11 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
2443
2465
|
!(0, types_1.isJsTypeFieldOption)(options, field)) {
|
|
2444
2466
|
return (0, ts_poet_1.code) `Long.fromValue(${from})`;
|
|
2445
2467
|
}
|
|
2468
|
+
else if (((0, types_1.isLong)(field) || (0, types_1.isLongValueType)(field)) &&
|
|
2469
|
+
options.forceLong === options_1.LongOption.BIGINT &&
|
|
2470
|
+
!(0, types_1.isJsTypeFieldOption)(options, field)) {
|
|
2471
|
+
return (0, ts_poet_1.code) `BigInt(${from})`;
|
|
2472
|
+
}
|
|
2446
2473
|
else if ((0, types_1.isObjectId)(field) && options.useMongoObjectId) {
|
|
2447
2474
|
return (0, ts_poet_1.code) `${from} as mongodb.ObjectId`;
|
|
2448
2475
|
}
|
package/build/src/types.js
CHANGED
|
@@ -296,7 +296,7 @@ function defaultValue(ctx, field) {
|
|
|
296
296
|
case ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_BOOL:
|
|
297
297
|
return useDefaultValue ? field.defaultValue : false;
|
|
298
298
|
case ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_STRING:
|
|
299
|
-
return useDefaultValue ?
|
|
299
|
+
return useDefaultValue ? JSON.stringify(field.defaultValue) : '""';
|
|
300
300
|
case ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_BYTES:
|
|
301
301
|
// todo(proto2): need to look into all the possible default values for the bytes type, and handle each one
|
|
302
302
|
if (options.env === options_1.EnvOption.NODE) {
|