@universal-middleware/express
Version:
Express adapter for universal middlewares
125 lines (118 loc) • 6.45 kB
TypeScript
import { IncomingMessage, ServerResponse, OutgoingHttpHeaders } from 'node:http';
import { Socket } from 'node:net';
import { Get, UniversalHandler, UniversalFn, contextSymbol, Awaitable, UniversalMiddleware, RuntimeAdapterTarget, UniversalRouter, UniversalRouterInterface, EnhancedMiddleware } from '@universal-middleware/core';
import { Readable } from 'node:stream';
import { Express as Express$2 } from 'express';
import { Express as Express$1 } from 'express4';
/** Adapter options */
interface NodeRequestAdapterOptions {
/**
* Set the origin part of the URL to a constant value.
* It defaults to `process.env.ORIGIN`. If neither is set,
* the origin is computed from the protocol and hostname.
* To determine the protocol, `req.protocol` is tried first.
* If `trustProxy` is set, `X-Forwarded-Proto` header is used.
* Otherwise, `req.socket.encrypted` is used.
* To determine the hostname, `X-Forwarded-Host`
* (if `trustProxy` is set) or `Host` header is used.
*/
origin?: string;
/**
* Whether to trust `X-Forwarded-*` headers. `X-Forwarded-Proto`
* and `X-Forwarded-Host` are used to determine the origin when
* `origin` and `process.env.ORIGIN` are not set. `X-Forwarded-For`
* is used to determine the IP address. The leftmost values are used
* if multiple values are set. Defaults to true if `process.env.TRUST_PROXY`
* is set to `1`, otherwise false.
*/
trustProxy?: boolean;
}
/** Create a function that converts a Node HTTP request into a fetch API `Request` object */
declare function createRequestAdapter(options?: NodeRequestAdapterOptions): (req: DecoratedRequest) => Request;
declare const requestSymbol: unique symbol;
declare const pendingMiddlewaresSymbol: unique symbol;
declare const wrappedResponseSymbol: unique symbol;
interface PossiblyEncryptedSocket extends Socket {
encrypted?: boolean;
}
/**
* `IncomingMessage` possibly augmented by Express-specific
* `ip` and `protocol` properties.
*/
interface DecoratedRequest<C extends Universal.Context = Universal.Context> extends Omit<IncomingMessage, "socket"> {
ip?: string;
protocol?: string;
socket?: PossiblyEncryptedSocket;
rawBody?: any;
originalUrl?: string;
params?: Record<string, string>;
[contextSymbol]?: C;
[requestSymbol]?: Request;
}
interface DecoratedServerResponse extends ServerResponse {
[pendingMiddlewaresSymbol]?: ((response: Response) => Awaitable<Response | undefined>)[];
[wrappedResponseSymbol]?: boolean;
}
/** Connect/Express style request listener/middleware */
type NodeMiddleware<In extends Universal.Context, Out extends Universal.Context> = UniversalFn<UniversalMiddleware<In, Out>, <R>(req: DecoratedRequest<In>, res: DecoratedServerResponse, next?: (err?: unknown) => void) => R>;
type NodeHandler<In extends Universal.Context> = UniversalFn<UniversalHandler<In>, <R>(req: DecoratedRequest<In>, res: DecoratedServerResponse, next?: (err?: unknown) => void) => R>;
/** Adapter options */
interface NodeAdapterHandlerOptions extends NodeRequestAdapterOptions {
}
interface NodeAdapterMiddlewareOptions extends NodeRequestAdapterOptions {
}
/**
* Creates a request handler to be passed to http.createServer() or used as a
* middleware in Connect-style frameworks like Express.
*/
declare function createHandler<T extends unknown[], InContext extends Universal.Context>(handlerFactory: Get<T, UniversalHandler<InContext>>, options?: NodeAdapterHandlerOptions): Get<T, NodeHandler<InContext>>;
/**
* Creates a middleware to be passed to Connect-style frameworks like Express
*/
declare function createMiddleware<T extends unknown[], InContext extends Universal.Context, OutContext extends Universal.Context>(middlewareFactory: Get<T, UniversalMiddleware<InContext, OutContext>>, options?: NodeAdapterMiddlewareOptions): Get<T, NodeMiddleware<InContext, OutContext>>;
declare function getContext<InContext extends Universal.Context = Universal.Context>(req: DecoratedRequest): InContext;
/**
* Send a fetch API Response into a Node.js HTTP response stream.
*/
declare function sendResponse(fetchResponse: Response, nodeResponse: DecoratedServerResponse): Promise<void>;
type Express = Express$1 | Express$2;
type ConnectMiddleware = (req: IncomingMessage, res: ServerResponse, next?: (err?: unknown) => void) => void | Promise<void>;
type ConnectMiddlewareBoolean = (req: IncomingMessage, res: ServerResponse, next?: (err?: unknown) => void) => boolean | Promise<boolean>;
type WebHandler<InContext extends Universal.Context = Universal.Context, Target = unknown> = (request: Request, context?: InContext, runtime?: RuntimeAdapterTarget<Target>) => Response | undefined | Promise<Response | undefined>;
/**
* Converts a Connect-style middleware to a web-compatible request handler.
* @beta
*/
declare function connectToWeb(handler: ConnectMiddleware | ConnectMiddlewareBoolean): WebHandler;
/**
* Creates an IncomingMessage object from a web Request.
* @beta
*/
declare function createIncomingMessage(request: Request): IncomingMessage;
/**
* Creates a custom ServerResponse object that allows for intercepting and streaming the response.
*
* @beta
* @returns
* An object containing:
* - res: The custom ServerResponse object.
* - onReadable: A function that takes a callback. The callback is invoked when the response is readable,
* providing an object with the readable stream, headers, and status code.
*/
declare function createServerResponse(incomingMessage: IncomingMessage): {
res: ServerResponse<IncomingMessage>;
onReadable: (cb: (result: {
readable: Readable;
headers: OutgoingHttpHeaders;
statusCode: number;
}) => void) => void;
};
type App = Express;
declare class UniversalExpressRouter<T extends App> extends UniversalRouter implements UniversalRouterInterface {
#private;
constructor(app: T);
use(middleware: EnhancedMiddleware): this;
applyCatchAll(): this;
}
declare function apply(app: Express, middlewares: EnhancedMiddleware[]): void;
export { type App, type ConnectMiddleware, type ConnectMiddlewareBoolean, type DecoratedRequest, type DecoratedServerResponse, type NodeHandler, type NodeMiddleware, UniversalExpressRouter, type WebHandler, apply, connectToWeb, createHandler, createIncomingMessage, createMiddleware, createRequestAdapter, createServerResponse, getContext, sendResponse };