/** * Type declarations for @farm.js/core/middleware * * These provide stable type definitions that don't depend on build hashes. */ declare module "@farm.js/core/middleware" { /** * Next function to call the next middleware in the chain */ export type NextFunction = () => Promise; /** * Cookie options for setting cookies */ export interface CookieOptions { maxAge?: number; expires?: Date; path?: string; domain?: string; secure?: boolean; httpOnly?: boolean; sameSite?: "strict" | "lax" | "none"; } /** * Cookie jar for reading and writing cookies */ export interface CookieJar { get(name: string): string | undefined; set(name: string, value: string, options?: CookieOptions): void; delete(name: string): void; has(name: string): boolean; getAll(): Record; } type MiddlewareStoreKey> = Extract; export interface ReadonlyMiddlewareStore< TValues extends Record = Record, > { readonly size: number; get>(key: TKey): TValues[TKey] | undefined; has>(key: TKey): boolean; entries(): IterableIterator< [MiddlewareStoreKey, TValues[MiddlewareStoreKey]] >; keys(): IterableIterator>; values(): IterableIterator]>; [Symbol.iterator](): IterableIterator< [MiddlewareStoreKey, TValues[MiddlewareStoreKey]] >; } export interface MiddlewareStore< TValues extends Record = Record, > extends ReadonlyMiddlewareStore { clear(): void; delete>(key: TKey): boolean; set>(key: TKey, value: TValues[TKey]): this; } /** * Middleware context passed to each middleware function */ export interface MiddlewareContext { /** Request pathname */ pathname: string; /** Request URL */ url: string; /** HTTP method (GET, POST, etc.) */ method: string; /** Request headers */ headers: Headers; /** Cookie jar for reading/writing cookies */ cookies: CookieJar; /** Key-value data store for passing data between middleware */ data: Map; /** Server-only request context shared with Server Components */ locals: Map; /** Set a response to short-circuit the middleware chain */ _response?: Response; /** Send a response and stop middleware chain */ respond(response: Response): void; /** Redirect to a URL */ redirect(url: string, status?: number): void; /** Send JSON response */ json(data: unknown, status?: number): void; /** Send text response */ text(content: string, status?: number): void; } /** * Middleware function signature */ export type MiddlewareFunction = ( ctx: MiddlewareContext, next: NextFunction, ) => void | Promise; export interface RequestMiddlewareContext< TLocals extends Record = Record, TData extends Record = Record, > { readonly url: URL; readonly pathname: string; readonly searchParams: URLSearchParams; readonly method: string; readonly params: Record; readonly route: string; readonly locals: MiddlewareStore; readonly data: MiddlewareStore; readonly headers: Map; readonly cookies: CookieJar; get>(key: TKey): TLocals[TKey] | undefined; has>(key: TKey): boolean; set>(key: TKey, value: TLocals[TKey]): void; delete>(key: TKey): boolean; redirect(url: string, status?: number): void; rewrite(url: string): void; json(data: unknown, status?: number): void; text(content: string, status?: number): void; html(content: string, status?: number): void; } export type RequestMiddleware< TLocals extends Record = Record, TData extends Record = Record, > = ( request: Request, context: RequestMiddlewareContext, ) => void | Response | Promise; /** * Rate limit configuration */ export interface RateLimitConfig { /** Maximum number of requests */ requests: number; /** Fixed window such as `500ms`, `10s`, `1m`, or `1h`. */ window: string; /** Optional custom key generator */ keyGenerator?: (ctx: MiddlewareContext) => string; /** Optional response customization when the limit is exceeded. */ onLimit?: (ctx: MiddlewareContext) => void | Response | Promise; /** Optional custom storage */ storage?: RateLimitStorage; } /** * Rate limit storage interface */ export interface RateLimitIncrementResult { count: number; resetAt: number; } export interface RateLimitStorage { increment( key: string, windowMs: number, ): RateLimitIncrementResult | Promise; get?(key: string): RateLimitIncrementResult | null | Promise; } export interface MemoryRateLimitStorageOptions { maxEntries?: number; } /** * Rate limit status */ export interface RateLimitStatus { requests: number; limit: number; remaining: number; resetIn: number | null; resetAt: Date | null; isLimited: boolean; } /** * Middleware chain configuration */ export interface MiddlewareConfig { basePath?: string; } /** * Middleware chain for composing middleware */ export interface MiddlewareChain { /** * Add a middleware function to the chain */ use(handler: MiddlewareFunction): MiddlewareChain; /** * Conditionally run middleware when the predicate returns true */ when( predicate: (ctx: MiddlewareContext) => boolean, handler: MiddlewareFunction, ): MiddlewareChain; /** * Add rate limiting middleware */ rateLimit(config: RateLimitConfig): MiddlewareChain; /** * Set the base path for this middleware chain */ setBasePath(path: string): void; /** * Build the middleware chain into executable form */ build(): { handlers: MiddlewareFunction[] }; } /** * Create a new middleware chain */ export function middleware(basePath?: string): MiddlewareChain; /** * Get rate limit status for a key */ export function getRateLimitStatus( key: string, limit: number, storage?: RateLimitStorage, ): Promise; /** Create an atomic, process-local fixed-window rate-limit store. */ export function memoryRateLimitStorage(options?: MemoryRateLimitStorageOptions): RateLimitStorage; export class UnsupportedRateLimitStorageError extends TypeError {} /** * Create a middleware context from request/response */ export function createContext(req: unknown, res: unknown, server?: unknown): MiddlewareContext; /** * Get middleware data from context */ export function getMiddlewareData = Record>(): Map< keyof T, T[keyof T] >; /** Get server-only middleware context for the current request. */ export function getMiddlewareContext< T extends Record = Record, >(): ReadonlyMiddlewareStore; /** * Get middleware value (alias for getMiddlewareData) */ export function getMiddlewareValue(key: string): T | undefined; /** * Get data from middleware context */ export function getFromMiddleware( ctx: MiddlewareContext, key: string, ): T | undefined; /** * Check if middleware has data for a key */ export function hasMiddlewareData(ctx: MiddlewareContext, key: string): boolean; /** * Unwrap middleware chain to get handlers */ export function unwrapMiddleware(chain: MiddlewareChain): MiddlewareFunction[]; /** * Middleware manager for plugin */ export class MiddlewareManager { constructor(options?: { srcDir?: string; debug?: boolean }); discover(root: string): Promise; getMiddleware(path: string): MiddlewareChain | undefined; execute(ctx: MiddlewareContext): Promise; } }