UNPKG

@wolfcoded/nestjs-bufconnect

Version:

NestJs BufConnect is a custom transport strategy for NestJs microservices that integrates with the Buf's gRPC implementation.

357 lines (348 loc) 13.8 kB
/// <reference types="node" /> import { ServiceType } from '@bufbuild/protobuf'; import { ConnectRouterOptions, ConnectRouter } from '@connectrpc/connect'; import * as http from 'node:http'; import * as https from 'node:https'; import * as http2 from 'node:http2'; import { Observable } from 'rxjs'; import { Server, CustomTransportStrategy, MessageHandler } from '@nestjs/microservices'; /** * Decorator for defining a gRPC service and its methods. It uses the metadata from * `BufMethod` and `BufStreamMethod` to initialize the service and its methods. * * @param serviceName - A `ServiceType` object that defines the gRPC service. * @returns A class decorator that can be applied to a class implementing the gRPC service. */ declare const BufService: (serviceName: ServiceType) => ClassDecorator; /** * Decorator for a unary gRPC method within a `BufService`. It stores the method's metadata, * which is later used by `BufService` to initialize the method. * * @returns A method decorator that can be applied to a method implementing a unary gRPC method. */ declare const BufMethod: () => MethodDecorator; /** * Decorator for a streaming gRPC method within a `BufService`. It stores the method's metadata, * which is later used by `BufService` to initialize the method. * * @returns A method decorator that can be applied to a method implementing a streaming gRPC method. */ declare const BufStreamMethod: () => MethodDecorator; /** * This module provides types and interfaces for configuring a server instance with various protocols * (HTTP, HTTPS, HTTP2, HTTP2_INSECURE) and their options. It also provides types for handling * server instances and other utility types. */ /** * Represents a pattern for BufConnect, which includes the service name, RPC method name, and streaming method type. */ interface BufConnectPattern { service: string; rpc: string; streaming: MethodType; } /** * Enum representing the different method types for gRPC streaming. */ declare enum MethodType { NO_STREAMING = "no_stream", RX_STREAMING = "rx_stream" } /** * Enum representing the supported server protocols. */ declare enum ServerProtocol { HTTP = "http", HTTPS = "https", HTTP2 = "http2", HTTP2_INSECURE = "http2_insecure" } /** * Base interface for server options, containing common properties. */ interface BaseServerOptions { port: number; connectOptions?: ConnectRouterOptions; callback?: () => void; } /** * Interface for HTTP server options, extending the BaseServerOptions with an HTTP protocol type and HTTP server options. */ interface HttpOptions extends BaseServerOptions { protocol: ServerProtocol.HTTP; serverOptions?: http.ServerOptions; } /** * Interface for HTTPS server options, extending the BaseServerOptions with an HTTPS protocol type and HTTPS server options. */ interface HttpsOptions extends BaseServerOptions { protocol: ServerProtocol.HTTPS; serverOptions: https.ServerOptions; } /** * Interface for HTTP2 server options (secure), extending the BaseServerOptions with an HTTP2 protocol type and secure HTTP2 server options. */ interface Http2Options extends BaseServerOptions { protocol: ServerProtocol.HTTP2; serverOptions: http2.SecureServerOptions; } /** * Interface for HTTP2 server options (insecure), extending the BaseServerOptions with an HTTP2_INSECURE protocol type and HTTP2 server options. */ interface Http2InsecureOptions extends BaseServerOptions { protocol: ServerProtocol.HTTP2_INSECURE; serverOptions?: http2.ServerOptions; } /** * Union type for all supported server options (HTTP, HTTPS, HTTP2, HTTP2_INSECURE). */ type ServerTypeOptions = HttpOptions | HttpsOptions | Http2Options | Http2InsecureOptions; /** * Union type for all supported server instances (http.Server, https.Server, http2.Http2Server) or a null instance. */ type ServerInstance = http.Server | https.Server | http2.Http2Server | null; /** * Interface representing a class with a prototype property that has a record of string keys mapping to property descriptors. */ interface ConstructorWithPrototype { prototype: Record<string, PropertyDescriptor>; } /** * Interface representing a method key object with a string key property and a method type. */ interface MethodKey { key: string; methodType: MethodType; } /** * Type representing an array of MethodKey objects. */ type MethodKeys = Array<MethodKey>; /** * Interface representing a property descriptor with a value that is a function with a specific signature. */ interface FunctionPropertyDescriptor extends PropertyDescriptor { value: (...arguments_: never[]) => never; } /** * Interface representing a property descriptor with a value that is a function with a specific signature. */ type ResultOrDeferred<T> = Observable<T> | { subscribe: () => void; } | { toPromise: () => Promise<T>; } | T; /** * A custom transport strategy for NestJS microservices that integrates with the '@connectrpc/connect-es' package. * * @remarks * This class extends the `Server` class provided by NestJS and implements the `CustomTransportStrategy` interface. * * @example * import { NestFactory } from '@nestjs/core'; * import { MicroserviceOptions, Transport } from '@nestjs/microservices'; * import { ServerBufConnect } from '@wolfcoded/nestjs-bufconnect'; * import { AppModule } from './app/app.module'; * * async function bootstrap() { * const serverOptions: HttpOptions = { * protocol: ServerProtocol.HTTP, * port: 3000, * } * * const app = await NestFactory.createMicroservice<MicroserviceOptions>( * AppModule, { * strategy: new ServerBufConnect(serverOptions), * } * ); * * await app.listen(); * } * * bootstrap(); */ declare class ServerBufConnect extends Server implements CustomTransportStrategy { private readonly CustomMetadataStore; private server; private readonly Options; /** * Constructor for ServerBufConnect. * @param options - The options for configuring the server. */ constructor(options: ServerTypeOptions); /** * Starts the HTTP server, listening on the specified port. * @param callback - An optional callback to be executed when the server starts listening. * @returns {Promise<void>} A promise that resolves when the server starts listening. */ listen(callback: (error?: unknown, ...optionalParameters: unknown[]) => void): Promise<void>; /** * Stops the HTTP server. * @returns {Promise<void>} A promise that resolves when the server stops. */ close(): Promise<void>; /** * Adds a message handler for the given pattern. * @param pattern - The pattern associated with the message handler. * @param callback - The message handler function. * @param isEventHandler - Optional flag to mark the message handler as an event handler. Defaults to false. */ addHandler(pattern: unknown, callback: MessageHandler, isEventHandler?: boolean): void; /** * Builds the ConnectRouter with the server's message handlers. * @returns A function that takes a ConnectRouter and configures it with the server's message handlers. * @private */ buildRouter(): (router: ConnectRouter) => void; } /** * Provides a storage mechanism for custom metadata associated with ServiceType instances from the '@bufbuild/protobuf' package. * * This is a singleton class, so use `CustomMetadataStore.getInstance()` to get the instance. * * Example usage: * * ```ts * const customMetadataStore = CustomMetadataStore.getInstance(); * * customMetadataStore.set('myKey', myServiceType); * const myServiceTypeFromStore = customMetadataStore.get('myKey'); * ``` */ declare class CustomMetadataStore { private static instance; private customMetadata; /** * Private constructor to enforce the singleton pattern. */ private constructor(); /** * getInstance returns the singleton instance of the CustomMetadataStore, * creating it if it does not already exist. * @returns {CustomMetadataStore} The singleton instance of CustomMetadataStore. */ static getInstance(): CustomMetadataStore; /** * set stores a ServiceType instance with the associated key in the store. * @param {string} key - The key to associate with the ServiceType instance. * @param {ServiceType} value - The ServiceType instance to store. */ set(key: string, value: ServiceType): void; /** * get retrieves the ServiceType instance associated with the given key, * returning undefined if the key is not found in the store. * @param {string} key - The key associated with the desired ServiceType instance. * @returns {ServiceType | undefined} The ServiceType instance associated with the key, * or undefined if not found. */ get(key: string): ServiceType | undefined; } /** * Checks if the given input is an AsyncGenerator. * * @param input - The object to check. * @returns True if the input is an AsyncGenerator, false otherwise. */ declare function isAsyncGenerator<T>(input: unknown): input is AsyncGenerator<T>; /** * Converts an Observable to an AsyncGenerator. * * @param observable - The Observable to be converted. * @returns An AsyncGenerator that yields values from the provided Observable. */ declare function observableToAsyncGenerator<T>(observable: Observable<T>): AsyncGenerator<T>; /** * Checks if the given object is an instance of Observable. * * @param object - The object to check. * @returns True if the object is an instance of Observable, false otherwise. */ declare const isObservable: <T>(object: unknown) => object is Observable<T>; /** * Checks if the given object has a 'subscribe' function. * * @param object - The object to check. * @returns True if the object has a 'subscribe' function, false otherwise. */ declare const hasSubscribe: (object: unknown) => object is { subscribe: () => void; }; /** * Checks if the given object has a 'toPromise' function. * * @param object - The object to check. * @returns True if the object has a 'toPromise' function, false otherwise. */ declare const hasToPromise: (object: unknown) => object is { toPromise: () => Promise<unknown>; }; /** * Transforms a given ResultOrDeferred into an Observable. * * @param resultOrDeferred - The ResultOrDeferred to be transformed. * @returns An Observable instance of the result or deferred. */ declare const transformToObservable: <T>(resultOrDeferred: ResultOrDeferred<T>) => Observable<T>; /** * Converts an Observable or AsyncGenerator to an AsyncGenerator. * * @param input - The Observable or AsyncGenerator to be converted. * @returns An AsyncGenerator that yields values from the provided input. * @throws An Error if the input is neither an Observable nor an AsyncGenerator. */ declare function toAsyncGenerator<T>(input: Observable<T> | AsyncGenerator<T>): AsyncGenerator<T>; /** * The HTTPServer class is responsible for creating and managing the server instance based on the given options. * It supports HTTP, HTTPS, and HTTP2 (secure and insecure) protocols. */ declare class HTTPServer { private readonly options; private readonly router; private serverPrivate; set server(value: http.Server | https.Server | http2.Http2Server | null); get server(): http.Server | https.Server | http2.Http2Server | null; /** * Constructor for the HTTPServer class. * @param options - Server configuration options. * @param router - A function that takes a ConnectRouter and configures it with the server's message handlers. */ constructor(options: ServerTypeOptions, router: (router: ConnectRouter) => void); /** * Starts the server and listens for incoming requests. * @returns A promise that resolves when the server starts listening. */ listen(): Promise<void>; /** * Creates an HTTP server. * @returns An instance of an HTTP server. */ createHttpServer(): http.Server; /** * Creates an HTTPS server. * @returns An instance of an HTTPS server. */ createHttpsServer(): https.Server; /** * Creates an HTTP2 server with secure connection. * @returns An instance of an HTTP2 server with secure connection. */ createHttp2Server(): http2.Http2Server; /** * Creates an HTTP2 server with secure connection. * @returns An instance of an HTTP2 server with secure connection. */ createHttp2InsecureServer(): http2.Http2Server; /** * Starts the server based on the provided protocol in the options. * @param resolve - A function that resolves the promise when the server starts successfully. * @param reject - A function that rejects the promise with an error when the server fails to start. */ startServer(resolve: () => void, reject: (error: Error) => void): void; /** * Stops the server and releases all resources. * @param callback - An optional callback function to be executed when the server stops. * @returns A promise that resolves when the server stops. */ close(callback?: () => void): Promise<void>; } export { BaseServerOptions, BufConnectPattern, BufMethod, BufService, BufStreamMethod, ConstructorWithPrototype, CustomMetadataStore, FunctionPropertyDescriptor, HTTPServer, Http2InsecureOptions, Http2Options, HttpOptions, HttpsOptions, MethodKey, MethodKeys, MethodType, ResultOrDeferred, ServerBufConnect, ServerInstance, ServerProtocol, ServerTypeOptions, hasSubscribe, hasToPromise, isAsyncGenerator, isObservable, observableToAsyncGenerator, toAsyncGenerator, transformToObservable };