@trpc-proto/runtime 0.1.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.
- package/LICENSE +21 -0
- package/README.md +19 -0
- package/dist/batch/grpcweb/direct_dispatcher.d.ts +10 -0
- package/dist/batch/grpcweb/direct_dispatcher.d.ts.map +1 -0
- package/dist/batch/grpcweb/direct_dispatcher.js +71 -0
- package/dist/batch/grpcweb/direct_dispatcher.js.map +1 -0
- package/dist/batch/grpcweb/forwarding_dispatcher.d.ts +5 -0
- package/dist/batch/grpcweb/forwarding_dispatcher.d.ts.map +1 -0
- package/dist/batch/grpcweb/forwarding_dispatcher.js +62 -0
- package/dist/batch/grpcweb/forwarding_dispatcher.js.map +1 -0
- package/dist/batch/index.d.ts +5 -0
- package/dist/batch/index.d.ts.map +1 -0
- package/dist/batch/index.js +4 -0
- package/dist/batch/index.js.map +1 -0
- package/dist/batch/link/web_link.d.ts +18 -0
- package/dist/batch/link/web_link.d.ts.map +1 -0
- package/dist/batch/link/web_link.js +216 -0
- package/dist/batch/link/web_link.js.map +1 -0
- package/dist/batch/proto/batch_router.d.ts +41 -0
- package/dist/batch/proto/batch_router.d.ts.map +1 -0
- package/dist/batch/proto/batch_router.js +59 -0
- package/dist/batch/proto/batch_router.js.map +1 -0
- package/dist/batch/proto/generated/schema.d.ts +262 -0
- package/dist/batch/proto/generated/schema.d.ts.map +1 -0
- package/dist/batch/proto/generated/schema.js +327 -0
- package/dist/batch/proto/generated/schema.js.map +1 -0
- package/dist/batch/proto/wire.d.ts +42 -0
- package/dist/batch/proto/wire.d.ts.map +1 -0
- package/dist/batch/proto/wire.js +52 -0
- package/dist/batch/proto/wire.js.map +1 -0
- package/dist/grpc/client.d.ts +10 -0
- package/dist/grpc/client.d.ts.map +1 -0
- package/dist/grpc/client.js +62 -0
- package/dist/grpc/client.js.map +1 -0
- package/dist/grpc/link.d.ts +11 -0
- package/dist/grpc/link.d.ts.map +1 -0
- package/dist/grpc/link.js +10 -0
- package/dist/grpc/link.js.map +1 -0
- package/dist/grpc/proto_link.d.ts +56 -0
- package/dist/grpc/proto_link.d.ts.map +1 -0
- package/dist/grpc/proto_link.js +112 -0
- package/dist/grpc/proto_link.js.map +1 -0
- package/dist/grpc/server.d.ts +28 -0
- package/dist/grpc/server.d.ts.map +1 -0
- package/dist/grpc/server.js +113 -0
- package/dist/grpc/server.js.map +1 -0
- package/dist/grpc/status.d.ts +5 -0
- package/dist/grpc/status.d.ts.map +1 -0
- package/dist/grpc/status.js +42 -0
- package/dist/grpc/status.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/noop.d.ts +10 -0
- package/dist/noop.d.ts.map +1 -0
- package/dist/noop.js +12 -0
- package/dist/noop.js.map +1 -0
- package/dist/proto_codec/index.d.ts +3 -0
- package/dist/proto_codec/index.d.ts.map +1 -0
- package/dist/proto_codec/index.js +2 -0
- package/dist/proto_codec/index.js.map +1 -0
- package/dist/proto_codec/proto_codec.d.ts +24 -0
- package/dist/proto_codec/proto_codec.d.ts.map +1 -0
- package/dist/proto_codec/proto_codec.js +327 -0
- package/dist/proto_codec/proto_codec.js.map +1 -0
- package/dist/router_invoker.d.ts +12 -0
- package/dist/router_invoker.d.ts.map +1 -0
- package/dist/router_invoker.js +79 -0
- package/dist/router_invoker.js.map +1 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/web/codec/base64_codec.d.ts +7 -0
- package/dist/web/codec/base64_codec.d.ts.map +1 -0
- package/dist/web/codec/base64_codec.js +57 -0
- package/dist/web/codec/base64_codec.js.map +1 -0
- package/dist/web/codec/codec.d.ts +33 -0
- package/dist/web/codec/codec.d.ts.map +1 -0
- package/dist/web/codec/codec.js +11 -0
- package/dist/web/codec/codec.js.map +1 -0
- package/dist/web/codec/compression.d.ts +15 -0
- package/dist/web/codec/compression.d.ts.map +1 -0
- package/dist/web/codec/compression.js +32 -0
- package/dist/web/codec/compression.js.map +1 -0
- package/dist/web/codec/frame_codec.d.ts +20 -0
- package/dist/web/codec/frame_codec.d.ts.map +1 -0
- package/dist/web/codec/frame_codec.js +109 -0
- package/dist/web/codec/frame_codec.js.map +1 -0
- package/dist/web/codec/protocol_codec.d.ts +40 -0
- package/dist/web/codec/protocol_codec.d.ts.map +1 -0
- package/dist/web/codec/protocol_codec.js +162 -0
- package/dist/web/codec/protocol_codec.js.map +1 -0
- package/dist/web/content_type.d.ts +19 -0
- package/dist/web/content_type.d.ts.map +1 -0
- package/dist/web/content_type.js +42 -0
- package/dist/web/content_type.js.map +1 -0
- package/dist/web/dispatchers/direct.d.ts +10 -0
- package/dist/web/dispatchers/direct.d.ts.map +1 -0
- package/dist/web/dispatchers/direct.js +72 -0
- package/dist/web/dispatchers/direct.js.map +1 -0
- package/dist/web/dispatchers/forward.d.ts +5 -0
- package/dist/web/dispatchers/forward.d.ts.map +1 -0
- package/dist/web/dispatchers/forward.js +99 -0
- package/dist/web/dispatchers/forward.js.map +1 -0
- package/dist/web/dispatchers/types.d.ts +21 -0
- package/dist/web/dispatchers/types.d.ts.map +1 -0
- package/dist/web/dispatchers/types.js +2 -0
- package/dist/web/dispatchers/types.js.map +1 -0
- package/dist/web/fetch_call.d.ts +13 -0
- package/dist/web/fetch_call.d.ts.map +1 -0
- package/dist/web/fetch_call.js +126 -0
- package/dist/web/fetch_call.js.map +1 -0
- package/dist/web/http_handler.d.ts +65 -0
- package/dist/web/http_handler.d.ts.map +1 -0
- package/dist/web/http_handler.js +295 -0
- package/dist/web/http_handler.js.map +1 -0
- package/dist/web/index.d.ts +8 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +4 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/link.d.ts +26 -0
- package/dist/web/link.d.ts.map +1 -0
- package/dist/web/link.js +24 -0
- package/dist/web/link.js.map +1 -0
- package/dist/web/server.d.ts +33 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +77 -0
- package/dist/web/server.js.map +1 -0
- package/package.json +90 -0
- package/src/batch/proto/generated/trpc_batch_v1.proto +40 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { isAsyncIterable } from '@trpc-proto/utility';
|
|
2
|
+
/** Iterates uniformly over one encoded chunk or an asynchronous chunk stream. */
|
|
3
|
+
export async function* codecChunks(encoded) {
|
|
4
|
+
if (isAsyncIterable(encoded)) {
|
|
5
|
+
yield* encoded;
|
|
6
|
+
}
|
|
7
|
+
else {
|
|
8
|
+
yield encoded;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../../src/web/codec/codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAqCtD,iFAAiF;AACjF,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,WAAW,CAChC,OAA0B;IAE1B,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,CAAC,OAAO,CAAC;IACjB,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,CAAC;IAChB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Codec, type CodecInput } from './codec.js';
|
|
2
|
+
/** Standard gzip grpc-encoding token. */
|
|
3
|
+
export declare const GRPC_GZIP_ENCODING = "gzip";
|
|
4
|
+
/** Message compressor selected by a grpc-encoding token. */
|
|
5
|
+
export interface GrpcWebCompressionCodec extends Codec<Uint8Array, Uint8Array> {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class GzipCompressionCodec implements GrpcWebCompressionCodec {
|
|
9
|
+
readonly name = "gzip";
|
|
10
|
+
encode(message: Uint8Array): Promise<Uint8Array>;
|
|
11
|
+
decode(encoded: CodecInput<Uint8Array>): AsyncIterable<Uint8Array>;
|
|
12
|
+
}
|
|
13
|
+
/** Finds a supported codec for a grpc-encoding header value. */
|
|
14
|
+
export declare function grpcWebCompressionCodec(encoding: string | null | undefined): GrpcWebCompressionCodec | undefined;
|
|
15
|
+
//# sourceMappingURL=compression.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compression.d.ts","sourceRoot":"","sources":["../../../src/web/codec/compression.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtE,yCAAyC;AACzC,eAAO,MAAM,kBAAkB,SAAS,CAAC;AAEzC,4DAA4D;AAC5D,MAAM,WAAW,uBAAwB,SAAQ,KAAK,CAAC,UAAU,EAAE,UAAU,CAAC;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAaD,qBAAa,oBAAqB,YAAW,uBAAuB;IAClE,QAAQ,CAAC,IAAI,UAAsB;IAEnC,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAIzC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC;CAQ1E;AASD,gEAAgE;AAChE,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAClC,uBAAuB,GAAG,SAAS,CAIrC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { codecChunks } from './codec.js';
|
|
2
|
+
/** Standard gzip grpc-encoding token. */
|
|
3
|
+
export const GRPC_GZIP_ENCODING = 'gzip';
|
|
4
|
+
async function transform(message, stream) {
|
|
5
|
+
const writer = stream.writable.getWriter();
|
|
6
|
+
const output = new Response(stream.readable).arrayBuffer();
|
|
7
|
+
const writing = writer.write(message).then(() => writer.close());
|
|
8
|
+
const [buffer] = await Promise.all([output, writing]);
|
|
9
|
+
return new Uint8Array(buffer);
|
|
10
|
+
}
|
|
11
|
+
export class GzipCompressionCodec {
|
|
12
|
+
name = GRPC_GZIP_ENCODING;
|
|
13
|
+
encode(message) {
|
|
14
|
+
return transform(message, new CompressionStream(GRPC_GZIP_ENCODING));
|
|
15
|
+
}
|
|
16
|
+
async *decode(encoded) {
|
|
17
|
+
for await (const message of codecChunks(encoded)) {
|
|
18
|
+
yield await transform(message, new DecompressionStream(GRPC_GZIP_ENCODING));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const COMPRESSION_CODEC_FACTORIES = {
|
|
23
|
+
[GRPC_GZIP_ENCODING]: () => new GzipCompressionCodec(),
|
|
24
|
+
};
|
|
25
|
+
/** Finds a supported codec for a grpc-encoding header value. */
|
|
26
|
+
export function grpcWebCompressionCodec(encoding) {
|
|
27
|
+
const name = encoding?.trim().toLowerCase();
|
|
28
|
+
if (!name || name === 'identity')
|
|
29
|
+
return undefined;
|
|
30
|
+
return COMPRESSION_CODEC_FACTORIES[name]?.();
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=compression.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compression.js","sourceRoot":"","sources":["../../../src/web/codec/compression.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAA+B,MAAM,YAAY,CAAC;AAEtE,yCAAyC;AACzC,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAOzC,KAAK,UAAU,SAAS,CACtB,OAAmB,EACnB,MAA+C;IAE/C,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACjE,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACtD,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,OAAO,oBAAoB;IACtB,IAAI,GAAG,kBAAkB,CAAC;IAEnC,MAAM,CAAC,OAAmB;QACxB,OAAO,SAAS,CAAC,OAAO,EAAE,IAAI,iBAAiB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CAAC,OAA+B;QAC3C,IAAI,KAAK,EAAE,MAAM,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YACjD,MAAM,MAAM,SAAS,CACnB,OAAO,EACP,IAAI,mBAAmB,CAAC,kBAAkB,CAAC,CAC5C,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AAED,MAAM,2BAA2B,GAG7B;IACF,CAAC,kBAAkB,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,oBAAoB,EAAE;CACvD,CAAC;AAEF,gEAAgE;AAChE,MAAM,UAAU,uBAAuB,CACrC,QAAmC;IAEnC,MAAM,IAAI,GAAG,QAAQ,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,UAAU;QAAE,OAAO,SAAS,CAAC;IACnD,OAAO,2BAA2B,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Codec, type CodecInput } from './codec.js';
|
|
2
|
+
/** One protobuf data frame. */
|
|
3
|
+
export interface GrpcWebMessageFrame {
|
|
4
|
+
kind: 'message';
|
|
5
|
+
compressed: boolean;
|
|
6
|
+
payload: Uint8Array;
|
|
7
|
+
}
|
|
8
|
+
/** One uncompressed in-body trailer frame. */
|
|
9
|
+
export interface GrpcWebTrailerFrame {
|
|
10
|
+
kind: 'trailers';
|
|
11
|
+
trailers: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
/** Complete frame emitted by the incremental binary decoder. */
|
|
14
|
+
export type GrpcWebFrame = GrpcWebMessageFrame | GrpcWebTrailerFrame;
|
|
15
|
+
/** Binary gRPC-Web frame codec. */
|
|
16
|
+
export declare class GrpcWebFrameCodec implements Codec<GrpcWebFrame, Uint8Array> {
|
|
17
|
+
encode(frame: GrpcWebFrame): Uint8Array;
|
|
18
|
+
decode(encoded: CodecInput<Uint8Array>): AsyncIterable<GrpcWebFrame>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=frame_codec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame_codec.d.ts","sourceRoot":"","sources":["../../../src/web/codec/frame_codec.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,KAAK,EACV,KAAK,UAAU,EAEhB,MAAM,YAAY,CAAC;AAMpB,+BAA+B;AAC/B,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,UAAU,CAAC;CACrB;AAED,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,gEAAgE;AAChE,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AA+FrE,mCAAmC;AACnC,qBAAa,iBAAkB,YAAW,KAAK,CAAC,YAAY,EAAE,UAAU,CAAC;IACvE,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU;IAsBhC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,YAAY,CAAC;CAO5E"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { assumeExhaustive, concat } from '@trpc-proto/utility';
|
|
2
|
+
import { codecChunks, } from './codec.js';
|
|
3
|
+
const TRAILER_FLAG = 0x80;
|
|
4
|
+
const COMPRESSED_FLAG = 0x01;
|
|
5
|
+
const NO_FRAMES = [];
|
|
6
|
+
function writeLength(out, length) {
|
|
7
|
+
out[1] = (length >>> 24) & 0xff;
|
|
8
|
+
out[2] = (length >>> 16) & 0xff;
|
|
9
|
+
out[3] = (length >>> 8) & 0xff;
|
|
10
|
+
out[4] = length & 0xff;
|
|
11
|
+
}
|
|
12
|
+
function byte(buf, offset) {
|
|
13
|
+
const value = buf[offset];
|
|
14
|
+
if (value === undefined)
|
|
15
|
+
throw new Error('truncated gRPC-Web frame');
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
function readLength(buf, offset) {
|
|
19
|
+
return (((byte(buf, offset) << 24) |
|
|
20
|
+
(byte(buf, offset + 1) << 16) |
|
|
21
|
+
(byte(buf, offset + 2) << 8) |
|
|
22
|
+
byte(buf, offset + 3)) >>>
|
|
23
|
+
0);
|
|
24
|
+
}
|
|
25
|
+
function encodeRawFrame(payload, flags) {
|
|
26
|
+
const out = new Uint8Array(5 + payload.length);
|
|
27
|
+
out[0] = flags;
|
|
28
|
+
writeLength(out, payload.length);
|
|
29
|
+
out.set(payload, 5);
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
function decodeTrailers(payload) {
|
|
33
|
+
const trailers = {};
|
|
34
|
+
const text = new TextDecoder().decode(payload);
|
|
35
|
+
for (const line of text.split('\r\n')) {
|
|
36
|
+
if (!line)
|
|
37
|
+
continue;
|
|
38
|
+
const colon = line.indexOf(':');
|
|
39
|
+
if (colon <= 0)
|
|
40
|
+
continue;
|
|
41
|
+
trailers[line.slice(0, colon).trim().toLowerCase()] = line
|
|
42
|
+
.slice(colon + 1)
|
|
43
|
+
.trim();
|
|
44
|
+
}
|
|
45
|
+
return trailers;
|
|
46
|
+
}
|
|
47
|
+
function encodeGrpcMessage(value) {
|
|
48
|
+
return [...new TextEncoder().encode(value)]
|
|
49
|
+
.map((byteValue) => byteValue === 0x25 || byteValue < 0x20 || byteValue > 0x7e
|
|
50
|
+
? `%${byteValue.toString(16).toUpperCase().padStart(2, '0')}`
|
|
51
|
+
: String.fromCharCode(byteValue))
|
|
52
|
+
.join('');
|
|
53
|
+
}
|
|
54
|
+
class FrameDecoder {
|
|
55
|
+
#buffer = new Uint8Array();
|
|
56
|
+
push(chunk) {
|
|
57
|
+
if (chunk.byteLength > 0)
|
|
58
|
+
this.#buffer = concat([this.#buffer, chunk]);
|
|
59
|
+
const frames = [];
|
|
60
|
+
while (this.#buffer.length >= 5) {
|
|
61
|
+
const flags = byte(this.#buffer, 0);
|
|
62
|
+
const length = readLength(this.#buffer, 1);
|
|
63
|
+
if (this.#buffer.length < 5 + length)
|
|
64
|
+
break;
|
|
65
|
+
const payload = this.#buffer.subarray(5, 5 + length);
|
|
66
|
+
this.#buffer = this.#buffer.subarray(5 + length);
|
|
67
|
+
const trailer = Boolean(flags & TRAILER_FLAG);
|
|
68
|
+
const compressed = Boolean(flags & COMPRESSED_FLAG);
|
|
69
|
+
if (trailer && compressed) {
|
|
70
|
+
throw new Error('compressed gRPC-Web trailers are not supported');
|
|
71
|
+
}
|
|
72
|
+
frames.push(trailer
|
|
73
|
+
? { kind: 'trailers', trailers: decodeTrailers(payload) }
|
|
74
|
+
: { kind: 'message', compressed, payload });
|
|
75
|
+
}
|
|
76
|
+
return frames;
|
|
77
|
+
}
|
|
78
|
+
finish() {
|
|
79
|
+
if (this.#buffer.length > 0) {
|
|
80
|
+
throw new Error(this.#buffer.length < 5
|
|
81
|
+
? 'truncated gRPC-Web frame header'
|
|
82
|
+
: 'truncated gRPC-Web frame');
|
|
83
|
+
}
|
|
84
|
+
return NO_FRAMES;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** Binary gRPC-Web frame codec. */
|
|
88
|
+
export class GrpcWebFrameCodec {
|
|
89
|
+
encode(frame) {
|
|
90
|
+
switch (frame.kind) {
|
|
91
|
+
case 'message':
|
|
92
|
+
return encodeRawFrame(frame.payload, frame.compressed ? COMPRESSED_FLAG : 0);
|
|
93
|
+
case 'trailers': {
|
|
94
|
+
const lines = Object.entries(frame.trailers).map(([name, value]) => `${name.toLowerCase()}: ${encodeGrpcMessage(value)}`);
|
|
95
|
+
return encodeRawFrame(new TextEncoder().encode(`${lines.join('\r\n')}\r\n`), TRAILER_FLAG);
|
|
96
|
+
}
|
|
97
|
+
default:
|
|
98
|
+
return assumeExhaustive(frame);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async *decode(encoded) {
|
|
102
|
+
const decoder = new FrameDecoder();
|
|
103
|
+
for await (const chunk of codecChunks(encoded)) {
|
|
104
|
+
yield* decoder.push(chunk);
|
|
105
|
+
}
|
|
106
|
+
yield* decoder.finish();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=frame_codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame_codec.js","sourceRoot":"","sources":["../../../src/web/codec/frame_codec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { GrpcWebEncoding } from '../content_type.js';
|
|
2
|
+
import { type Codec, type CodecInput } from './codec.js';
|
|
3
|
+
/**
|
|
4
|
+
* gRPC-Web HTTP headers used to communicate the final status of a call.
|
|
5
|
+
*/
|
|
6
|
+
export declare const GRPC_STATUS_HEADER = "grpc-status";
|
|
7
|
+
/** gRPC-Web HTTP headers used to communicate the final status message of a call. */
|
|
8
|
+
export declare const GRPC_MESSAGE_HEADER = "grpc-message";
|
|
9
|
+
/** One protobuf message independent of its gRPC-Web wire representation. */
|
|
10
|
+
export interface GrpcWebProtocolMessage {
|
|
11
|
+
readonly kind: 'message';
|
|
12
|
+
readonly payload: Uint8Array;
|
|
13
|
+
}
|
|
14
|
+
/** Final gRPC status and metadata independent of its trailer frame. */
|
|
15
|
+
export interface GrpcWebProtocolTrailers {
|
|
16
|
+
readonly kind: 'trailers';
|
|
17
|
+
readonly status: number;
|
|
18
|
+
readonly message: string;
|
|
19
|
+
readonly metadata?: Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
/** Semantic value encoded in a gRPC-Web HTTP body. */
|
|
22
|
+
export type GrpcWebProtocolValue = GrpcWebProtocolMessage | GrpcWebProtocolTrailers;
|
|
23
|
+
/** Wire choices applied by the protocol codec. */
|
|
24
|
+
export interface GrpcWebProtocolCodecOptions {
|
|
25
|
+
readonly encoding: GrpcWebEncoding;
|
|
26
|
+
readonly compress?: boolean;
|
|
27
|
+
readonly compression?: string | null;
|
|
28
|
+
}
|
|
29
|
+
/** Error represented by a non-zero or malformed gRPC-Web status. */
|
|
30
|
+
export declare class GrpcWebError extends Error {
|
|
31
|
+
readonly code: number;
|
|
32
|
+
constructor(code: number, message: string);
|
|
33
|
+
}
|
|
34
|
+
/** Composes frames, compression, and body encoding through Codec only. */
|
|
35
|
+
export declare class GrpcWebProtocolCodec implements Codec<GrpcWebProtocolValue, Uint8Array, GrpcWebProtocolCodecOptions> {
|
|
36
|
+
#private;
|
|
37
|
+
encode(value: GrpcWebProtocolValue, options?: GrpcWebProtocolCodecOptions): Promise<Uint8Array>;
|
|
38
|
+
decode(encoded: CodecInput<Uint8Array>, options?: GrpcWebProtocolCodecOptions): AsyncIterable<GrpcWebProtocolValue>;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=protocol_codec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol_codec.d.ts","sourceRoot":"","sources":["../../../src/web/codec/protocol_codec.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAe,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAKtE;;GAEG;AACH,eAAO,MAAM,kBAAkB,gBAAgB,CAAC;AAChD,oFAAoF;AACpF,eAAO,MAAM,mBAAmB,iBAAiB,CAAC;AAElD,4EAA4E;AAC5E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;CAC9B;AAED,uEAAuE;AACvE,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED,sDAAsD;AACtD,MAAM,MAAM,oBAAoB,GAC9B,sBAAsB,GAAG,uBAAuB,CAAC;AAEnD,kDAAkD;AAClD,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,oEAAoE;AACpE,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK1C;AAkFD,0EAA0E;AAC1E,qBAAa,oBAAqB,YAAW,KAAK,CAChD,oBAAoB,EACpB,UAAU,EACV,2BAA2B,CAC5B;;IAIO,MAAM,CACV,KAAK,EAAE,oBAAoB,EAC3B,OAAO,GAAE,2BAAoD,GAC5D,OAAO,CAAC,UAAU,CAAC;IAuCf,MAAM,CACX,OAAO,EAAE,UAAU,CAAC,UAAU,CAAC,EAC/B,OAAO,GAAE,2BAAoD,GAC5D,aAAa,CAAC,oBAAoB,CAAC;CA8CvC"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { Status as grpcStatus } from '@grpc/grpc-js/build/src/constants.js';
|
|
2
|
+
import { assumeExhaustive } from '@trpc-proto/utility';
|
|
3
|
+
import { codecChunks } from './codec.js';
|
|
4
|
+
import { GRPC_GZIP_ENCODING, grpcWebCompressionCodec } from './compression.js';
|
|
5
|
+
import { GrpcWebFrameCodec } from './frame_codec.js';
|
|
6
|
+
import { GrpcWebBase64Codec } from './base64_codec.js';
|
|
7
|
+
/**
|
|
8
|
+
* gRPC-Web HTTP headers used to communicate the final status of a call.
|
|
9
|
+
*/
|
|
10
|
+
export const GRPC_STATUS_HEADER = 'grpc-status';
|
|
11
|
+
/** gRPC-Web HTTP headers used to communicate the final status message of a call. */
|
|
12
|
+
export const GRPC_MESSAGE_HEADER = 'grpc-message';
|
|
13
|
+
/** Error represented by a non-zero or malformed gRPC-Web status. */
|
|
14
|
+
export class GrpcWebError extends Error {
|
|
15
|
+
code;
|
|
16
|
+
constructor(code, message) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = 'GrpcWebError';
|
|
19
|
+
this.code = code;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function parseGrpcStatus(encoded) {
|
|
23
|
+
if (encoded === undefined) {
|
|
24
|
+
throw new GrpcWebError(grpcStatus.UNKNOWN, 'missing grpc-status trailer');
|
|
25
|
+
}
|
|
26
|
+
if (!/^[0-9]+$/u.test(encoded)) {
|
|
27
|
+
throw new GrpcWebError(grpcStatus.UNKNOWN, `invalid grpc-status trailer: ${JSON.stringify(encoded)}`);
|
|
28
|
+
}
|
|
29
|
+
const status = Number(encoded);
|
|
30
|
+
if (!Number.isSafeInteger(status) ||
|
|
31
|
+
status < grpcStatus.OK ||
|
|
32
|
+
status > grpcStatus.UNAUTHENTICATED) {
|
|
33
|
+
throw new GrpcWebError(grpcStatus.UNKNOWN, `invalid grpc-status trailer: ${JSON.stringify(encoded)}`);
|
|
34
|
+
}
|
|
35
|
+
return status;
|
|
36
|
+
}
|
|
37
|
+
function decodeGrpcMessage(encoded) {
|
|
38
|
+
try {
|
|
39
|
+
return decodeURIComponent(encoded);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
throw new GrpcWebError(grpcStatus.UNKNOWN, `invalid grpc-message trailer: ${JSON.stringify(encoded)}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function trailerFrame(value) {
|
|
46
|
+
const trailers = {
|
|
47
|
+
[GRPC_STATUS_HEADER]: String(value.status),
|
|
48
|
+
[GRPC_MESSAGE_HEADER]: value.message,
|
|
49
|
+
};
|
|
50
|
+
for (const [key, metadataValue] of Object.entries(value.metadata ?? {})) {
|
|
51
|
+
const name = key.toLowerCase();
|
|
52
|
+
if (name === GRPC_STATUS_HEADER || name === GRPC_MESSAGE_HEADER)
|
|
53
|
+
continue;
|
|
54
|
+
trailers[name] = metadataValue;
|
|
55
|
+
}
|
|
56
|
+
return { kind: 'trailers', trailers };
|
|
57
|
+
}
|
|
58
|
+
async function* base64Chunks(encoded) {
|
|
59
|
+
const decoder = new TextDecoder();
|
|
60
|
+
for await (const chunk of codecChunks(encoded)) {
|
|
61
|
+
const text = decoder.decode(chunk, { stream: true });
|
|
62
|
+
if (text)
|
|
63
|
+
yield text;
|
|
64
|
+
}
|
|
65
|
+
const finalText = decoder.decode();
|
|
66
|
+
if (finalText)
|
|
67
|
+
yield finalText;
|
|
68
|
+
}
|
|
69
|
+
async function decodeCompressedMessage(payload, encoding) {
|
|
70
|
+
const compression = grpcWebCompressionCodec(encoding);
|
|
71
|
+
if (!compression) {
|
|
72
|
+
throw new Error(`unsupported grpc-encoding for compressed message: ${encoding ?? 'identity'}`);
|
|
73
|
+
}
|
|
74
|
+
let decoded;
|
|
75
|
+
for await (const value of compression.decode(payload)) {
|
|
76
|
+
if (decoded)
|
|
77
|
+
throw new Error('compression codec returned multiple messages');
|
|
78
|
+
decoded = value;
|
|
79
|
+
}
|
|
80
|
+
if (!decoded)
|
|
81
|
+
throw new Error('compression codec returned no message');
|
|
82
|
+
return decoded;
|
|
83
|
+
}
|
|
84
|
+
/** Composes frames, compression, and body encoding through Codec only. */
|
|
85
|
+
export class GrpcWebProtocolCodec {
|
|
86
|
+
#frameCodec = new GrpcWebFrameCodec();
|
|
87
|
+
#base64Codec = new GrpcWebBase64Codec();
|
|
88
|
+
async encode(value, options = { encoding: 'base64' }) {
|
|
89
|
+
let frame;
|
|
90
|
+
switch (value.kind) {
|
|
91
|
+
case 'message':
|
|
92
|
+
if (options.compress) {
|
|
93
|
+
const encoding = options.compression ?? GRPC_GZIP_ENCODING;
|
|
94
|
+
const compression = grpcWebCompressionCodec(encoding);
|
|
95
|
+
if (!compression) {
|
|
96
|
+
throw new GrpcWebError(12, `unsupported grpc-encoding: ${encoding}`);
|
|
97
|
+
}
|
|
98
|
+
frame = {
|
|
99
|
+
kind: 'message',
|
|
100
|
+
compressed: true,
|
|
101
|
+
payload: await compression.encode(value.payload),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
frame = {
|
|
106
|
+
kind: 'message',
|
|
107
|
+
compressed: false,
|
|
108
|
+
payload: value.payload,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
break;
|
|
112
|
+
case 'trailers':
|
|
113
|
+
frame = trailerFrame(value);
|
|
114
|
+
break;
|
|
115
|
+
default:
|
|
116
|
+
return assumeExhaustive(value);
|
|
117
|
+
}
|
|
118
|
+
const encodedFrame = await this.#frameCodec.encode(frame);
|
|
119
|
+
if (options.encoding === 'raw')
|
|
120
|
+
return encodedFrame;
|
|
121
|
+
const base64 = await this.#base64Codec.encode(encodedFrame);
|
|
122
|
+
return new TextEncoder().encode(base64);
|
|
123
|
+
}
|
|
124
|
+
async *decode(encoded, options = { encoding: 'base64' }) {
|
|
125
|
+
const body = options.encoding === 'base64'
|
|
126
|
+
? this.#base64Codec.decode(base64Chunks(encoded))
|
|
127
|
+
: codecChunks(encoded);
|
|
128
|
+
for await (const frame of this.#frameCodec.decode(body)) {
|
|
129
|
+
switch (frame.kind) {
|
|
130
|
+
case 'message':
|
|
131
|
+
if (!frame.compressed) {
|
|
132
|
+
yield { kind: 'message', payload: frame.payload };
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
yield {
|
|
137
|
+
kind: 'message',
|
|
138
|
+
payload: await decodeCompressedMessage(frame.payload, options.compression),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
143
|
+
throw new GrpcWebError(13, message);
|
|
144
|
+
}
|
|
145
|
+
break;
|
|
146
|
+
case 'trailers': {
|
|
147
|
+
const { [GRPC_STATUS_HEADER]: encodedStatus, [GRPC_MESSAGE_HEADER]: message = '', ...metadata } = frame.trailers;
|
|
148
|
+
yield {
|
|
149
|
+
kind: 'trailers',
|
|
150
|
+
status: parseGrpcStatus(encodedStatus),
|
|
151
|
+
message: decodeGrpcMessage(message),
|
|
152
|
+
metadata,
|
|
153
|
+
};
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
default:
|
|
157
|
+
assumeExhaustive(frame);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=protocol_codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol_codec.js","sourceRoot":"","sources":["../../../src/web/codec/protocol_codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAAE,WAAW,EAA+B,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAqB,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAChD,oFAAoF;AACpF,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAC;AA2BlD,oEAAoE;AACpE,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAAe;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,SAAS,eAAe,CAAC,OAA2B;IAClD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,YAAY,CAAC,UAAU,CAAC,OAAO,EAAE,6BAA6B,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,YAAY,CACpB,UAAU,CAAC,OAAO,EAClB,gCAAgC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAC1D,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,IACE,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC;QAC7B,MAAM,GAAG,UAAU,CAAC,EAAE;QACtB,MAAM,GAAG,UAAU,CAAC,eAAe,EACnC,CAAC;QACD,MAAM,IAAI,YAAY,CACpB,UAAU,CAAC,OAAO,EAClB,gCAAgC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAC1D,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAe;IACxC,IAAI,CAAC;QACH,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,YAAY,CACpB,UAAU,CAAC,OAAO,EAClB,iCAAiC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAC3D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,KAA8B;IAClD,MAAM,QAAQ,GAA2B;QACvC,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;QAC1C,CAAC,mBAAmB,CAAC,EAAE,KAAK,CAAC,OAAO;KACrC,CAAC;IACF,KAAK,MAAM,CAAC,GAAG,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAC/B,IAAI,IAAI,KAAK,kBAAkB,IAAI,IAAI,KAAK,mBAAmB;YAAE,SAAS;QAC1E,QAAQ,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;IACjC,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AACxC,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,YAAY,CAC1B,OAA+B;IAE/B,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,IAAI,IAAI;YAAE,MAAM,IAAI,CAAC;IACvB,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IACnC,IAAI,SAAS;QAAE,MAAM,SAAS,CAAC;AACjC,CAAC;AAED,KAAK,UAAU,uBAAuB,CACpC,OAAmB,EACnB,QAAmC;IAEnC,MAAM,WAAW,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACtD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,qDAAqD,QAAQ,IAAI,UAAU,EAAE,CAC9E,CAAC;IACJ,CAAC;IACD,IAAI,OAA+B,CAAC;IACpC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACtD,IAAI,OAAO;YACT,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAClE,OAAO,GAAG,KAAK,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IACvE,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,0EAA0E;AAC1E,MAAM,OAAO,oBAAoB;IAKtB,WAAW,GAAG,IAAI,iBAAiB,EAAE,CAAC;IACtC,YAAY,GAAG,IAAI,kBAAkB,EAAE,CAAC;IAEjD,KAAK,CAAC,MAAM,CACV,KAA2B,EAC3B,UAAuC,EAAE,QAAQ,EAAE,QAAQ,EAAE;QAE7D,IAAI,KAAmB,CAAC;QACxB,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,SAAS;gBACZ,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;oBACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,IAAI,kBAAkB,CAAC;oBAC3D,MAAM,WAAW,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;oBACtD,IAAI,CAAC,WAAW,EAAE,CAAC;wBACjB,MAAM,IAAI,YAAY,CACpB,EAAE,EACF,8BAA8B,QAAQ,EAAE,CACzC,CAAC;oBACJ,CAAC;oBACD,KAAK,GAAG;wBACN,IAAI,EAAE,SAAS;wBACf,UAAU,EAAE,IAAI;wBAChB,OAAO,EAAE,MAAM,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;qBACjD,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,KAAK,GAAG;wBACN,IAAI,EAAE,SAAS;wBACf,UAAU,EAAE,KAAK;wBACjB,OAAO,EAAE,KAAK,CAAC,OAAO;qBACvB,CAAC;gBACJ,CAAC;gBACD,MAAM;YACR,KAAK,UAAU;gBACb,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;gBAC5B,MAAM;YACR;gBACE,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1D,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK;YAAE,OAAO,YAAY,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC5D,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CACX,OAA+B,EAC/B,UAAuC,EAAE,QAAQ,EAAE,QAAQ,EAAE;QAE7D,MAAM,IAAI,GACR,OAAO,CAAC,QAAQ,KAAK,QAAQ;YAC3B,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YACjD,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAE3B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACxD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnB,KAAK,SAAS;oBACZ,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;wBACtB,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;wBAClD,MAAM;oBACR,CAAC;oBACD,IAAI,CAAC;wBACH,MAAM;4BACJ,IAAI,EAAE,SAAS;4BACf,OAAO,EAAE,MAAM,uBAAuB,CACpC,KAAK,CAAC,OAAO,EACb,OAAO,CAAC,WAAW,CACpB;yBACF,CAAC;oBACJ,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,MAAM,OAAO,GACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;wBACzD,MAAM,IAAI,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;oBACtC,CAAC;oBACD,MAAM;gBACR,KAAK,UAAU,CAAC,CAAC,CAAC;oBAChB,MAAM,EACJ,CAAC,kBAAkB,CAAC,EAAE,aAAa,EACnC,CAAC,mBAAmB,CAAC,EAAE,OAAO,GAAG,EAAE,EACnC,GAAG,QAAQ,EACZ,GAAG,KAAK,CAAC,QAAQ,CAAC;oBACnB,MAAM;wBACJ,IAAI,EAAE,UAAU;wBAChB,MAAM,EAAE,eAAe,CAAC,aAAa,CAAC;wBACtC,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC;wBACnC,QAAQ;qBACT,CAAC;oBACF,MAAM;gBACR,CAAC;gBACD;oBACE,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Binary protobuf gRPC-Web content type. */
|
|
2
|
+
export declare const GRPC_WEB_CONTENT_TYPE = "application/grpc-web+proto";
|
|
3
|
+
/** Base64-encoded protobuf gRPC-Web content type. */
|
|
4
|
+
export declare const GRPC_WEB_TEXT_CONTENT_TYPE = "application/grpc-web-text+proto";
|
|
5
|
+
/** HTTP body representation used for gRPC-Web requests and responses. */
|
|
6
|
+
export type GrpcWebEncoding =
|
|
7
|
+
/** Raw binary gRPC-Web frames without base64 wrapping. */
|
|
8
|
+
'raw'
|
|
9
|
+
/** Base64 text representation of complete binary gRPC-Web frames. */
|
|
10
|
+
| 'base64';
|
|
11
|
+
/** Returns the concrete protobuf content type for an encoding. */
|
|
12
|
+
export declare function grpcWebContentType(encoding: GrpcWebEncoding): string;
|
|
13
|
+
/** Recognizes supported gRPC-Web content types, ignoring media parameters. */
|
|
14
|
+
export declare function grpcWebEncoding(value: string | null | undefined): GrpcWebEncoding | undefined;
|
|
15
|
+
/** Chooses the first supported Accept value, then falls back to the request. */
|
|
16
|
+
export declare function negotiateGrpcWebResponseEncoding(accept: string | undefined, requestEncoding: GrpcWebEncoding): GrpcWebEncoding;
|
|
17
|
+
/** Whether a value is one of the supported gRPC-Web content types. */
|
|
18
|
+
export declare function isGrpcWebContentType(value: string | undefined): boolean;
|
|
19
|
+
//# sourceMappingURL=content_type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content_type.d.ts","sourceRoot":"","sources":["../../src/web/content_type.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,eAAO,MAAM,qBAAqB,+BAA+B,CAAC;AAClE,qDAAqD;AACrD,eAAO,MAAM,0BAA0B,oCAAoC,CAAC;AAK5E,yEAAyE;AACzE,MAAM,MAAM,eAAe;AACzB,0DAA0D;AACxD,KAAK;AACP,qEAAqE;GACnE,QAAQ,CAAC;AAOb,kEAAkE;AAClE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAEpE;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,eAAe,GAAG,SAAS,CAY7B;AAED,gFAAgF;AAChF,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,eAAe,EAAE,eAAe,GAC/B,eAAe,CAMjB;AAED,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEvE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Binary protobuf gRPC-Web content type. */
|
|
2
|
+
export const GRPC_WEB_CONTENT_TYPE = 'application/grpc-web+proto';
|
|
3
|
+
/** Base64-encoded protobuf gRPC-Web content type. */
|
|
4
|
+
export const GRPC_WEB_TEXT_CONTENT_TYPE = 'application/grpc-web-text+proto';
|
|
5
|
+
const GRPC_WEB_BASE_CONTENT_TYPE = 'application/grpc-web';
|
|
6
|
+
const GRPC_WEB_TEXT_BASE_CONTENT_TYPE = 'application/grpc-web-text';
|
|
7
|
+
const CONTENT_TYPE_BY_ENCODING = {
|
|
8
|
+
raw: GRPC_WEB_CONTENT_TYPE,
|
|
9
|
+
base64: GRPC_WEB_TEXT_CONTENT_TYPE,
|
|
10
|
+
};
|
|
11
|
+
/** Returns the concrete protobuf content type for an encoding. */
|
|
12
|
+
export function grpcWebContentType(encoding) {
|
|
13
|
+
return CONTENT_TYPE_BY_ENCODING[encoding];
|
|
14
|
+
}
|
|
15
|
+
/** Recognizes supported gRPC-Web content types, ignoring media parameters. */
|
|
16
|
+
export function grpcWebEncoding(value) {
|
|
17
|
+
const mediaType = value?.split(';', 1)[0]?.trim().toLowerCase();
|
|
18
|
+
switch (mediaType) {
|
|
19
|
+
case GRPC_WEB_TEXT_BASE_CONTENT_TYPE:
|
|
20
|
+
case GRPC_WEB_TEXT_CONTENT_TYPE:
|
|
21
|
+
return 'base64';
|
|
22
|
+
case GRPC_WEB_BASE_CONTENT_TYPE:
|
|
23
|
+
case GRPC_WEB_CONTENT_TYPE:
|
|
24
|
+
return 'raw';
|
|
25
|
+
default:
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** Chooses the first supported Accept value, then falls back to the request. */
|
|
30
|
+
export function negotiateGrpcWebResponseEncoding(accept, requestEncoding) {
|
|
31
|
+
for (const value of accept?.split(',') ?? []) {
|
|
32
|
+
const encoding = grpcWebEncoding(value);
|
|
33
|
+
if (encoding)
|
|
34
|
+
return encoding;
|
|
35
|
+
}
|
|
36
|
+
return requestEncoding;
|
|
37
|
+
}
|
|
38
|
+
/** Whether a value is one of the supported gRPC-Web content types. */
|
|
39
|
+
export function isGrpcWebContentType(value) {
|
|
40
|
+
return grpcWebEncoding(value) !== undefined;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=content_type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content_type.js","sourceRoot":"","sources":["../../src/web/content_type.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,MAAM,CAAC,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAClE,qDAAqD;AACrD,MAAM,CAAC,MAAM,0BAA0B,GAAG,iCAAiC,CAAC;AAE5E,MAAM,0BAA0B,GAAG,sBAAsB,CAAC;AAC1D,MAAM,+BAA+B,GAAG,2BAA2B,CAAC;AASpE,MAAM,wBAAwB,GAAoC;IAChE,GAAG,EAAE,qBAAqB;IAC1B,MAAM,EAAE,0BAA0B;CACnC,CAAC;AAEF,kEAAkE;AAClE,MAAM,UAAU,kBAAkB,CAAC,QAAyB;IAC1D,OAAO,wBAAwB,CAAC,QAAQ,CAAC,CAAC;AAC5C,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,eAAe,CAC7B,KAAgC;IAEhC,MAAM,SAAS,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAChE,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,+BAA+B,CAAC;QACrC,KAAK,0BAA0B;YAC7B,OAAO,QAAQ,CAAC;QAClB,KAAK,0BAA0B,CAAC;QAChC,KAAK,qBAAqB;YACxB,OAAO,KAAK,CAAC;QACf;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,gCAAgC,CAC9C,MAA0B,EAC1B,eAAgC;IAEhC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;IAChC,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,oBAAoB,CAAC,KAAyB;IAC5D,OAAO,eAAe,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type AnyRouter } from '@trpc/server';
|
|
2
|
+
import type { ProtoSchema } from '@trpc-proto/schema_ir';
|
|
3
|
+
import type { GrpcWebDispatcher } from './types.js';
|
|
4
|
+
/** Dependencies needed to execute gRPC-Web calls against a tRPC router. */
|
|
5
|
+
export interface DirectDispatcherOptions {
|
|
6
|
+
schema: ProtoSchema;
|
|
7
|
+
createContext?: () => unknown | Promise<unknown>;
|
|
8
|
+
}
|
|
9
|
+
export declare function createDirectDispatcher(router: AnyRouter, options: DirectDispatcherOptions): GrpcWebDispatcher;
|
|
10
|
+
//# sourceMappingURL=direct.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"direct.d.ts","sourceRoot":"","sources":["../../../src/web/dispatchers/direct.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,2EAA2E;AAC3E,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,WAAW,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAClD;AAwBD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,uBAAuB,GAC/B,iBAAiB,CAqDnB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import * as grpc from '@grpc/grpc-js';
|
|
2
|
+
import { TRPCError } from '@trpc/server';
|
|
3
|
+
import { createDirectBatchDispatcher } from '../../batch/grpcweb/direct_dispatcher.js';
|
|
4
|
+
import { grpcStatus } from '../../grpc/status.js';
|
|
5
|
+
import { ProtoCodec } from '../../proto_codec/proto_codec.js';
|
|
6
|
+
import { createRouterInvoker, toAsyncIterable } from '../../router_invoker.js';
|
|
7
|
+
function grpcWebRoutes(schema) {
|
|
8
|
+
const routes = new Map();
|
|
9
|
+
for (const service of schema.services) {
|
|
10
|
+
for (const method of service.methods) {
|
|
11
|
+
routes.set(`/${schema.package}.${service.name}/${method.name}`, {
|
|
12
|
+
procedurePath: method.path,
|
|
13
|
+
requestType: method.requestType,
|
|
14
|
+
responseType: method.responseType,
|
|
15
|
+
responseStream: method.isResponseStreaming,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return routes;
|
|
20
|
+
}
|
|
21
|
+
export function createDirectDispatcher(router, options) {
|
|
22
|
+
const protoCodec = new ProtoCodec(options.schema);
|
|
23
|
+
const routes = grpcWebRoutes(options.schema);
|
|
24
|
+
const invoke = createRouterInvoker(router, {
|
|
25
|
+
createContext: options.createContext,
|
|
26
|
+
});
|
|
27
|
+
const dispatch = async ({ grpcPath, message, signal }, emit, dispatchOptions) => {
|
|
28
|
+
const route = routes.get(grpcPath);
|
|
29
|
+
if (!route) {
|
|
30
|
+
return {
|
|
31
|
+
code: grpc.status.UNIMPLEMENTED,
|
|
32
|
+
message: `no gRPC mapping for ${grpcPath}`,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const input = protoCodec.decode(route.requestType, message);
|
|
37
|
+
const result = await invoke({
|
|
38
|
+
path: route.procedurePath,
|
|
39
|
+
input,
|
|
40
|
+
signal,
|
|
41
|
+
...(dispatchOptions && 'directContext' in dispatchOptions
|
|
42
|
+
? { context: dispatchOptions.directContext }
|
|
43
|
+
: {}),
|
|
44
|
+
});
|
|
45
|
+
if (route.responseStream) {
|
|
46
|
+
for await (const item of toAsyncIterable(result)) {
|
|
47
|
+
if (signal.aborted)
|
|
48
|
+
break;
|
|
49
|
+
await emit(protoCodec.encode(route.responseType, item));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
await emit(protoCodec.encode(route.responseType, result));
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
code: signal.aborted ? grpc.status.CANCELLED : grpc.status.OK,
|
|
57
|
+
message: '',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
return {
|
|
62
|
+
code: error instanceof TRPCError ? grpcStatus(error) : grpc.status.UNKNOWN,
|
|
63
|
+
message: error instanceof Error ? error.message : String(error),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
return createDirectBatchDispatcher(dispatch, {
|
|
68
|
+
schema: options.schema,
|
|
69
|
+
createContext: options.createContext,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=direct.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"direct.js","sourceRoot":"","sources":["../../../src/web/dispatchers/direct.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as grpc from '@grpc/grpc-js';
|
|
2
|
+
import type { ProtoSchema } from '@trpc-proto/schema_ir';
|
|
3
|
+
import type { GrpcWebDispatcher } from './types.js';
|
|
4
|
+
export declare function createForwardingDispatcher(client: grpc.Client, schema: ProtoSchema): GrpcWebDispatcher;
|
|
5
|
+
//# sourceMappingURL=forward.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forward.d.ts","sourceRoot":"","sources":["../../../src/web/dispatchers/forward.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAwEpD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,IAAI,CAAC,MAAM,EACnB,MAAM,EAAE,WAAW,GAClB,iBAAiB,CA6DnB"}
|