ts-proto 2.18.1 → 2.18.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.
- package/README.markdown +1 -1
- package/build/src/generate-grpc-web.js +121 -0
- package/build/src/types.js +6 -0
- package/package.json +1 -1
package/README.markdown
CHANGED
|
@@ -548,7 +548,7 @@ With `--ts_proto_opt=protoJsonFormat=false`, strict proto3 compliance is disable
|
|
|
548
548
|
|
|
549
549
|
- With `--ts_proto_opt=useJsonWireFormat=true`, the generated code will reflect the JSON representation of Protobuf messages.
|
|
550
550
|
|
|
551
|
-
Requires `onlyTypes=true`. Implies `useDate=string` and `stringEnums=true
|
|
551
|
+
Requires `onlyTypes=true`. Implies `useDate=string` and `stringEnums=true`, and types `bytes` fields as base64-encoded `string`s. This option is to generate types that can be directly used with marshalling/unmarshalling Protobuf messages serialized as JSON.
|
|
552
552
|
You may also want to set `useOptionals=all`, as gRPC gateways are not required to send default value for scalar values.
|
|
553
553
|
|
|
554
554
|
- With `--ts_proto_opt=useNumericEnumForJson=true`, the JSON converter (`toJSON`) will encode enum values as int, rather than a string literal.
|
|
@@ -300,6 +300,9 @@ function createObservableUnaryMethod(ctx) {
|
|
|
300
300
|
function createInvokeMethod(ctx) {
|
|
301
301
|
const { options } = ctx;
|
|
302
302
|
const { useAbortSignal } = options;
|
|
303
|
+
if (options.useAsyncIterable) {
|
|
304
|
+
return createAsyncIterableInvokeMethod(ctx);
|
|
305
|
+
}
|
|
303
306
|
return (0, ts_poet_1.code) `
|
|
304
307
|
invoke<T extends UnaryMethodDefinitionish>(
|
|
305
308
|
methodDesc: T,
|
|
@@ -363,3 +366,121 @@ function createInvokeMethod(ctx) {
|
|
|
363
366
|
}
|
|
364
367
|
`;
|
|
365
368
|
}
|
|
369
|
+
/** Creates the streaming `invoke` method for `useAsyncIterable=true`, which returns an async generator. */
|
|
370
|
+
function createAsyncIterableInvokeMethod(ctx) {
|
|
371
|
+
const { useAbortSignal } = ctx.options;
|
|
372
|
+
return (0, ts_poet_1.code) `
|
|
373
|
+
invoke<T extends UnaryMethodDefinitionish>(
|
|
374
|
+
methodDesc: T,
|
|
375
|
+
_request: any,
|
|
376
|
+
metadata: grpc.Metadata | undefined,
|
|
377
|
+
${useAbortSignal ? "abortSignal?: AbortSignal," : ""}
|
|
378
|
+
): AsyncIterable<any> {
|
|
379
|
+
const upStreamCodes = this.options.upStreamRetryCodes ?? [];
|
|
380
|
+
const DEFAULT_TIMEOUT_TIME: number = 3_000;
|
|
381
|
+
const request = { ..._request, ...methodDesc.requestType };
|
|
382
|
+
const transport = this.options.streamingTransport ?? this.options.transport;
|
|
383
|
+
const maybeCombinedMetadata = metadata && this.options.metadata
|
|
384
|
+
? new ${BrowserHeaders}({ ...this.options?.metadata.headersMap, ...metadata?.headersMap })
|
|
385
|
+
: metadata ?? this.options.metadata;
|
|
386
|
+
const host = this.host;
|
|
387
|
+
const debug = this.options.debug ?? false;
|
|
388
|
+
return (async function* () {
|
|
389
|
+
${useAbortSignal
|
|
390
|
+
? `
|
|
391
|
+
// A listener added after the abort would never run.
|
|
392
|
+
if (abortSignal?.aborted) {
|
|
393
|
+
throw abortSignal.reason;
|
|
394
|
+
}
|
|
395
|
+
`
|
|
396
|
+
: ""}
|
|
397
|
+
const queue: any[] = [];
|
|
398
|
+
let done = false;
|
|
399
|
+
let error: unknown = undefined;
|
|
400
|
+
${useAbortSignal ? "let aborted = false;" : ""}
|
|
401
|
+
let wake: (() => void) | undefined;
|
|
402
|
+
const notify = () => {
|
|
403
|
+
const resolve = wake;
|
|
404
|
+
wake = undefined;
|
|
405
|
+
resolve?.();
|
|
406
|
+
};
|
|
407
|
+
let client: { close(): void } | undefined;
|
|
408
|
+
let retryTimer: ReturnType<typeof setTimeout> | undefined;
|
|
409
|
+
let closed = false;
|
|
410
|
+
// Stops the retry timer and closes the active call, at most once.
|
|
411
|
+
const close = () => {
|
|
412
|
+
closed = true;
|
|
413
|
+
clearTimeout(retryTimer);
|
|
414
|
+
retryTimer = undefined;
|
|
415
|
+
const active = client;
|
|
416
|
+
client = undefined;
|
|
417
|
+
active?.close();
|
|
418
|
+
};
|
|
419
|
+
const upStream = () => {
|
|
420
|
+
retryTimer = undefined;
|
|
421
|
+
if (closed) {
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
client = ${grpc}.invoke(methodDesc, {
|
|
425
|
+
host,
|
|
426
|
+
request,
|
|
427
|
+
...(transport !== undefined ? {transport} : {}),
|
|
428
|
+
metadata: maybeCombinedMetadata ?? {},
|
|
429
|
+
debug,
|
|
430
|
+
onMessage: (next) => {
|
|
431
|
+
queue.push(next);
|
|
432
|
+
notify();
|
|
433
|
+
},
|
|
434
|
+
onEnd: (code: ${grpc}.Code, message: string, trailers: ${grpc}.Metadata) => {
|
|
435
|
+
if (code === 0) {
|
|
436
|
+
done = true;
|
|
437
|
+
} else if (upStreamCodes.includes(code)) {
|
|
438
|
+
retryTimer = setTimeout(upStream, DEFAULT_TIMEOUT_TIME);
|
|
439
|
+
return;
|
|
440
|
+
} else {
|
|
441
|
+
const err = new Error(message) as any;
|
|
442
|
+
err.code = code;
|
|
443
|
+
err.metadata = trailers;
|
|
444
|
+
error = err;
|
|
445
|
+
done = true;
|
|
446
|
+
}
|
|
447
|
+
notify();
|
|
448
|
+
},
|
|
449
|
+
});
|
|
450
|
+
};
|
|
451
|
+
${useAbortSignal
|
|
452
|
+
? `
|
|
453
|
+
const abort = () => {
|
|
454
|
+
aborted = true;
|
|
455
|
+
error = abortSignal!.reason;
|
|
456
|
+
done = true;
|
|
457
|
+
close();
|
|
458
|
+
notify();
|
|
459
|
+
};
|
|
460
|
+
abortSignal?.addEventListener("abort", abort);
|
|
461
|
+
`
|
|
462
|
+
: ""}
|
|
463
|
+
upStream();
|
|
464
|
+
try {
|
|
465
|
+
while (true) {
|
|
466
|
+
if (${useAbortSignal ? "!aborted && " : ""}queue.length > 0) {
|
|
467
|
+
yield queue.shift();
|
|
468
|
+
} else if (done) {
|
|
469
|
+
break;
|
|
470
|
+
} else {
|
|
471
|
+
await new Promise<void>((resolve) => {
|
|
472
|
+
wake = resolve;
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
if (error !== undefined) {
|
|
477
|
+
throw error;
|
|
478
|
+
}
|
|
479
|
+
} finally {
|
|
480
|
+
${useAbortSignal ? `abortSignal?.removeEventListener("abort", abort);` : ""}
|
|
481
|
+
close();
|
|
482
|
+
}
|
|
483
|
+
})();
|
|
484
|
+
}
|
|
485
|
+
`;
|
|
486
|
+
}
|
package/build/src/types.js
CHANGED
|
@@ -138,6 +138,9 @@ function basicTypeName(ctx, field, typeOptions = {}) {
|
|
|
138
138
|
if (options.env === options_1.EnvOption.NODE) {
|
|
139
139
|
return (0, ts_poet_1.code) `Buffer`;
|
|
140
140
|
}
|
|
141
|
+
else if (options.useJsonWireFormat) {
|
|
142
|
+
return (0, ts_poet_1.code) `string`;
|
|
143
|
+
}
|
|
141
144
|
else {
|
|
142
145
|
return (0, ts_poet_1.code) `Uint8Array`;
|
|
143
146
|
}
|
|
@@ -303,6 +306,9 @@ function defaultValue(ctx, field) {
|
|
|
303
306
|
if (options.env === options_1.EnvOption.NODE) {
|
|
304
307
|
return "Buffer.alloc(0)";
|
|
305
308
|
}
|
|
309
|
+
if (options.useJsonWireFormat) {
|
|
310
|
+
return '""';
|
|
311
|
+
}
|
|
306
312
|
return "new Uint8Array(0)";
|
|
307
313
|
case ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_MESSAGE:
|
|
308
314
|
case ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_GROUP:
|