import http from 'http'; export { a as ApiContext, A as ApiMiddleware, b as GenerateStaticParams, G as GlobalMiddleware, L as LoaderResult, M as MetadataLoader, N as NotFoundResponse, d as RedirectResponse, R as RouteMiddleware, S as ServerContext, c as ServerLoader, W as WssActions } from './index.types-Duhjyfit.js'; import { Socket } from 'socket.io'; import { Request, Response } from 'express'; export { c as bootstrapClient } from './bootstrap-BfGTMUkj.js'; import { ZodSchema, z } from 'zod'; import * as express_rate_limit from 'express-rate-limit'; import pino, { Logger as Logger$1 } from 'pino'; /** * Framework configuration interface. * * Allows customization of framework behavior without code changes. */ interface FrameworkConfig { directories: { app: string; build: string; static: string; }; conventions: { page: string; layout: string; notFound: string; error: string; api: string; }; routing: { trailingSlash: 'always' | 'never' | 'ignore'; caseSensitive: boolean; basePath: string; }; build: { clientBundler: 'rspack' | 'webpack' | 'vite'; serverBundler: 'esbuild' | 'tsup' | 'swc'; }; server: { adapter: 'express' | 'fastify' | 'koa'; port: number; host: string; }; rendering: { framework: 'react' | 'preact' | 'vue' | 'svelte'; streaming: boolean; ssr: boolean; ssg: boolean; }; plugins?: any[]; images?: ImageConfig; } /** * Remote pattern for image domain whitelisting. */ interface RemotePattern { protocol?: 'http' | 'https'; hostname: string; port?: string; pathname?: string; } /** * Image optimization configuration. */ interface ImageConfig { remotePatterns?: RemotePattern[]; domains?: string[]; deviceSizes?: number[]; imageSizes?: number[]; formats?: ('image/webp' | 'image/avif')[]; quality?: number; minimumCacheTTL?: number; dangerouslyAllowSVG?: boolean; contentSecurityPolicy?: string; maxWidth?: number; maxHeight?: number; } /** * Default framework configuration. */ declare const DEFAULT_CONFIG: FrameworkConfig; /** * Loads framework configuration from project root. * * Looks for configuration in the following order: * 1. loly.config.ts (TypeScript) * 2. loly.config.js (JavaScript) * 3. loly.config.json (JSON) * * Merges user config with defaults and validates. * * @param projectRoot - Root directory of the project * @returns Framework configuration * @throws ConfigValidationError if configuration is invalid */ declare function loadConfig(projectRoot: string): FrameworkConfig; /** * Gets the resolved app directory path. * * @param projectRoot - Root directory of the project * @param config - Framework configuration * @returns Resolved app directory path */ declare function getAppDir(projectRoot: string, config: FrameworkConfig): string; /** * Gets the resolved build directory path. * * @param projectRoot - Root directory of the project * @param config - Framework configuration * @returns Resolved build directory path */ declare function getBuildDir(projectRoot: string, config: FrameworkConfig): string; /** * Gets the resolved static directory path. * * @param projectRoot - Root directory of the project * @param config - Framework configuration * @returns Resolved static directory path */ declare function getStaticDir(projectRoot: string, config: FrameworkConfig): string; interface StartDevServerOptions { port?: number; rootDir?: string; appDir?: string; } /** * Development server startup. * Wrapper around startServer for backward compatibility. * * @param options - Server options */ declare function startDevServer(options?: StartDevServerOptions): Promise; interface StartProdServerOptions { port?: number; rootDir?: string; appDir?: string; } /** * Production server startup. * Wrapper around startServer for backward compatibility. * * @param options - Server options */ declare function startProdServer(options?: StartProdServerOptions): Promise; interface InitServerData { server: http.Server; } /** * Authentication context provided to the auth hook. * Contains request metadata needed for authentication. */ interface AuthContext { /** Request headers */ req: { headers: Record; ip?: string; url?: string; cookies?: Record; }; /** Socket.IO socket instance */ socket: Socket; /** Namespace path (e.g., "/chat") */ namespace: string; } /** * Rate limit configuration for events. */ interface RateLimitCfg { /** Maximum events per second */ eventsPerSecond: number; /** Burst capacity (optional, defaults to eventsPerSecond * 2) */ burst?: number; } /** * Guard function type. Returns true to allow, false to block. */ type GuardFn = (ctx: { user: TUser | null; req: AuthContext["req"]; namespace: string; }) => boolean | Promise; /** * Authentication function type. * Returns the authenticated user or null. */ type AuthFn = (ctx: AuthContext) => TUser | null | Promise; /** * Schema validation adapter. * Must support Zod-like interface: schema.parse(data) or schema.safeParse(data) */ type Schema = { parse?: (data: any) => any; safeParse?: (data: any) => { success: boolean; error?: any; data?: any; }; } & Record; /** * Realtime state store interface. * Provides key-value storage, lists, sets, and atomic operations. */ interface RealtimeStateStore { /** Get a value by key */ get(key: string): Promise; /** Set a value with optional TTL */ set(key: string, value: T, opts?: { ttlMs?: number; }): Promise; /** Delete a key */ del(key: string): Promise; /** Increment a numeric value */ incr(key: string, by?: number): Promise; /** Decrement a numeric value */ decr(key: string, by?: number): Promise; /** Push to a list (left push) */ listPush(key: string, value: any, opts?: { maxLen?: number; }): Promise; /** Get range from a list */ listRange(key: string, start: number, end: number): Promise; /** Add member to a set */ setAdd(key: string, member: string): Promise; /** Remove member from a set */ setRem(key: string, member: string): Promise; /** Get all members of a set */ setMembers(key: string): Promise; /** Optional: Acquire a distributed lock (returns unlock function) */ lock?(key: string, ttlMs: number): Promise<() => Promise>; } /** * Logger interface for realtime events. */ interface RealtimeLogger { debug(message: string, meta?: Record): void; info(message: string, meta?: Record): void; warn(message: string, meta?: Record): void; error(message: string, meta?: Record): void; } /** * Metrics interface (optional for v1). */ interface RealtimeMetrics { incrementCounter(name: string, labels?: Record): void; recordLatency(name: string, ms: number, labels?: Record): void; } /** * Extended WssActions with full RFC support. */ interface WssActions { /** * Emit to current socket only (reply) */ reply(event: string, payload?: any): void; /** * Emit to all sockets in current namespace */ emit(event: string, payload?: any): void; /** * Emit to everyone except current socket */ broadcast(event: string, payload?: any, opts?: { excludeSelf?: boolean; }): void; /** * Join a room */ join(room: string): Promise; /** * Leave a room */ leave(room: string): Promise; /** * Emit to a specific room */ toRoom(room: string): { emit(event: string, payload?: any): void; }; /** * Emit to a specific user (by userId) * Uses presence mapping to find user's sockets */ toUser(userId: string): { emit(event: string, payload?: any): void; }; /** * Emit error event (reserved event: __loly:error) */ error(code: string, message: string, details?: any): void; /** * Legacy: Emit to a specific socket by Socket.IO socket ID * @deprecated Use toUser() for user targeting */ emitTo?: (socketId: string, event: string, ...args: any[]) => void; /** * Legacy: Emit to a specific client by custom clientId * @deprecated Use toUser() for user targeting */ emitToClient?: (clientId: string, event: string, ...args: any[]) => void; } /** * Extended WssContext with full RFC support. */ interface WssContext { /** Request metadata */ req: { headers: Record; ip?: string; url?: string; cookies?: Record; }; /** Authenticated user (set by auth hook) */ user: TUser | null; /** Incoming payload for current event */ data: TData; /** Route params (from dynamic routes) */ params: Record; /** Route pathname */ pathname: string; /** Framework utilities */ actions: WssActions; /** State store for shared state */ state: RealtimeStateStore; /** Logger with WSS context */ log: RealtimeLogger; /** Metrics (optional) */ metrics?: RealtimeMetrics; } /** * WSS event handler type. */ type WssHandler = (ctx: WssContext) => void | Promise; /** * WSS event definition. * Can be a simple handler or an object with validation, guards, and rate limiting. */ type WssEventDefinition = WssHandler | { /** Schema for validation (Zod/Valibot compatible) */ schema?: Schema; /** Per-event rate limit config */ rateLimit?: RateLimitCfg; /** Guard function (auth/roles/permissions) */ guard?: GuardFn; /** Event handler */ handler: WssHandler; }; /** * WSS route definition (result of defineWssRoute). */ interface WssRouteDefinition { /** Namespace (optional, inferred from folder name) */ namespace?: string; /** Authentication hook */ auth?: AuthFn; /** Connection hook */ onConnect?: WssHandler; /** Disconnection hook */ onDisconnect?: (ctx: WssContext, reason?: string) => void | Promise; /** Event handlers */ events: Record>; } /** * Rewrite condition types. * Used in the `has` array to conditionally apply rewrites. */ type RewriteConditionType = "host" | "header" | "cookie" | "query"; /** * Rewrite condition. * Defines when a rewrite should be applied. */ interface RewriteCondition { type: RewriteConditionType; key?: string; value: string; } /** * Rewrite destination can be: * - A string (static or with :param placeholders) * - An async function that returns a string (for dynamic rewrites) */ type RewriteDestination = string | ((params: Record, req: Request) => Promise | string); /** * Rewrite rule configuration. * Defines how to rewrite a URL pattern. */ interface RewriteRule { source: string; destination: RewriteDestination; has?: RewriteCondition[]; } /** * Rewrite configuration. * Array of rewrite rules to apply in order. */ type RewriteConfig = RewriteRule[]; /** * Realtime/WebSocket configuration */ interface RealtimeConfig { /** Enable realtime features */ enabled?: boolean; /** Socket.IO server settings */ path?: string; transports?: ("websocket" | "polling")[]; pingIntervalMs?: number; pingTimeoutMs?: number; maxPayloadBytes?: number; /** Security */ allowedOrigins?: string | string[]; cors?: { credentials?: boolean; allowedHeaders?: string[]; }; /** Scaling configuration */ scale?: { mode?: "single" | "cluster"; adapter?: { name: "redis"; url: string; pubClientName?: string; subClientName?: string; }; stateStore?: { name: "memory" | "redis"; url?: string; prefix?: string; }; }; /** Rate limiting */ limits?: { connectionsPerIp?: number; eventsPerSecond?: number; burst?: number; }; /** Logging */ logging?: { level?: "debug" | "info" | "warn" | "error"; pretty?: boolean; }; } interface ServerConfig { bodyLimit?: string; corsOrigin?: string | string[] | boolean | ((origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void) => void); rateLimit?: { windowMs?: number; max?: number; apiMax?: number; strictMax?: number; strictPatterns?: string[]; }; security?: { contentSecurityPolicy?: boolean | Record; hsts?: boolean | { maxAge?: number; includeSubDomains?: boolean; }; }; /** Realtime/WebSocket configuration */ realtime?: RealtimeConfig; } interface BuildAppOptions { rootDir?: string; appDir?: string; config?: FrameworkConfig; } declare function buildApp(options?: BuildAppOptions): Promise; /** * Defines a WebSocket route with authentication, hooks, and event handlers. * * This is the new, recommended way to define WSS routes. It provides: * - Type safety * - Built-in validation * - Auth hooks * - Connection/disconnection hooks * - Per-event validation, guards, and rate limiting * * @example * ```ts * import { defineWssRoute } from "@lolyjs/core"; * import { z } from "zod"; * * export default defineWssRoute({ * auth: async (ctx) => { * const token = ctx.req.headers.authorization; * return await verifyToken(token); * }, * onConnect: (ctx) => { * console.log("User connected:", ctx.user?.id); * }, * events: { * message: { * schema: z.object({ text: z.string() }), * guard: ({ user }) => !!user, * handler: (ctx) => { * ctx.actions.broadcast("message", ctx.data); * } * } * } * }); * ``` */ declare function defineWssRoute(definition: WssRouteDefinition): WssRouteDefinition; declare function withCache(fn: any, options: any): any; /** * Validation error with detailed information. */ declare class ValidationError extends Error { errors: z.ZodIssue[]; constructor(errors: z.ZodIssue[], message?: string); /** * Formats validation errors into a user-friendly format. */ format(): Record; } /** * Validates data against a Zod schema. * * @param schema - Zod schema to validate against * @param data - Data to validate * @returns Validated data * @throws ValidationError if validation fails */ declare function validate(schema: ZodSchema, data: unknown): T; /** * Safely validates data and returns a result object. * * @param schema - Zod schema to validate against * @param data - Data to validate * @returns Result object with success flag and data/error */ declare function safeValidate(schema: ZodSchema, data: unknown): { success: true; data: T; } | { success: false; error: ValidationError; }; /** * Common validation schemas for reuse. */ declare const commonSchemas: { /** * Validates a string parameter (e.g., route params). */ stringParam: z.ZodString; /** * Validates an optional string parameter. */ optionalStringParam: z.ZodOptional; /** * Validates a numeric ID parameter. */ idParam: z.ZodEffects; /** * Validates a UUID parameter. */ uuidParam: z.ZodString; /** * Validates pagination parameters. */ pagination: z.ZodObject<{ page: z.ZodDefault>; limit: z.ZodDefault>; }, "strip", z.ZodTypeAny, { page: number; limit: number; }, { page?: string | undefined; limit?: string | undefined; }>; /** * Validates a search query parameter. */ searchQuery: z.ZodOptional; }; /** * Security utilities for input sanitization. */ /** * Sanitizes a string by removing potentially dangerous characters. * Basic sanitization - for production, consider using a library like DOMPurify. * * @param input - String to sanitize * @returns Sanitized string */ declare function sanitizeString(input: string): string; /** * Sanitizes an object by recursively sanitizing all string values. * * @param obj - Object to sanitize * @returns Sanitized object */ declare function sanitizeObject>(obj: T): T; /** * Sanitizes route parameters. * * @param params - Route parameters object * @returns Sanitized parameters */ declare function sanitizeParams>(params: T): T; /** * Sanitizes query parameters. * * @param query - Query parameters object * @returns Sanitized query parameters */ declare function sanitizeQuery>(query: T): T; interface RateLimitConfig { windowMs?: number; max?: number; message?: string; standardHeaders?: boolean; legacyHeaders?: boolean; skipSuccessfulRequests?: boolean; skipFailedRequests?: boolean; keyGenerator?: (req: any) => string; skip?: (req: any) => boolean; } /** * Creates a rate limiter middleware with configurable options. * * @param config - Rate limiting configuration * @returns Express rate limit middleware * @throws Error if configuration is invalid */ declare function createRateLimiter(config?: RateLimitConfig): express_rate_limit.RateLimitRequestHandler; /** * Default rate limiter for general API routes. * Limits: 100 requests per 15 minutes per IP */ declare const defaultRateLimiter: express_rate_limit.RateLimitRequestHandler; /** * Strict rate limiter for authentication and sensitive endpoints. * Limits: 5 requests per 15 minutes per IP */ declare const strictRateLimiter: express_rate_limit.RateLimitRequestHandler; /** * Lenient rate limiter for public pages. * Limits: 200 requests per 15 minutes per IP */ declare const lenientRateLimiter: express_rate_limit.RateLimitRequestHandler; type LogLevel = "fatal" | "error" | "warn" | "info" | "debug" | "trace"; interface LoggerContext { [key: string]: unknown; } interface LoggerOptions { level?: LogLevel; enabled?: boolean; pretty?: boolean; destination?: pino.DestinationStream; } /** * Gets or creates the singleton logger instance. */ declare function getLogger(options?: LoggerOptions): Logger$1; /** * Sets a custom logger instance (useful for testing or custom configuration). */ declare function setLogger(customLogger: Logger$1): void; /** * Resets the logger instance (useful for testing). */ declare function resetLogger(): void; /** * Logger class wrapper for easier usage with context. */ declare class Logger { private pino; private context; constructor(logger?: Logger$1, context?: LoggerContext); /** * Creates a child logger with additional context. */ child(context: LoggerContext): Logger; /** * Logs a fatal error (application should terminate). */ fatal(message: string, context?: LoggerContext): void; /** * Logs an error. */ error(message: string, error?: Error | unknown, context?: LoggerContext): void; /** * Logs a warning. */ warn(message: string, context?: LoggerContext): void; /** * Logs informational message. */ info(message: string, context?: LoggerContext): void; /** * Logs a debug message (only in development or when level is debug). */ debug(message: string, context?: LoggerContext): void; /** * Logs a trace message (most verbose). */ trace(message: string, context?: LoggerContext): void; } /** * Default logger instance. */ declare const logger: Logger; /** * Creates a logger for a specific module/component. */ declare function createModuleLogger(module: string, context?: LoggerContext): Logger; /** * Generates a unique request ID for request tracking. */ declare function generateRequestId(): string; /** * Express middleware for request logging. * Adds request ID to res.locals and logs incoming requests. */ declare function requestLoggerMiddleware(options?: { logger?: Logger; logRequests?: boolean; logResponses?: boolean; ignorePaths?: (string | RegExp)[]; logStaticAssets?: boolean; }): (req: Request, res: Response, next: () => void) => void; /** * Gets the logger from the request object (set by requestLoggerMiddleware). */ declare function getRequestLogger(req: Request): Logger; export { type AuthContext, type AuthFn, DEFAULT_CONFIG, type FrameworkConfig, type GuardFn, type InitServerData, type LogLevel, Logger, type LoggerContext, type LoggerOptions, type RateLimitCfg, type RealtimeConfig, type RealtimeLogger, type RealtimeMetrics, type RealtimeStateStore, type RewriteCondition, type RewriteConfig, type RewriteDestination, type RewriteRule, type Schema, type ServerConfig, ValidationError, type WssContext, type WssEventDefinition, type WssHandler, type WssRouteDefinition, buildApp, commonSchemas, createModuleLogger, createRateLimiter, defaultRateLimiter, defineWssRoute, generateRequestId, getAppDir, getBuildDir, getLogger, getRequestLogger, getStaticDir, lenientRateLimiter, loadConfig, logger, requestLoggerMiddleware, resetLogger, safeValidate, sanitizeObject, sanitizeParams, sanitizeQuery, sanitizeString, setLogger, startDevServer, startProdServer, strictRateLimiter, validate, withCache };