import type { AnyMessage, Message, MethodInfo, ServiceType } from "@bufbuild/protobuf"; /** * An interceptor can add logic to clients, similar to the decorators * or middleware you may have seen in other libraries. Interceptors may * mutate the request and response, catch errors and retry/recover, emit * logs, or do nearly everything else. * * For a simple example, the following interceptor logs all requests: * * ```ts * const logger: Interceptor = (next) => async (req) => { * console.log(`sending message to ${req.url}`); * return await next(req); * }; * ``` * * You can think of interceptors like a layered onion. A request initiated * by a client goes through the outermost layer first. In the center, the * actual HTTP request is run by the transport. The response then comes back * through all layers and is returned to the client. * * To implement that layering, Interceptors are functions that wrap a call * invocation. In an array of interceptors, the interceptor at the end of * the array is applied first. */ export type Interceptor = (next: AnyFn) => AnyFn; /** * AnyFn represents the client-side invocation of an RPC. Interceptors can wrap * this invocation, add request headers, and wrap parts of the request or * response to inspect and log. */ type AnyFn = (req: UnaryRequest | StreamRequest) => Promise; /** * UnaryRequest is used in interceptors to represent a request with a * single input message. */ export interface UnaryRequest = AnyMessage, O extends Message = AnyMessage> extends RequestCommon { /** * The `stream` property discriminates between UnaryRequest and * StreamingRequest. */ readonly stream: false; /** * The input message that will be transmitted. */ readonly message: I; } /** * UnaryResponse is used in interceptors to represent a response with * a single output message. */ export interface UnaryResponse = AnyMessage, O extends Message = AnyMessage> extends ResponseCommon { /** * The `stream` property discriminates between UnaryResponse and * StreamingConn. */ readonly stream: false; /** * The received output message. */ readonly message: O; } /** * StreamRequest is used in interceptors to represent a request that has * zero or more input messages, and zero or more output messages. */ export interface StreamRequest = AnyMessage, O extends Message = AnyMessage> extends RequestCommon { /** * The `stream` property discriminates between UnaryRequest and * StreamingRequest. */ readonly stream: true; /** * The input messages that will be transmitted. */ readonly message: AsyncIterable; } /** * StreamResponse is used in interceptors to represent an ongoing call that has * zero or more input messages, and zero or more output messages. */ export interface StreamResponse = AnyMessage, O extends Message = AnyMessage> extends ResponseCommon { /** * The `stream` property discriminates between UnaryResponse and * StreamingConn. */ readonly stream: true; /** * The output messages. */ readonly message: AsyncIterable; } interface RequestCommon, O extends Message> { /** * Metadata related to the service that is being called. */ readonly service: ServiceType; /** * Metadata related to the service method that is being called. */ readonly method: MethodInfo; /** * The URL the request is going to hit. */ readonly url: string; /** * Optional parameters to the fetch API. */ readonly init: Exclude; /** * The AbortSignal for the current call. */ readonly signal: AbortSignal; /** * Headers that will be sent along with the request. */ readonly header: Headers; } interface ResponseCommon, O extends Message> { /** * Metadata related to the service that is being called. */ readonly service: ServiceType; /** * Metadata related to the service method that is being called. */ readonly method: MethodInfo; /** * Headers received from the response. */ readonly header: Headers; /** * Trailers received from the response. * Note that trailers are only populated when the entirety of the response * has been read. */ readonly trailer: Headers; } export {};