Files
smartserve/ts/core/smartserve.interfaces.ts

349 lines
9.4 KiB
TypeScript
Raw Normal View History

2025-11-29 15:24:00 +00:00
/**
* Core interfaces for @push.rocks/smartserve
* Uses Web Standards API (Request/Response) for cross-platform compatibility
*/
// =============================================================================
// HTTP Types
// =============================================================================
export type THttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'ALL';
export type TRuntime = 'node' | 'deno' | 'bun';
// =============================================================================
// Request Context
// =============================================================================
/**
* Request context passed to handlers and interceptors
* Wraps Web Standard Request with additional utilities
*/
export interface IRequestContext<TBody = unknown> {
/** Original Web Standards Request */
readonly request: Request;
/** Parsed request body (typed) */
readonly body: TBody;
/** URL path parameters extracted from route */
readonly params: Record<string, string>;
/** URL query parameters */
readonly query: Record<string, string>;
/** Request headers accessor */
readonly headers: Headers;
/** Matched route path pattern */
readonly path: string;
/** HTTP method */
readonly method: THttpMethod;
/** Full URL object */
readonly url: URL;
/** Runtime environment */
readonly runtime: TRuntime;
/** Route-specific state bag for passing data between interceptors */
state: Record<string, unknown>;
}
// =============================================================================
// Interceptor Types
// =============================================================================
/**
* Request interceptor - runs BEFORE the handler
* Can:
* - Return modified context to continue
* - Return Response to short-circuit
* - Return void/undefined to continue with original context
* - Throw to trigger error handling
*/
export type TRequestInterceptor<TBody = unknown> = (
ctx: IRequestContext<TBody>
) => Promise<IRequestContext<TBody> | Response | void> | IRequestContext<TBody> | Response | void;
/**
* Response interceptor - runs AFTER the handler
* Can:
* - Return modified response data
* - Return a Response object directly
*/
export type TResponseInterceptor<TRes = unknown> = (
response: TRes,
ctx: IRequestContext
) => Promise<TRes | Response> | TRes | Response;
/**
* Guard function - simplified boolean check for authorization
* Returns true to allow, false to reject with 403
*/
export type TGuardFunction<TBody = unknown> = (
ctx: IRequestContext<TBody>
) => Promise<boolean> | boolean;
/**
* Combined interceptor options for @Intercept decorator
*/
export interface IInterceptOptions<TBody = unknown, TRes = unknown> {
/** Request interceptors (run before handler) */
request?: TRequestInterceptor<TBody> | TRequestInterceptor<TBody>[];
/** Response interceptors (run after handler) */
response?: TResponseInterceptor<TRes> | TResponseInterceptor<TRes>[];
}
/**
* Options for @Guard decorator
*/
export interface IGuardOptions {
/** Custom response when guard rejects (default: 403 Forbidden) */
onReject?: (ctx: IRequestContext) => Response | Promise<Response>;
}
// =============================================================================
// Route Handler Types
// =============================================================================
/**
* Route handler function signature
*/
export type TRouteHandler<TReq = unknown, TRes = unknown> = (
ctx: IRequestContext<TReq>
) => Promise<TRes> | TRes;
/**
* Options for method decorators (@Get, @Post, etc.)
*/
export interface IMethodOptions {
/** Path segment (appended to class route) */
path?: string;
/** Content-Type for response */
contentType?: string;
/** HTTP status code for successful response */
statusCode?: number;
}
/**
* Options for @Route class decorator
*/
export interface IRouteOptions {
/** Base path for all routes in this controller */
path?: string;
}
// =============================================================================
// WebSocket Types
// =============================================================================
/**
* WebSocket message types
*/
export interface IWebSocketMessage {
type: 'text' | 'binary';
text?: string;
data?: Uint8Array;
size: number;
}
/**
* WebSocket peer connection
*/
export interface IWebSocketPeer {
/** Unique connection ID */
id: string;
/** Connection URL */
url: string;
/** WebSocket ready state */
readyState: 0 | 1 | 2 | 3;
/** Negotiated subprotocol */
protocol: string;
/** Negotiated extensions */
extensions: string;
/** Send text message */
send(data: string): void;
/** Send binary message */
sendBinary(data: Uint8Array | ArrayBuffer): void;
/** Close connection */
close(code?: number, reason?: string): void;
/** Send ping */
ping(data?: Uint8Array): void;
/** Force close without handshake */
terminate(): void;
/** Request context from upgrade */
context: IRequestContext;
/** Custom per-peer data storage */
data: Map<string, unknown>;
}
/**
* WebSocket event hooks
*/
export interface IWebSocketHooks {
onOpen?: (peer: IWebSocketPeer) => void | Promise<void>;
onMessage?: (peer: IWebSocketPeer, message: IWebSocketMessage) => void | Promise<void>;
onClose?: (peer: IWebSocketPeer, code: number, reason: string) => void | Promise<void>;
onError?: (peer: IWebSocketPeer, error: Error) => void | Promise<void>;
onPing?: (peer: IWebSocketPeer, data: Uint8Array) => void | Promise<void>;
onPong?: (peer: IWebSocketPeer, data: Uint8Array) => void | Promise<void>;
}
// =============================================================================
// Server Configuration
// =============================================================================
/**
* TLS/SSL configuration
*/
export interface ITLSConfig {
/** Certificate (PEM format) */
cert: string | Uint8Array;
/** Private key (PEM format) */
key: string | Uint8Array;
/** CA chain (PEM format) */
ca?: string | Uint8Array;
/** ALPN protocols */
alpnProtocols?: string[];
/** Minimum TLS version */
minVersion?: 'TLSv1.2' | 'TLSv1.3';
/** Passphrase for encrypted key */
passphrase?: string;
}
/**
* Keep-alive configuration
*/
export interface IKeepAliveConfig {
enabled: boolean;
timeout?: number;
maxRequests?: number;
}
/**
* Static file serving options
*/
export interface IStaticOptions {
/** Root directory path */
root: string;
/** Index files to look for */
index?: string[];
/** How to handle dotfiles */
dotFiles?: 'allow' | 'deny' | 'ignore';
/** Generate ETags */
etag?: boolean;
/** Add Last-Modified header */
lastModified?: boolean;
/** Cache-Control header value or function */
cacheControl?: string | ((path: string) => string);
/** File extensions to try */
extensions?: string[];
/** Enable directory listing */
directoryListing?: boolean | IDirectoryListingOptions;
}
/**
* Directory listing options
*/
export interface IDirectoryListingOptions {
/** Custom template function */
template?: (files: IFileEntry[]) => string | Response;
/** Show hidden files */
showHidden?: boolean;
/** Sort field */
sortBy?: 'name' | 'size' | 'modified';
/** Sort order */
sortOrder?: 'asc' | 'desc';
}
/**
* File entry for directory listing
*/
export interface IFileEntry {
name: string;
path: string;
isDirectory: boolean;
size: number;
modified: Date;
}
/**
* WebDAV configuration
*/
export interface IWebDAVConfig {
/** Root directory path */
root: string;
/** Authentication handler */
auth?: (ctx: IRequestContext) => boolean | Promise<boolean>;
/** Enable locking */
locking?: boolean;
}
/**
* Main server configuration
*/
export interface ISmartServeOptions {
/** Port to listen on */
port: number;
/** Hostname to bind to */
hostname?: string;
/** TLS configuration for HTTPS */
tls?: ITLSConfig;
/** WebSocket configuration */
websocket?: IWebSocketHooks;
/** Static file serving */
static?: IStaticOptions | string;
/** WebDAV configuration */
webdav?: IWebDAVConfig;
/** Connection timeout (ms) */
connectionTimeout?: number;
/** Keep-alive settings */
keepAlive?: IKeepAliveConfig;
/** Global error handler */
onError?: (error: Error, request?: Request) => Response | Promise<Response>;
}
// =============================================================================
// Server Instance
// =============================================================================
/**
* Server statistics
*/
export interface IServerStats {
uptime: number;
requestsTotal: number;
requestsActive: number;
connectionsTotal: number;
connectionsActive: number;
bytesReceived: number;
bytesSent: number;
}
/**
* Running server instance
*/
export interface ISmartServeInstance {
/** Listening port */
port: number;
/** Bound hostname */
hostname: string;
/** Is HTTPS enabled */
secure: boolean;
/** Runtime environment */
runtime: TRuntime;
/** Stop the server */
stop(): Promise<void>;
/** Get server statistics */
stats(): IServerStats;
}
// =============================================================================
// Connection Info
// =============================================================================
/**
* Connection information
*/
export interface IConnectionInfo {
remoteAddr: string;
remotePort: number;
localAddr: string;
localPort: number;
encrypted: boolean;
tlsVersion?: string;
}