@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
TypeScript
/// <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 };