ts-proto 2.15.0 → 2.15.2
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/build/src/generate-services.js +2 -2
- package/build/src/main.d.ts +4 -1
- package/build/src/main.js +81 -15
- package/package.json +1 -1
|
@@ -339,10 +339,10 @@ function generateCachingRpcMethod(ctx, fileDesc, serviceDesc, methodDesc) {
|
|
|
339
339
|
function generateRpcType(ctx, hasStreamingMethods) {
|
|
340
340
|
const { options } = ctx;
|
|
341
341
|
const metadata = options.metadataType ? (0, ts_poet_1.imp)(options.metadataType) : (0, ts_poet_1.imp)("t:Metadata@@grpc/grpc-js");
|
|
342
|
-
const metadataType = metadata.symbol;
|
|
343
342
|
const maybeContext = options.context ? "<Context>" : "";
|
|
344
343
|
const maybeContextParam = options.context ? "ctx: Context," : "";
|
|
345
|
-
|
|
344
|
+
// Use the import itself, so it is added even if no method of the service refers to it.
|
|
345
|
+
const maybeMetadataParam = options.metadataType || options.addGrpcMetadata ? (0, ts_poet_1.code) `metadata?: ${metadata},` : "";
|
|
346
346
|
const maybeAbortSignalParam = options.useAbortSignal ? "abortSignal?: AbortSignal," : "";
|
|
347
347
|
const methods = [[(0, ts_poet_1.code) `request`, (0, ts_poet_1.code) `Uint8Array`, (0, ts_poet_1.code) `Promise<Uint8Array>`]];
|
|
348
348
|
const additionalMethods = [];
|
package/build/src/main.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ declare function makeDeepPartial(options: Options, longs: ReturnType<typeof make
|
|
|
24
24
|
Exact: ConditionalOutput;
|
|
25
25
|
};
|
|
26
26
|
declare function makeMessageFns(options: Options, deepPartial: ReturnType<typeof makeDeepPartial>, extension: ReturnType<typeof makeExtensionClass>): {
|
|
27
|
-
MessageFns: ConditionalOutput;
|
|
27
|
+
MessageFns: ConditionalOutput | undefined;
|
|
28
28
|
ExtensionFns: ConditionalOutput;
|
|
29
29
|
ExtensionHolder: ConditionalOutput;
|
|
30
30
|
StructWrapperFns: ConditionalOutput;
|
|
@@ -42,6 +42,9 @@ declare function makeTimestampMethods(options: Options, longs: ReturnType<typeof
|
|
|
42
42
|
fromTimestamp: ConditionalOutput;
|
|
43
43
|
timestampFractionRegex: ConditionalOutput;
|
|
44
44
|
fromJsonTimestamp: ConditionalOutput;
|
|
45
|
+
timestampJsonRegex: ConditionalOutput;
|
|
46
|
+
timestampFromJson: ConditionalOutput;
|
|
47
|
+
timestampToJson: ConditionalOutput;
|
|
45
48
|
};
|
|
46
49
|
declare function makeAnyJsonUtils(): {
|
|
47
50
|
anyJsonValueTypes: ConditionalOutput;
|
package/build/src/main.js
CHANGED
|
@@ -88,14 +88,15 @@ function generateFile(ctx, fileDesc) {
|
|
|
88
88
|
(0, visit_1.visit)(fileDesc, sourceInfo, (fullName, message, _sInfo, fullProtoTypeName) => {
|
|
89
89
|
const fullTypeName = (0, utils_1.maybePrefixPackage)(fileDesc, fullProtoTypeName);
|
|
90
90
|
const outputWrapAndUnwrap = (0, generate_struct_wrappers_1.isWrapperType)(fullTypeName);
|
|
91
|
-
// Only decode, fromPartial, and wrap use the createBase method
|
|
91
|
+
// Only decode, fromPartial, and wrap use the createBase method. The deep `Value.wrap`
|
|
92
|
+
// generated for NestJS builds its result without it.
|
|
92
93
|
if ((options.outputEncodeMethods &&
|
|
93
94
|
options.outputEncodeMethods !== "encode-no-creation" &&
|
|
94
95
|
options.outputEncodeMethods !== "encode-only" &&
|
|
95
96
|
(options.outputDecodeIncludeTypes === "" ||
|
|
96
97
|
new RegExp(options.outputDecodeIncludeTypes).test(fullTypeName))) ||
|
|
97
98
|
options.outputPartialMethods ||
|
|
98
|
-
outputWrapAndUnwrap) {
|
|
99
|
+
(outputWrapAndUnwrap && !(options.nestJs && (0, types_1.isAnyValueTypeName)(fullTypeName)))) {
|
|
99
100
|
chunks.push(generateBaseInstanceFactory(ctx, fullName, message, fullTypeName));
|
|
100
101
|
}
|
|
101
102
|
const staticMembers = [];
|
|
@@ -172,7 +173,10 @@ function generateFile(ctx, fileDesc) {
|
|
|
172
173
|
const messageFnsTypeParameters = [fullName, hasTypeMember && `'${fullTypeName}'`]
|
|
173
174
|
.filter((p) => !!p)
|
|
174
175
|
.join(", ");
|
|
175
|
-
const interfaces = [
|
|
176
|
+
const interfaces = [];
|
|
177
|
+
if (utils.MessageFns) {
|
|
178
|
+
interfaces.push((0, ts_poet_1.code) `${utils.MessageFns}<${messageFnsTypeParameters}>`);
|
|
179
|
+
}
|
|
176
180
|
if (options.outputEncodeMethods &&
|
|
177
181
|
options.outputExtensions &&
|
|
178
182
|
options.unknownFields &&
|
|
@@ -601,11 +605,15 @@ function makeMessageFns(options, deepPartial, extension) {
|
|
|
601
605
|
}
|
|
602
606
|
}
|
|
603
607
|
const maybeExport = options.exportCommonSymbols ? "export" : "";
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
608
|
+
// Without any common members, e.g. with only the NestJS wrappers, the interface
|
|
609
|
+
// would be empty and its type parameter unused, so it is not generated at all.
|
|
610
|
+
const MessageFns = commonStaticMembers.length > 0
|
|
611
|
+
? (0, ts_poet_1.conditionalOutput)("MessageFns", (0, ts_poet_1.code) `
|
|
612
|
+
${maybeExport} interface MessageFns<T${hasTypeMember ? ", V extends string" : ""}> {
|
|
613
|
+
${(0, ts_poet_1.joinCode)(commonStaticMembers, { on: "\n" })}
|
|
614
|
+
}
|
|
615
|
+
`)
|
|
616
|
+
: undefined;
|
|
609
617
|
const ExtensionFns = (0, ts_poet_1.conditionalOutput)("ExtensionFns", (0, ts_poet_1.code) `
|
|
610
618
|
${maybeExport} interface ExtensionFns<T> {
|
|
611
619
|
${(0, ts_poet_1.joinCode)(extensionStaticMembers, { on: "\n" })}
|
|
@@ -829,7 +837,43 @@ function makeTimestampMethods(options, longs, bytes) {
|
|
|
829
837
|
}
|
|
830
838
|
}
|
|
831
839
|
`);
|
|
832
|
-
|
|
840
|
+
// Declared once per file, so the regex isn't compiled on each timestampFromJson call
|
|
841
|
+
const timestampJsonRegex = (0, ts_poet_1.conditionalOutput)("timestampJsonRegex", (0, ts_poet_1.code) `const timestampJsonRegex = /^.+T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$/;`);
|
|
842
|
+
// Parses the canonical JSON of a Timestamp, an RFC 3339 string
|
|
843
|
+
const timestampFromJson = (0, ts_poet_1.conditionalOutput)("timestampFromJson", (0, ts_poet_1.code) `
|
|
844
|
+
function timestampFromJson(value: string): { seconds: number; nanos: number } {
|
|
845
|
+
const match = ${timestampJsonRegex}.exec(value);
|
|
846
|
+
// Date only keeps milliseconds, so it parses the string without the fractional seconds
|
|
847
|
+
const fraction = match?.[1];
|
|
848
|
+
const millis = match
|
|
849
|
+
? new ${bytes.globalThis}.Date(fraction === undefined ? value : value.replace(fraction, "")).getTime()
|
|
850
|
+
: NaN;
|
|
851
|
+
if (!match || ${bytes.globalThis}.Number.isNaN(millis)) {
|
|
852
|
+
throw new ${bytes.globalThis}.Error(\`Invalid timestamp: \${value}\`);
|
|
853
|
+
}
|
|
854
|
+
const nanos = fraction === undefined ? 0 : ${bytes.globalThis}.Number(fraction.slice(1, 10).padEnd(9, "0"));
|
|
855
|
+
return { seconds: millis / 1_000, nanos };
|
|
856
|
+
}
|
|
857
|
+
`);
|
|
858
|
+
// Writes the canonical JSON of a Timestamp, an RFC 3339 string
|
|
859
|
+
const timestampToJson = (0, ts_poet_1.conditionalOutput)("timestampToJson", (0, ts_poet_1.code) `
|
|
860
|
+
function timestampToJson(seconds: number, nanos: number): string {
|
|
861
|
+
const date = new ${bytes.globalThis}.Date(seconds * 1_000).toISOString().slice(0, 19);
|
|
862
|
+
if (nanos === 0) return \`\${date}Z\`;
|
|
863
|
+
const padded = nanos.toString().padStart(9, "0");
|
|
864
|
+
const len = nanos % 1_000_000 === 0 ? 3 : nanos % 1_000 === 0 ? 6 : 9;
|
|
865
|
+
return \`\${date}.\${padded.slice(0, len)}Z\`;
|
|
866
|
+
}
|
|
867
|
+
`);
|
|
868
|
+
return {
|
|
869
|
+
toTimestamp,
|
|
870
|
+
fromTimestamp,
|
|
871
|
+
timestampFractionRegex,
|
|
872
|
+
fromJsonTimestamp,
|
|
873
|
+
timestampJsonRegex,
|
|
874
|
+
timestampFromJson,
|
|
875
|
+
timestampToJson,
|
|
876
|
+
};
|
|
833
877
|
}
|
|
834
878
|
function makeAnyJsonUtils() {
|
|
835
879
|
// Well-known types whose JSON is not an object of their fields. Packed in an Any, that
|
|
@@ -1905,10 +1949,22 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1905
1949
|
`;
|
|
1906
1950
|
}
|
|
1907
1951
|
// create the basic function declaration
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1952
|
+
if (fullTypeName === "google.protobuf.Timestamp") {
|
|
1953
|
+
// The canonical JSON of a Timestamp is an RFC 3339 string; the object form is still accepted.
|
|
1954
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1955
|
+
fromJSON(object: any): ${fullName} {
|
|
1956
|
+
if (typeof object === "string") {
|
|
1957
|
+
return ${fullName}.fromJSON(${utils.timestampFromJson}(object));
|
|
1958
|
+
}
|
|
1959
|
+
return {
|
|
1960
|
+
`);
|
|
1961
|
+
}
|
|
1962
|
+
else {
|
|
1963
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1964
|
+
fromJSON(${messageDesc.field.length > 0 ? "object" : "_"}: any): ${fullName} {
|
|
1965
|
+
return {
|
|
1966
|
+
`);
|
|
1967
|
+
}
|
|
1912
1968
|
if ((0, options_1.addTypeToMessages)(options)) {
|
|
1913
1969
|
chunks.push((0, ts_poet_1.code) `$type: ${fullName}.$type,`);
|
|
1914
1970
|
}
|
|
@@ -2223,7 +2279,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
2223
2279
|
chunks.push((0, ts_poet_1.code) `}`);
|
|
2224
2280
|
return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
|
|
2225
2281
|
}
|
|
2226
|
-
function generateCanonicalToJson(fullName, fullProtobufTypeName, { useOptionals, useNullAsOptional, useDuration, forceLong }) {
|
|
2282
|
+
function generateCanonicalToJson(fullName, fullProtobufTypeName, { useOptionals, useNullAsOptional, useDuration, useJsonTimestamp, forceLong }, utils) {
|
|
2227
2283
|
if ((0, types_1.isFieldMaskTypeName)(fullProtobufTypeName)) {
|
|
2228
2284
|
const returnType = useOptionals === "all" ? `string | ${(0, utils_1.nullOrUndefined)({ useNullAsOptional })}` : "string";
|
|
2229
2285
|
const pathModifier = useOptionals === "all" ? "?" : "";
|
|
@@ -2269,6 +2325,16 @@ function generateCanonicalToJson(fullName, fullProtobufTypeName, { useOptionals,
|
|
|
2269
2325
|
}
|
|
2270
2326
|
`;
|
|
2271
2327
|
}
|
|
2328
|
+
if (fullProtobufTypeName === "google.protobuf.Timestamp" && useJsonTimestamp === options_1.JsonTimestampOption.RFC3339) {
|
|
2329
|
+
const seconds = forceLong === options_1.LongOption.LONG
|
|
2330
|
+
? (0, ts_poet_1.code) `message.seconds?.toNumber() ?? 0`
|
|
2331
|
+
: (0, ts_poet_1.code) `${utils.globalThis}.Number(message.seconds ?? 0)`;
|
|
2332
|
+
return (0, ts_poet_1.code) `
|
|
2333
|
+
toJSON(message: ${fullName}): string {
|
|
2334
|
+
return ${utils.timestampToJson}(${seconds}, message.nanos ?? 0);
|
|
2335
|
+
}
|
|
2336
|
+
`;
|
|
2337
|
+
}
|
|
2272
2338
|
return undefined;
|
|
2273
2339
|
}
|
|
2274
2340
|
/** Whether `google.protobuf.Any` gets its canonical `@type` JSON form, see the `anyType` option. */
|
|
@@ -2348,7 +2414,7 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
2348
2414
|
chunks.push(generateCanonicalAnyToJson(ctx, fullName, messageDesc));
|
|
2349
2415
|
return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
|
|
2350
2416
|
}
|
|
2351
|
-
const canonicalToJson = generateCanonicalToJson(fullName, fullProtobufTypeName, options);
|
|
2417
|
+
const canonicalToJson = generateCanonicalToJson(fullName, fullProtobufTypeName, options, utils);
|
|
2352
2418
|
if (canonicalToJson) {
|
|
2353
2419
|
chunks.push(canonicalToJson);
|
|
2354
2420
|
return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
|