@parsrun/server 0.1.28 → 0.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js.map +1 -1
- package/dist/context.d.ts +21 -1
- package/dist/context.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/index.d.ts +7 -771
- package/dist/middleware/index.js.map +1 -1
- package/dist/module-loader.js.map +1 -1
- package/dist/quota-enforcement-CN3z5bfc.d.ts +744 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/validation/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/app.ts","../src/context.ts","../src/module-loader.ts","../src/rls.ts","../src/rbac.ts","../src/middleware/error-handler.ts","../src/middleware/auth.ts","../src/middleware/cors.ts","../src/middleware/csrf.ts","../src/middleware/rate-limit.ts","../src/middleware/request-logger.ts","../src/middleware/usage-tracking.ts","../src/middleware/quota-enforcement.ts","../src/validation/index.ts","../src/utils/pagination.ts","../src/utils/response.ts","../src/health.ts"],"sourcesContent":["/**\n * @parsrun/server - App Factory\n * Create and configure Hono server instances\n */\n\nimport { Hono } from \"hono\";\nimport { createLogger } from \"@parsrun/core\";\nimport type {\n ServerConfig,\n ServerContextVariables,\n HonoApp,\n} from \"./context.js\";\nimport { generateRequestId } from \"./context.js\";\n\n/**\n * Extended server options\n */\nexport interface CreateServerOptions extends ServerConfig {\n /** Enable request logging */\n logging?: boolean;\n /** Enable request ID generation */\n requestId?: boolean;\n /** Base path for all routes */\n basePath?: string;\n /** Strict mode - trailing slashes matter */\n strict?: boolean;\n}\n\n/**\n * Create a new Pars server instance\n *\n * @example\n * ```typescript\n * const app = createServer({\n * database: db,\n * cors: { origin: '*' },\n * logging: true,\n * });\n *\n * app.get('/health', (c) => c.json({ status: 'ok' }));\n *\n * export default app;\n * ```\n */\nexport function createServer(options: CreateServerOptions): HonoApp {\n const app = new Hono<{ Variables: ServerContextVariables }>({\n strict: options.strict ?? false,\n });\n\n const logger = options.logger ?? createLogger({ name: \"pars-server\" });\n\n // Initialize context for all requests\n app.use(\"*\", async (c, next) => {\n // Set core context variables\n c.set(\"db\", options.database);\n c.set(\"config\", options);\n c.set(\"logger\", logger);\n c.set(\"enabledModules\", new Set<string>());\n c.set(\"cookiePrefix\", options.cookiePrefix);\n c.set(\"custom\", options.custom ?? {});\n\n // Generate request ID if enabled\n if (options.requestId !== false) {\n const requestId = c.req.header(\"x-request-id\") ?? generateRequestId();\n c.set(\"requestId\", requestId);\n c.header(\"x-request-id\", requestId);\n }\n\n await next();\n });\n\n return app;\n}\n\n/**\n * Create a router (sub-app) with shared context\n *\n * @example\n * ```typescript\n * const usersRouter = createRouter();\n *\n * usersRouter.get('/', async (c) => {\n * const users = await getUsers(c.get('db'));\n * return c.json(success(users));\n * });\n *\n * usersRouter.post('/', async (c) => {\n * // ...\n * });\n *\n * app.route('/api/users', usersRouter);\n * ```\n */\nexport function createRouter(): HonoApp {\n return new Hono<{ Variables: ServerContextVariables }>();\n}\n\n/**\n * Create a versioned API router\n *\n * @example\n * ```typescript\n * const v1 = createVersionedRouter('v1');\n * v1.get('/users', handler);\n *\n * app.route('/api', v1); // Results in /api/v1/users\n * ```\n */\nexport function createVersionedRouter(version: string): HonoApp {\n const router = new Hono<{ Variables: ServerContextVariables }>();\n\n // Add version to all routes\n const versionedRouter = new Hono<{ Variables: ServerContextVariables }>();\n versionedRouter.route(`/${version}`, router);\n\n return versionedRouter;\n}\n\n/**\n * Create a module router with prefix\n *\n * @example\n * ```typescript\n * const inventoryModule = createModuleRouter('inventory', {\n * routes: (router) => {\n * router.get('/items', listItems);\n * router.post('/items', createItem);\n * },\n * });\n *\n * app.route('/api', inventoryModule);\n * ```\n */\nexport function createModuleRouter(\n moduleName: string,\n options: {\n routes: (router: HonoApp) => void;\n middleware?: Array<(c: import(\"hono\").Context, next: () => Promise<void>) => Promise<Response | void>>;\n }\n): HonoApp {\n const moduleRouter = new Hono<{ Variables: ServerContextVariables }>();\n\n // Apply module-specific middleware\n if (options.middleware) {\n for (const mw of options.middleware) {\n moduleRouter.use(\"*\", mw);\n }\n }\n\n // Register routes\n options.routes(moduleRouter);\n\n // Wrap in module path\n const wrappedRouter = new Hono<{ Variables: ServerContextVariables }>();\n wrappedRouter.route(`/${moduleName}`, moduleRouter);\n\n return wrappedRouter;\n}\n","/**\n * @parsrun/server - Server Context\n * Type definitions for server context and configuration\n */\n\nimport type { Logger } from \"@parsrun/core\";\n\n/**\n * Database adapter interface\n * Implement this for your database (Drizzle, Prisma, etc.)\n */\nexport interface DatabaseAdapter {\n /** Execute raw SQL query */\n execute(sql: string): Promise<unknown>;\n /** Check connection */\n ping?(): Promise<boolean>;\n}\n\n/**\n * Module manifest for registering modules\n */\nexport interface ModuleManifest {\n /** Unique module name */\n name: string;\n /** Module version */\n version: string;\n /** Module description */\n description: string;\n /** Required permissions for this module */\n permissions: Record<string, string[]>;\n /** Module dependencies (other module names) */\n dependencies?: string[];\n /** Register routes for this module */\n registerRoutes: (app: HonoApp) => void;\n /** Called when module is enabled */\n onEnable?: () => Promise<void>;\n /** Called when module is disabled */\n onDisable?: () => Promise<void>;\n}\n\n/**\n * Server configuration\n */\nexport interface ServerConfig {\n /** Database adapter */\n database: DatabaseAdapter;\n /** CORS configuration */\n cors?: CorsConfig;\n /** Base path for API */\n basePath?: string;\n /** Cookie prefix for all cookies */\n cookiePrefix?: string;\n /** Logger instance */\n logger?: Logger;\n /** Custom context data */\n custom?: Record<string, unknown>;\n}\n\n/**\n * CORS configuration\n */\nexport interface CorsConfig {\n /** Allowed origins */\n origin: string | string[] | ((origin: string) => boolean);\n /** Allow credentials */\n credentials?: boolean;\n /** Allowed methods */\n methods?: string[];\n /** Allowed headers */\n allowedHeaders?: string[];\n /** Exposed headers */\n exposedHeaders?: string[];\n /** Max age in seconds */\n maxAge?: number;\n}\n\n/**\n * User information in context\n */\nexport interface ContextUser {\n id: string;\n email: string | undefined;\n tenantId: string | undefined;\n role: string | undefined;\n permissions: string[];\n}\n\n/**\n * Tenant information in context\n */\nexport interface ContextTenant {\n id: string;\n slug: string | undefined;\n name: string | undefined;\n status: string;\n}\n\n/**\n * Server context variables\n * Available in Hono context via c.get()\n */\nexport interface ServerContextVariables {\n /** Database adapter */\n db: DatabaseAdapter;\n /** Server configuration */\n config: ServerConfig;\n /** Enabled modules set */\n enabledModules: Set<string>;\n /** Current user (if authenticated) */\n user: ContextUser | undefined;\n /** Current tenant (if resolved) */\n tenant: ContextTenant | undefined;\n /** Request logger */\n logger: Logger;\n /** Request ID */\n requestId: string;\n /** Cookie prefix */\n cookiePrefix: string | undefined;\n /** Custom context data */\n custom: Record<string, unknown>;\n}\n\n/**\n * Hono app type with server context\n */\nexport type HonoApp = import(\"hono\").Hono<{ Variables: ServerContextVariables }>;\n\n/**\n * Hono context type with server context\n */\nexport type HonoContext = import(\"hono\").Context<{ Variables: ServerContextVariables }>;\n\n/**\n * Middleware next function\n */\nexport type HonoNext = () => Promise<void>;\n\n/**\n * Middleware function type\n */\nexport type Middleware = (c: HonoContext, next: HonoNext) => Promise<Response | void>;\n\n/**\n * Route handler function type\n */\nexport type RouteHandler = (c: HonoContext) => Promise<Response> | Response;\n\n/**\n * Permission check input\n */\nexport interface PermissionCheck {\n /** Resource name (e.g., \"users\", \"items\") */\n resource: string;\n /** Action name (e.g., \"read\", \"create\", \"update\", \"delete\") */\n action: string;\n /** Permission scope */\n scope?: \"tenant\" | \"global\" | \"own\";\n}\n\n/**\n * Permission definition\n */\nexport interface PermissionDefinition {\n /** Permission name (e.g., \"users:read\") */\n name: string;\n /** Resource part */\n resource: string;\n /** Action part */\n action: string;\n /** Description */\n description?: string;\n /** Scope */\n scope?: \"tenant\" | \"global\" | \"own\";\n}\n\n/**\n * Role definition\n */\nexport interface RoleDefinition {\n /** Role name */\n name: string;\n /** Display name */\n displayName?: string;\n /** Description */\n description?: string;\n /** Permissions assigned to this role */\n permissions: string[];\n /** Is this a system role */\n isSystem?: boolean;\n}\n\n/**\n * Standard API response structure\n */\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: {\n code: string;\n message: string;\n details?: Record<string, unknown> | undefined;\n };\n meta?: {\n page?: number | undefined;\n limit?: number | undefined;\n total?: number | undefined;\n requestId?: string | undefined;\n } | undefined;\n}\n\n/**\n * Create a success response\n */\nexport function success<T>(data: T, meta?: ApiResponse[\"meta\"]): ApiResponse<T> {\n return {\n success: true,\n data,\n meta: meta ?? undefined,\n };\n}\n\n/**\n * Create an error response\n */\nexport function error(\n code: string,\n message: string,\n details?: Record<string, unknown>\n): ApiResponse<never> {\n return {\n success: false,\n error: { code, message, details: details ?? undefined },\n };\n}\n\n/**\n * Generate a request ID\n */\nexport function generateRequestId(): string {\n return crypto.randomUUID();\n}\n","/**\n * @parsrun/server - Module Loader\n * Dynamic module loading system for Pars server\n */\n\nimport { Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport { createLogger, type Logger } from \"@parsrun/core\";\nimport type {\n CorsConfig,\n DatabaseAdapter,\n HonoApp,\n ModuleManifest,\n ServerConfig,\n ServerContextVariables,\n} from \"./context.js\";\nimport { generateRequestId } from \"./context.js\";\n\n/**\n * Module Loader options\n */\nexport interface ModuleLoaderOptions {\n /** Server configuration */\n config: ServerConfig;\n /** Cookie prefix */\n cookiePrefix?: string;\n /** Logger instance */\n logger?: Logger;\n}\n\n/**\n * Module Loader\n * Manages dynamic module registration and lifecycle\n *\n * @example\n * ```typescript\n * const loader = new ModuleLoader({\n * config: {\n * database: drizzleDb,\n * cors: { origin: '*' },\n * },\n * });\n *\n * await loader.initialize();\n *\n * // Register modules\n * loader.registerModule(itemsModule);\n * loader.registerModule(usersModule);\n *\n * // Enable modules\n * await loader.enableModule('items');\n * await loader.enableModule('users');\n *\n * // Get Hono app\n * export default loader.getApp();\n * ```\n */\nexport class ModuleLoader {\n private app: HonoApp;\n private db: DatabaseAdapter;\n private enabledModules: Set<string> = new Set();\n private moduleRegistry: Map<string, ModuleManifest> = new Map();\n private logger: Logger;\n private config: ServerConfig;\n private cookiePrefix: string | undefined;\n private initialized = false;\n\n constructor(options: ModuleLoaderOptions) {\n this.config = options.config;\n this.db = options.config.database;\n this.cookiePrefix = options.cookiePrefix;\n this.logger = options.logger ?? createLogger({ name: \"ModuleLoader\" });\n\n // Create Hono app with typed context\n this.app = new Hono<{ Variables: ServerContextVariables }>();\n\n this.setupMiddleware();\n this.setupCoreRoutes();\n }\n\n /**\n * Initialize the module loader\n * Checks database connection\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n this.logger.warn(\"ModuleLoader already initialized\");\n return;\n }\n\n this.logger.info(\"Initializing ModuleLoader...\");\n\n // Check database connection\n try {\n if (this.db.ping) {\n const ok = await this.db.ping();\n if (!ok) throw new Error(\"Database ping returned false\");\n } else {\n await this.db.execute(\"SELECT 1\");\n }\n this.logger.info(\"Database connection: OK\");\n } catch (error) {\n this.logger.error(\"Database connection failed\", error);\n throw new Error(\"Database connection failed\");\n }\n\n this.initialized = true;\n this.logger.info(\"ModuleLoader initialized successfully\");\n }\n\n /**\n * Setup core middleware\n */\n private setupMiddleware(): void {\n // Request ID and logging\n this.app.use(\"*\", async (c, next) => {\n const requestId = generateRequestId();\n const requestLogger = this.logger.child({ requestId });\n\n // Set context variables\n c.set(\"db\", this.db);\n c.set(\"config\", this.config);\n c.set(\"enabledModules\", this.enabledModules);\n c.set(\"logger\", requestLogger);\n c.set(\"requestId\", requestId);\n c.set(\"cookiePrefix\", this.cookiePrefix);\n c.set(\"custom\", this.config.custom ?? {});\n c.set(\"user\", undefined);\n c.set(\"tenant\", undefined);\n\n const start = Date.now();\n\n await next();\n\n const duration = Date.now() - start;\n requestLogger.debug(\"Request completed\", {\n method: c.req.method,\n path: c.req.path,\n status: c.res.status,\n durationMs: duration,\n });\n });\n\n // CORS\n if (this.config.cors) {\n this.app.use(\"*\", cors(this.normalizeCorsConfig(this.config.cors)));\n }\n }\n\n /**\n * Normalize CORS config for Hono\n */\n private normalizeCorsConfig(config: CorsConfig): Parameters<typeof cors>[0] {\n const result: Parameters<typeof cors>[0] = {\n origin: typeof config.origin === \"function\"\n ? (origin) => (config.origin as (origin: string) => boolean)(origin) ? origin : null\n : config.origin,\n };\n\n if (config.credentials !== undefined) {\n result.credentials = config.credentials;\n }\n if (config.methods !== undefined) {\n result.allowMethods = config.methods;\n }\n if (config.allowedHeaders !== undefined) {\n result.allowHeaders = config.allowedHeaders;\n }\n if (config.exposedHeaders !== undefined) {\n result.exposeHeaders = config.exposedHeaders;\n }\n if (config.maxAge !== undefined) {\n result.maxAge = config.maxAge;\n }\n\n return result;\n }\n\n /**\n * Setup core routes\n */\n private setupCoreRoutes(): void {\n const basePath = this.config.basePath ?? \"/api/v1\";\n\n // Health check\n this.app.get(\"/health\", (c) => {\n return c.json({\n status: \"ok\",\n timestamp: new Date().toISOString(),\n });\n });\n\n // Health check with details\n this.app.get(\"/health/details\", async (c) => {\n let dbStatus = \"unknown\";\n try {\n if (this.db.ping) {\n dbStatus = (await this.db.ping()) ? \"ok\" : \"error\";\n } else {\n await this.db.execute(\"SELECT 1\");\n dbStatus = \"ok\";\n }\n } catch {\n dbStatus = \"error\";\n }\n\n return c.json({\n status: dbStatus === \"ok\" ? \"ok\" : \"degraded\",\n timestamp: new Date().toISOString(),\n services: {\n database: dbStatus,\n },\n modules: {\n enabled: Array.from(this.enabledModules),\n registered: Array.from(this.moduleRegistry.keys()),\n },\n });\n });\n\n // API info\n this.app.get(basePath, (c) => {\n const endpoints: Record<string, string> = {\n health: \"/health\",\n features: `${basePath}/features`,\n };\n\n // Add module endpoints\n for (const moduleName of this.enabledModules) {\n endpoints[moduleName] = `${basePath}/${moduleName}`;\n }\n\n return c.json({\n name: \"Pars API\",\n version: \"1.0.0\",\n endpoints,\n });\n });\n\n // Feature discovery\n this.app.get(`${basePath}/features`, (c) => {\n const features = Array.from(this.enabledModules).map((name) => {\n const module = this.moduleRegistry.get(name);\n return {\n name,\n version: module?.version ?? \"1.0.0\",\n description: module?.description ?? \"\",\n permissions: module?.permissions ?? {},\n };\n });\n\n return c.json({\n enabled: Array.from(this.enabledModules),\n features,\n });\n });\n }\n\n /**\n * Register a module\n */\n registerModule(manifest: ModuleManifest): void {\n if (this.moduleRegistry.has(manifest.name)) {\n this.logger.warn(`Module already registered: ${manifest.name}`);\n return;\n }\n\n this.moduleRegistry.set(manifest.name, manifest);\n this.logger.info(`Registered module: ${manifest.name}`);\n }\n\n /**\n * Enable a registered module\n */\n async enableModule(moduleName: string): Promise<boolean> {\n const module = this.moduleRegistry.get(moduleName);\n\n if (!module) {\n this.logger.error(`Module not found: ${moduleName}`);\n return false;\n }\n\n if (this.enabledModules.has(moduleName)) {\n this.logger.warn(`Module already enabled: ${moduleName}`);\n return true;\n }\n\n // Check dependencies\n if (module.dependencies) {\n for (const dep of module.dependencies) {\n if (!this.enabledModules.has(dep)) {\n this.logger.error(\n `Module ${moduleName} requires ${dep} to be enabled first`\n );\n return false;\n }\n }\n }\n\n try {\n this.logger.info(`Enabling module: ${moduleName}`);\n\n // Run onEnable hook\n if (module.onEnable) {\n await module.onEnable();\n }\n\n // Register routes\n module.registerRoutes(this.app);\n\n // Mark as enabled\n this.enabledModules.add(moduleName);\n\n this.logger.info(`Enabled module: ${moduleName}`);\n return true;\n } catch (error) {\n this.logger.error(`Failed to enable module ${moduleName}`, error);\n return false;\n }\n }\n\n /**\n * Disable an enabled module\n */\n async disableModule(moduleName: string): Promise<boolean> {\n if (!this.enabledModules.has(moduleName)) {\n this.logger.warn(`Module not enabled: ${moduleName}`);\n return true;\n }\n\n const module = this.moduleRegistry.get(moduleName);\n if (!module) {\n this.logger.error(`Module not found: ${moduleName}`);\n return false;\n }\n\n // Check if other modules depend on this one\n for (const [name, m] of this.moduleRegistry) {\n if (this.enabledModules.has(name) && m.dependencies?.includes(moduleName)) {\n this.logger.error(\n `Cannot disable ${moduleName}: ${name} depends on it`\n );\n return false;\n }\n }\n\n try {\n // Run onDisable hook\n if (module.onDisable) {\n await module.onDisable();\n }\n\n // Note: Routes cannot be easily unregistered in Hono\n // The module will remain registered but marked as disabled\n this.enabledModules.delete(moduleName);\n\n this.logger.info(`Disabled module: ${moduleName}`);\n return true;\n } catch (error) {\n this.logger.error(`Failed to disable module ${moduleName}`, error);\n return false;\n }\n }\n\n /**\n * Get the Hono app instance\n */\n getApp(): HonoApp {\n return this.app;\n }\n\n /**\n * Get enabled modules\n */\n getEnabledModules(): string[] {\n return Array.from(this.enabledModules);\n }\n\n /**\n * Get registered modules\n */\n getRegisteredModules(): string[] {\n return Array.from(this.moduleRegistry.keys());\n }\n\n /**\n * Check if module is enabled\n */\n isModuleEnabled(moduleName: string): boolean {\n return this.enabledModules.has(moduleName);\n }\n\n /**\n * Check if module is registered\n */\n isModuleRegistered(moduleName: string): boolean {\n return this.moduleRegistry.has(moduleName);\n }\n\n /**\n * Get database adapter\n */\n getDatabase(): DatabaseAdapter {\n return this.db;\n }\n\n /**\n * Get logger\n */\n getLogger(): Logger {\n return this.logger;\n }\n}\n\n/**\n * Create a module loader\n */\nexport function createModuleLoader(options: ModuleLoaderOptions): ModuleLoader {\n return new ModuleLoader(options);\n}\n\n/**\n * Create a module manifest helper\n */\nexport function defineModule(manifest: ModuleManifest): ModuleManifest {\n return manifest;\n}\n","/**\n * @parsrun/server - Row Level Security (RLS) Manager\n * PostgreSQL RLS integration for multi-tenant isolation\n */\n\nimport type { DatabaseAdapter, HonoContext, HonoNext, Middleware } from \"./context.js\";\n\n/**\n * RLS configuration\n */\nexport interface RLSConfig {\n /** Tenant ID column name (default: tenant_id) */\n tenantIdColumn?: string;\n /** PostgreSQL session variable name (default: app.current_tenant_id) */\n sessionVariable?: string;\n /** Enable RLS by default */\n enabled?: boolean;\n}\n\n/**\n * Default RLS configuration\n */\nconst DEFAULT_RLS_CONFIG: Required<RLSConfig> = {\n tenantIdColumn: \"tenant_id\",\n sessionVariable: \"app.current_tenant_id\",\n enabled: true,\n};\n\n/**\n * RLS Manager for tenant isolation\n *\n * @example\n * ```typescript\n * const rls = new RLSManager(db);\n *\n * // Set tenant context\n * await rls.setTenantId(\"tenant-123\");\n *\n * // All queries now filtered by tenant\n * const items = await db.select().from(items);\n *\n * // Clear when done\n * await rls.clearTenantId();\n *\n * // Or use withTenant helper\n * await rls.withTenant(\"tenant-123\", async () => {\n * return await db.select().from(items);\n * });\n * ```\n */\nexport class RLSManager {\n private config: Required<RLSConfig>;\n\n constructor(\n private db: DatabaseAdapter,\n config: RLSConfig = {}\n ) {\n this.config = { ...DEFAULT_RLS_CONFIG, ...config };\n }\n\n /**\n * Set current tenant ID in database session\n * This enables RLS policies to filter by tenant\n */\n async setTenantId(tenantId: string): Promise<void> {\n if (!this.config.enabled) return;\n\n try {\n // Use parameterized query to prevent SQL injection\n // PostgreSQL SET command with escaped string\n const escapedTenantId = tenantId.replace(/'/g, \"''\");\n await this.db.execute(`SET ${this.config.sessionVariable} = '${escapedTenantId}'`);\n } catch (error) {\n console.error(\"Failed to set tenant ID for RLS:\", error);\n throw new RLSError(\"Failed to set tenant context\", \"RLS_SET_FAILED\", error);\n }\n }\n\n /**\n * Clear current tenant ID from database session\n */\n async clearTenantId(): Promise<void> {\n if (!this.config.enabled) return;\n\n try {\n await this.db.execute(`RESET ${this.config.sessionVariable}`);\n } catch (error) {\n console.error(\"Failed to clear tenant ID for RLS:\", error);\n throw new RLSError(\"Failed to clear tenant context\", \"RLS_CLEAR_FAILED\", error);\n }\n }\n\n /**\n * Execute a function with tenant context\n * Automatically sets and clears tenant ID\n */\n async withTenant<T>(tenantId: string, operation: () => Promise<T>): Promise<T> {\n await this.setTenantId(tenantId);\n try {\n return await operation();\n } finally {\n await this.clearTenantId();\n }\n }\n\n /**\n * Check if RLS is enabled\n */\n isEnabled(): boolean {\n return this.config.enabled;\n }\n\n /**\n * Get current configuration\n */\n getConfig(): Required<RLSConfig> {\n return { ...this.config };\n }\n}\n\n/**\n * RLS Error class\n */\nexport class RLSError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = \"RLSError\";\n }\n}\n\n/**\n * Create RLS manager\n */\nexport function createRLSManager(db: DatabaseAdapter, config?: RLSConfig): RLSManager {\n return new RLSManager(db, config);\n}\n\n/**\n * RLS Middleware\n * Automatically sets tenant context for authenticated requests\n *\n * @example\n * ```typescript\n * app.use('*', rlsMiddleware());\n * ```\n */\nexport function rlsMiddleware(config?: RLSConfig): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n const db = c.get(\"db\");\n\n // Skip if no user or no tenant\n if (!user?.tenantId || !db) {\n return next();\n }\n\n const rls = new RLSManager(db, config);\n\n try {\n await rls.setTenantId(user.tenantId);\n await next();\n } finally {\n await rls.clearTenantId();\n }\n };\n}\n\n/**\n * Create SQL for enabling RLS on a table\n *\n * @example\n * ```sql\n * -- Generated SQL:\n * ALTER TABLE items ENABLE ROW LEVEL SECURITY;\n * CREATE POLICY items_tenant_isolation ON items\n * USING (tenant_id = current_setting('app.current_tenant_id')::uuid);\n * ```\n */\nexport function generateRLSPolicy(\n tableName: string,\n options: {\n tenantIdColumn?: string;\n sessionVariable?: string;\n policyName?: string;\n castType?: string;\n } = {}\n): string {\n const {\n tenantIdColumn = \"tenant_id\",\n sessionVariable = \"app.current_tenant_id\",\n policyName = `${tableName}_tenant_isolation`,\n castType = \"uuid\",\n } = options;\n\n return `\n-- Enable RLS on table\nALTER TABLE ${tableName} ENABLE ROW LEVEL SECURITY;\n\n-- Force RLS for table owner too\nALTER TABLE ${tableName} FORCE ROW LEVEL SECURITY;\n\n-- Create tenant isolation policy\nDROP POLICY IF EXISTS ${policyName} ON ${tableName};\nCREATE POLICY ${policyName} ON ${tableName}\n FOR ALL\n USING (${tenantIdColumn} = current_setting('${sessionVariable}', true)::${castType});\n`.trim();\n}\n\n/**\n * Create SQL for disabling RLS on a table\n */\nexport function generateDisableRLS(tableName: string): string {\n return `\nALTER TABLE ${tableName} DISABLE ROW LEVEL SECURITY;\nALTER TABLE ${tableName} NO FORCE ROW LEVEL SECURITY;\n`.trim();\n}\n","/**\n * @parsrun/server - Role-Based Access Control (RBAC)\n * Permission and role management with middleware\n */\n\nimport { ForbiddenError, UnauthorizedError } from \"@parsrun/core\";\nimport type {\n ContextUser,\n HonoContext,\n HonoNext,\n Middleware,\n PermissionCheck,\n PermissionDefinition,\n RoleDefinition,\n} from \"./context.js\";\n\n/**\n * RBAC Permission Checker interface\n * Implement this for database-backed permission checks\n */\nexport interface PermissionChecker {\n /** Get user's permissions in a tenant */\n getUserPermissions(userId: string, tenantId?: string): Promise<string[]>;\n /** Get user's roles in a tenant */\n getUserRoles(userId: string, tenantId?: string): Promise<string[]>;\n /** Check if user has specific permission */\n hasPermission(userId: string, check: PermissionCheck, tenantId?: string): Promise<boolean>;\n /** Check if user is member of tenant */\n isTenantMember(userId: string, tenantId: string): Promise<boolean>;\n}\n\n/**\n * In-memory RBAC service\n * For simple use cases or testing\n */\nexport class InMemoryRBAC implements PermissionChecker {\n private userPermissions: Map<string, Set<string>> = new Map();\n private userRoles: Map<string, Set<string>> = new Map();\n private rolePermissions: Map<string, Set<string>> = new Map();\n private tenantMembers: Map<string, Set<string>> = new Map();\n\n /**\n * Grant permission to user\n */\n grantPermission(userId: string, permission: string): void {\n if (!this.userPermissions.has(userId)) {\n this.userPermissions.set(userId, new Set());\n }\n this.userPermissions.get(userId)!.add(permission);\n }\n\n /**\n * Revoke permission from user\n */\n revokePermission(userId: string, permission: string): void {\n this.userPermissions.get(userId)?.delete(permission);\n }\n\n /**\n * Assign role to user\n */\n assignRole(userId: string, role: string): void {\n if (!this.userRoles.has(userId)) {\n this.userRoles.set(userId, new Set());\n }\n this.userRoles.get(userId)!.add(role);\n }\n\n /**\n * Remove role from user\n */\n removeRole(userId: string, role: string): void {\n this.userRoles.get(userId)?.delete(role);\n }\n\n /**\n * Define role with permissions\n */\n defineRole(roleName: string, permissions: string[]): void {\n this.rolePermissions.set(roleName, new Set(permissions));\n }\n\n /**\n * Add user to tenant\n */\n addTenantMember(tenantId: string, userId: string): void {\n if (!this.tenantMembers.has(tenantId)) {\n this.tenantMembers.set(tenantId, new Set());\n }\n this.tenantMembers.get(tenantId)!.add(userId);\n }\n\n /**\n * Remove user from tenant\n */\n removeTenantMember(tenantId: string, userId: string): void {\n this.tenantMembers.get(tenantId)?.delete(userId);\n }\n\n // PermissionChecker implementation\n\n async getUserPermissions(userId: string, _tenantId?: string): Promise<string[]> {\n const permissions = new Set<string>();\n\n // Direct permissions\n const direct = this.userPermissions.get(userId);\n if (direct) {\n direct.forEach((p) => permissions.add(p));\n }\n\n // Role-based permissions\n const roles = this.userRoles.get(userId);\n if (roles) {\n roles.forEach((role) => {\n const rolePerms = this.rolePermissions.get(role);\n if (rolePerms) {\n rolePerms.forEach((p) => permissions.add(p));\n }\n });\n }\n\n return Array.from(permissions);\n }\n\n async getUserRoles(userId: string, _tenantId?: string): Promise<string[]> {\n return Array.from(this.userRoles.get(userId) ?? []);\n }\n\n async hasPermission(\n userId: string,\n check: PermissionCheck,\n tenantId?: string\n ): Promise<boolean> {\n const permissions = await this.getUserPermissions(userId, tenantId);\n const permissionName = `${check.resource}:${check.action}`;\n\n // Check exact match\n if (permissions.includes(permissionName)) {\n return true;\n }\n\n // Check wildcard patterns\n // users:* matches users:read, users:create, etc.\n // *:read matches items:read, users:read, etc.\n // * matches everything\n for (const perm of permissions) {\n if (perm === \"*\") return true;\n if (perm === `${check.resource}:*`) return true;\n if (perm === `*:${check.action}`) return true;\n }\n\n return false;\n }\n\n async isTenantMember(userId: string, tenantId: string): Promise<boolean> {\n return this.tenantMembers.get(tenantId)?.has(userId) ?? false;\n }\n}\n\n/**\n * RBAC Service for authorization checks\n */\nexport class RBACService {\n constructor(private checker: PermissionChecker) {}\n\n /**\n * Get user's permissions\n */\n async getUserPermissions(userId: string, tenantId?: string): Promise<string[]> {\n return this.checker.getUserPermissions(userId, tenantId);\n }\n\n /**\n * Get user's roles\n */\n async getUserRoles(userId: string, tenantId?: string): Promise<string[]> {\n return this.checker.getUserRoles(userId, tenantId);\n }\n\n /**\n * Check if user has specific permission\n */\n async hasPermission(\n userId: string,\n check: PermissionCheck,\n tenantId?: string\n ): Promise<boolean> {\n return this.checker.hasPermission(userId, check, tenantId);\n }\n\n /**\n * Check if user has any of the specified permissions\n */\n async hasAnyPermission(\n userId: string,\n checks: PermissionCheck[],\n tenantId?: string\n ): Promise<boolean> {\n for (const check of checks) {\n if (await this.hasPermission(userId, check, tenantId)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Check if user has all specified permissions\n */\n async hasAllPermissions(\n userId: string,\n checks: PermissionCheck[],\n tenantId?: string\n ): Promise<boolean> {\n for (const check of checks) {\n if (!(await this.hasPermission(userId, check, tenantId))) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Check if user is member of tenant\n */\n async isTenantMember(userId: string, tenantId: string): Promise<boolean> {\n return this.checker.isTenantMember(userId, tenantId);\n }\n\n /**\n * Check if user has specific role\n */\n async hasRole(userId: string, role: string, tenantId?: string): Promise<boolean> {\n const roles = await this.getUserRoles(userId, tenantId);\n return roles.includes(role);\n }\n\n /**\n * Check if user has any of the specified roles\n */\n async hasAnyRole(userId: string, roles: string[], tenantId?: string): Promise<boolean> {\n const userRoles = await this.getUserRoles(userId, tenantId);\n return roles.some((role) => userRoles.includes(role));\n }\n}\n\n/**\n * Create RBAC service with in-memory checker\n */\nexport function createInMemoryRBAC(): { rbac: RBACService; checker: InMemoryRBAC } {\n const checker = new InMemoryRBAC();\n const rbac = new RBACService(checker);\n return { rbac, checker };\n}\n\n/**\n * Create RBAC service with custom checker\n */\nexport function createRBACService(checker: PermissionChecker): RBACService {\n return new RBACService(checker);\n}\n\n// ============================================\n// MIDDLEWARE FACTORIES\n// ============================================\n\n/**\n * Require authentication middleware\n */\nexport function requireAuth(): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n\n if (!user) {\n throw new UnauthorizedError(\"Authentication required\");\n }\n\n return next();\n };\n}\n\n/**\n * Require specific permission middleware\n *\n * @example\n * ```typescript\n * app.get('/items', requirePermission('items', 'read'), handler);\n * app.post('/items', requirePermission('items', 'create'), handler);\n * ```\n */\nexport function requirePermission(\n resource: string,\n action: string,\n options: { scope?: \"tenant\" | \"global\" | \"own\"; checker?: PermissionChecker } = {}\n): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n\n if (!user) {\n throw new UnauthorizedError(\"Authentication required\");\n }\n\n const check: PermissionCheck = {\n resource,\n action,\n scope: options.scope ?? \"tenant\",\n };\n\n // Use custom checker or check from user permissions\n let hasPermission = false;\n\n if (options.checker) {\n hasPermission = await options.checker.hasPermission(user.id, check, user.tenantId);\n } else {\n // Check from user's loaded permissions\n hasPermission = checkUserPermission(user, check);\n }\n\n if (!hasPermission) {\n throw new ForbiddenError(`Permission denied: ${resource}:${action}`);\n }\n\n return next();\n };\n}\n\n/**\n * Require any of specified permissions middleware\n */\nexport function requireAnyPermission(\n permissions: Array<{ resource: string; action: string }>,\n options: { checker?: PermissionChecker } = {}\n): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n\n if (!user) {\n throw new UnauthorizedError(\"Authentication required\");\n }\n\n let hasAny = false;\n\n for (const perm of permissions) {\n const check: PermissionCheck = { resource: perm.resource, action: perm.action };\n\n if (options.checker) {\n if (await options.checker.hasPermission(user.id, check, user.tenantId)) {\n hasAny = true;\n break;\n }\n } else {\n if (checkUserPermission(user, check)) {\n hasAny = true;\n break;\n }\n }\n }\n\n if (!hasAny) {\n throw new ForbiddenError(\"Insufficient permissions\");\n }\n\n return next();\n };\n}\n\n/**\n * Require specific role middleware\n */\nexport function requireRole(role: string): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n\n if (!user) {\n throw new UnauthorizedError(\"Authentication required\");\n }\n\n if (user.role !== role) {\n throw new ForbiddenError(`Role required: ${role}`);\n }\n\n return next();\n };\n}\n\n/**\n * Require any of specified roles middleware\n */\nexport function requireAnyRole(roles: string[]): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n\n if (!user) {\n throw new UnauthorizedError(\"Authentication required\");\n }\n\n if (!user.role || !roles.includes(user.role)) {\n throw new ForbiddenError(`One of these roles required: ${roles.join(\", \")}`);\n }\n\n return next();\n };\n}\n\n/**\n * Require tenant membership middleware\n */\nexport function requireTenantMember(requiredRole?: string): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n const tenant = c.get(\"tenant\");\n\n if (!user) {\n throw new UnauthorizedError(\"Authentication required\");\n }\n\n if (!tenant) {\n throw new ForbiddenError(\"Tenant context required\");\n }\n\n if (user.tenantId !== tenant.id) {\n throw new ForbiddenError(\"Not a member of this tenant\");\n }\n\n if (requiredRole && user.role !== requiredRole) {\n throw new ForbiddenError(`Role required in tenant: ${requiredRole}`);\n }\n\n return next();\n };\n}\n\n/**\n * Check user permission from loaded permissions array\n */\nfunction checkUserPermission(user: ContextUser, check: PermissionCheck): boolean {\n const permissionName = `${check.resource}:${check.action}`;\n\n for (const perm of user.permissions) {\n if (perm === permissionName) return true;\n if (perm === \"*\") return true;\n if (perm === `${check.resource}:*`) return true;\n if (perm === `*:${check.action}`) return true;\n }\n\n return false;\n}\n\n// ============================================\n// PERMISSION UTILITIES\n// ============================================\n\n/**\n * Parse permission string to PermissionCheck\n */\nexport function parsePermission(permission: string): PermissionCheck {\n const [resource, action] = permission.split(\":\");\n if (!resource || !action) {\n throw new Error(`Invalid permission format: ${permission}`);\n }\n return { resource, action };\n}\n\n/**\n * Create permission string from parts\n */\nexport function createPermission(resource: string, action: string): string {\n return `${resource}:${action}`;\n}\n\n/**\n * Standard CRUD permissions for a resource\n */\nexport function crudPermissions(resource: string): PermissionDefinition[] {\n return [\n { name: `${resource}:create`, resource, action: \"create\" },\n { name: `${resource}:read`, resource, action: \"read\" },\n { name: `${resource}:update`, resource, action: \"update\" },\n { name: `${resource}:delete`, resource, action: \"delete\" },\n { name: `${resource}:list`, resource, action: \"list\" },\n ];\n}\n\n/**\n * Standard roles\n */\nexport const StandardRoles: Record<string, RoleDefinition> = {\n OWNER: {\n name: \"owner\",\n displayName: \"Owner\",\n description: \"Full access to all resources\",\n permissions: [\"*\"],\n isSystem: true,\n },\n ADMIN: {\n name: \"admin\",\n displayName: \"Administrator\",\n description: \"Administrative access\",\n permissions: [\"*:read\", \"*:create\", \"*:update\", \"*:list\"],\n isSystem: true,\n },\n MEMBER: {\n name: \"member\",\n displayName: \"Member\",\n description: \"Standard member access\",\n permissions: [\"*:read\", \"*:list\"],\n isSystem: true,\n },\n VIEWER: {\n name: \"viewer\",\n displayName: \"Viewer\",\n description: \"Read-only access\",\n permissions: [\"*:read\", \"*:list\"],\n isSystem: true,\n },\n};\n","/**\n * @parsrun/server - Error Handler Middleware\n * Global error handling and response formatting\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\nimport { error as errorResponse } from \"../context.js\";\nimport type { ErrorTransport, ErrorContext } from \"@parsrun/core/transports\";\n\n/**\n * Base API error class\n */\nexport class ApiError extends Error {\n constructor(\n public readonly statusCode: number,\n public readonly code: string,\n message: string,\n public readonly details?: Record<string, unknown>\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n\n toResponse() {\n return errorResponse(this.code, this.message, this.details);\n }\n}\n\n/**\n * 400 Bad Request\n */\nexport class BadRequestError extends ApiError {\n constructor(message = \"Bad request\", details?: Record<string, unknown>) {\n super(400, \"BAD_REQUEST\", message, details);\n this.name = \"BadRequestError\";\n }\n}\n\n/**\n * 401 Unauthorized\n */\nexport class UnauthorizedError extends ApiError {\n constructor(message = \"Unauthorized\", details?: Record<string, unknown>) {\n super(401, \"UNAUTHORIZED\", message, details);\n this.name = \"UnauthorizedError\";\n }\n}\n\n/**\n * 403 Forbidden\n */\nexport class ForbiddenError extends ApiError {\n constructor(message = \"Forbidden\", details?: Record<string, unknown>) {\n super(403, \"FORBIDDEN\", message, details);\n this.name = \"ForbiddenError\";\n }\n}\n\n/**\n * 404 Not Found\n */\nexport class NotFoundError extends ApiError {\n constructor(message = \"Not found\", details?: Record<string, unknown>) {\n super(404, \"NOT_FOUND\", message, details);\n this.name = \"NotFoundError\";\n }\n}\n\n/**\n * 409 Conflict\n */\nexport class ConflictError extends ApiError {\n constructor(message = \"Conflict\", details?: Record<string, unknown>) {\n super(409, \"CONFLICT\", message, details);\n this.name = \"ConflictError\";\n }\n}\n\n/**\n * 422 Unprocessable Entity (Validation Error)\n */\nexport class ValidationError extends ApiError {\n constructor(message = \"Validation failed\", details?: Record<string, unknown>) {\n super(422, \"VALIDATION_ERROR\", message, details);\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * 429 Too Many Requests\n */\nexport class RateLimitError extends ApiError {\n constructor(\n message = \"Too many requests\",\n public readonly retryAfter?: number\n ) {\n super(429, \"RATE_LIMIT_EXCEEDED\", message, { retryAfter });\n this.name = \"RateLimitError\";\n }\n}\n\n/**\n * 500 Internal Server Error\n */\nexport class InternalError extends ApiError {\n constructor(message = \"Internal server error\", details?: Record<string, unknown>) {\n super(500, \"INTERNAL_ERROR\", message, details);\n this.name = \"InternalError\";\n }\n}\n\n/**\n * 503 Service Unavailable\n */\nexport class ServiceUnavailableError extends ApiError {\n constructor(message = \"Service unavailable\", details?: Record<string, unknown>) {\n super(503, \"SERVICE_UNAVAILABLE\", message, details);\n this.name = \"ServiceUnavailableError\";\n }\n}\n\n/**\n * Error handler options\n */\nexport interface ErrorHandlerOptions {\n /** Include stack trace in development */\n includeStack?: boolean;\n /** Custom error logger */\n onError?: (error: Error, c: HonoContext) => void;\n /**\n * Error transport for external error tracking (e.g., Sentry)\n * Automatically captures exceptions with request context\n */\n errorTransport?: ErrorTransport;\n /**\n * Capture all errors including 4xx client errors\n * By default, only 5xx server errors are captured\n * @default false\n */\n captureAllErrors?: boolean;\n /**\n * Custom function to determine if an error should be captured\n * Overrides the default captureAllErrors behavior\n */\n shouldCapture?: (error: Error, statusCode: number) => boolean;\n}\n\n/**\n * Global error handler middleware\n *\n * @example Basic usage\n * ```typescript\n * app.use('*', errorHandler({\n * includeStack: process.env.NODE_ENV === 'development',\n * onError: (error, c) => {\n * console.error(`[${c.get('requestId')}]`, error);\n * },\n * }));\n * ```\n *\n * @example With Sentry error tracking\n * ```typescript\n * import { SentryTransport } from '@parsrun/core/transports';\n *\n * const sentry = new SentryTransport({\n * dsn: process.env.SENTRY_DSN!,\n * environment: process.env.NODE_ENV,\n * });\n *\n * app.use('*', errorHandler({\n * errorTransport: sentry,\n * captureAllErrors: false, // Only capture 5xx errors\n * }));\n * ```\n */\nexport function errorHandler(options: ErrorHandlerOptions = {}) {\n const {\n includeStack = false,\n onError,\n errorTransport,\n captureAllErrors = false,\n shouldCapture,\n } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n try {\n await next();\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n\n // Determine status code\n const statusCode = error instanceof ApiError ? error.statusCode : 500;\n\n // Log error\n if (onError) {\n onError(error, c);\n } else {\n const logger = c.get(\"logger\");\n if (logger) {\n logger.error(\"Request error\", {\n requestId: c.get(\"requestId\"),\n error: error.message,\n stack: error.stack,\n });\n }\n }\n\n // Capture to error transport if configured\n if (errorTransport) {\n const shouldCaptureError = shouldCapture\n ? shouldCapture(error, statusCode)\n : captureAllErrors || statusCode >= 500;\n\n if (shouldCaptureError) {\n const user = c.get(\"user\");\n const tenant = c.get(\"tenant\");\n\n // Build error context with only defined values\n const errorContext: ErrorContext = {\n requestId: c.get(\"requestId\"),\n tags: {\n path: c.req.path,\n method: c.req.method,\n statusCode: String(statusCode),\n },\n };\n\n if (user?.id) {\n errorContext.userId = user.id;\n }\n if (tenant?.id) {\n errorContext.tenantId = tenant.id;\n }\n\n // Add extra context\n const extra: Record<string, unknown> = {\n query: c.req.query(),\n };\n if (error instanceof ApiError) {\n extra[\"errorCode\"] = error.code;\n }\n errorContext.extra = extra;\n\n // Capture asynchronously to not block response\n Promise.resolve(\n errorTransport.captureException(error, errorContext)\n ).catch(() => {\n // Silent fail - don't let transport errors affect response\n });\n }\n }\n\n // Handle known API errors\n if (error instanceof ApiError) {\n return c.json(error.toResponse(), error.statusCode as 400);\n }\n\n // Handle unknown errors\n const details: Record<string, unknown> = {};\n\n if (includeStack && error.stack) {\n details[\"stack\"] = error.stack;\n }\n\n return c.json(\n errorResponse(\"INTERNAL_ERROR\", \"An unexpected error occurred\", details),\n 500\n );\n }\n };\n}\n\n/**\n * Not found handler\n *\n * @example\n * ```typescript\n * app.notFound(notFoundHandler);\n * ```\n */\nexport function notFoundHandler(c: HonoContext) {\n return c.json(\n errorResponse(\"NOT_FOUND\", `Route ${c.req.method} ${c.req.path} not found`),\n 404\n );\n}\n","/**\n * @parsrun/server - Auth Middleware\n * JWT authentication middleware\n */\n\nimport type { HonoContext, HonoNext, ContextUser } from \"../context.js\";\nimport { UnauthorizedError } from \"./error-handler.js\";\n\n/**\n * JWT payload structure\n */\nexport interface JwtPayload {\n sub: string; // User ID\n email?: string;\n tenantId?: string;\n role?: string;\n permissions?: string[];\n iat?: number;\n exp?: number;\n jti?: string;\n}\n\n/**\n * JWT verification function type\n */\nexport type JwtVerifier = (token: string) => Promise<JwtPayload | null>;\n\n/**\n * Auth middleware options\n */\nexport interface AuthMiddlewareOptions {\n /** JWT verification function */\n verify: JwtVerifier;\n /** Header name for token (default: Authorization) */\n header?: string;\n /** Token prefix (default: Bearer) */\n prefix?: string;\n /** Cookie name for token (alternative to header) */\n cookie?: string;\n /** Skip auth for certain requests */\n skip?: (c: HonoContext) => boolean;\n /** Custom error message */\n message?: string;\n}\n\n/**\n * Extract token from request\n */\nfunction extractToken(\n c: HonoContext,\n header: string,\n prefix: string,\n cookie?: string\n): string | null {\n // Try header first\n const authHeader = c.req.header(header);\n if (authHeader) {\n if (prefix && authHeader.startsWith(`${prefix} `)) {\n return authHeader.slice(prefix.length + 1);\n }\n return authHeader;\n }\n\n // Try cookie\n if (cookie) {\n const cookieHeader = c.req.header(\"cookie\");\n if (cookieHeader) {\n const cookies = cookieHeader.split(\";\").map((c) => c.trim());\n for (const c of cookies) {\n const [key, ...valueParts] = c.split(\"=\");\n if (key === cookie) {\n return valueParts.join(\"=\");\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Auth middleware - requires valid JWT\n *\n * @example\n * ```typescript\n * import { verifyJwt } from '@parsrun/auth';\n *\n * const authMiddleware = auth({\n * verify: (token) => verifyJwt(token, secret),\n * cookie: 'auth_token',\n * });\n *\n * app.use('/api/*', authMiddleware);\n *\n * // Access user in handlers\n * app.get('/api/me', (c) => {\n * const user = c.get('user');\n * return c.json({ user });\n * });\n * ```\n */\nexport function auth(options: AuthMiddlewareOptions) {\n const {\n verify,\n header = \"authorization\",\n prefix = \"Bearer\",\n cookie,\n skip,\n message = \"Authentication required\",\n } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n // Skip if configured\n if (skip?.(c)) {\n return next();\n }\n\n // Extract token\n const token = extractToken(c, header, prefix, cookie);\n\n if (!token) {\n throw new UnauthorizedError(message);\n }\n\n // Verify token\n const payload = await verify(token);\n\n if (!payload) {\n throw new UnauthorizedError(\"Invalid or expired token\");\n }\n\n // Set user in context\n const user: ContextUser = {\n id: payload.sub,\n email: payload.email,\n tenantId: payload.tenantId,\n role: payload.role,\n permissions: payload.permissions ?? [],\n };\n\n c.set(\"user\", user);\n\n await next();\n };\n}\n\n/**\n * Optional auth middleware - sets user if token present, but doesn't require it\n *\n * @example\n * ```typescript\n * app.use('/api/public/*', optionalAuth({\n * verify: (token) => verifyJwt(token, secret),\n * }));\n *\n * // User may or may not be present\n * app.get('/api/public/items', (c) => {\n * const user = c.get('user'); // may be undefined\n * // Return different data based on auth status\n * });\n * ```\n */\nexport function optionalAuth(options: Omit<AuthMiddlewareOptions, \"message\">) {\n const { verify, header = \"authorization\", prefix = \"Bearer\", cookie, skip } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n // Skip if configured\n if (skip?.(c)) {\n return next();\n }\n\n // Extract token\n const token = extractToken(c, header, prefix, cookie);\n\n if (token) {\n try {\n const payload = await verify(token);\n\n if (payload) {\n // Set user in context\n const user: ContextUser = {\n id: payload.sub,\n email: payload.email,\n tenantId: payload.tenantId,\n role: payload.role,\n permissions: payload.permissions ?? [],\n };\n\n c.set(\"user\", user);\n }\n } catch {\n // Ignore verification errors for optional auth\n }\n }\n\n await next();\n };\n}\n\n/**\n * Create auth middleware from verifier function\n *\n * @example\n * ```typescript\n * const { auth, optionalAuth } = createAuthMiddleware({\n * verify: async (token) => {\n * return verifyJwt(token, process.env.JWT_SECRET);\n * },\n * cookie: 'session',\n * });\n *\n * app.use('/api/*', auth);\n * app.use('/public/*', optionalAuth);\n * ```\n */\nexport function createAuthMiddleware(\n baseOptions: Omit<AuthMiddlewareOptions, \"skip\" | \"message\">\n) {\n return {\n auth: (options?: Partial<AuthMiddlewareOptions>) =>\n auth({ ...baseOptions, ...options }),\n optionalAuth: (options?: Partial<Omit<AuthMiddlewareOptions, \"message\">>) =>\n optionalAuth({ ...baseOptions, ...options }),\n };\n}\n","/**\n * @parsrun/server - CORS Middleware\n * Cross-Origin Resource Sharing configuration\n */\n\nimport type { HonoContext, HonoNext, CorsConfig } from \"../context.js\";\n\n/**\n * Default CORS configuration\n */\nconst defaultCorsConfig: CorsConfig = {\n origin: \"*\",\n credentials: false,\n methods: [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\"],\n allowedHeaders: [\"Content-Type\", \"Authorization\", \"X-Request-ID\", \"X-CSRF-Token\"],\n exposedHeaders: [\"X-Request-ID\", \"X-Total-Count\"],\n maxAge: 86400, // 24 hours\n};\n\n/**\n * Check if origin is allowed\n */\nfunction isOriginAllowed(origin: string, config: CorsConfig): boolean {\n if (config.origin === \"*\") return true;\n\n if (typeof config.origin === \"string\") {\n return origin === config.origin;\n }\n\n if (Array.isArray(config.origin)) {\n return config.origin.includes(origin);\n }\n\n if (typeof config.origin === \"function\") {\n return config.origin(origin);\n }\n\n return false;\n}\n\n/**\n * CORS middleware\n *\n * @example\n * ```typescript\n * app.use('*', cors({\n * origin: ['https://example.com', 'https://app.example.com'],\n * credentials: true,\n * }));\n * ```\n */\nexport function cors(config?: Partial<CorsConfig>): (c: HonoContext, next: HonoNext) => Promise<Response | void> {\n const corsConfig = { ...defaultCorsConfig, ...config };\n\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const origin = c.req.header(\"origin\") ?? \"\";\n\n // Handle preflight requests\n if (c.req.method === \"OPTIONS\") {\n const response = new Response(null, { status: 204 });\n\n if (isOriginAllowed(origin, corsConfig)) {\n response.headers.set(\"Access-Control-Allow-Origin\", origin || \"*\");\n }\n\n if (corsConfig.credentials) {\n response.headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n if (corsConfig.methods) {\n response.headers.set(\n \"Access-Control-Allow-Methods\",\n corsConfig.methods.join(\", \")\n );\n }\n\n if (corsConfig.allowedHeaders) {\n response.headers.set(\n \"Access-Control-Allow-Headers\",\n corsConfig.allowedHeaders.join(\", \")\n );\n }\n\n if (corsConfig.maxAge) {\n response.headers.set(\"Access-Control-Max-Age\", String(corsConfig.maxAge));\n }\n\n return response;\n }\n\n // Handle actual requests\n await next();\n\n // Add CORS headers to response\n if (isOriginAllowed(origin, corsConfig)) {\n c.header(\"Access-Control-Allow-Origin\", origin || \"*\");\n }\n\n if (corsConfig.credentials) {\n c.header(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n if (corsConfig.exposedHeaders) {\n c.header(\"Access-Control-Expose-Headers\", corsConfig.exposedHeaders.join(\", \"));\n }\n };\n}\n","/**\n * @parsrun/server - CSRF Middleware\n * Cross-Site Request Forgery protection\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\nimport { ForbiddenError } from \"./error-handler.js\";\n\n/**\n * CSRF options\n */\nexport interface CsrfOptions {\n /** Cookie name for CSRF token */\n cookieName?: string;\n /** Header name for CSRF token */\n headerName?: string;\n /** Methods that require CSRF validation */\n methods?: string[];\n /** Paths to exclude from CSRF protection */\n excludePaths?: string[];\n /** Skip CSRF for certain requests */\n skip?: (c: HonoContext) => boolean;\n /** Token generator */\n generateToken?: () => string;\n /** Cookie options */\n cookie?: {\n secure?: boolean;\n httpOnly?: boolean;\n sameSite?: \"strict\" | \"lax\" | \"none\";\n path?: string;\n maxAge?: number;\n };\n}\n\n/**\n * Generate random token\n */\nfunction generateRandomToken(): string {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/**\n * Get cookie value\n */\nfunction getCookie(c: HonoContext, name: string): string | undefined {\n const cookieHeader = c.req.header(\"cookie\");\n if (!cookieHeader) return undefined;\n\n const cookies = cookieHeader.split(\";\").map((c) => c.trim());\n for (const cookie of cookies) {\n const [key, ...valueParts] = cookie.split(\"=\");\n if (key === name) {\n return valueParts.join(\"=\");\n }\n }\n return undefined;\n}\n\n/**\n * CSRF protection middleware\n *\n * @example\n * ```typescript\n * app.use('*', csrf({\n * cookieName: '_csrf',\n * headerName: 'X-CSRF-Token',\n * methods: ['POST', 'PUT', 'PATCH', 'DELETE'],\n * cookie: {\n * secure: true,\n * sameSite: 'strict',\n * },\n * }));\n *\n * // Get token in handler\n * app.get('/csrf-token', (c) => {\n * return c.json({ token: c.get('csrfToken') });\n * });\n * ```\n */\nexport function csrf(options: CsrfOptions = {}) {\n const {\n cookieName = \"_csrf\",\n headerName = \"x-csrf-token\",\n methods = [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"],\n excludePaths = [],\n skip,\n generateToken = generateRandomToken,\n cookie = {},\n } = options;\n\n const cookieOptions = {\n secure: cookie.secure ?? true,\n httpOnly: cookie.httpOnly ?? true,\n sameSite: cookie.sameSite ?? (\"lax\" as const),\n path: cookie.path ?? \"/\",\n maxAge: cookie.maxAge ?? 86400, // 24 hours\n };\n\n return async (c: HonoContext, next: HonoNext) => {\n // Skip if configured\n if (skip?.(c)) {\n return next();\n }\n\n // Skip excluded paths\n const path = c.req.path;\n if (excludePaths.some((p) => path.startsWith(p))) {\n return next();\n }\n\n // Get or create token\n let token = getCookie(c, cookieName);\n\n if (!token) {\n // Generate new token\n token = generateToken();\n\n // Set cookie\n const cookieValue = [\n `${cookieName}=${token}`,\n `Path=${cookieOptions.path}`,\n `Max-Age=${cookieOptions.maxAge}`,\n cookieOptions.sameSite && `SameSite=${cookieOptions.sameSite}`,\n cookieOptions.secure && \"Secure\",\n cookieOptions.httpOnly && \"HttpOnly\",\n ]\n .filter(Boolean)\n .join(\"; \");\n\n c.header(\"Set-Cookie\", cookieValue);\n }\n\n // Store token in context for handlers\n (c as HonoContext & { csrfToken: string }).set(\"csrfToken\" as never, token as never);\n\n // Validate token for protected methods\n if (methods.includes(c.req.method)) {\n const headerToken = c.req.header(headerName);\n const bodyToken = await getBodyToken(c);\n\n const providedToken = headerToken ?? bodyToken;\n\n if (!providedToken || providedToken !== token) {\n throw new ForbiddenError(\"Invalid CSRF token\");\n }\n }\n\n await next();\n };\n}\n\n/**\n * Try to get CSRF token from request body\n */\nasync function getBodyToken(c: HonoContext): Promise<string | undefined> {\n try {\n const contentType = c.req.header(\"content-type\") ?? \"\";\n\n if (contentType.includes(\"application/json\")) {\n const body = (await c.req.json()) as Record<string, unknown>;\n return (body[\"_csrf\"] ?? body[\"csrfToken\"] ?? body[\"csrf_token\"]) as string | undefined;\n }\n\n if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n const body = await c.req.parseBody();\n return body[\"_csrf\"] as string | undefined;\n }\n } catch {\n // Ignore parsing errors\n }\n return undefined;\n}\n\n/**\n * Double Submit Cookie pattern\n * Generates a token and validates it matches between cookie and header\n */\nexport function doubleSubmitCookie(options: CsrfOptions = {}) {\n return csrf({\n ...options,\n cookie: {\n ...options.cookie,\n httpOnly: false, // Allow JS to read the cookie\n },\n });\n}\n","/**\n * @parsrun/server - Rate Limit Middleware\n * Request throttling with multiple storage backends\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\nimport { RateLimitError } from \"./error-handler.js\";\n\n/**\n * Rate limit storage interface\n */\nexport interface RateLimitStorage {\n /** Get current count for key */\n get(key: string): Promise<number>;\n /** Increment count and set expiry */\n increment(key: string, windowMs: number): Promise<number>;\n /** Reset count for key */\n reset(key: string): Promise<void>;\n}\n\n/**\n * In-memory rate limit storage\n * For single-instance deployments or development\n */\nexport class MemoryRateLimitStorage implements RateLimitStorage {\n private store = new Map<string, { count: number; expires: number }>();\n\n async get(key: string): Promise<number> {\n const entry = this.store.get(key);\n if (!entry || entry.expires < Date.now()) {\n return 0;\n }\n return entry.count;\n }\n\n async increment(key: string, windowMs: number): Promise<number> {\n const now = Date.now();\n const entry = this.store.get(key);\n\n if (!entry || entry.expires < now) {\n // Start new window\n this.store.set(key, { count: 1, expires: now + windowMs });\n return 1;\n }\n\n // Increment existing\n entry.count++;\n return entry.count;\n }\n\n async reset(key: string): Promise<void> {\n this.store.delete(key);\n }\n\n /** Clean up expired entries */\n cleanup(): void {\n const now = Date.now();\n for (const [key, entry] of this.store) {\n if (entry.expires < now) {\n this.store.delete(key);\n }\n }\n }\n}\n\n/**\n * Rate limit options\n */\nexport interface RateLimitOptions {\n /** Time window in milliseconds */\n windowMs?: number;\n /** Maximum requests per window */\n max?: number;\n /** Generate key from request (default: IP address) */\n keyGenerator?: (c: HonoContext) => string;\n /** Skip rate limiting for certain requests */\n skip?: (c: HonoContext) => boolean;\n /** Custom storage backend */\n storage?: RateLimitStorage;\n /** Error message */\n message?: string;\n /** Include rate limit headers */\n headers?: boolean;\n /** Handler when limit is exceeded */\n onLimitReached?: (c: HonoContext, key: string) => void;\n}\n\n// Global default storage\nlet defaultStorage: RateLimitStorage | null = null;\n\n/**\n * Get or create default memory storage\n */\nfunction getDefaultStorage(): RateLimitStorage {\n if (!defaultStorage) {\n defaultStorage = new MemoryRateLimitStorage();\n }\n return defaultStorage;\n}\n\n/**\n * Rate limit middleware\n *\n * @example\n * ```typescript\n * // Basic usage - 100 requests per minute\n * app.use('/api/*', rateLimit({\n * windowMs: 60 * 1000,\n * max: 100,\n * }));\n *\n * // Per-user rate limiting\n * app.use('/api/*', rateLimit({\n * keyGenerator: (c) => c.get('user')?.id ?? getIP(c),\n * max: 1000,\n * }));\n *\n * // Strict limit for auth endpoints\n * app.use('/api/auth/*', rateLimit({\n * windowMs: 15 * 60 * 1000, // 15 minutes\n * max: 5,\n * message: 'Too many login attempts',\n * }));\n * ```\n */\nexport function rateLimit(options: RateLimitOptions = {}) {\n const {\n windowMs = 60 * 1000, // 1 minute\n max = 100,\n keyGenerator = defaultKeyGenerator,\n skip,\n storage = getDefaultStorage(),\n message = \"Too many requests, please try again later\",\n headers = true,\n onLimitReached,\n } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n // Skip if configured\n if (skip?.(c)) {\n return next();\n }\n\n const key = `ratelimit:${keyGenerator(c)}`;\n const current = await storage.increment(key, windowMs);\n\n // Set rate limit headers\n if (headers) {\n c.header(\"X-RateLimit-Limit\", String(max));\n c.header(\"X-RateLimit-Remaining\", String(Math.max(0, max - current)));\n c.header(\"X-RateLimit-Reset\", String(Math.ceil((Date.now() + windowMs) / 1000)));\n }\n\n // Check if limit exceeded\n if (current > max) {\n if (onLimitReached) {\n onLimitReached(c, key);\n }\n\n const retryAfter = Math.ceil(windowMs / 1000);\n c.header(\"Retry-After\", String(retryAfter));\n\n throw new RateLimitError(message, retryAfter);\n }\n\n await next();\n };\n}\n\n/**\n * Default key generator - uses IP address\n */\nfunction defaultKeyGenerator(c: HonoContext): string {\n return (\n c.req.header(\"x-forwarded-for\")?.split(\",\")[0]?.trim() ??\n c.req.header(\"x-real-ip\") ??\n c.req.header(\"cf-connecting-ip\") ??\n \"unknown\"\n );\n}\n\n/**\n * Create rate limiter for specific routes\n *\n * @example\n * ```typescript\n * const apiLimiter = createRateLimiter({\n * windowMs: 60000,\n * max: 100,\n * });\n *\n * app.use('/api/*', apiLimiter.middleware);\n *\n * // Reset limit for a user after successful auth\n * await apiLimiter.reset('user:123');\n * ```\n */\nexport function createRateLimiter(options: RateLimitOptions = {}) {\n const storage = options.storage ?? getDefaultStorage();\n\n return {\n middleware: rateLimit({ ...options, storage }),\n storage,\n reset: (key: string) => storage.reset(`ratelimit:${key}`),\n get: (key: string) => storage.get(`ratelimit:${key}`),\n };\n}\n","/**\n * @parsrun/server - Request Logger Middleware\n * HTTP request/response logging\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\n\n/**\n * Request logger options\n */\nexport interface RequestLoggerOptions {\n /** Skip logging for certain paths */\n skip?: (c: HonoContext) => boolean;\n /** Custom log format */\n format?: \"json\" | \"combined\" | \"short\";\n /** Include request body in logs */\n includeBody?: boolean;\n /** Include response body in logs (be careful with large responses) */\n includeResponseBody?: boolean;\n /** Maximum body length to log */\n maxBodyLength?: number;\n}\n\n/**\n * Format bytes to human readable\n */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes}B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n}\n\n/**\n * Request logger middleware\n *\n * @example\n * ```typescript\n * app.use('*', requestLogger({\n * skip: (c) => c.req.path === '/health',\n * format: 'json',\n * }));\n * ```\n */\nexport function requestLogger(options: RequestLoggerOptions = {}) {\n const {\n skip,\n format = \"json\",\n includeBody = false,\n maxBodyLength = 1000,\n } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n // Skip if configured\n if (skip?.(c)) {\n return next();\n }\n\n const start = Date.now();\n const logger = c.get(\"logger\");\n const requestId = c.get(\"requestId\");\n\n // Request info\n const method = c.req.method;\n const path = c.req.path;\n const query = c.req.query();\n const userAgent = c.req.header(\"user-agent\");\n const ip = c.req.header(\"x-forwarded-for\") ?? c.req.header(\"x-real-ip\") ?? \"unknown\";\n\n // Log request start\n if (format === \"json\") {\n logger?.debug(\"Request started\", {\n requestId,\n method,\n path,\n query: Object.keys(query).length > 0 ? query : undefined,\n ip,\n userAgent,\n });\n }\n\n // Get body if needed\n let requestBody: string | undefined;\n if (includeBody && [\"POST\", \"PUT\", \"PATCH\"].includes(method)) {\n try {\n const contentType = c.req.header(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n const body = await c.req.text();\n requestBody = body.length > maxBodyLength\n ? body.substring(0, maxBodyLength) + \"...\"\n : body;\n }\n } catch {\n // Ignore body parsing errors\n }\n }\n\n // Process request\n await next();\n\n // Calculate duration\n const duration = Date.now() - start;\n const status = c.res.status;\n\n // Get response size\n const contentLength = c.res.headers.get(\"content-length\");\n const size = contentLength ? parseInt(contentLength, 10) : 0;\n\n // Log based on format\n if (format === \"json\") {\n const logData: Record<string, unknown> = {\n requestId,\n method,\n path,\n status,\n duration: `${duration}ms`,\n size: formatBytes(size),\n };\n\n if (requestBody) {\n logData[\"requestBody\"] = requestBody;\n }\n\n // Use appropriate log level\n if (status >= 500) {\n logger?.error(\"Request completed\", logData);\n } else if (status >= 400) {\n logger?.warn(\"Request completed\", logData);\n } else {\n logger?.info(\"Request completed\", logData);\n }\n } else if (format === \"combined\") {\n // Apache combined log format\n const log = `${ip} - - [${new Date().toISOString()}] \"${method} ${path}\" ${status} ${size} \"-\" \"${userAgent}\" ${duration}ms`;\n console.log(log);\n } else {\n // Short format\n const log = `${method} ${path} ${status} ${duration}ms`;\n console.log(log);\n }\n };\n}\n","/**\n * @parsrun/server - Usage Tracking Middleware\n * Automatically track API usage per request\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\n\n/**\n * Usage service interface (from @parsrun/payments)\n * Defined here to avoid circular dependency\n */\nexport interface UsageServiceLike {\n trackUsage(options: {\n tenantId: string;\n customerId: string;\n subscriptionId?: string;\n featureKey: string;\n quantity?: number;\n metadata?: Record<string, unknown>;\n idempotencyKey?: string;\n }): Promise<unknown>;\n}\n\n/**\n * Usage tracking middleware options\n */\nexport interface UsageTrackingOptions {\n /**\n * Usage service instance\n */\n usageService: UsageServiceLike;\n\n /**\n * Feature key to track\n * Can be a static string or a function that extracts it from context\n * @default \"api_calls\"\n */\n featureKey?: string | ((c: HonoContext) => string);\n\n /**\n * Quantity to track\n * Can be a static number or a function that calculates it from context\n * @default 1\n */\n quantity?: number | ((c: HonoContext) => number);\n\n /**\n * Skip tracking for certain requests\n */\n skip?: (c: HonoContext) => boolean;\n\n /**\n * When to track: before or after the request\n * @default \"response\"\n */\n trackOn?: \"request\" | \"response\";\n\n /**\n * Only track successful responses (2xx)\n * @default true\n */\n successOnly?: boolean;\n\n /**\n * Custom customer ID extractor\n * @default Uses c.get(\"user\")?.id\n */\n getCustomerId?: (c: HonoContext) => string | undefined;\n\n /**\n * Custom tenant ID extractor\n * @default Uses c.get(\"tenant\")?.id or c.get(\"user\")?.tenantId\n */\n getTenantId?: (c: HonoContext) => string | undefined;\n\n /**\n * Custom subscription ID extractor\n */\n getSubscriptionId?: (c: HonoContext) => string | undefined;\n\n /**\n * Include request metadata\n * @default true\n */\n includeMetadata?: boolean;\n\n /**\n * Generate idempotency key to prevent duplicates\n */\n getIdempotencyKey?: (c: HonoContext) => string | undefined;\n}\n\n/**\n * Usage tracking middleware\n *\n * Automatically tracks API usage for authenticated requests.\n *\n * @example\n * ```typescript\n * import { usageTracking } from \"@parsrun/server\";\n * import { createUsageService, createMemoryUsageStorage } from \"@parsrun/payments\";\n *\n * const usageService = createUsageService({\n * storage: createMemoryUsageStorage(),\n * });\n *\n * // Track all API calls\n * app.use(\"/api/*\", usageTracking({\n * usageService,\n * featureKey: \"api_calls\",\n * }));\n *\n * // Track with custom feature key based on route\n * app.use(\"/api/ai/*\", usageTracking({\n * usageService,\n * featureKey: \"ai_requests\",\n * quantity: (c) => {\n * // Track tokens used from response\n * return c.get(\"tokensUsed\") ?? 1;\n * },\n * }));\n *\n * // Skip certain routes\n * app.use(\"/api/*\", usageTracking({\n * usageService,\n * skip: (c) => c.req.path.startsWith(\"/api/health\"),\n * }));\n * ```\n */\nexport function usageTracking(options: UsageTrackingOptions) {\n const {\n usageService,\n featureKey = \"api_calls\",\n quantity = 1,\n skip,\n trackOn = \"response\",\n successOnly = true,\n getCustomerId = (c) => c.get(\"user\")?.id,\n getTenantId = (c) => c.get(\"tenant\")?.id ?? c.get(\"user\")?.tenantId,\n getSubscriptionId,\n includeMetadata = true,\n getIdempotencyKey,\n } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n // Track on request (before processing)\n if (trackOn === \"request\") {\n await trackUsage(c);\n return next();\n }\n\n // Track on response (after processing)\n await next();\n\n // Skip if configured\n if (skip?.(c)) return;\n\n // Skip failed responses if configured\n if (successOnly && c.res.status >= 400) return;\n\n await trackUsage(c);\n };\n\n async function trackUsage(c: HonoContext) {\n const customerId = getCustomerId(c);\n const tenantId = getTenantId(c);\n\n // Skip if no user or tenant\n if (!customerId || !tenantId) return;\n\n const resolvedFeatureKey =\n typeof featureKey === \"function\" ? featureKey(c) : featureKey;\n\n const resolvedQuantity =\n typeof quantity === \"function\" ? quantity(c) : quantity;\n\n const metadata = includeMetadata\n ? {\n path: c.req.path,\n method: c.req.method,\n statusCode: c.res.status,\n userAgent: c.req.header(\"user-agent\"),\n }\n : undefined;\n\n try {\n // Build track options with only defined optional properties\n const trackOptions: {\n tenantId: string;\n customerId: string;\n featureKey: string;\n quantity?: number;\n subscriptionId?: string;\n metadata?: Record<string, unknown>;\n idempotencyKey?: string;\n } = {\n tenantId,\n customerId,\n featureKey: resolvedFeatureKey,\n quantity: resolvedQuantity,\n };\n\n const subscriptionId = getSubscriptionId?.(c);\n if (subscriptionId !== undefined) {\n trackOptions.subscriptionId = subscriptionId;\n }\n\n if (metadata !== undefined) {\n trackOptions.metadata = metadata;\n }\n\n const idempotencyKey = getIdempotencyKey?.(c);\n if (idempotencyKey !== undefined) {\n trackOptions.idempotencyKey = idempotencyKey;\n }\n\n await usageService.trackUsage(trackOptions);\n } catch (error) {\n // Log but don't fail the request\n const logger = c.get(\"logger\");\n if (logger) {\n logger.error(\"Usage tracking failed\", {\n error: error instanceof Error ? error.message : String(error),\n customerId,\n featureKey: resolvedFeatureKey,\n });\n }\n }\n }\n}\n\n/**\n * Create usage tracking middleware with pre-configured options\n */\nexport function createUsageTracking(baseOptions: UsageTrackingOptions) {\n return (overrides?: Partial<UsageTrackingOptions>) => {\n return usageTracking({ ...baseOptions, ...overrides });\n };\n}\n","/**\n * @parsrun/server - Quota Enforcement Middleware\n * Enforce usage quotas before processing requests\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\n\n/**\n * Quota check result interface (from @parsrun/payments)\n */\nexport interface QuotaCheckResult {\n allowed: boolean;\n currentUsage: number;\n limit: number | null;\n remaining: number | null;\n wouldExceed: boolean;\n percentAfter: number | null;\n}\n\n/**\n * Quota manager interface (from @parsrun/payments)\n * Defined here to avoid circular dependency\n */\nexport interface QuotaManagerLike {\n checkQuota(\n customerId: string,\n featureKey: string,\n quantity?: number\n ): Promise<QuotaCheckResult>;\n\n enforceQuota(\n customerId: string,\n featureKey: string,\n quantity?: number\n ): Promise<void>;\n}\n\n/**\n * Quota exceeded error class\n */\nexport class QuotaExceededError extends Error {\n public readonly statusCode = 429;\n public readonly code = \"QUOTA_EXCEEDED\";\n\n constructor(\n public readonly featureKey: string,\n public readonly limit: number | null,\n public readonly currentUsage: number,\n public readonly requestedQuantity: number = 1\n ) {\n super(\n `Quota exceeded for \"${featureKey}\": ${currentUsage}/${limit ?? \"unlimited\"} used`\n );\n this.name = \"QuotaExceededError\";\n }\n}\n\n/**\n * Quota enforcement middleware options\n */\nexport interface QuotaEnforcementOptions {\n /**\n * Quota manager instance\n */\n quotaManager: QuotaManagerLike;\n\n /**\n * Feature key to check\n * Can be a static string or a function that extracts it from context\n */\n featureKey: string | ((c: HonoContext) => string);\n\n /**\n * Quantity to check (default: 1)\n */\n quantity?: number | ((c: HonoContext) => number);\n\n /**\n * Skip quota check for certain requests\n */\n skip?: (c: HonoContext) => boolean;\n\n /**\n * Custom customer ID extractor\n * @default Uses c.get(\"user\")?.id\n */\n getCustomerId?: (c: HonoContext) => string | undefined;\n\n /**\n * Include quota headers in response\n * @default true\n */\n includeHeaders?: boolean;\n\n /**\n * Custom error handler\n */\n onQuotaExceeded?: (\n c: HonoContext,\n result: QuotaCheckResult,\n featureKey: string\n ) => Response | void;\n\n /**\n * Soft limit mode - warn but don't block\n * @default false\n */\n softLimit?: boolean;\n\n /**\n * Callback when quota is close to limit (>80%)\n */\n onQuotaWarning?: (\n c: HonoContext,\n result: QuotaCheckResult,\n featureKey: string\n ) => void;\n}\n\n/**\n * Quota enforcement middleware\n *\n * Checks and enforces usage quotas before processing requests.\n *\n * @example\n * ```typescript\n * import { quotaEnforcement } from \"@parsrun/server\";\n * import { createQuotaManager, createMemoryUsageStorage } from \"@parsrun/payments\";\n *\n * const quotaManager = createQuotaManager({\n * storage: createMemoryUsageStorage(),\n * });\n *\n * // Enforce API call quota\n * app.use(\"/api/*\", quotaEnforcement({\n * quotaManager,\n * featureKey: \"api_calls\",\n * }));\n *\n * // Enforce with dynamic feature key\n * app.use(\"/api/*\", quotaEnforcement({\n * quotaManager,\n * featureKey: (c) => {\n * if (c.req.path.startsWith(\"/api/ai\")) return \"ai_requests\";\n * return \"api_calls\";\n * },\n * }));\n *\n * // Soft limit mode (warn but allow)\n * app.use(\"/api/*\", quotaEnforcement({\n * quotaManager,\n * featureKey: \"api_calls\",\n * softLimit: true,\n * onQuotaWarning: (c, result) => {\n * console.warn(\"Quota warning:\", result);\n * },\n * }));\n * ```\n */\nexport function quotaEnforcement(options: QuotaEnforcementOptions) {\n const {\n quotaManager,\n featureKey,\n quantity = 1,\n skip,\n getCustomerId = (c) => c.get(\"user\")?.id,\n includeHeaders = true,\n onQuotaExceeded,\n softLimit = false,\n onQuotaWarning,\n } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n // Skip if configured\n if (skip?.(c)) {\n return next();\n }\n\n const customerId = getCustomerId(c);\n\n // Skip if no user (unauthenticated requests)\n if (!customerId) {\n return next();\n }\n\n const resolvedFeatureKey =\n typeof featureKey === \"function\" ? featureKey(c) : featureKey;\n\n const resolvedQuantity =\n typeof quantity === \"function\" ? quantity(c) : quantity;\n\n try {\n const result = await quotaManager.checkQuota(\n customerId,\n resolvedFeatureKey,\n resolvedQuantity\n );\n\n // Set quota headers\n if (includeHeaders) {\n c.header(\"X-Quota-Limit\", String(result.limit ?? \"unlimited\"));\n c.header(\"X-Quota-Remaining\", String(result.remaining ?? \"unlimited\"));\n c.header(\"X-Quota-Used\", String(result.currentUsage));\n\n if (result.percentAfter !== null) {\n c.header(\"X-Quota-Percent\", String(result.percentAfter));\n }\n }\n\n // Check for warning threshold (>80%)\n if (\n result.percentAfter !== null &&\n result.percentAfter >= 80 &&\n onQuotaWarning\n ) {\n onQuotaWarning(c, result, resolvedFeatureKey);\n }\n\n // Check if quota exceeded\n if (!result.allowed && !softLimit) {\n // Custom error handler\n if (onQuotaExceeded) {\n const response = onQuotaExceeded(c, result, resolvedFeatureKey);\n if (response) return response;\n }\n\n // Default error response\n throw new QuotaExceededError(\n resolvedFeatureKey,\n result.limit,\n result.currentUsage,\n resolvedQuantity\n );\n }\n\n // Continue to next middleware\n await next();\n } catch (error) {\n // Re-throw quota errors\n if (error instanceof QuotaExceededError) {\n throw error;\n }\n\n // Log other errors but continue\n const logger = c.get(\"logger\");\n if (logger) {\n logger.error(\"Quota check failed\", {\n error: error instanceof Error ? error.message : String(error),\n customerId,\n featureKey: resolvedFeatureKey,\n });\n }\n\n // Continue on error (fail open)\n await next();\n }\n };\n}\n\n/**\n * Create quota enforcement middleware with pre-configured options\n */\nexport function createQuotaEnforcement(\n baseOptions: Omit<QuotaEnforcementOptions, \"featureKey\">\n) {\n return (featureKey: string | ((c: HonoContext) => string)) => {\n return quotaEnforcement({ ...baseOptions, featureKey });\n };\n}\n\n/**\n * Multiple quota enforcement\n * Check multiple features at once\n */\nexport function multiQuotaEnforcement(\n options: Omit<QuotaEnforcementOptions, \"featureKey\"> & {\n features: Array<{\n featureKey: string;\n quantity?: number | ((c: HonoContext) => number);\n }>;\n }\n) {\n const { features } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n const customerId = (options.getCustomerId ?? ((ctx) => ctx.get(\"user\")?.id))(c);\n\n if (!customerId || options.skip?.(c)) {\n return next();\n }\n\n // Check all quotas\n for (const feature of features) {\n const resolvedQuantity =\n typeof feature.quantity === \"function\"\n ? feature.quantity(c)\n : feature.quantity ?? 1;\n\n const result = await options.quotaManager.checkQuota(\n customerId,\n feature.featureKey,\n resolvedQuantity\n );\n\n if (!result.allowed && !options.softLimit) {\n if (options.onQuotaExceeded) {\n const response = options.onQuotaExceeded(c, result, feature.featureKey);\n if (response) return response;\n }\n\n throw new QuotaExceededError(\n feature.featureKey,\n result.limit,\n result.currentUsage,\n resolvedQuantity\n );\n }\n }\n\n await next();\n };\n}\n","/**\n * @parsrun/server - ArkType Validation\n * Request validation with ArkType (powered by @parsrun/types)\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\nimport { ValidationError } from \"../middleware/error-handler.js\";\nimport type { Type } from \"@parsrun/types\";\n\n// Re-export from @parsrun/types\nexport {\n type,\n // Common schemas\n uuid,\n timestamp,\n email,\n url,\n nonEmptyString,\n positiveInt,\n nonNegativeInt,\n status,\n pagination,\n paginationMeta,\n cursorPagination,\n cursorPaginationMeta,\n // Server schemas\n uuidParam,\n paginationQuery,\n cursorPaginationQuery,\n searchQuery,\n dateRangeQuery,\n healthResponse,\n apiInfoResponse,\n corsConfig,\n serverRateLimitConfig,\n loggerConfig,\n serverConfig,\n authContext,\n requestContext,\n // Response helpers\n successResponse,\n errorResponse,\n paginatedResponse,\n cursorPaginatedResponse,\n parsError,\n // Validation helpers\n validateWithSchema,\n safeValidate,\n isValid,\n formatErrors,\n // Types\n type UUID,\n type Timestamp,\n type Email,\n type Url,\n type NonEmptyString,\n type PositiveInt,\n type NonNegativeInt,\n type Status,\n type Pagination,\n type PaginationMeta,\n type CursorPagination,\n type CursorPaginationMeta,\n type UuidParam,\n type PaginationQuery,\n type CursorPaginationQuery,\n type SearchQuery,\n type DateRangeQuery,\n type HealthResponse,\n type ApiInfoResponse,\n type CorsConfig,\n type ServerRateLimitConfig,\n type LoggerConfig,\n type ServerConfig,\n type AuthContext,\n type RequestContext,\n type ErrorResponse,\n type ParsError,\n type ApiResponse,\n type ApiErrorResponse,\n type ApiPaginatedResponse,\n type ApiCursorPaginatedResponse,\n} from \"@parsrun/types\";\n\nimport { type, formatErrors as formatArkErrors } from \"@parsrun/types\";\n\nexport type { Type } from \"@parsrun/types\";\n\n/**\n * Infer type from ArkType schema\n */\nexport type Infer<T extends Type> = T[\"infer\"];\n\n/**\n * Validation target\n */\nexport type ValidationTarget = \"json\" | \"query\" | \"param\" | \"header\" | \"form\";\n\n/**\n * Validation options\n */\nexport interface ValidateOptions {\n /** Error message prefix */\n messagePrefix?: string;\n}\n\n/**\n * Format ArkType errors to a simple object with arrays\n */\nfunction formatValidationErrors(errors: type.errors): Record<string, string[]> {\n const formatted = formatArkErrors(errors);\n const result: Record<string, string[]> = {};\n\n for (const [key, value] of Object.entries(formatted)) {\n result[key] = [value];\n }\n\n return result;\n}\n\n/**\n * Validate request body with ArkType schema\n *\n * @example\n * ```typescript\n * import { type } from '@parsrun/types';\n *\n * const CreateUserSchema = type({\n * email: 'string.email',\n * name: 'string',\n * age: 'number >= 0',\n * });\n *\n * app.post('/users', validateBody(CreateUserSchema), async (c) => {\n * const data = c.get('validatedBody');\n * // data is typed as { email: string; name: string; age: number }\n * });\n * ```\n */\nexport function validateBody<T extends Type>(schema: T, options: ValidateOptions = {}) {\n return async (c: HonoContext, next: HonoNext): Promise<void> => {\n let body: unknown;\n\n try {\n body = await c.req.json();\n } catch {\n throw new ValidationError(\"Invalid JSON body\");\n }\n\n const result = schema(body);\n\n if (result instanceof type.errors) {\n throw new ValidationError(\n options.messagePrefix ?? \"Validation failed\",\n { errors: formatValidationErrors(result) }\n );\n }\n\n // Store validated data in context\n (c as HonoContext & { validatedBody: T[\"infer\"] }).set(\"validatedBody\" as never, result as never);\n\n await next();\n };\n}\n\n/**\n * Validate query parameters\n *\n * @example\n * ```typescript\n * const PaginationSchema = type({\n * 'page?': 'string',\n * 'limit?': 'string',\n * 'search?': 'string',\n * });\n *\n * app.get('/users', validateQuery(PaginationSchema), async (c) => {\n * const { page, limit, search } = c.get('validatedQuery');\n * });\n * ```\n */\nexport function validateQuery<T extends Type>(schema: T, options: ValidateOptions = {}) {\n return async (c: HonoContext, next: HonoNext): Promise<void> => {\n const query = c.req.query();\n const result = schema(query);\n\n if (result instanceof type.errors) {\n throw new ValidationError(\n options.messagePrefix ?? \"Invalid query parameters\",\n { errors: formatValidationErrors(result) }\n );\n }\n\n (c as HonoContext & { validatedQuery: T[\"infer\"] }).set(\"validatedQuery\" as never, result as never);\n\n await next();\n };\n}\n\n/**\n * Validate route parameters\n *\n * @example\n * ```typescript\n * const IdParamSchema = type({\n * id: 'string',\n * });\n *\n * app.get('/users/:id', validateParams(IdParamSchema), async (c) => {\n * const { id } = c.get('validatedParams');\n * });\n * ```\n */\nexport function validateParams<T extends Type>(schema: T, options: ValidateOptions = {}) {\n return async (c: HonoContext, next: HonoNext): Promise<void> => {\n const params = c.req.param();\n const result = schema(params);\n\n if (result instanceof type.errors) {\n throw new ValidationError(\n options.messagePrefix ?? \"Invalid route parameters\",\n { errors: formatValidationErrors(result) }\n );\n }\n\n (c as HonoContext & { validatedParams: T[\"infer\"] }).set(\"validatedParams\" as never, result as never);\n\n await next();\n };\n}\n\n/**\n * Validate headers\n *\n * @example\n * ```typescript\n * const ApiKeySchema = type({\n * 'x-api-key': 'string',\n * });\n *\n * app.use('/api/*', validateHeaders(ApiKeySchema));\n * ```\n */\nexport function validateHeaders<T extends Type>(schema: T, options: ValidateOptions = {}) {\n return async (c: HonoContext, next: HonoNext): Promise<void> => {\n // Convert headers to plain object\n const headers: Record<string, string> = {};\n c.req.raw.headers.forEach((value, key) => {\n headers[key.toLowerCase()] = value;\n });\n\n const result = schema(headers);\n\n if (result instanceof type.errors) {\n throw new ValidationError(\n options.messagePrefix ?? \"Invalid headers\",\n { errors: formatValidationErrors(result) }\n );\n }\n\n (c as HonoContext & { validatedHeaders: T[\"infer\"] }).set(\"validatedHeaders\" as never, result as never);\n\n await next();\n };\n}\n\n/**\n * Combined validation middleware\n *\n * @example\n * ```typescript\n * app.post('/users/:id',\n * validate({\n * params: type({ id: 'string' }),\n * body: type({ name: 'string', email: 'string.email' }),\n * query: type({ 'include?': 'string' }),\n * }),\n * async (c) => {\n * const params = c.get('validatedParams');\n * const body = c.get('validatedBody');\n * const query = c.get('validatedQuery');\n * }\n * );\n * ```\n */\nexport function validate<\n TParams extends Type | undefined = undefined,\n TBody extends Type | undefined = undefined,\n TQuery extends Type | undefined = undefined,\n THeaders extends Type | undefined = undefined\n>(schemas: {\n params?: TParams;\n body?: TBody;\n query?: TQuery;\n headers?: THeaders;\n}) {\n return async (c: HonoContext, next: HonoNext): Promise<void> => {\n // Validate params\n if (schemas.params) {\n const params = c.req.param();\n const result = schemas.params(params);\n if (result instanceof type.errors) {\n throw new ValidationError(\"Invalid route parameters\", {\n errors: formatValidationErrors(result),\n });\n }\n (c as HonoContext & { validatedParams: unknown }).set(\"validatedParams\" as never, result as never);\n }\n\n // Validate query\n if (schemas.query) {\n const query = c.req.query();\n const result = schemas.query(query);\n if (result instanceof type.errors) {\n throw new ValidationError(\"Invalid query parameters\", {\n errors: formatValidationErrors(result),\n });\n }\n (c as HonoContext & { validatedQuery: unknown }).set(\"validatedQuery\" as never, result as never);\n }\n\n // Validate headers\n if (schemas.headers) {\n const headers: Record<string, string> = {};\n c.req.raw.headers.forEach((value, key) => {\n headers[key.toLowerCase()] = value;\n });\n const result = schemas.headers(headers);\n if (result instanceof type.errors) {\n throw new ValidationError(\"Invalid headers\", {\n errors: formatValidationErrors(result),\n });\n }\n (c as HonoContext & { validatedHeaders: unknown }).set(\"validatedHeaders\" as never, result as never);\n }\n\n // Validate body\n if (schemas.body) {\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n throw new ValidationError(\"Invalid JSON body\");\n }\n const result = schemas.body(body);\n if (result instanceof type.errors) {\n throw new ValidationError(\"Validation failed\", {\n errors: formatValidationErrors(result),\n });\n }\n (c as HonoContext & { validatedBody: unknown }).set(\"validatedBody\" as never, result as never);\n }\n\n await next();\n };\n}\n\n// ============================================================================\n// Legacy Aliases (for backward compatibility)\n// ============================================================================\n\n// Schema aliases with PascalCase for backward compatibility\n// Use the camelCase versions from @parsrun/types for new code\nexport {\n uuidParam as UuidParamSchema,\n paginationQuery as PaginationQuerySchema,\n searchQuery as SearchQuerySchema,\n dateRangeQuery as DateRangeQuerySchema,\n} from \"@parsrun/types\";\n","/**\n * @parsrun/server - Pagination Utilities\n * Helpers for paginated API responses\n */\n\nimport type { HonoContext } from \"../context.js\";\n\n/**\n * Pagination parameters\n */\nexport interface PaginationParams {\n page: number;\n limit: number;\n offset: number;\n}\n\n/**\n * Pagination metadata\n */\nexport interface PaginationMeta {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n hasNext: boolean;\n hasPrev: boolean;\n}\n\n/**\n * Paginated response\n */\nexport interface PaginatedResponse<T> {\n data: T[];\n pagination: PaginationMeta;\n}\n\n/**\n * Pagination options\n */\nexport interface PaginationOptions {\n /** Default page size */\n defaultLimit?: number;\n /** Maximum page size */\n maxLimit?: number;\n /** Page query parameter name */\n pageParam?: string;\n /** Limit query parameter name */\n limitParam?: string;\n}\n\nconst defaultOptions: Required<PaginationOptions> = {\n defaultLimit: 20,\n maxLimit: 100,\n pageParam: \"page\",\n limitParam: \"limit\",\n};\n\n/**\n * Parse pagination from request query\n *\n * @example\n * ```typescript\n * app.get('/users', async (c) => {\n * const { page, limit, offset } = parsePagination(c);\n *\n * const users = await db.query.users.findMany({\n * limit,\n * offset,\n * });\n *\n * const total = await db.query.users.count();\n *\n * return c.json(paginate(users, { page, limit, total }));\n * });\n * ```\n */\nexport function parsePagination(\n c: HonoContext,\n options: PaginationOptions = {}\n): PaginationParams {\n const opts = { ...defaultOptions, ...options };\n\n const pageStr = c.req.query(opts.pageParam);\n const limitStr = c.req.query(opts.limitParam);\n\n let page = pageStr ? parseInt(pageStr, 10) : 1;\n let limit = limitStr ? parseInt(limitStr, 10) : opts.defaultLimit;\n\n // Validate and clamp values\n if (isNaN(page) || page < 1) page = 1;\n if (isNaN(limit) || limit < 1) limit = opts.defaultLimit;\n if (limit > opts.maxLimit) limit = opts.maxLimit;\n\n const offset = (page - 1) * limit;\n\n return { page, limit, offset };\n}\n\n/**\n * Create pagination metadata\n */\nexport function createPaginationMeta(params: {\n page: number;\n limit: number;\n total: number;\n}): PaginationMeta {\n const { page, limit, total } = params;\n const totalPages = Math.ceil(total / limit);\n\n return {\n page,\n limit,\n total,\n totalPages,\n hasNext: page < totalPages,\n hasPrev: page > 1,\n };\n}\n\n/**\n * Create paginated response\n *\n * @example\n * ```typescript\n * const users = await getUsers({ limit, offset });\n * const total = await countUsers();\n *\n * return c.json(paginate(users, { page, limit, total }));\n * ```\n */\nexport function paginate<T>(\n data: T[],\n params: { page: number; limit: number; total: number }\n): PaginatedResponse<T> {\n return {\n data,\n pagination: createPaginationMeta(params),\n };\n}\n\n/**\n * Cursor-based pagination params\n */\nexport interface CursorPaginationParams {\n cursor?: string | undefined;\n limit: number;\n direction: \"forward\" | \"backward\";\n}\n\n/**\n * Cursor pagination metadata\n */\nexport interface CursorPaginationMeta {\n cursor?: string | undefined;\n nextCursor?: string | undefined;\n prevCursor?: string | undefined;\n hasMore: boolean;\n limit: number;\n}\n\n/**\n * Cursor paginated response\n */\nexport interface CursorPaginatedResponse<T> {\n data: T[];\n pagination: CursorPaginationMeta;\n}\n\n/**\n * Parse cursor pagination from request\n *\n * @example\n * ```typescript\n * app.get('/feed', async (c) => {\n * const { cursor, limit, direction } = parseCursorPagination(c);\n *\n * const items = await db.query.posts.findMany({\n * where: cursor ? { id: { gt: cursor } } : undefined,\n * limit: limit + 1, // Fetch one extra to check hasMore\n * orderBy: { createdAt: 'desc' },\n * });\n *\n * return c.json(cursorPaginate(items, { cursor, limit }));\n * });\n * ```\n */\nexport function parseCursorPagination(\n c: HonoContext,\n options: PaginationOptions = {}\n): CursorPaginationParams {\n const opts = { ...defaultOptions, ...options };\n\n const cursor = c.req.query(\"cursor\") ?? undefined;\n const limitStr = c.req.query(opts.limitParam);\n const direction = c.req.query(\"direction\") === \"backward\" ? \"backward\" : \"forward\";\n\n let limit = limitStr ? parseInt(limitStr, 10) : opts.defaultLimit;\n if (isNaN(limit) || limit < 1) limit = opts.defaultLimit;\n if (limit > opts.maxLimit) limit = opts.maxLimit;\n\n return { cursor, limit, direction };\n}\n\n/**\n * Create cursor paginated response\n *\n * @example\n * ```typescript\n * // Fetch limit + 1 items\n * const items = await fetchItems(limit + 1);\n * return c.json(cursorPaginate(items, { cursor, limit }));\n * ```\n */\nexport function cursorPaginate<T extends { id: string }>(\n data: T[],\n params: { cursor?: string; limit: number }\n): CursorPaginatedResponse<T> {\n const { cursor, limit } = params;\n const hasMore = data.length > limit;\n\n // Remove the extra item if we have more\n const items = hasMore ? data.slice(0, limit) : data;\n\n const lastItem = items[items.length - 1];\n const firstItem = items[0];\n\n return {\n data: items,\n pagination: {\n cursor,\n nextCursor: hasMore && lastItem ? lastItem.id : undefined,\n prevCursor: cursor && firstItem ? firstItem.id : undefined,\n hasMore,\n limit,\n },\n };\n}\n\n/**\n * Add pagination headers to response\n */\nexport function setPaginationHeaders(\n c: HonoContext,\n meta: PaginationMeta\n): void {\n c.header(\"X-Total-Count\", String(meta.total));\n c.header(\"X-Total-Pages\", String(meta.totalPages));\n c.header(\"X-Page\", String(meta.page));\n c.header(\"X-Per-Page\", String(meta.limit));\n c.header(\"X-Has-Next\", String(meta.hasNext));\n c.header(\"X-Has-Prev\", String(meta.hasPrev));\n}\n","/**\n * @parsrun/server - Response Utilities\n * Helpers for API responses\n */\n\nimport type { HonoContext, ApiResponse } from \"../context.js\";\nimport { success, error } from \"../context.js\";\n\n/**\n * Send JSON success response\n *\n * @example\n * ```typescript\n * app.get('/users/:id', async (c) => {\n * const user = await getUser(c.req.param('id'));\n * return json(c, user);\n * });\n * ```\n */\nexport function json<T>(c: HonoContext, data: T, status = 200): Response {\n return c.json(success(data), status as 200);\n}\n\n/**\n * Send JSON success response with metadata\n *\n * @example\n * ```typescript\n * app.get('/users', async (c) => {\n * const { users, total } = await getUsers();\n * return jsonWithMeta(c, users, { total, page: 1, limit: 20 });\n * });\n * ```\n */\nexport function jsonWithMeta<T>(\n c: HonoContext,\n data: T,\n meta: ApiResponse[\"meta\"],\n status = 200\n): Response {\n return c.json(success(data, meta), status as 200);\n}\n\n/**\n * Send JSON error response\n *\n * @example\n * ```typescript\n * app.get('/users/:id', async (c) => {\n * const user = await getUser(c.req.param('id'));\n * if (!user) {\n * return jsonError(c, 'USER_NOT_FOUND', 'User not found', 404);\n * }\n * return json(c, user);\n * });\n * ```\n */\nexport function jsonError(\n c: HonoContext,\n code: string,\n message: string,\n status = 400,\n details?: Record<string, unknown>\n): Response {\n return c.json(error(code, message, details), status as 400);\n}\n\n/**\n * Send created response (201)\n */\nexport function created<T>(c: HonoContext, data: T, location?: string): Response {\n if (location) {\n c.header(\"Location\", location);\n }\n return c.json(success(data), 201);\n}\n\n/**\n * Send no content response (204)\n */\nexport function noContent(_c: HonoContext): Response {\n return new Response(null, { status: 204 });\n}\n\n/**\n * Send accepted response (202) - for async operations\n */\nexport function accepted<T>(c: HonoContext, data?: T): Response {\n if (data) {\n return c.json(success(data), 202);\n }\n return new Response(null, { status: 202 });\n}\n\n/**\n * Redirect response\n */\nexport function redirect(c: HonoContext, url: string, status: 301 | 302 | 303 | 307 | 308 = 302): Response {\n return c.redirect(url, status);\n}\n\n/**\n * Stream response helper\n *\n * @example\n * ```typescript\n * app.get('/stream', (c) => {\n * return stream(c, async (write) => {\n * for (let i = 0; i < 10; i++) {\n * await write(`data: ${i}\\n\\n`);\n * await new Promise(r => setTimeout(r, 1000));\n * }\n * });\n * });\n * ```\n */\nexport function stream(\n _c: HonoContext,\n callback: (write: (chunk: string) => Promise<void>) => Promise<void>,\n options: {\n contentType?: string;\n headers?: Record<string, string>;\n } = {}\n): Response {\n const encoder = new TextEncoder();\n\n const readableStream = new ReadableStream({\n async start(controller) {\n const write = async (chunk: string) => {\n controller.enqueue(encoder.encode(chunk));\n };\n\n try {\n await callback(write);\n } finally {\n controller.close();\n }\n },\n });\n\n return new Response(readableStream, {\n headers: {\n \"Content-Type\": options.contentType ?? \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n ...options.headers,\n },\n });\n}\n\n/**\n * Server-Sent Events helper\n *\n * @example\n * ```typescript\n * app.get('/events', (c) => {\n * return sse(c, async (send) => {\n * for await (const event of eventStream) {\n * await send({ event: 'update', data: event });\n * }\n * });\n * });\n * ```\n */\nexport function sse(\n c: HonoContext,\n callback: (\n send: (event: { event?: string; data: unknown; id?: string; retry?: number }) => Promise<void>\n ) => Promise<void>\n): Response {\n return stream(c, async (write) => {\n const send = async (event: { event?: string; data: unknown; id?: string; retry?: number }) => {\n let message = \"\";\n\n if (event.id) {\n message += `id: ${event.id}\\n`;\n }\n\n if (event.event) {\n message += `event: ${event.event}\\n`;\n }\n\n if (event.retry) {\n message += `retry: ${event.retry}\\n`;\n }\n\n const data = typeof event.data === \"string\" ? event.data : JSON.stringify(event.data);\n message += `data: ${data}\\n\\n`;\n\n await write(message);\n };\n\n await callback(send);\n });\n}\n\n/**\n * File download response\n */\nexport function download(\n c: HonoContext,\n data: Uint8Array | ArrayBuffer | string,\n filename: string,\n contentType = \"application/octet-stream\"\n): Response {\n c.header(\"Content-Disposition\", `attachment; filename=\"${filename}\"`);\n c.header(\"Content-Type\", contentType);\n\n if (typeof data === \"string\") {\n return c.body(data);\n }\n\n return new Response(data, {\n headers: c.res.headers,\n });\n}\n","/**\n * @parsrun/server - Health Check Endpoints\n * Kubernetes-compatible health and readiness probes\n */\n\nimport { Hono } from \"hono\";\nimport type { HonoApp, ServerContextVariables } from \"./context.js\";\n\n/**\n * Health check status\n */\nexport type HealthStatus = \"healthy\" | \"degraded\" | \"unhealthy\";\n\n/**\n * Health check result\n */\nexport interface HealthCheckResult {\n status: HealthStatus;\n message?: string;\n latency?: number;\n}\n\n/**\n * Health check function\n */\nexport type HealthCheck = () => Promise<HealthCheckResult> | HealthCheckResult;\n\n/**\n * Health response\n */\nexport interface HealthResponse {\n status: HealthStatus;\n timestamp: string;\n uptime: number;\n checks: Record<string, HealthCheckResult>;\n}\n\n/**\n * Health check options\n */\nexport interface HealthCheckOptions {\n /** Custom health checks */\n checks?: Record<string, HealthCheck>;\n /** Include detailed info (disable in production) */\n detailed?: boolean;\n}\n\n// Track server start time\nconst startTime = Date.now();\n\n/**\n * Database health check\n */\nasync function checkDatabase(db: { ping?: () => Promise<boolean> }): Promise<HealthCheckResult> {\n const start = Date.now();\n\n try {\n if (db.ping) {\n await db.ping();\n }\n return {\n status: \"healthy\",\n latency: Date.now() - start,\n };\n } catch (err) {\n return {\n status: \"unhealthy\",\n message: err instanceof Error ? err.message : \"Database connection failed\",\n latency: Date.now() - start,\n };\n }\n}\n\n/**\n * Determine overall status from individual checks\n */\nfunction aggregateStatus(checks: Record<string, HealthCheckResult>): HealthStatus {\n const statuses = Object.values(checks).map((c) => c.status);\n\n if (statuses.some((s) => s === \"unhealthy\")) {\n return \"unhealthy\";\n }\n\n if (statuses.some((s) => s === \"degraded\")) {\n return \"degraded\";\n }\n\n return \"healthy\";\n}\n\n/**\n * Create health check router\n *\n * @example\n * ```typescript\n * const health = createHealthRouter({\n * checks: {\n * redis: async () => {\n * await redis.ping();\n * return { status: 'healthy' };\n * },\n * external: async () => {\n * const res = await fetch('https://api.example.com/health');\n * return { status: res.ok ? 'healthy' : 'unhealthy' };\n * },\n * },\n * });\n *\n * app.route('/health', health);\n * // GET /health - Full health check\n * // GET /health/live - Liveness probe\n * // GET /health/ready - Readiness probe\n * ```\n */\nexport function createHealthRouter(options: HealthCheckOptions = {}): HonoApp {\n const router = new Hono<{ Variables: ServerContextVariables }>();\n const { checks = {}, detailed = true } = options;\n\n /**\n * GET /health - Full health check\n * Returns detailed status of all checks\n */\n router.get(\"/\", async (c) => {\n const db = c.get(\"db\");\n const results: Record<string, HealthCheckResult> = {};\n\n // Run database check\n results[\"database\"] = await checkDatabase(db);\n\n // Run custom checks in parallel\n const customCheckResults = await Promise.all(\n Object.entries(checks).map(async ([name, check]) => {\n try {\n const result = await check();\n return [name, result] as const;\n } catch (err) {\n return [\n name,\n {\n status: \"unhealthy\" as const,\n message: err instanceof Error ? err.message : \"Check failed\",\n },\n ] as const;\n }\n })\n );\n\n for (const [name, result] of customCheckResults) {\n results[name] = result;\n }\n\n const overallStatus = aggregateStatus(results);\n const response: HealthResponse = {\n status: overallStatus,\n timestamp: new Date().toISOString(),\n uptime: Math.floor((Date.now() - startTime) / 1000),\n checks: detailed ? results : {},\n };\n\n const statusCode = overallStatus === \"healthy\" ? 200 : overallStatus === \"degraded\" ? 200 : 503;\n\n return c.json(response, statusCode as 200);\n });\n\n /**\n * GET /health/live - Liveness probe\n * Kubernetes liveness probe - returns 200 if server is running\n */\n router.get(\"/live\", (c) => {\n return c.json({\n status: \"ok\",\n timestamp: new Date().toISOString(),\n });\n });\n\n /**\n * GET /health/ready - Readiness probe\n * Kubernetes readiness probe - returns 200 if server can handle traffic\n */\n router.get(\"/ready\", async (c) => {\n const db = c.get(\"db\");\n\n // Check database connection\n const dbHealth = await checkDatabase(db);\n\n if (dbHealth.status === \"unhealthy\") {\n return c.json(\n {\n status: \"not_ready\",\n reason: \"database\",\n timestamp: new Date().toISOString(),\n },\n 503\n );\n }\n\n return c.json({\n status: \"ready\",\n timestamp: new Date().toISOString(),\n });\n });\n\n /**\n * GET /health/startup - Startup probe\n * For slow-starting containers\n */\n router.get(\"/startup\", (c) => {\n return c.json({\n status: \"started\",\n uptime: Math.floor((Date.now() - startTime) / 1000),\n timestamp: new Date().toISOString(),\n });\n });\n\n return router;\n}\n\n/**\n * Simple health endpoint handler\n *\n * @example\n * ```typescript\n * app.get('/health', healthHandler);\n * ```\n */\nexport async function healthHandler(c: import(\"hono\").Context<{ Variables: ServerContextVariables }>) {\n return c.json({\n status: \"ok\",\n timestamp: new Date().toISOString(),\n uptime: Math.floor((Date.now() - startTime) / 1000),\n });\n}\n"],"mappings":"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","names":["Hono","createLogger","createLogger","Hono","error","requestLogger","error","UnauthorizedError","ForbiddenError","error","c","UnauthorizedError","cors","corsConfig","c","ForbiddenError","status","error","error","type","uuidParam","paginationQuery","searchQuery","dateRangeQuery","status","url","Hono"]}
|
|
1
|
+
{"version":3,"sources":["../src/app.ts","../src/context.ts","../src/module-loader.ts","../src/rls.ts","../src/rbac.ts","../src/middleware/error-handler.ts","../src/middleware/auth.ts","../src/middleware/cors.ts","../src/middleware/csrf.ts","../src/middleware/rate-limit.ts","../src/middleware/request-logger.ts","../src/middleware/usage-tracking.ts","../src/middleware/quota-enforcement.ts","../src/validation/index.ts","../src/utils/pagination.ts","../src/utils/response.ts","../src/health.ts"],"sourcesContent":["/**\n * @parsrun/server - App Factory\n * Create and configure Hono server instances\n */\n\nimport { Hono } from \"hono\";\nimport { createLogger } from \"@parsrun/core\";\nimport type {\n ServerConfig,\n ServerContextVariables,\n HonoApp,\n} from \"./context.js\";\nimport { generateRequestId } from \"./context.js\";\n\n/**\n * Extended server options\n */\nexport interface CreateServerOptions extends ServerConfig {\n /** Enable request logging */\n logging?: boolean;\n /** Enable request ID generation */\n requestId?: boolean;\n /** Base path for all routes */\n basePath?: string;\n /** Strict mode - trailing slashes matter */\n strict?: boolean;\n}\n\n/**\n * Create a new Pars server instance\n *\n * @example\n * ```typescript\n * const app = createServer({\n * database: db,\n * cors: { origin: '*' },\n * logging: true,\n * });\n *\n * app.get('/health', (c) => c.json({ status: 'ok' }));\n *\n * export default app;\n * ```\n */\nexport function createServer(options: CreateServerOptions): HonoApp {\n const app = new Hono<{ Variables: ServerContextVariables }>({\n strict: options.strict ?? false,\n });\n\n const logger = options.logger ?? createLogger({ name: \"pars-server\" });\n\n // Initialize context for all requests\n app.use(\"*\", async (c, next) => {\n // Set core context variables\n c.set(\"db\", options.database);\n c.set(\"config\", options);\n c.set(\"logger\", logger);\n c.set(\"enabledModules\", new Set<string>());\n c.set(\"cookiePrefix\", options.cookiePrefix);\n c.set(\"custom\", options.custom ?? {});\n\n // Generate request ID if enabled\n if (options.requestId !== false) {\n const requestId = c.req.header(\"x-request-id\") ?? generateRequestId();\n c.set(\"requestId\", requestId);\n c.header(\"x-request-id\", requestId);\n }\n\n await next();\n });\n\n return app;\n}\n\n/**\n * Create a router (sub-app) with shared context\n *\n * @example\n * ```typescript\n * const usersRouter = createRouter();\n *\n * usersRouter.get('/', async (c) => {\n * const users = await getUsers(c.get('db'));\n * return c.json(success(users));\n * });\n *\n * usersRouter.post('/', async (c) => {\n * // ...\n * });\n *\n * app.route('/api/users', usersRouter);\n * ```\n */\nexport function createRouter(): HonoApp {\n return new Hono<{ Variables: ServerContextVariables }>();\n}\n\n/**\n * Create a versioned API router\n *\n * @example\n * ```typescript\n * const v1 = createVersionedRouter('v1');\n * v1.get('/users', handler);\n *\n * app.route('/api', v1); // Results in /api/v1/users\n * ```\n */\nexport function createVersionedRouter(version: string): HonoApp {\n const router = new Hono<{ Variables: ServerContextVariables }>();\n\n // Add version to all routes\n const versionedRouter = new Hono<{ Variables: ServerContextVariables }>();\n versionedRouter.route(`/${version}`, router);\n\n return versionedRouter;\n}\n\n/**\n * Create a module router with prefix\n *\n * @example\n * ```typescript\n * const inventoryModule = createModuleRouter('inventory', {\n * routes: (router) => {\n * router.get('/items', listItems);\n * router.post('/items', createItem);\n * },\n * });\n *\n * app.route('/api', inventoryModule);\n * ```\n */\nexport function createModuleRouter(\n moduleName: string,\n options: {\n routes: (router: HonoApp) => void;\n middleware?: Array<(c: import(\"hono\").Context, next: () => Promise<void>) => Promise<Response | void>>;\n }\n): HonoApp {\n const moduleRouter = new Hono<{ Variables: ServerContextVariables }>();\n\n // Apply module-specific middleware\n if (options.middleware) {\n for (const mw of options.middleware) {\n moduleRouter.use(\"*\", mw);\n }\n }\n\n // Register routes\n options.routes(moduleRouter);\n\n // Wrap in module path\n const wrappedRouter = new Hono<{ Variables: ServerContextVariables }>();\n wrappedRouter.route(`/${moduleName}`, moduleRouter);\n\n return wrappedRouter;\n}\n","/**\n * @parsrun/server - Server Context\n * Type definitions for server context and configuration\n */\n\nimport type { Logger } from \"@parsrun/core\";\n\n/**\n * Database adapter interface\n * Implement this for your database (Drizzle, Prisma, etc.)\n */\nexport interface DatabaseAdapter {\n /** Execute raw SQL query */\n execute(sql: string): Promise<unknown>;\n /** Check connection */\n ping?(): Promise<boolean>;\n}\n\n/**\n * Module manifest for registering modules\n */\nexport interface ModuleManifest {\n /** Unique module name */\n name: string;\n /** Module version */\n version: string;\n /** Module description */\n description: string;\n /** Required permissions for this module */\n permissions: Record<string, string[]>;\n /** Module dependencies (other module names) */\n dependencies?: string[];\n /** Register routes for this module */\n registerRoutes: (app: HonoApp) => void;\n /** Called when module is enabled */\n onEnable?: () => Promise<void>;\n /** Called when module is disabled */\n onDisable?: () => Promise<void>;\n}\n\n/**\n * Server configuration\n */\nexport interface ServerConfig {\n /** Database adapter */\n database: DatabaseAdapter;\n /** CORS configuration */\n cors?: CorsConfig;\n /** Base path for API */\n basePath?: string;\n /** Cookie prefix for all cookies */\n cookiePrefix?: string;\n /** Logger instance */\n logger?: Logger;\n /** Custom context data */\n custom?: Record<string, unknown>;\n}\n\n/**\n * CORS configuration\n */\nexport interface CorsConfig {\n /** Allowed origins */\n origin: string | string[] | ((origin: string) => boolean);\n /** Allow credentials */\n credentials?: boolean;\n /** Allowed methods */\n methods?: string[];\n /** Allowed headers */\n allowedHeaders?: string[];\n /** Exposed headers */\n exposedHeaders?: string[];\n /** Max age in seconds */\n maxAge?: number;\n}\n\n/**\n * User information in context\n */\nexport interface ContextUser {\n id: string;\n email: string | undefined;\n tenantId: string | undefined;\n role: string | undefined;\n permissions: string[];\n}\n\n/**\n * Tenant information in context\n */\nexport interface ContextTenant {\n id: string;\n slug: string | undefined;\n name: string | undefined;\n status: string;\n}\n\n/**\n * Server context variables\n * Available in Hono context via c.get()\n */\n/**\n * W3C Trace Context - Parsed traceparent header\n * Format: {version}-{trace-id}-{parent-id}-{trace-flags}\n */\nexport interface TraceContext {\n /** Trace version (currently \"00\") */\n version: string;\n /** 32 hex character trace ID */\n traceId: string;\n /** 16 hex character parent span ID */\n parentId: string;\n /** Trace flags (sampled, etc.) */\n traceFlags: number;\n}\n\nexport interface ServerContextVariables {\n /** Database adapter */\n db: DatabaseAdapter;\n /** Server configuration */\n config: ServerConfig;\n /** Enabled modules set */\n enabledModules: Set<string>;\n /** Current user (if authenticated) */\n user: ContextUser | undefined;\n /** Current tenant (if resolved) */\n tenant: ContextTenant | undefined;\n /** Request logger */\n logger: Logger;\n /** Request ID */\n requestId: string;\n /** Cookie prefix */\n cookiePrefix: string | undefined;\n /** Custom context data */\n custom: Record<string, unknown>;\n /** W3C trace context (if propagation is enabled) */\n traceContext?: TraceContext;\n /** Current span ID for this request */\n spanId?: string;\n /** Tracestate header value (for forwarding) */\n traceState?: string;\n}\n\n/**\n * Hono app type with server context\n */\nexport type HonoApp = import(\"hono\").Hono<{ Variables: ServerContextVariables }>;\n\n/**\n * Hono context type with server context\n */\nexport type HonoContext = import(\"hono\").Context<{ Variables: ServerContextVariables }>;\n\n/**\n * Middleware next function\n */\nexport type HonoNext = () => Promise<void>;\n\n/**\n * Middleware function type\n */\nexport type Middleware = (c: HonoContext, next: HonoNext) => Promise<Response | void>;\n\n/**\n * Route handler function type\n */\nexport type RouteHandler = (c: HonoContext) => Promise<Response> | Response;\n\n/**\n * Permission check input\n */\nexport interface PermissionCheck {\n /** Resource name (e.g., \"users\", \"items\") */\n resource: string;\n /** Action name (e.g., \"read\", \"create\", \"update\", \"delete\") */\n action: string;\n /** Permission scope */\n scope?: \"tenant\" | \"global\" | \"own\";\n}\n\n/**\n * Permission definition\n */\nexport interface PermissionDefinition {\n /** Permission name (e.g., \"users:read\") */\n name: string;\n /** Resource part */\n resource: string;\n /** Action part */\n action: string;\n /** Description */\n description?: string;\n /** Scope */\n scope?: \"tenant\" | \"global\" | \"own\";\n}\n\n/**\n * Role definition\n */\nexport interface RoleDefinition {\n /** Role name */\n name: string;\n /** Display name */\n displayName?: string;\n /** Description */\n description?: string;\n /** Permissions assigned to this role */\n permissions: string[];\n /** Is this a system role */\n isSystem?: boolean;\n}\n\n/**\n * Standard API response structure\n */\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: {\n code: string;\n message: string;\n details?: Record<string, unknown> | undefined;\n };\n meta?: {\n page?: number | undefined;\n limit?: number | undefined;\n total?: number | undefined;\n requestId?: string | undefined;\n } | undefined;\n}\n\n/**\n * Create a success response\n */\nexport function success<T>(data: T, meta?: ApiResponse[\"meta\"]): ApiResponse<T> {\n return {\n success: true,\n data,\n meta: meta ?? undefined,\n };\n}\n\n/**\n * Create an error response\n */\nexport function error(\n code: string,\n message: string,\n details?: Record<string, unknown>\n): ApiResponse<never> {\n return {\n success: false,\n error: { code, message, details: details ?? undefined },\n };\n}\n\n/**\n * Generate a request ID\n */\nexport function generateRequestId(): string {\n return crypto.randomUUID();\n}\n","/**\n * @parsrun/server - Module Loader\n * Dynamic module loading system for Pars server\n */\n\nimport { Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport { createLogger, type Logger } from \"@parsrun/core\";\nimport type {\n CorsConfig,\n DatabaseAdapter,\n HonoApp,\n ModuleManifest,\n ServerConfig,\n ServerContextVariables,\n} from \"./context.js\";\nimport { generateRequestId } from \"./context.js\";\n\n/**\n * Module Loader options\n */\nexport interface ModuleLoaderOptions {\n /** Server configuration */\n config: ServerConfig;\n /** Cookie prefix */\n cookiePrefix?: string;\n /** Logger instance */\n logger?: Logger;\n}\n\n/**\n * Module Loader\n * Manages dynamic module registration and lifecycle\n *\n * @example\n * ```typescript\n * const loader = new ModuleLoader({\n * config: {\n * database: drizzleDb,\n * cors: { origin: '*' },\n * },\n * });\n *\n * await loader.initialize();\n *\n * // Register modules\n * loader.registerModule(itemsModule);\n * loader.registerModule(usersModule);\n *\n * // Enable modules\n * await loader.enableModule('items');\n * await loader.enableModule('users');\n *\n * // Get Hono app\n * export default loader.getApp();\n * ```\n */\nexport class ModuleLoader {\n private app: HonoApp;\n private db: DatabaseAdapter;\n private enabledModules: Set<string> = new Set();\n private moduleRegistry: Map<string, ModuleManifest> = new Map();\n private logger: Logger;\n private config: ServerConfig;\n private cookiePrefix: string | undefined;\n private initialized = false;\n\n constructor(options: ModuleLoaderOptions) {\n this.config = options.config;\n this.db = options.config.database;\n this.cookiePrefix = options.cookiePrefix;\n this.logger = options.logger ?? createLogger({ name: \"ModuleLoader\" });\n\n // Create Hono app with typed context\n this.app = new Hono<{ Variables: ServerContextVariables }>();\n\n this.setupMiddleware();\n this.setupCoreRoutes();\n }\n\n /**\n * Initialize the module loader\n * Checks database connection\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n this.logger.warn(\"ModuleLoader already initialized\");\n return;\n }\n\n this.logger.info(\"Initializing ModuleLoader...\");\n\n // Check database connection\n try {\n if (this.db.ping) {\n const ok = await this.db.ping();\n if (!ok) throw new Error(\"Database ping returned false\");\n } else {\n await this.db.execute(\"SELECT 1\");\n }\n this.logger.info(\"Database connection: OK\");\n } catch (error) {\n this.logger.error(\"Database connection failed\", error);\n throw new Error(\"Database connection failed\");\n }\n\n this.initialized = true;\n this.logger.info(\"ModuleLoader initialized successfully\");\n }\n\n /**\n * Setup core middleware\n */\n private setupMiddleware(): void {\n // Request ID and logging\n this.app.use(\"*\", async (c, next) => {\n const requestId = generateRequestId();\n const requestLogger = this.logger.child({ requestId });\n\n // Set context variables\n c.set(\"db\", this.db);\n c.set(\"config\", this.config);\n c.set(\"enabledModules\", this.enabledModules);\n c.set(\"logger\", requestLogger);\n c.set(\"requestId\", requestId);\n c.set(\"cookiePrefix\", this.cookiePrefix);\n c.set(\"custom\", this.config.custom ?? {});\n c.set(\"user\", undefined);\n c.set(\"tenant\", undefined);\n\n const start = Date.now();\n\n await next();\n\n const duration = Date.now() - start;\n requestLogger.debug(\"Request completed\", {\n method: c.req.method,\n path: c.req.path,\n status: c.res.status,\n durationMs: duration,\n });\n });\n\n // CORS\n if (this.config.cors) {\n this.app.use(\"*\", cors(this.normalizeCorsConfig(this.config.cors)));\n }\n }\n\n /**\n * Normalize CORS config for Hono\n */\n private normalizeCorsConfig(config: CorsConfig): Parameters<typeof cors>[0] {\n const result: Parameters<typeof cors>[0] = {\n origin: typeof config.origin === \"function\"\n ? (origin) => (config.origin as (origin: string) => boolean)(origin) ? origin : null\n : config.origin,\n };\n\n if (config.credentials !== undefined) {\n result.credentials = config.credentials;\n }\n if (config.methods !== undefined) {\n result.allowMethods = config.methods;\n }\n if (config.allowedHeaders !== undefined) {\n result.allowHeaders = config.allowedHeaders;\n }\n if (config.exposedHeaders !== undefined) {\n result.exposeHeaders = config.exposedHeaders;\n }\n if (config.maxAge !== undefined) {\n result.maxAge = config.maxAge;\n }\n\n return result;\n }\n\n /**\n * Setup core routes\n */\n private setupCoreRoutes(): void {\n const basePath = this.config.basePath ?? \"/api/v1\";\n\n // Health check\n this.app.get(\"/health\", (c) => {\n return c.json({\n status: \"ok\",\n timestamp: new Date().toISOString(),\n });\n });\n\n // Health check with details\n this.app.get(\"/health/details\", async (c) => {\n let dbStatus = \"unknown\";\n try {\n if (this.db.ping) {\n dbStatus = (await this.db.ping()) ? \"ok\" : \"error\";\n } else {\n await this.db.execute(\"SELECT 1\");\n dbStatus = \"ok\";\n }\n } catch {\n dbStatus = \"error\";\n }\n\n return c.json({\n status: dbStatus === \"ok\" ? \"ok\" : \"degraded\",\n timestamp: new Date().toISOString(),\n services: {\n database: dbStatus,\n },\n modules: {\n enabled: Array.from(this.enabledModules),\n registered: Array.from(this.moduleRegistry.keys()),\n },\n });\n });\n\n // API info\n this.app.get(basePath, (c) => {\n const endpoints: Record<string, string> = {\n health: \"/health\",\n features: `${basePath}/features`,\n };\n\n // Add module endpoints\n for (const moduleName of this.enabledModules) {\n endpoints[moduleName] = `${basePath}/${moduleName}`;\n }\n\n return c.json({\n name: \"Pars API\",\n version: \"1.0.0\",\n endpoints,\n });\n });\n\n // Feature discovery\n this.app.get(`${basePath}/features`, (c) => {\n const features = Array.from(this.enabledModules).map((name) => {\n const module = this.moduleRegistry.get(name);\n return {\n name,\n version: module?.version ?? \"1.0.0\",\n description: module?.description ?? \"\",\n permissions: module?.permissions ?? {},\n };\n });\n\n return c.json({\n enabled: Array.from(this.enabledModules),\n features,\n });\n });\n }\n\n /**\n * Register a module\n */\n registerModule(manifest: ModuleManifest): void {\n if (this.moduleRegistry.has(manifest.name)) {\n this.logger.warn(`Module already registered: ${manifest.name}`);\n return;\n }\n\n this.moduleRegistry.set(manifest.name, manifest);\n this.logger.info(`Registered module: ${manifest.name}`);\n }\n\n /**\n * Enable a registered module\n */\n async enableModule(moduleName: string): Promise<boolean> {\n const module = this.moduleRegistry.get(moduleName);\n\n if (!module) {\n this.logger.error(`Module not found: ${moduleName}`);\n return false;\n }\n\n if (this.enabledModules.has(moduleName)) {\n this.logger.warn(`Module already enabled: ${moduleName}`);\n return true;\n }\n\n // Check dependencies\n if (module.dependencies) {\n for (const dep of module.dependencies) {\n if (!this.enabledModules.has(dep)) {\n this.logger.error(\n `Module ${moduleName} requires ${dep} to be enabled first`\n );\n return false;\n }\n }\n }\n\n try {\n this.logger.info(`Enabling module: ${moduleName}`);\n\n // Run onEnable hook\n if (module.onEnable) {\n await module.onEnable();\n }\n\n // Register routes\n module.registerRoutes(this.app);\n\n // Mark as enabled\n this.enabledModules.add(moduleName);\n\n this.logger.info(`Enabled module: ${moduleName}`);\n return true;\n } catch (error) {\n this.logger.error(`Failed to enable module ${moduleName}`, error);\n return false;\n }\n }\n\n /**\n * Disable an enabled module\n */\n async disableModule(moduleName: string): Promise<boolean> {\n if (!this.enabledModules.has(moduleName)) {\n this.logger.warn(`Module not enabled: ${moduleName}`);\n return true;\n }\n\n const module = this.moduleRegistry.get(moduleName);\n if (!module) {\n this.logger.error(`Module not found: ${moduleName}`);\n return false;\n }\n\n // Check if other modules depend on this one\n for (const [name, m] of this.moduleRegistry) {\n if (this.enabledModules.has(name) && m.dependencies?.includes(moduleName)) {\n this.logger.error(\n `Cannot disable ${moduleName}: ${name} depends on it`\n );\n return false;\n }\n }\n\n try {\n // Run onDisable hook\n if (module.onDisable) {\n await module.onDisable();\n }\n\n // Note: Routes cannot be easily unregistered in Hono\n // The module will remain registered but marked as disabled\n this.enabledModules.delete(moduleName);\n\n this.logger.info(`Disabled module: ${moduleName}`);\n return true;\n } catch (error) {\n this.logger.error(`Failed to disable module ${moduleName}`, error);\n return false;\n }\n }\n\n /**\n * Get the Hono app instance\n */\n getApp(): HonoApp {\n return this.app;\n }\n\n /**\n * Get enabled modules\n */\n getEnabledModules(): string[] {\n return Array.from(this.enabledModules);\n }\n\n /**\n * Get registered modules\n */\n getRegisteredModules(): string[] {\n return Array.from(this.moduleRegistry.keys());\n }\n\n /**\n * Check if module is enabled\n */\n isModuleEnabled(moduleName: string): boolean {\n return this.enabledModules.has(moduleName);\n }\n\n /**\n * Check if module is registered\n */\n isModuleRegistered(moduleName: string): boolean {\n return this.moduleRegistry.has(moduleName);\n }\n\n /**\n * Get database adapter\n */\n getDatabase(): DatabaseAdapter {\n return this.db;\n }\n\n /**\n * Get logger\n */\n getLogger(): Logger {\n return this.logger;\n }\n}\n\n/**\n * Create a module loader\n */\nexport function createModuleLoader(options: ModuleLoaderOptions): ModuleLoader {\n return new ModuleLoader(options);\n}\n\n/**\n * Create a module manifest helper\n */\nexport function defineModule(manifest: ModuleManifest): ModuleManifest {\n return manifest;\n}\n","/**\n * @parsrun/server - Row Level Security (RLS) Manager\n * PostgreSQL RLS integration for multi-tenant isolation\n */\n\nimport type { DatabaseAdapter, HonoContext, HonoNext, Middleware } from \"./context.js\";\n\n/**\n * RLS configuration\n */\nexport interface RLSConfig {\n /** Tenant ID column name (default: tenant_id) */\n tenantIdColumn?: string;\n /** PostgreSQL session variable name (default: app.current_tenant_id) */\n sessionVariable?: string;\n /** Enable RLS by default */\n enabled?: boolean;\n}\n\n/**\n * Default RLS configuration\n */\nconst DEFAULT_RLS_CONFIG: Required<RLSConfig> = {\n tenantIdColumn: \"tenant_id\",\n sessionVariable: \"app.current_tenant_id\",\n enabled: true,\n};\n\n/**\n * RLS Manager for tenant isolation\n *\n * @example\n * ```typescript\n * const rls = new RLSManager(db);\n *\n * // Set tenant context\n * await rls.setTenantId(\"tenant-123\");\n *\n * // All queries now filtered by tenant\n * const items = await db.select().from(items);\n *\n * // Clear when done\n * await rls.clearTenantId();\n *\n * // Or use withTenant helper\n * await rls.withTenant(\"tenant-123\", async () => {\n * return await db.select().from(items);\n * });\n * ```\n */\nexport class RLSManager {\n private config: Required<RLSConfig>;\n\n constructor(\n private db: DatabaseAdapter,\n config: RLSConfig = {}\n ) {\n this.config = { ...DEFAULT_RLS_CONFIG, ...config };\n }\n\n /**\n * Set current tenant ID in database session\n * This enables RLS policies to filter by tenant\n */\n async setTenantId(tenantId: string): Promise<void> {\n if (!this.config.enabled) return;\n\n try {\n // Use parameterized query to prevent SQL injection\n // PostgreSQL SET command with escaped string\n const escapedTenantId = tenantId.replace(/'/g, \"''\");\n await this.db.execute(`SET ${this.config.sessionVariable} = '${escapedTenantId}'`);\n } catch (error) {\n console.error(\"Failed to set tenant ID for RLS:\", error);\n throw new RLSError(\"Failed to set tenant context\", \"RLS_SET_FAILED\", error);\n }\n }\n\n /**\n * Clear current tenant ID from database session\n */\n async clearTenantId(): Promise<void> {\n if (!this.config.enabled) return;\n\n try {\n await this.db.execute(`RESET ${this.config.sessionVariable}`);\n } catch (error) {\n console.error(\"Failed to clear tenant ID for RLS:\", error);\n throw new RLSError(\"Failed to clear tenant context\", \"RLS_CLEAR_FAILED\", error);\n }\n }\n\n /**\n * Execute a function with tenant context\n * Automatically sets and clears tenant ID\n */\n async withTenant<T>(tenantId: string, operation: () => Promise<T>): Promise<T> {\n await this.setTenantId(tenantId);\n try {\n return await operation();\n } finally {\n await this.clearTenantId();\n }\n }\n\n /**\n * Check if RLS is enabled\n */\n isEnabled(): boolean {\n return this.config.enabled;\n }\n\n /**\n * Get current configuration\n */\n getConfig(): Required<RLSConfig> {\n return { ...this.config };\n }\n}\n\n/**\n * RLS Error class\n */\nexport class RLSError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = \"RLSError\";\n }\n}\n\n/**\n * Create RLS manager\n */\nexport function createRLSManager(db: DatabaseAdapter, config?: RLSConfig): RLSManager {\n return new RLSManager(db, config);\n}\n\n/**\n * RLS Middleware\n * Automatically sets tenant context for authenticated requests\n *\n * @example\n * ```typescript\n * app.use('*', rlsMiddleware());\n * ```\n */\nexport function rlsMiddleware(config?: RLSConfig): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n const db = c.get(\"db\");\n\n // Skip if no user or no tenant\n if (!user?.tenantId || !db) {\n return next();\n }\n\n const rls = new RLSManager(db, config);\n\n try {\n await rls.setTenantId(user.tenantId);\n await next();\n } finally {\n await rls.clearTenantId();\n }\n };\n}\n\n/**\n * Create SQL for enabling RLS on a table\n *\n * @example\n * ```sql\n * -- Generated SQL:\n * ALTER TABLE items ENABLE ROW LEVEL SECURITY;\n * CREATE POLICY items_tenant_isolation ON items\n * USING (tenant_id = current_setting('app.current_tenant_id')::uuid);\n * ```\n */\nexport function generateRLSPolicy(\n tableName: string,\n options: {\n tenantIdColumn?: string;\n sessionVariable?: string;\n policyName?: string;\n castType?: string;\n } = {}\n): string {\n const {\n tenantIdColumn = \"tenant_id\",\n sessionVariable = \"app.current_tenant_id\",\n policyName = `${tableName}_tenant_isolation`,\n castType = \"uuid\",\n } = options;\n\n return `\n-- Enable RLS on table\nALTER TABLE ${tableName} ENABLE ROW LEVEL SECURITY;\n\n-- Force RLS for table owner too\nALTER TABLE ${tableName} FORCE ROW LEVEL SECURITY;\n\n-- Create tenant isolation policy\nDROP POLICY IF EXISTS ${policyName} ON ${tableName};\nCREATE POLICY ${policyName} ON ${tableName}\n FOR ALL\n USING (${tenantIdColumn} = current_setting('${sessionVariable}', true)::${castType});\n`.trim();\n}\n\n/**\n * Create SQL for disabling RLS on a table\n */\nexport function generateDisableRLS(tableName: string): string {\n return `\nALTER TABLE ${tableName} DISABLE ROW LEVEL SECURITY;\nALTER TABLE ${tableName} NO FORCE ROW LEVEL SECURITY;\n`.trim();\n}\n","/**\n * @parsrun/server - Role-Based Access Control (RBAC)\n * Permission and role management with middleware\n */\n\nimport { ForbiddenError, UnauthorizedError } from \"@parsrun/core\";\nimport type {\n ContextUser,\n HonoContext,\n HonoNext,\n Middleware,\n PermissionCheck,\n PermissionDefinition,\n RoleDefinition,\n} from \"./context.js\";\n\n/**\n * RBAC Permission Checker interface\n * Implement this for database-backed permission checks\n */\nexport interface PermissionChecker {\n /** Get user's permissions in a tenant */\n getUserPermissions(userId: string, tenantId?: string): Promise<string[]>;\n /** Get user's roles in a tenant */\n getUserRoles(userId: string, tenantId?: string): Promise<string[]>;\n /** Check if user has specific permission */\n hasPermission(userId: string, check: PermissionCheck, tenantId?: string): Promise<boolean>;\n /** Check if user is member of tenant */\n isTenantMember(userId: string, tenantId: string): Promise<boolean>;\n}\n\n/**\n * In-memory RBAC service\n * For simple use cases or testing\n */\nexport class InMemoryRBAC implements PermissionChecker {\n private userPermissions: Map<string, Set<string>> = new Map();\n private userRoles: Map<string, Set<string>> = new Map();\n private rolePermissions: Map<string, Set<string>> = new Map();\n private tenantMembers: Map<string, Set<string>> = new Map();\n\n /**\n * Grant permission to user\n */\n grantPermission(userId: string, permission: string): void {\n if (!this.userPermissions.has(userId)) {\n this.userPermissions.set(userId, new Set());\n }\n this.userPermissions.get(userId)!.add(permission);\n }\n\n /**\n * Revoke permission from user\n */\n revokePermission(userId: string, permission: string): void {\n this.userPermissions.get(userId)?.delete(permission);\n }\n\n /**\n * Assign role to user\n */\n assignRole(userId: string, role: string): void {\n if (!this.userRoles.has(userId)) {\n this.userRoles.set(userId, new Set());\n }\n this.userRoles.get(userId)!.add(role);\n }\n\n /**\n * Remove role from user\n */\n removeRole(userId: string, role: string): void {\n this.userRoles.get(userId)?.delete(role);\n }\n\n /**\n * Define role with permissions\n */\n defineRole(roleName: string, permissions: string[]): void {\n this.rolePermissions.set(roleName, new Set(permissions));\n }\n\n /**\n * Add user to tenant\n */\n addTenantMember(tenantId: string, userId: string): void {\n if (!this.tenantMembers.has(tenantId)) {\n this.tenantMembers.set(tenantId, new Set());\n }\n this.tenantMembers.get(tenantId)!.add(userId);\n }\n\n /**\n * Remove user from tenant\n */\n removeTenantMember(tenantId: string, userId: string): void {\n this.tenantMembers.get(tenantId)?.delete(userId);\n }\n\n // PermissionChecker implementation\n\n async getUserPermissions(userId: string, _tenantId?: string): Promise<string[]> {\n const permissions = new Set<string>();\n\n // Direct permissions\n const direct = this.userPermissions.get(userId);\n if (direct) {\n direct.forEach((p) => permissions.add(p));\n }\n\n // Role-based permissions\n const roles = this.userRoles.get(userId);\n if (roles) {\n roles.forEach((role) => {\n const rolePerms = this.rolePermissions.get(role);\n if (rolePerms) {\n rolePerms.forEach((p) => permissions.add(p));\n }\n });\n }\n\n return Array.from(permissions);\n }\n\n async getUserRoles(userId: string, _tenantId?: string): Promise<string[]> {\n return Array.from(this.userRoles.get(userId) ?? []);\n }\n\n async hasPermission(\n userId: string,\n check: PermissionCheck,\n tenantId?: string\n ): Promise<boolean> {\n const permissions = await this.getUserPermissions(userId, tenantId);\n const permissionName = `${check.resource}:${check.action}`;\n\n // Check exact match\n if (permissions.includes(permissionName)) {\n return true;\n }\n\n // Check wildcard patterns\n // users:* matches users:read, users:create, etc.\n // *:read matches items:read, users:read, etc.\n // * matches everything\n for (const perm of permissions) {\n if (perm === \"*\") return true;\n if (perm === `${check.resource}:*`) return true;\n if (perm === `*:${check.action}`) return true;\n }\n\n return false;\n }\n\n async isTenantMember(userId: string, tenantId: string): Promise<boolean> {\n return this.tenantMembers.get(tenantId)?.has(userId) ?? false;\n }\n}\n\n/**\n * RBAC Service for authorization checks\n */\nexport class RBACService {\n constructor(private checker: PermissionChecker) {}\n\n /**\n * Get user's permissions\n */\n async getUserPermissions(userId: string, tenantId?: string): Promise<string[]> {\n return this.checker.getUserPermissions(userId, tenantId);\n }\n\n /**\n * Get user's roles\n */\n async getUserRoles(userId: string, tenantId?: string): Promise<string[]> {\n return this.checker.getUserRoles(userId, tenantId);\n }\n\n /**\n * Check if user has specific permission\n */\n async hasPermission(\n userId: string,\n check: PermissionCheck,\n tenantId?: string\n ): Promise<boolean> {\n return this.checker.hasPermission(userId, check, tenantId);\n }\n\n /**\n * Check if user has any of the specified permissions\n */\n async hasAnyPermission(\n userId: string,\n checks: PermissionCheck[],\n tenantId?: string\n ): Promise<boolean> {\n for (const check of checks) {\n if (await this.hasPermission(userId, check, tenantId)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Check if user has all specified permissions\n */\n async hasAllPermissions(\n userId: string,\n checks: PermissionCheck[],\n tenantId?: string\n ): Promise<boolean> {\n for (const check of checks) {\n if (!(await this.hasPermission(userId, check, tenantId))) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Check if user is member of tenant\n */\n async isTenantMember(userId: string, tenantId: string): Promise<boolean> {\n return this.checker.isTenantMember(userId, tenantId);\n }\n\n /**\n * Check if user has specific role\n */\n async hasRole(userId: string, role: string, tenantId?: string): Promise<boolean> {\n const roles = await this.getUserRoles(userId, tenantId);\n return roles.includes(role);\n }\n\n /**\n * Check if user has any of the specified roles\n */\n async hasAnyRole(userId: string, roles: string[], tenantId?: string): Promise<boolean> {\n const userRoles = await this.getUserRoles(userId, tenantId);\n return roles.some((role) => userRoles.includes(role));\n }\n}\n\n/**\n * Create RBAC service with in-memory checker\n */\nexport function createInMemoryRBAC(): { rbac: RBACService; checker: InMemoryRBAC } {\n const checker = new InMemoryRBAC();\n const rbac = new RBACService(checker);\n return { rbac, checker };\n}\n\n/**\n * Create RBAC service with custom checker\n */\nexport function createRBACService(checker: PermissionChecker): RBACService {\n return new RBACService(checker);\n}\n\n// ============================================\n// MIDDLEWARE FACTORIES\n// ============================================\n\n/**\n * Require authentication middleware\n */\nexport function requireAuth(): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n\n if (!user) {\n throw new UnauthorizedError(\"Authentication required\");\n }\n\n return next();\n };\n}\n\n/**\n * Require specific permission middleware\n *\n * @example\n * ```typescript\n * app.get('/items', requirePermission('items', 'read'), handler);\n * app.post('/items', requirePermission('items', 'create'), handler);\n * ```\n */\nexport function requirePermission(\n resource: string,\n action: string,\n options: { scope?: \"tenant\" | \"global\" | \"own\"; checker?: PermissionChecker } = {}\n): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n\n if (!user) {\n throw new UnauthorizedError(\"Authentication required\");\n }\n\n const check: PermissionCheck = {\n resource,\n action,\n scope: options.scope ?? \"tenant\",\n };\n\n // Use custom checker or check from user permissions\n let hasPermission = false;\n\n if (options.checker) {\n hasPermission = await options.checker.hasPermission(user.id, check, user.tenantId);\n } else {\n // Check from user's loaded permissions\n hasPermission = checkUserPermission(user, check);\n }\n\n if (!hasPermission) {\n throw new ForbiddenError(`Permission denied: ${resource}:${action}`);\n }\n\n return next();\n };\n}\n\n/**\n * Require any of specified permissions middleware\n */\nexport function requireAnyPermission(\n permissions: Array<{ resource: string; action: string }>,\n options: { checker?: PermissionChecker } = {}\n): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n\n if (!user) {\n throw new UnauthorizedError(\"Authentication required\");\n }\n\n let hasAny = false;\n\n for (const perm of permissions) {\n const check: PermissionCheck = { resource: perm.resource, action: perm.action };\n\n if (options.checker) {\n if (await options.checker.hasPermission(user.id, check, user.tenantId)) {\n hasAny = true;\n break;\n }\n } else {\n if (checkUserPermission(user, check)) {\n hasAny = true;\n break;\n }\n }\n }\n\n if (!hasAny) {\n throw new ForbiddenError(\"Insufficient permissions\");\n }\n\n return next();\n };\n}\n\n/**\n * Require specific role middleware\n */\nexport function requireRole(role: string): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n\n if (!user) {\n throw new UnauthorizedError(\"Authentication required\");\n }\n\n if (user.role !== role) {\n throw new ForbiddenError(`Role required: ${role}`);\n }\n\n return next();\n };\n}\n\n/**\n * Require any of specified roles middleware\n */\nexport function requireAnyRole(roles: string[]): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n\n if (!user) {\n throw new UnauthorizedError(\"Authentication required\");\n }\n\n if (!user.role || !roles.includes(user.role)) {\n throw new ForbiddenError(`One of these roles required: ${roles.join(\", \")}`);\n }\n\n return next();\n };\n}\n\n/**\n * Require tenant membership middleware\n */\nexport function requireTenantMember(requiredRole?: string): Middleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const user = c.get(\"user\");\n const tenant = c.get(\"tenant\");\n\n if (!user) {\n throw new UnauthorizedError(\"Authentication required\");\n }\n\n if (!tenant) {\n throw new ForbiddenError(\"Tenant context required\");\n }\n\n if (user.tenantId !== tenant.id) {\n throw new ForbiddenError(\"Not a member of this tenant\");\n }\n\n if (requiredRole && user.role !== requiredRole) {\n throw new ForbiddenError(`Role required in tenant: ${requiredRole}`);\n }\n\n return next();\n };\n}\n\n/**\n * Check user permission from loaded permissions array\n */\nfunction checkUserPermission(user: ContextUser, check: PermissionCheck): boolean {\n const permissionName = `${check.resource}:${check.action}`;\n\n for (const perm of user.permissions) {\n if (perm === permissionName) return true;\n if (perm === \"*\") return true;\n if (perm === `${check.resource}:*`) return true;\n if (perm === `*:${check.action}`) return true;\n }\n\n return false;\n}\n\n// ============================================\n// PERMISSION UTILITIES\n// ============================================\n\n/**\n * Parse permission string to PermissionCheck\n */\nexport function parsePermission(permission: string): PermissionCheck {\n const [resource, action] = permission.split(\":\");\n if (!resource || !action) {\n throw new Error(`Invalid permission format: ${permission}`);\n }\n return { resource, action };\n}\n\n/**\n * Create permission string from parts\n */\nexport function createPermission(resource: string, action: string): string {\n return `${resource}:${action}`;\n}\n\n/**\n * Standard CRUD permissions for a resource\n */\nexport function crudPermissions(resource: string): PermissionDefinition[] {\n return [\n { name: `${resource}:create`, resource, action: \"create\" },\n { name: `${resource}:read`, resource, action: \"read\" },\n { name: `${resource}:update`, resource, action: \"update\" },\n { name: `${resource}:delete`, resource, action: \"delete\" },\n { name: `${resource}:list`, resource, action: \"list\" },\n ];\n}\n\n/**\n * Standard roles\n */\nexport const StandardRoles: Record<string, RoleDefinition> = {\n OWNER: {\n name: \"owner\",\n displayName: \"Owner\",\n description: \"Full access to all resources\",\n permissions: [\"*\"],\n isSystem: true,\n },\n ADMIN: {\n name: \"admin\",\n displayName: \"Administrator\",\n description: \"Administrative access\",\n permissions: [\"*:read\", \"*:create\", \"*:update\", \"*:list\"],\n isSystem: true,\n },\n MEMBER: {\n name: \"member\",\n displayName: \"Member\",\n description: \"Standard member access\",\n permissions: [\"*:read\", \"*:list\"],\n isSystem: true,\n },\n VIEWER: {\n name: \"viewer\",\n displayName: \"Viewer\",\n description: \"Read-only access\",\n permissions: [\"*:read\", \"*:list\"],\n isSystem: true,\n },\n};\n","/**\n * @parsrun/server - Error Handler Middleware\n * Global error handling and response formatting\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\nimport { error as errorResponse } from \"../context.js\";\nimport type { ErrorTransport, ErrorContext } from \"@parsrun/core/transports\";\n\n/**\n * Base API error class\n */\nexport class ApiError extends Error {\n constructor(\n public readonly statusCode: number,\n public readonly code: string,\n message: string,\n public readonly details?: Record<string, unknown>\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n\n toResponse() {\n return errorResponse(this.code, this.message, this.details);\n }\n}\n\n/**\n * 400 Bad Request\n */\nexport class BadRequestError extends ApiError {\n constructor(message = \"Bad request\", details?: Record<string, unknown>) {\n super(400, \"BAD_REQUEST\", message, details);\n this.name = \"BadRequestError\";\n }\n}\n\n/**\n * 401 Unauthorized\n */\nexport class UnauthorizedError extends ApiError {\n constructor(message = \"Unauthorized\", details?: Record<string, unknown>) {\n super(401, \"UNAUTHORIZED\", message, details);\n this.name = \"UnauthorizedError\";\n }\n}\n\n/**\n * 403 Forbidden\n */\nexport class ForbiddenError extends ApiError {\n constructor(message = \"Forbidden\", details?: Record<string, unknown>) {\n super(403, \"FORBIDDEN\", message, details);\n this.name = \"ForbiddenError\";\n }\n}\n\n/**\n * 404 Not Found\n */\nexport class NotFoundError extends ApiError {\n constructor(message = \"Not found\", details?: Record<string, unknown>) {\n super(404, \"NOT_FOUND\", message, details);\n this.name = \"NotFoundError\";\n }\n}\n\n/**\n * 409 Conflict\n */\nexport class ConflictError extends ApiError {\n constructor(message = \"Conflict\", details?: Record<string, unknown>) {\n super(409, \"CONFLICT\", message, details);\n this.name = \"ConflictError\";\n }\n}\n\n/**\n * 422 Unprocessable Entity (Validation Error)\n */\nexport class ValidationError extends ApiError {\n constructor(message = \"Validation failed\", details?: Record<string, unknown>) {\n super(422, \"VALIDATION_ERROR\", message, details);\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * 429 Too Many Requests\n */\nexport class RateLimitError extends ApiError {\n constructor(\n message = \"Too many requests\",\n public readonly retryAfter?: number\n ) {\n super(429, \"RATE_LIMIT_EXCEEDED\", message, { retryAfter });\n this.name = \"RateLimitError\";\n }\n}\n\n/**\n * 500 Internal Server Error\n */\nexport class InternalError extends ApiError {\n constructor(message = \"Internal server error\", details?: Record<string, unknown>) {\n super(500, \"INTERNAL_ERROR\", message, details);\n this.name = \"InternalError\";\n }\n}\n\n/**\n * 503 Service Unavailable\n */\nexport class ServiceUnavailableError extends ApiError {\n constructor(message = \"Service unavailable\", details?: Record<string, unknown>) {\n super(503, \"SERVICE_UNAVAILABLE\", message, details);\n this.name = \"ServiceUnavailableError\";\n }\n}\n\n/**\n * Error handler options\n */\nexport interface ErrorHandlerOptions {\n /** Include stack trace in development */\n includeStack?: boolean;\n /** Custom error logger */\n onError?: (error: Error, c: HonoContext) => void;\n /**\n * Error transport for external error tracking (e.g., Sentry)\n * Automatically captures exceptions with request context\n */\n errorTransport?: ErrorTransport;\n /**\n * Capture all errors including 4xx client errors\n * By default, only 5xx server errors are captured\n * @default false\n */\n captureAllErrors?: boolean;\n /**\n * Custom function to determine if an error should be captured\n * Overrides the default captureAllErrors behavior\n */\n shouldCapture?: (error: Error, statusCode: number) => boolean;\n}\n\n/**\n * Global error handler middleware\n *\n * @example Basic usage\n * ```typescript\n * app.use('*', errorHandler({\n * includeStack: process.env.NODE_ENV === 'development',\n * onError: (error, c) => {\n * console.error(`[${c.get('requestId')}]`, error);\n * },\n * }));\n * ```\n *\n * @example With Sentry error tracking\n * ```typescript\n * import { SentryTransport } from '@parsrun/core/transports';\n *\n * const sentry = new SentryTransport({\n * dsn: process.env.SENTRY_DSN!,\n * environment: process.env.NODE_ENV,\n * });\n *\n * app.use('*', errorHandler({\n * errorTransport: sentry,\n * captureAllErrors: false, // Only capture 5xx errors\n * }));\n * ```\n */\nexport function errorHandler(options: ErrorHandlerOptions = {}) {\n const {\n includeStack = false,\n onError,\n errorTransport,\n captureAllErrors = false,\n shouldCapture,\n } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n try {\n await next();\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n\n // Determine status code\n const statusCode = error instanceof ApiError ? error.statusCode : 500;\n\n // Log error\n if (onError) {\n onError(error, c);\n } else {\n const logger = c.get(\"logger\");\n if (logger) {\n logger.error(\"Request error\", {\n requestId: c.get(\"requestId\"),\n error: error.message,\n stack: error.stack,\n });\n }\n }\n\n // Capture to error transport if configured\n if (errorTransport) {\n const shouldCaptureError = shouldCapture\n ? shouldCapture(error, statusCode)\n : captureAllErrors || statusCode >= 500;\n\n if (shouldCaptureError) {\n const user = c.get(\"user\");\n const tenant = c.get(\"tenant\");\n\n // Build error context with only defined values\n const errorContext: ErrorContext = {\n requestId: c.get(\"requestId\"),\n tags: {\n path: c.req.path,\n method: c.req.method,\n statusCode: String(statusCode),\n },\n };\n\n if (user?.id) {\n errorContext.userId = user.id;\n }\n if (tenant?.id) {\n errorContext.tenantId = tenant.id;\n }\n\n // Add extra context\n const extra: Record<string, unknown> = {\n query: c.req.query(),\n };\n if (error instanceof ApiError) {\n extra[\"errorCode\"] = error.code;\n }\n errorContext.extra = extra;\n\n // Capture asynchronously to not block response\n Promise.resolve(\n errorTransport.captureException(error, errorContext)\n ).catch(() => {\n // Silent fail - don't let transport errors affect response\n });\n }\n }\n\n // Handle known API errors\n if (error instanceof ApiError) {\n return c.json(error.toResponse(), error.statusCode as 400);\n }\n\n // Handle unknown errors\n const details: Record<string, unknown> = {};\n\n if (includeStack && error.stack) {\n details[\"stack\"] = error.stack;\n }\n\n return c.json(\n errorResponse(\"INTERNAL_ERROR\", \"An unexpected error occurred\", details),\n 500\n );\n }\n };\n}\n\n/**\n * Not found handler\n *\n * @example\n * ```typescript\n * app.notFound(notFoundHandler);\n * ```\n */\nexport function notFoundHandler(c: HonoContext) {\n return c.json(\n errorResponse(\"NOT_FOUND\", `Route ${c.req.method} ${c.req.path} not found`),\n 404\n );\n}\n","/**\n * @parsrun/server - Auth Middleware\n * JWT authentication middleware\n */\n\nimport type { HonoContext, HonoNext, ContextUser } from \"../context.js\";\nimport { UnauthorizedError } from \"./error-handler.js\";\n\n/**\n * JWT payload structure\n */\nexport interface JwtPayload {\n sub: string; // User ID\n email?: string;\n tenantId?: string;\n role?: string;\n permissions?: string[];\n iat?: number;\n exp?: number;\n jti?: string;\n}\n\n/**\n * JWT verification function type\n */\nexport type JwtVerifier = (token: string) => Promise<JwtPayload | null>;\n\n/**\n * Auth middleware options\n */\nexport interface AuthMiddlewareOptions {\n /** JWT verification function */\n verify: JwtVerifier;\n /** Header name for token (default: Authorization) */\n header?: string;\n /** Token prefix (default: Bearer) */\n prefix?: string;\n /** Cookie name for token (alternative to header) */\n cookie?: string;\n /** Skip auth for certain requests */\n skip?: (c: HonoContext) => boolean;\n /** Custom error message */\n message?: string;\n}\n\n/**\n * Extract token from request\n */\nfunction extractToken(\n c: HonoContext,\n header: string,\n prefix: string,\n cookie?: string\n): string | null {\n // Try header first\n const authHeader = c.req.header(header);\n if (authHeader) {\n if (prefix && authHeader.startsWith(`${prefix} `)) {\n return authHeader.slice(prefix.length + 1);\n }\n return authHeader;\n }\n\n // Try cookie\n if (cookie) {\n const cookieHeader = c.req.header(\"cookie\");\n if (cookieHeader) {\n const cookies = cookieHeader.split(\";\").map((c) => c.trim());\n for (const c of cookies) {\n const [key, ...valueParts] = c.split(\"=\");\n if (key === cookie) {\n return valueParts.join(\"=\");\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Auth middleware - requires valid JWT\n *\n * @example\n * ```typescript\n * import { verifyJwt } from '@parsrun/auth';\n *\n * const authMiddleware = auth({\n * verify: (token) => verifyJwt(token, secret),\n * cookie: 'auth_token',\n * });\n *\n * app.use('/api/*', authMiddleware);\n *\n * // Access user in handlers\n * app.get('/api/me', (c) => {\n * const user = c.get('user');\n * return c.json({ user });\n * });\n * ```\n */\nexport function auth(options: AuthMiddlewareOptions) {\n const {\n verify,\n header = \"authorization\",\n prefix = \"Bearer\",\n cookie,\n skip,\n message = \"Authentication required\",\n } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n // Skip if configured\n if (skip?.(c)) {\n return next();\n }\n\n // Extract token\n const token = extractToken(c, header, prefix, cookie);\n\n if (!token) {\n throw new UnauthorizedError(message);\n }\n\n // Verify token\n const payload = await verify(token);\n\n if (!payload) {\n throw new UnauthorizedError(\"Invalid or expired token\");\n }\n\n // Set user in context\n const user: ContextUser = {\n id: payload.sub,\n email: payload.email,\n tenantId: payload.tenantId,\n role: payload.role,\n permissions: payload.permissions ?? [],\n };\n\n c.set(\"user\", user);\n\n await next();\n };\n}\n\n/**\n * Optional auth middleware - sets user if token present, but doesn't require it\n *\n * @example\n * ```typescript\n * app.use('/api/public/*', optionalAuth({\n * verify: (token) => verifyJwt(token, secret),\n * }));\n *\n * // User may or may not be present\n * app.get('/api/public/items', (c) => {\n * const user = c.get('user'); // may be undefined\n * // Return different data based on auth status\n * });\n * ```\n */\nexport function optionalAuth(options: Omit<AuthMiddlewareOptions, \"message\">) {\n const { verify, header = \"authorization\", prefix = \"Bearer\", cookie, skip } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n // Skip if configured\n if (skip?.(c)) {\n return next();\n }\n\n // Extract token\n const token = extractToken(c, header, prefix, cookie);\n\n if (token) {\n try {\n const payload = await verify(token);\n\n if (payload) {\n // Set user in context\n const user: ContextUser = {\n id: payload.sub,\n email: payload.email,\n tenantId: payload.tenantId,\n role: payload.role,\n permissions: payload.permissions ?? [],\n };\n\n c.set(\"user\", user);\n }\n } catch {\n // Ignore verification errors for optional auth\n }\n }\n\n await next();\n };\n}\n\n/**\n * Create auth middleware from verifier function\n *\n * @example\n * ```typescript\n * const { auth, optionalAuth } = createAuthMiddleware({\n * verify: async (token) => {\n * return verifyJwt(token, process.env.JWT_SECRET);\n * },\n * cookie: 'session',\n * });\n *\n * app.use('/api/*', auth);\n * app.use('/public/*', optionalAuth);\n * ```\n */\nexport function createAuthMiddleware(\n baseOptions: Omit<AuthMiddlewareOptions, \"skip\" | \"message\">\n) {\n return {\n auth: (options?: Partial<AuthMiddlewareOptions>) =>\n auth({ ...baseOptions, ...options }),\n optionalAuth: (options?: Partial<Omit<AuthMiddlewareOptions, \"message\">>) =>\n optionalAuth({ ...baseOptions, ...options }),\n };\n}\n","/**\n * @parsrun/server - CORS Middleware\n * Cross-Origin Resource Sharing configuration\n */\n\nimport type { HonoContext, HonoNext, CorsConfig } from \"../context.js\";\n\n/**\n * Default CORS configuration\n */\nconst defaultCorsConfig: CorsConfig = {\n origin: \"*\",\n credentials: false,\n methods: [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\"],\n allowedHeaders: [\"Content-Type\", \"Authorization\", \"X-Request-ID\", \"X-CSRF-Token\"],\n exposedHeaders: [\"X-Request-ID\", \"X-Total-Count\"],\n maxAge: 86400, // 24 hours\n};\n\n/**\n * Check if origin is allowed\n */\nfunction isOriginAllowed(origin: string, config: CorsConfig): boolean {\n if (config.origin === \"*\") return true;\n\n if (typeof config.origin === \"string\") {\n return origin === config.origin;\n }\n\n if (Array.isArray(config.origin)) {\n return config.origin.includes(origin);\n }\n\n if (typeof config.origin === \"function\") {\n return config.origin(origin);\n }\n\n return false;\n}\n\n/**\n * CORS middleware\n *\n * @example\n * ```typescript\n * app.use('*', cors({\n * origin: ['https://example.com', 'https://app.example.com'],\n * credentials: true,\n * }));\n * ```\n */\nexport function cors(config?: Partial<CorsConfig>): (c: HonoContext, next: HonoNext) => Promise<Response | void> {\n const corsConfig = { ...defaultCorsConfig, ...config };\n\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n const origin = c.req.header(\"origin\") ?? \"\";\n\n // Handle preflight requests\n if (c.req.method === \"OPTIONS\") {\n const response = new Response(null, { status: 204 });\n\n if (isOriginAllowed(origin, corsConfig)) {\n response.headers.set(\"Access-Control-Allow-Origin\", origin || \"*\");\n }\n\n if (corsConfig.credentials) {\n response.headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n if (corsConfig.methods) {\n response.headers.set(\n \"Access-Control-Allow-Methods\",\n corsConfig.methods.join(\", \")\n );\n }\n\n if (corsConfig.allowedHeaders) {\n response.headers.set(\n \"Access-Control-Allow-Headers\",\n corsConfig.allowedHeaders.join(\", \")\n );\n }\n\n if (corsConfig.maxAge) {\n response.headers.set(\"Access-Control-Max-Age\", String(corsConfig.maxAge));\n }\n\n return response;\n }\n\n // Handle actual requests\n await next();\n\n // Add CORS headers to response\n if (isOriginAllowed(origin, corsConfig)) {\n c.header(\"Access-Control-Allow-Origin\", origin || \"*\");\n }\n\n if (corsConfig.credentials) {\n c.header(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n if (corsConfig.exposedHeaders) {\n c.header(\"Access-Control-Expose-Headers\", corsConfig.exposedHeaders.join(\", \"));\n }\n };\n}\n","/**\n * @parsrun/server - CSRF Middleware\n * Cross-Site Request Forgery protection\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\nimport { ForbiddenError } from \"./error-handler.js\";\n\n/**\n * CSRF options\n */\nexport interface CsrfOptions {\n /** Cookie name for CSRF token */\n cookieName?: string;\n /** Header name for CSRF token */\n headerName?: string;\n /** Methods that require CSRF validation */\n methods?: string[];\n /** Paths to exclude from CSRF protection */\n excludePaths?: string[];\n /** Skip CSRF for certain requests */\n skip?: (c: HonoContext) => boolean;\n /** Token generator */\n generateToken?: () => string;\n /** Cookie options */\n cookie?: {\n secure?: boolean;\n httpOnly?: boolean;\n sameSite?: \"strict\" | \"lax\" | \"none\";\n path?: string;\n maxAge?: number;\n };\n}\n\n/**\n * Generate random token\n */\nfunction generateRandomToken(): string {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/**\n * Get cookie value\n */\nfunction getCookie(c: HonoContext, name: string): string | undefined {\n const cookieHeader = c.req.header(\"cookie\");\n if (!cookieHeader) return undefined;\n\n const cookies = cookieHeader.split(\";\").map((c) => c.trim());\n for (const cookie of cookies) {\n const [key, ...valueParts] = cookie.split(\"=\");\n if (key === name) {\n return valueParts.join(\"=\");\n }\n }\n return undefined;\n}\n\n/**\n * CSRF protection middleware\n *\n * @example\n * ```typescript\n * app.use('*', csrf({\n * cookieName: '_csrf',\n * headerName: 'X-CSRF-Token',\n * methods: ['POST', 'PUT', 'PATCH', 'DELETE'],\n * cookie: {\n * secure: true,\n * sameSite: 'strict',\n * },\n * }));\n *\n * // Get token in handler\n * app.get('/csrf-token', (c) => {\n * return c.json({ token: c.get('csrfToken') });\n * });\n * ```\n */\nexport function csrf(options: CsrfOptions = {}) {\n const {\n cookieName = \"_csrf\",\n headerName = \"x-csrf-token\",\n methods = [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"],\n excludePaths = [],\n skip,\n generateToken = generateRandomToken,\n cookie = {},\n } = options;\n\n const cookieOptions = {\n secure: cookie.secure ?? true,\n httpOnly: cookie.httpOnly ?? true,\n sameSite: cookie.sameSite ?? (\"lax\" as const),\n path: cookie.path ?? \"/\",\n maxAge: cookie.maxAge ?? 86400, // 24 hours\n };\n\n return async (c: HonoContext, next: HonoNext) => {\n // Skip if configured\n if (skip?.(c)) {\n return next();\n }\n\n // Skip excluded paths\n const path = c.req.path;\n if (excludePaths.some((p) => path.startsWith(p))) {\n return next();\n }\n\n // Get or create token\n let token = getCookie(c, cookieName);\n\n if (!token) {\n // Generate new token\n token = generateToken();\n\n // Set cookie\n const cookieValue = [\n `${cookieName}=${token}`,\n `Path=${cookieOptions.path}`,\n `Max-Age=${cookieOptions.maxAge}`,\n cookieOptions.sameSite && `SameSite=${cookieOptions.sameSite}`,\n cookieOptions.secure && \"Secure\",\n cookieOptions.httpOnly && \"HttpOnly\",\n ]\n .filter(Boolean)\n .join(\"; \");\n\n c.header(\"Set-Cookie\", cookieValue);\n }\n\n // Store token in context for handlers\n (c as HonoContext & { csrfToken: string }).set(\"csrfToken\" as never, token as never);\n\n // Validate token for protected methods\n if (methods.includes(c.req.method)) {\n const headerToken = c.req.header(headerName);\n const bodyToken = await getBodyToken(c);\n\n const providedToken = headerToken ?? bodyToken;\n\n if (!providedToken || providedToken !== token) {\n throw new ForbiddenError(\"Invalid CSRF token\");\n }\n }\n\n await next();\n };\n}\n\n/**\n * Try to get CSRF token from request body\n */\nasync function getBodyToken(c: HonoContext): Promise<string | undefined> {\n try {\n const contentType = c.req.header(\"content-type\") ?? \"\";\n\n if (contentType.includes(\"application/json\")) {\n const body = (await c.req.json()) as Record<string, unknown>;\n return (body[\"_csrf\"] ?? body[\"csrfToken\"] ?? body[\"csrf_token\"]) as string | undefined;\n }\n\n if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n const body = await c.req.parseBody();\n return body[\"_csrf\"] as string | undefined;\n }\n } catch {\n // Ignore parsing errors\n }\n return undefined;\n}\n\n/**\n * Double Submit Cookie pattern\n * Generates a token and validates it matches between cookie and header\n */\nexport function doubleSubmitCookie(options: CsrfOptions = {}) {\n return csrf({\n ...options,\n cookie: {\n ...options.cookie,\n httpOnly: false, // Allow JS to read the cookie\n },\n });\n}\n","/**\n * @parsrun/server - Rate Limit Middleware\n * Request throttling with multiple storage backends\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\nimport { RateLimitError } from \"./error-handler.js\";\n\n/**\n * Rate limit storage interface\n */\nexport interface RateLimitStorage {\n /** Get current count for key */\n get(key: string): Promise<number>;\n /** Increment count and set expiry */\n increment(key: string, windowMs: number): Promise<number>;\n /** Reset count for key */\n reset(key: string): Promise<void>;\n}\n\n/**\n * In-memory rate limit storage\n * For single-instance deployments or development\n */\nexport class MemoryRateLimitStorage implements RateLimitStorage {\n private store = new Map<string, { count: number; expires: number }>();\n\n async get(key: string): Promise<number> {\n const entry = this.store.get(key);\n if (!entry || entry.expires < Date.now()) {\n return 0;\n }\n return entry.count;\n }\n\n async increment(key: string, windowMs: number): Promise<number> {\n const now = Date.now();\n const entry = this.store.get(key);\n\n if (!entry || entry.expires < now) {\n // Start new window\n this.store.set(key, { count: 1, expires: now + windowMs });\n return 1;\n }\n\n // Increment existing\n entry.count++;\n return entry.count;\n }\n\n async reset(key: string): Promise<void> {\n this.store.delete(key);\n }\n\n /** Clean up expired entries */\n cleanup(): void {\n const now = Date.now();\n for (const [key, entry] of this.store) {\n if (entry.expires < now) {\n this.store.delete(key);\n }\n }\n }\n}\n\n/**\n * Rate limit options\n */\nexport interface RateLimitOptions {\n /** Time window in milliseconds */\n windowMs?: number;\n /** Maximum requests per window */\n max?: number;\n /** Generate key from request (default: IP address) */\n keyGenerator?: (c: HonoContext) => string;\n /** Skip rate limiting for certain requests */\n skip?: (c: HonoContext) => boolean;\n /** Custom storage backend */\n storage?: RateLimitStorage;\n /** Error message */\n message?: string;\n /** Include rate limit headers */\n headers?: boolean;\n /** Handler when limit is exceeded */\n onLimitReached?: (c: HonoContext, key: string) => void;\n}\n\n// Global default storage\nlet defaultStorage: RateLimitStorage | null = null;\n\n/**\n * Get or create default memory storage\n */\nfunction getDefaultStorage(): RateLimitStorage {\n if (!defaultStorage) {\n defaultStorage = new MemoryRateLimitStorage();\n }\n return defaultStorage;\n}\n\n/**\n * Rate limit middleware\n *\n * @example\n * ```typescript\n * // Basic usage - 100 requests per minute\n * app.use('/api/*', rateLimit({\n * windowMs: 60 * 1000,\n * max: 100,\n * }));\n *\n * // Per-user rate limiting\n * app.use('/api/*', rateLimit({\n * keyGenerator: (c) => c.get('user')?.id ?? getIP(c),\n * max: 1000,\n * }));\n *\n * // Strict limit for auth endpoints\n * app.use('/api/auth/*', rateLimit({\n * windowMs: 15 * 60 * 1000, // 15 minutes\n * max: 5,\n * message: 'Too many login attempts',\n * }));\n * ```\n */\nexport function rateLimit(options: RateLimitOptions = {}) {\n const {\n windowMs = 60 * 1000, // 1 minute\n max = 100,\n keyGenerator = defaultKeyGenerator,\n skip,\n storage = getDefaultStorage(),\n message = \"Too many requests, please try again later\",\n headers = true,\n onLimitReached,\n } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n // Skip if configured\n if (skip?.(c)) {\n return next();\n }\n\n const key = `ratelimit:${keyGenerator(c)}`;\n const current = await storage.increment(key, windowMs);\n\n // Set rate limit headers\n if (headers) {\n c.header(\"X-RateLimit-Limit\", String(max));\n c.header(\"X-RateLimit-Remaining\", String(Math.max(0, max - current)));\n c.header(\"X-RateLimit-Reset\", String(Math.ceil((Date.now() + windowMs) / 1000)));\n }\n\n // Check if limit exceeded\n if (current > max) {\n if (onLimitReached) {\n onLimitReached(c, key);\n }\n\n const retryAfter = Math.ceil(windowMs / 1000);\n c.header(\"Retry-After\", String(retryAfter));\n\n throw new RateLimitError(message, retryAfter);\n }\n\n await next();\n };\n}\n\n/**\n * Default key generator - uses IP address\n */\nfunction defaultKeyGenerator(c: HonoContext): string {\n return (\n c.req.header(\"x-forwarded-for\")?.split(\",\")[0]?.trim() ??\n c.req.header(\"x-real-ip\") ??\n c.req.header(\"cf-connecting-ip\") ??\n \"unknown\"\n );\n}\n\n/**\n * Create rate limiter for specific routes\n *\n * @example\n * ```typescript\n * const apiLimiter = createRateLimiter({\n * windowMs: 60000,\n * max: 100,\n * });\n *\n * app.use('/api/*', apiLimiter.middleware);\n *\n * // Reset limit for a user after successful auth\n * await apiLimiter.reset('user:123');\n * ```\n */\nexport function createRateLimiter(options: RateLimitOptions = {}) {\n const storage = options.storage ?? getDefaultStorage();\n\n return {\n middleware: rateLimit({ ...options, storage }),\n storage,\n reset: (key: string) => storage.reset(`ratelimit:${key}`),\n get: (key: string) => storage.get(`ratelimit:${key}`),\n };\n}\n","/**\n * @parsrun/server - Request Logger Middleware\n * HTTP request/response logging\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\n\n/**\n * Request logger options\n */\nexport interface RequestLoggerOptions {\n /** Skip logging for certain paths */\n skip?: (c: HonoContext) => boolean;\n /** Custom log format */\n format?: \"json\" | \"combined\" | \"short\";\n /** Include request body in logs */\n includeBody?: boolean;\n /** Include response body in logs (be careful with large responses) */\n includeResponseBody?: boolean;\n /** Maximum body length to log */\n maxBodyLength?: number;\n}\n\n/**\n * Format bytes to human readable\n */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes}B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n}\n\n/**\n * Request logger middleware\n *\n * @example\n * ```typescript\n * app.use('*', requestLogger({\n * skip: (c) => c.req.path === '/health',\n * format: 'json',\n * }));\n * ```\n */\nexport function requestLogger(options: RequestLoggerOptions = {}) {\n const {\n skip,\n format = \"json\",\n includeBody = false,\n maxBodyLength = 1000,\n } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n // Skip if configured\n if (skip?.(c)) {\n return next();\n }\n\n const start = Date.now();\n const logger = c.get(\"logger\");\n const requestId = c.get(\"requestId\");\n\n // Request info\n const method = c.req.method;\n const path = c.req.path;\n const query = c.req.query();\n const userAgent = c.req.header(\"user-agent\");\n const ip = c.req.header(\"x-forwarded-for\") ?? c.req.header(\"x-real-ip\") ?? \"unknown\";\n\n // Log request start\n if (format === \"json\") {\n logger?.debug(\"Request started\", {\n requestId,\n method,\n path,\n query: Object.keys(query).length > 0 ? query : undefined,\n ip,\n userAgent,\n });\n }\n\n // Get body if needed\n let requestBody: string | undefined;\n if (includeBody && [\"POST\", \"PUT\", \"PATCH\"].includes(method)) {\n try {\n const contentType = c.req.header(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n const body = await c.req.text();\n requestBody = body.length > maxBodyLength\n ? body.substring(0, maxBodyLength) + \"...\"\n : body;\n }\n } catch {\n // Ignore body parsing errors\n }\n }\n\n // Process request\n await next();\n\n // Calculate duration\n const duration = Date.now() - start;\n const status = c.res.status;\n\n // Get response size\n const contentLength = c.res.headers.get(\"content-length\");\n const size = contentLength ? parseInt(contentLength, 10) : 0;\n\n // Log based on format\n if (format === \"json\") {\n const logData: Record<string, unknown> = {\n requestId,\n method,\n path,\n status,\n duration: `${duration}ms`,\n size: formatBytes(size),\n };\n\n if (requestBody) {\n logData[\"requestBody\"] = requestBody;\n }\n\n // Use appropriate log level\n if (status >= 500) {\n logger?.error(\"Request completed\", logData);\n } else if (status >= 400) {\n logger?.warn(\"Request completed\", logData);\n } else {\n logger?.info(\"Request completed\", logData);\n }\n } else if (format === \"combined\") {\n // Apache combined log format\n const log = `${ip} - - [${new Date().toISOString()}] \"${method} ${path}\" ${status} ${size} \"-\" \"${userAgent}\" ${duration}ms`;\n console.log(log);\n } else {\n // Short format\n const log = `${method} ${path} ${status} ${duration}ms`;\n console.log(log);\n }\n };\n}\n","/**\n * @parsrun/server - Usage Tracking Middleware\n * Automatically track API usage per request\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\n\n/**\n * Usage service interface (from @parsrun/payments)\n * Defined here to avoid circular dependency\n */\nexport interface UsageServiceLike {\n trackUsage(options: {\n tenantId: string;\n customerId: string;\n subscriptionId?: string;\n featureKey: string;\n quantity?: number;\n metadata?: Record<string, unknown>;\n idempotencyKey?: string;\n }): Promise<unknown>;\n}\n\n/**\n * Usage tracking middleware options\n */\nexport interface UsageTrackingOptions {\n /**\n * Usage service instance\n */\n usageService: UsageServiceLike;\n\n /**\n * Feature key to track\n * Can be a static string or a function that extracts it from context\n * @default \"api_calls\"\n */\n featureKey?: string | ((c: HonoContext) => string);\n\n /**\n * Quantity to track\n * Can be a static number or a function that calculates it from context\n * @default 1\n */\n quantity?: number | ((c: HonoContext) => number);\n\n /**\n * Skip tracking for certain requests\n */\n skip?: (c: HonoContext) => boolean;\n\n /**\n * When to track: before or after the request\n * @default \"response\"\n */\n trackOn?: \"request\" | \"response\";\n\n /**\n * Only track successful responses (2xx)\n * @default true\n */\n successOnly?: boolean;\n\n /**\n * Custom customer ID extractor\n * @default Uses c.get(\"user\")?.id\n */\n getCustomerId?: (c: HonoContext) => string | undefined;\n\n /**\n * Custom tenant ID extractor\n * @default Uses c.get(\"tenant\")?.id or c.get(\"user\")?.tenantId\n */\n getTenantId?: (c: HonoContext) => string | undefined;\n\n /**\n * Custom subscription ID extractor\n */\n getSubscriptionId?: (c: HonoContext) => string | undefined;\n\n /**\n * Include request metadata\n * @default true\n */\n includeMetadata?: boolean;\n\n /**\n * Generate idempotency key to prevent duplicates\n */\n getIdempotencyKey?: (c: HonoContext) => string | undefined;\n}\n\n/**\n * Usage tracking middleware\n *\n * Automatically tracks API usage for authenticated requests.\n *\n * @example\n * ```typescript\n * import { usageTracking } from \"@parsrun/server\";\n * import { createUsageService, createMemoryUsageStorage } from \"@parsrun/payments\";\n *\n * const usageService = createUsageService({\n * storage: createMemoryUsageStorage(),\n * });\n *\n * // Track all API calls\n * app.use(\"/api/*\", usageTracking({\n * usageService,\n * featureKey: \"api_calls\",\n * }));\n *\n * // Track with custom feature key based on route\n * app.use(\"/api/ai/*\", usageTracking({\n * usageService,\n * featureKey: \"ai_requests\",\n * quantity: (c) => {\n * // Track tokens used from response\n * return c.get(\"tokensUsed\") ?? 1;\n * },\n * }));\n *\n * // Skip certain routes\n * app.use(\"/api/*\", usageTracking({\n * usageService,\n * skip: (c) => c.req.path.startsWith(\"/api/health\"),\n * }));\n * ```\n */\nexport function usageTracking(options: UsageTrackingOptions) {\n const {\n usageService,\n featureKey = \"api_calls\",\n quantity = 1,\n skip,\n trackOn = \"response\",\n successOnly = true,\n getCustomerId = (c) => c.get(\"user\")?.id,\n getTenantId = (c) => c.get(\"tenant\")?.id ?? c.get(\"user\")?.tenantId,\n getSubscriptionId,\n includeMetadata = true,\n getIdempotencyKey,\n } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n // Track on request (before processing)\n if (trackOn === \"request\") {\n await trackUsage(c);\n return next();\n }\n\n // Track on response (after processing)\n await next();\n\n // Skip if configured\n if (skip?.(c)) return;\n\n // Skip failed responses if configured\n if (successOnly && c.res.status >= 400) return;\n\n await trackUsage(c);\n };\n\n async function trackUsage(c: HonoContext) {\n const customerId = getCustomerId(c);\n const tenantId = getTenantId(c);\n\n // Skip if no user or tenant\n if (!customerId || !tenantId) return;\n\n const resolvedFeatureKey =\n typeof featureKey === \"function\" ? featureKey(c) : featureKey;\n\n const resolvedQuantity =\n typeof quantity === \"function\" ? quantity(c) : quantity;\n\n const metadata = includeMetadata\n ? {\n path: c.req.path,\n method: c.req.method,\n statusCode: c.res.status,\n userAgent: c.req.header(\"user-agent\"),\n }\n : undefined;\n\n try {\n // Build track options with only defined optional properties\n const trackOptions: {\n tenantId: string;\n customerId: string;\n featureKey: string;\n quantity?: number;\n subscriptionId?: string;\n metadata?: Record<string, unknown>;\n idempotencyKey?: string;\n } = {\n tenantId,\n customerId,\n featureKey: resolvedFeatureKey,\n quantity: resolvedQuantity,\n };\n\n const subscriptionId = getSubscriptionId?.(c);\n if (subscriptionId !== undefined) {\n trackOptions.subscriptionId = subscriptionId;\n }\n\n if (metadata !== undefined) {\n trackOptions.metadata = metadata;\n }\n\n const idempotencyKey = getIdempotencyKey?.(c);\n if (idempotencyKey !== undefined) {\n trackOptions.idempotencyKey = idempotencyKey;\n }\n\n await usageService.trackUsage(trackOptions);\n } catch (error) {\n // Log but don't fail the request\n const logger = c.get(\"logger\");\n if (logger) {\n logger.error(\"Usage tracking failed\", {\n error: error instanceof Error ? error.message : String(error),\n customerId,\n featureKey: resolvedFeatureKey,\n });\n }\n }\n }\n}\n\n/**\n * Create usage tracking middleware with pre-configured options\n */\nexport function createUsageTracking(baseOptions: UsageTrackingOptions) {\n return (overrides?: Partial<UsageTrackingOptions>) => {\n return usageTracking({ ...baseOptions, ...overrides });\n };\n}\n","/**\n * @parsrun/server - Quota Enforcement Middleware\n * Enforce usage quotas before processing requests\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\n\n/**\n * Quota check result interface (from @parsrun/payments)\n */\nexport interface QuotaCheckResult {\n allowed: boolean;\n currentUsage: number;\n limit: number | null;\n remaining: number | null;\n wouldExceed: boolean;\n percentAfter: number | null;\n}\n\n/**\n * Quota manager interface (from @parsrun/payments)\n * Defined here to avoid circular dependency\n */\nexport interface QuotaManagerLike {\n checkQuota(\n customerId: string,\n featureKey: string,\n quantity?: number\n ): Promise<QuotaCheckResult>;\n\n enforceQuota(\n customerId: string,\n featureKey: string,\n quantity?: number\n ): Promise<void>;\n}\n\n/**\n * Quota exceeded error class\n */\nexport class QuotaExceededError extends Error {\n public readonly statusCode = 429;\n public readonly code = \"QUOTA_EXCEEDED\";\n\n constructor(\n public readonly featureKey: string,\n public readonly limit: number | null,\n public readonly currentUsage: number,\n public readonly requestedQuantity: number = 1\n ) {\n super(\n `Quota exceeded for \"${featureKey}\": ${currentUsage}/${limit ?? \"unlimited\"} used`\n );\n this.name = \"QuotaExceededError\";\n }\n}\n\n/**\n * Quota enforcement middleware options\n */\nexport interface QuotaEnforcementOptions {\n /**\n * Quota manager instance\n */\n quotaManager: QuotaManagerLike;\n\n /**\n * Feature key to check\n * Can be a static string or a function that extracts it from context\n */\n featureKey: string | ((c: HonoContext) => string);\n\n /**\n * Quantity to check (default: 1)\n */\n quantity?: number | ((c: HonoContext) => number);\n\n /**\n * Skip quota check for certain requests\n */\n skip?: (c: HonoContext) => boolean;\n\n /**\n * Custom customer ID extractor\n * @default Uses c.get(\"user\")?.id\n */\n getCustomerId?: (c: HonoContext) => string | undefined;\n\n /**\n * Include quota headers in response\n * @default true\n */\n includeHeaders?: boolean;\n\n /**\n * Custom error handler\n */\n onQuotaExceeded?: (\n c: HonoContext,\n result: QuotaCheckResult,\n featureKey: string\n ) => Response | void;\n\n /**\n * Soft limit mode - warn but don't block\n * @default false\n */\n softLimit?: boolean;\n\n /**\n * Callback when quota is close to limit (>80%)\n */\n onQuotaWarning?: (\n c: HonoContext,\n result: QuotaCheckResult,\n featureKey: string\n ) => void;\n}\n\n/**\n * Quota enforcement middleware\n *\n * Checks and enforces usage quotas before processing requests.\n *\n * @example\n * ```typescript\n * import { quotaEnforcement } from \"@parsrun/server\";\n * import { createQuotaManager, createMemoryUsageStorage } from \"@parsrun/payments\";\n *\n * const quotaManager = createQuotaManager({\n * storage: createMemoryUsageStorage(),\n * });\n *\n * // Enforce API call quota\n * app.use(\"/api/*\", quotaEnforcement({\n * quotaManager,\n * featureKey: \"api_calls\",\n * }));\n *\n * // Enforce with dynamic feature key\n * app.use(\"/api/*\", quotaEnforcement({\n * quotaManager,\n * featureKey: (c) => {\n * if (c.req.path.startsWith(\"/api/ai\")) return \"ai_requests\";\n * return \"api_calls\";\n * },\n * }));\n *\n * // Soft limit mode (warn but allow)\n * app.use(\"/api/*\", quotaEnforcement({\n * quotaManager,\n * featureKey: \"api_calls\",\n * softLimit: true,\n * onQuotaWarning: (c, result) => {\n * console.warn(\"Quota warning:\", result);\n * },\n * }));\n * ```\n */\nexport function quotaEnforcement(options: QuotaEnforcementOptions) {\n const {\n quotaManager,\n featureKey,\n quantity = 1,\n skip,\n getCustomerId = (c) => c.get(\"user\")?.id,\n includeHeaders = true,\n onQuotaExceeded,\n softLimit = false,\n onQuotaWarning,\n } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n // Skip if configured\n if (skip?.(c)) {\n return next();\n }\n\n const customerId = getCustomerId(c);\n\n // Skip if no user (unauthenticated requests)\n if (!customerId) {\n return next();\n }\n\n const resolvedFeatureKey =\n typeof featureKey === \"function\" ? featureKey(c) : featureKey;\n\n const resolvedQuantity =\n typeof quantity === \"function\" ? quantity(c) : quantity;\n\n try {\n const result = await quotaManager.checkQuota(\n customerId,\n resolvedFeatureKey,\n resolvedQuantity\n );\n\n // Set quota headers\n if (includeHeaders) {\n c.header(\"X-Quota-Limit\", String(result.limit ?? \"unlimited\"));\n c.header(\"X-Quota-Remaining\", String(result.remaining ?? \"unlimited\"));\n c.header(\"X-Quota-Used\", String(result.currentUsage));\n\n if (result.percentAfter !== null) {\n c.header(\"X-Quota-Percent\", String(result.percentAfter));\n }\n }\n\n // Check for warning threshold (>80%)\n if (\n result.percentAfter !== null &&\n result.percentAfter >= 80 &&\n onQuotaWarning\n ) {\n onQuotaWarning(c, result, resolvedFeatureKey);\n }\n\n // Check if quota exceeded\n if (!result.allowed && !softLimit) {\n // Custom error handler\n if (onQuotaExceeded) {\n const response = onQuotaExceeded(c, result, resolvedFeatureKey);\n if (response) return response;\n }\n\n // Default error response\n throw new QuotaExceededError(\n resolvedFeatureKey,\n result.limit,\n result.currentUsage,\n resolvedQuantity\n );\n }\n\n // Continue to next middleware\n await next();\n } catch (error) {\n // Re-throw quota errors\n if (error instanceof QuotaExceededError) {\n throw error;\n }\n\n // Log other errors but continue\n const logger = c.get(\"logger\");\n if (logger) {\n logger.error(\"Quota check failed\", {\n error: error instanceof Error ? error.message : String(error),\n customerId,\n featureKey: resolvedFeatureKey,\n });\n }\n\n // Continue on error (fail open)\n await next();\n }\n };\n}\n\n/**\n * Create quota enforcement middleware with pre-configured options\n */\nexport function createQuotaEnforcement(\n baseOptions: Omit<QuotaEnforcementOptions, \"featureKey\">\n) {\n return (featureKey: string | ((c: HonoContext) => string)) => {\n return quotaEnforcement({ ...baseOptions, featureKey });\n };\n}\n\n/**\n * Multiple quota enforcement\n * Check multiple features at once\n */\nexport function multiQuotaEnforcement(\n options: Omit<QuotaEnforcementOptions, \"featureKey\"> & {\n features: Array<{\n featureKey: string;\n quantity?: number | ((c: HonoContext) => number);\n }>;\n }\n) {\n const { features } = options;\n\n return async (c: HonoContext, next: HonoNext) => {\n const customerId = (options.getCustomerId ?? ((ctx) => ctx.get(\"user\")?.id))(c);\n\n if (!customerId || options.skip?.(c)) {\n return next();\n }\n\n // Check all quotas\n for (const feature of features) {\n const resolvedQuantity =\n typeof feature.quantity === \"function\"\n ? feature.quantity(c)\n : feature.quantity ?? 1;\n\n const result = await options.quotaManager.checkQuota(\n customerId,\n feature.featureKey,\n resolvedQuantity\n );\n\n if (!result.allowed && !options.softLimit) {\n if (options.onQuotaExceeded) {\n const response = options.onQuotaExceeded(c, result, feature.featureKey);\n if (response) return response;\n }\n\n throw new QuotaExceededError(\n feature.featureKey,\n result.limit,\n result.currentUsage,\n resolvedQuantity\n );\n }\n }\n\n await next();\n };\n}\n","/**\n * @parsrun/server - ArkType Validation\n * Request validation with ArkType (powered by @parsrun/types)\n */\n\nimport type { HonoContext, HonoNext } from \"../context.js\";\nimport { ValidationError } from \"../middleware/error-handler.js\";\nimport type { Type } from \"@parsrun/types\";\n\n// Re-export from @parsrun/types\nexport {\n type,\n // Common schemas\n uuid,\n timestamp,\n email,\n url,\n nonEmptyString,\n positiveInt,\n nonNegativeInt,\n status,\n pagination,\n paginationMeta,\n cursorPagination,\n cursorPaginationMeta,\n // Server schemas\n uuidParam,\n paginationQuery,\n cursorPaginationQuery,\n searchQuery,\n dateRangeQuery,\n healthResponse,\n apiInfoResponse,\n corsConfig,\n serverRateLimitConfig,\n loggerConfig,\n serverConfig,\n authContext,\n requestContext,\n // Response helpers\n successResponse,\n errorResponse,\n paginatedResponse,\n cursorPaginatedResponse,\n parsError,\n // Validation helpers\n validateWithSchema,\n safeValidate,\n isValid,\n formatErrors,\n // Types\n type UUID,\n type Timestamp,\n type Email,\n type Url,\n type NonEmptyString,\n type PositiveInt,\n type NonNegativeInt,\n type Status,\n type Pagination,\n type PaginationMeta,\n type CursorPagination,\n type CursorPaginationMeta,\n type UuidParam,\n type PaginationQuery,\n type CursorPaginationQuery,\n type SearchQuery,\n type DateRangeQuery,\n type HealthResponse,\n type ApiInfoResponse,\n type CorsConfig,\n type ServerRateLimitConfig,\n type LoggerConfig,\n type ServerConfig,\n type AuthContext,\n type RequestContext,\n type ErrorResponse,\n type ParsError,\n type ApiResponse,\n type ApiErrorResponse,\n type ApiPaginatedResponse,\n type ApiCursorPaginatedResponse,\n} from \"@parsrun/types\";\n\nimport { type, formatErrors as formatArkErrors } from \"@parsrun/types\";\n\nexport type { Type } from \"@parsrun/types\";\n\n/**\n * Infer type from ArkType schema\n */\nexport type Infer<T extends Type> = T[\"infer\"];\n\n/**\n * Validation target\n */\nexport type ValidationTarget = \"json\" | \"query\" | \"param\" | \"header\" | \"form\";\n\n/**\n * Validation options\n */\nexport interface ValidateOptions {\n /** Error message prefix */\n messagePrefix?: string;\n}\n\n/**\n * Format ArkType errors to a simple object with arrays\n */\nfunction formatValidationErrors(errors: type.errors): Record<string, string[]> {\n const formatted = formatArkErrors(errors);\n const result: Record<string, string[]> = {};\n\n for (const [key, value] of Object.entries(formatted)) {\n result[key] = [value];\n }\n\n return result;\n}\n\n/**\n * Validate request body with ArkType schema\n *\n * @example\n * ```typescript\n * import { type } from '@parsrun/types';\n *\n * const CreateUserSchema = type({\n * email: 'string.email',\n * name: 'string',\n * age: 'number >= 0',\n * });\n *\n * app.post('/users', validateBody(CreateUserSchema), async (c) => {\n * const data = c.get('validatedBody');\n * // data is typed as { email: string; name: string; age: number }\n * });\n * ```\n */\nexport function validateBody<T extends Type>(schema: T, options: ValidateOptions = {}) {\n return async (c: HonoContext, next: HonoNext): Promise<void> => {\n let body: unknown;\n\n try {\n body = await c.req.json();\n } catch {\n throw new ValidationError(\"Invalid JSON body\");\n }\n\n const result = schema(body);\n\n if (result instanceof type.errors) {\n throw new ValidationError(\n options.messagePrefix ?? \"Validation failed\",\n { errors: formatValidationErrors(result) }\n );\n }\n\n // Store validated data in context\n (c as HonoContext & { validatedBody: T[\"infer\"] }).set(\"validatedBody\" as never, result as never);\n\n await next();\n };\n}\n\n/**\n * Validate query parameters\n *\n * @example\n * ```typescript\n * const PaginationSchema = type({\n * 'page?': 'string',\n * 'limit?': 'string',\n * 'search?': 'string',\n * });\n *\n * app.get('/users', validateQuery(PaginationSchema), async (c) => {\n * const { page, limit, search } = c.get('validatedQuery');\n * });\n * ```\n */\nexport function validateQuery<T extends Type>(schema: T, options: ValidateOptions = {}) {\n return async (c: HonoContext, next: HonoNext): Promise<void> => {\n const query = c.req.query();\n const result = schema(query);\n\n if (result instanceof type.errors) {\n throw new ValidationError(\n options.messagePrefix ?? \"Invalid query parameters\",\n { errors: formatValidationErrors(result) }\n );\n }\n\n (c as HonoContext & { validatedQuery: T[\"infer\"] }).set(\"validatedQuery\" as never, result as never);\n\n await next();\n };\n}\n\n/**\n * Validate route parameters\n *\n * @example\n * ```typescript\n * const IdParamSchema = type({\n * id: 'string',\n * });\n *\n * app.get('/users/:id', validateParams(IdParamSchema), async (c) => {\n * const { id } = c.get('validatedParams');\n * });\n * ```\n */\nexport function validateParams<T extends Type>(schema: T, options: ValidateOptions = {}) {\n return async (c: HonoContext, next: HonoNext): Promise<void> => {\n const params = c.req.param();\n const result = schema(params);\n\n if (result instanceof type.errors) {\n throw new ValidationError(\n options.messagePrefix ?? \"Invalid route parameters\",\n { errors: formatValidationErrors(result) }\n );\n }\n\n (c as HonoContext & { validatedParams: T[\"infer\"] }).set(\"validatedParams\" as never, result as never);\n\n await next();\n };\n}\n\n/**\n * Validate headers\n *\n * @example\n * ```typescript\n * const ApiKeySchema = type({\n * 'x-api-key': 'string',\n * });\n *\n * app.use('/api/*', validateHeaders(ApiKeySchema));\n * ```\n */\nexport function validateHeaders<T extends Type>(schema: T, options: ValidateOptions = {}) {\n return async (c: HonoContext, next: HonoNext): Promise<void> => {\n // Convert headers to plain object\n const headers: Record<string, string> = {};\n c.req.raw.headers.forEach((value, key) => {\n headers[key.toLowerCase()] = value;\n });\n\n const result = schema(headers);\n\n if (result instanceof type.errors) {\n throw new ValidationError(\n options.messagePrefix ?? \"Invalid headers\",\n { errors: formatValidationErrors(result) }\n );\n }\n\n (c as HonoContext & { validatedHeaders: T[\"infer\"] }).set(\"validatedHeaders\" as never, result as never);\n\n await next();\n };\n}\n\n/**\n * Combined validation middleware\n *\n * @example\n * ```typescript\n * app.post('/users/:id',\n * validate({\n * params: type({ id: 'string' }),\n * body: type({ name: 'string', email: 'string.email' }),\n * query: type({ 'include?': 'string' }),\n * }),\n * async (c) => {\n * const params = c.get('validatedParams');\n * const body = c.get('validatedBody');\n * const query = c.get('validatedQuery');\n * }\n * );\n * ```\n */\nexport function validate<\n TParams extends Type | undefined = undefined,\n TBody extends Type | undefined = undefined,\n TQuery extends Type | undefined = undefined,\n THeaders extends Type | undefined = undefined\n>(schemas: {\n params?: TParams;\n body?: TBody;\n query?: TQuery;\n headers?: THeaders;\n}) {\n return async (c: HonoContext, next: HonoNext): Promise<void> => {\n // Validate params\n if (schemas.params) {\n const params = c.req.param();\n const result = schemas.params(params);\n if (result instanceof type.errors) {\n throw new ValidationError(\"Invalid route parameters\", {\n errors: formatValidationErrors(result),\n });\n }\n (c as HonoContext & { validatedParams: unknown }).set(\"validatedParams\" as never, result as never);\n }\n\n // Validate query\n if (schemas.query) {\n const query = c.req.query();\n const result = schemas.query(query);\n if (result instanceof type.errors) {\n throw new ValidationError(\"Invalid query parameters\", {\n errors: formatValidationErrors(result),\n });\n }\n (c as HonoContext & { validatedQuery: unknown }).set(\"validatedQuery\" as never, result as never);\n }\n\n // Validate headers\n if (schemas.headers) {\n const headers: Record<string, string> = {};\n c.req.raw.headers.forEach((value, key) => {\n headers[key.toLowerCase()] = value;\n });\n const result = schemas.headers(headers);\n if (result instanceof type.errors) {\n throw new ValidationError(\"Invalid headers\", {\n errors: formatValidationErrors(result),\n });\n }\n (c as HonoContext & { validatedHeaders: unknown }).set(\"validatedHeaders\" as never, result as never);\n }\n\n // Validate body\n if (schemas.body) {\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n throw new ValidationError(\"Invalid JSON body\");\n }\n const result = schemas.body(body);\n if (result instanceof type.errors) {\n throw new ValidationError(\"Validation failed\", {\n errors: formatValidationErrors(result),\n });\n }\n (c as HonoContext & { validatedBody: unknown }).set(\"validatedBody\" as never, result as never);\n }\n\n await next();\n };\n}\n\n// ============================================================================\n// Legacy Aliases (for backward compatibility)\n// ============================================================================\n\n// Schema aliases with PascalCase for backward compatibility\n// Use the camelCase versions from @parsrun/types for new code\nexport {\n uuidParam as UuidParamSchema,\n paginationQuery as PaginationQuerySchema,\n searchQuery as SearchQuerySchema,\n dateRangeQuery as DateRangeQuerySchema,\n} from \"@parsrun/types\";\n","/**\n * @parsrun/server - Pagination Utilities\n * Helpers for paginated API responses\n */\n\nimport type { HonoContext } from \"../context.js\";\n\n/**\n * Pagination parameters\n */\nexport interface PaginationParams {\n page: number;\n limit: number;\n offset: number;\n}\n\n/**\n * Pagination metadata\n */\nexport interface PaginationMeta {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n hasNext: boolean;\n hasPrev: boolean;\n}\n\n/**\n * Paginated response\n */\nexport interface PaginatedResponse<T> {\n data: T[];\n pagination: PaginationMeta;\n}\n\n/**\n * Pagination options\n */\nexport interface PaginationOptions {\n /** Default page size */\n defaultLimit?: number;\n /** Maximum page size */\n maxLimit?: number;\n /** Page query parameter name */\n pageParam?: string;\n /** Limit query parameter name */\n limitParam?: string;\n}\n\nconst defaultOptions: Required<PaginationOptions> = {\n defaultLimit: 20,\n maxLimit: 100,\n pageParam: \"page\",\n limitParam: \"limit\",\n};\n\n/**\n * Parse pagination from request query\n *\n * @example\n * ```typescript\n * app.get('/users', async (c) => {\n * const { page, limit, offset } = parsePagination(c);\n *\n * const users = await db.query.users.findMany({\n * limit,\n * offset,\n * });\n *\n * const total = await db.query.users.count();\n *\n * return c.json(paginate(users, { page, limit, total }));\n * });\n * ```\n */\nexport function parsePagination(\n c: HonoContext,\n options: PaginationOptions = {}\n): PaginationParams {\n const opts = { ...defaultOptions, ...options };\n\n const pageStr = c.req.query(opts.pageParam);\n const limitStr = c.req.query(opts.limitParam);\n\n let page = pageStr ? parseInt(pageStr, 10) : 1;\n let limit = limitStr ? parseInt(limitStr, 10) : opts.defaultLimit;\n\n // Validate and clamp values\n if (isNaN(page) || page < 1) page = 1;\n if (isNaN(limit) || limit < 1) limit = opts.defaultLimit;\n if (limit > opts.maxLimit) limit = opts.maxLimit;\n\n const offset = (page - 1) * limit;\n\n return { page, limit, offset };\n}\n\n/**\n * Create pagination metadata\n */\nexport function createPaginationMeta(params: {\n page: number;\n limit: number;\n total: number;\n}): PaginationMeta {\n const { page, limit, total } = params;\n const totalPages = Math.ceil(total / limit);\n\n return {\n page,\n limit,\n total,\n totalPages,\n hasNext: page < totalPages,\n hasPrev: page > 1,\n };\n}\n\n/**\n * Create paginated response\n *\n * @example\n * ```typescript\n * const users = await getUsers({ limit, offset });\n * const total = await countUsers();\n *\n * return c.json(paginate(users, { page, limit, total }));\n * ```\n */\nexport function paginate<T>(\n data: T[],\n params: { page: number; limit: number; total: number }\n): PaginatedResponse<T> {\n return {\n data,\n pagination: createPaginationMeta(params),\n };\n}\n\n/**\n * Cursor-based pagination params\n */\nexport interface CursorPaginationParams {\n cursor?: string | undefined;\n limit: number;\n direction: \"forward\" | \"backward\";\n}\n\n/**\n * Cursor pagination metadata\n */\nexport interface CursorPaginationMeta {\n cursor?: string | undefined;\n nextCursor?: string | undefined;\n prevCursor?: string | undefined;\n hasMore: boolean;\n limit: number;\n}\n\n/**\n * Cursor paginated response\n */\nexport interface CursorPaginatedResponse<T> {\n data: T[];\n pagination: CursorPaginationMeta;\n}\n\n/**\n * Parse cursor pagination from request\n *\n * @example\n * ```typescript\n * app.get('/feed', async (c) => {\n * const { cursor, limit, direction } = parseCursorPagination(c);\n *\n * const items = await db.query.posts.findMany({\n * where: cursor ? { id: { gt: cursor } } : undefined,\n * limit: limit + 1, // Fetch one extra to check hasMore\n * orderBy: { createdAt: 'desc' },\n * });\n *\n * return c.json(cursorPaginate(items, { cursor, limit }));\n * });\n * ```\n */\nexport function parseCursorPagination(\n c: HonoContext,\n options: PaginationOptions = {}\n): CursorPaginationParams {\n const opts = { ...defaultOptions, ...options };\n\n const cursor = c.req.query(\"cursor\") ?? undefined;\n const limitStr = c.req.query(opts.limitParam);\n const direction = c.req.query(\"direction\") === \"backward\" ? \"backward\" : \"forward\";\n\n let limit = limitStr ? parseInt(limitStr, 10) : opts.defaultLimit;\n if (isNaN(limit) || limit < 1) limit = opts.defaultLimit;\n if (limit > opts.maxLimit) limit = opts.maxLimit;\n\n return { cursor, limit, direction };\n}\n\n/**\n * Create cursor paginated response\n *\n * @example\n * ```typescript\n * // Fetch limit + 1 items\n * const items = await fetchItems(limit + 1);\n * return c.json(cursorPaginate(items, { cursor, limit }));\n * ```\n */\nexport function cursorPaginate<T extends { id: string }>(\n data: T[],\n params: { cursor?: string; limit: number }\n): CursorPaginatedResponse<T> {\n const { cursor, limit } = params;\n const hasMore = data.length > limit;\n\n // Remove the extra item if we have more\n const items = hasMore ? data.slice(0, limit) : data;\n\n const lastItem = items[items.length - 1];\n const firstItem = items[0];\n\n return {\n data: items,\n pagination: {\n cursor,\n nextCursor: hasMore && lastItem ? lastItem.id : undefined,\n prevCursor: cursor && firstItem ? firstItem.id : undefined,\n hasMore,\n limit,\n },\n };\n}\n\n/**\n * Add pagination headers to response\n */\nexport function setPaginationHeaders(\n c: HonoContext,\n meta: PaginationMeta\n): void {\n c.header(\"X-Total-Count\", String(meta.total));\n c.header(\"X-Total-Pages\", String(meta.totalPages));\n c.header(\"X-Page\", String(meta.page));\n c.header(\"X-Per-Page\", String(meta.limit));\n c.header(\"X-Has-Next\", String(meta.hasNext));\n c.header(\"X-Has-Prev\", String(meta.hasPrev));\n}\n","/**\n * @parsrun/server - Response Utilities\n * Helpers for API responses\n */\n\nimport type { HonoContext, ApiResponse } from \"../context.js\";\nimport { success, error } from \"../context.js\";\n\n/**\n * Send JSON success response\n *\n * @example\n * ```typescript\n * app.get('/users/:id', async (c) => {\n * const user = await getUser(c.req.param('id'));\n * return json(c, user);\n * });\n * ```\n */\nexport function json<T>(c: HonoContext, data: T, status = 200): Response {\n return c.json(success(data), status as 200);\n}\n\n/**\n * Send JSON success response with metadata\n *\n * @example\n * ```typescript\n * app.get('/users', async (c) => {\n * const { users, total } = await getUsers();\n * return jsonWithMeta(c, users, { total, page: 1, limit: 20 });\n * });\n * ```\n */\nexport function jsonWithMeta<T>(\n c: HonoContext,\n data: T,\n meta: ApiResponse[\"meta\"],\n status = 200\n): Response {\n return c.json(success(data, meta), status as 200);\n}\n\n/**\n * Send JSON error response\n *\n * @example\n * ```typescript\n * app.get('/users/:id', async (c) => {\n * const user = await getUser(c.req.param('id'));\n * if (!user) {\n * return jsonError(c, 'USER_NOT_FOUND', 'User not found', 404);\n * }\n * return json(c, user);\n * });\n * ```\n */\nexport function jsonError(\n c: HonoContext,\n code: string,\n message: string,\n status = 400,\n details?: Record<string, unknown>\n): Response {\n return c.json(error(code, message, details), status as 400);\n}\n\n/**\n * Send created response (201)\n */\nexport function created<T>(c: HonoContext, data: T, location?: string): Response {\n if (location) {\n c.header(\"Location\", location);\n }\n return c.json(success(data), 201);\n}\n\n/**\n * Send no content response (204)\n */\nexport function noContent(_c: HonoContext): Response {\n return new Response(null, { status: 204 });\n}\n\n/**\n * Send accepted response (202) - for async operations\n */\nexport function accepted<T>(c: HonoContext, data?: T): Response {\n if (data) {\n return c.json(success(data), 202);\n }\n return new Response(null, { status: 202 });\n}\n\n/**\n * Redirect response\n */\nexport function redirect(c: HonoContext, url: string, status: 301 | 302 | 303 | 307 | 308 = 302): Response {\n return c.redirect(url, status);\n}\n\n/**\n * Stream response helper\n *\n * @example\n * ```typescript\n * app.get('/stream', (c) => {\n * return stream(c, async (write) => {\n * for (let i = 0; i < 10; i++) {\n * await write(`data: ${i}\\n\\n`);\n * await new Promise(r => setTimeout(r, 1000));\n * }\n * });\n * });\n * ```\n */\nexport function stream(\n _c: HonoContext,\n callback: (write: (chunk: string) => Promise<void>) => Promise<void>,\n options: {\n contentType?: string;\n headers?: Record<string, string>;\n } = {}\n): Response {\n const encoder = new TextEncoder();\n\n const readableStream = new ReadableStream({\n async start(controller) {\n const write = async (chunk: string) => {\n controller.enqueue(encoder.encode(chunk));\n };\n\n try {\n await callback(write);\n } finally {\n controller.close();\n }\n },\n });\n\n return new Response(readableStream, {\n headers: {\n \"Content-Type\": options.contentType ?? \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n ...options.headers,\n },\n });\n}\n\n/**\n * Server-Sent Events helper\n *\n * @example\n * ```typescript\n * app.get('/events', (c) => {\n * return sse(c, async (send) => {\n * for await (const event of eventStream) {\n * await send({ event: 'update', data: event });\n * }\n * });\n * });\n * ```\n */\nexport function sse(\n c: HonoContext,\n callback: (\n send: (event: { event?: string; data: unknown; id?: string; retry?: number }) => Promise<void>\n ) => Promise<void>\n): Response {\n return stream(c, async (write) => {\n const send = async (event: { event?: string; data: unknown; id?: string; retry?: number }) => {\n let message = \"\";\n\n if (event.id) {\n message += `id: ${event.id}\\n`;\n }\n\n if (event.event) {\n message += `event: ${event.event}\\n`;\n }\n\n if (event.retry) {\n message += `retry: ${event.retry}\\n`;\n }\n\n const data = typeof event.data === \"string\" ? event.data : JSON.stringify(event.data);\n message += `data: ${data}\\n\\n`;\n\n await write(message);\n };\n\n await callback(send);\n });\n}\n\n/**\n * File download response\n */\nexport function download(\n c: HonoContext,\n data: Uint8Array | ArrayBuffer | string,\n filename: string,\n contentType = \"application/octet-stream\"\n): Response {\n c.header(\"Content-Disposition\", `attachment; filename=\"${filename}\"`);\n c.header(\"Content-Type\", contentType);\n\n if (typeof data === \"string\") {\n return c.body(data);\n }\n\n return new Response(data, {\n headers: c.res.headers,\n });\n}\n","/**\n * @parsrun/server - Health Check Endpoints\n * Kubernetes-compatible health and readiness probes\n */\n\nimport { Hono } from \"hono\";\nimport type { HonoApp, ServerContextVariables } from \"./context.js\";\n\n/**\n * Health check status\n */\nexport type HealthStatus = \"healthy\" | \"degraded\" | \"unhealthy\";\n\n/**\n * Health check result\n */\nexport interface HealthCheckResult {\n status: HealthStatus;\n message?: string;\n latency?: number;\n}\n\n/**\n * Health check function\n */\nexport type HealthCheck = () => Promise<HealthCheckResult> | HealthCheckResult;\n\n/**\n * Health response\n */\nexport interface HealthResponse {\n status: HealthStatus;\n timestamp: string;\n uptime: number;\n checks: Record<string, HealthCheckResult>;\n}\n\n/**\n * Health check options\n */\nexport interface HealthCheckOptions {\n /** Custom health checks */\n checks?: Record<string, HealthCheck>;\n /** Include detailed info (disable in production) */\n detailed?: boolean;\n}\n\n// Track server start time\nconst startTime = Date.now();\n\n/**\n * Database health check\n */\nasync function checkDatabase(db: { ping?: () => Promise<boolean> }): Promise<HealthCheckResult> {\n const start = Date.now();\n\n try {\n if (db.ping) {\n await db.ping();\n }\n return {\n status: \"healthy\",\n latency: Date.now() - start,\n };\n } catch (err) {\n return {\n status: \"unhealthy\",\n message: err instanceof Error ? err.message : \"Database connection failed\",\n latency: Date.now() - start,\n };\n }\n}\n\n/**\n * Determine overall status from individual checks\n */\nfunction aggregateStatus(checks: Record<string, HealthCheckResult>): HealthStatus {\n const statuses = Object.values(checks).map((c) => c.status);\n\n if (statuses.some((s) => s === \"unhealthy\")) {\n return \"unhealthy\";\n }\n\n if (statuses.some((s) => s === \"degraded\")) {\n return \"degraded\";\n }\n\n return \"healthy\";\n}\n\n/**\n * Create health check router\n *\n * @example\n * ```typescript\n * const health = createHealthRouter({\n * checks: {\n * redis: async () => {\n * await redis.ping();\n * return { status: 'healthy' };\n * },\n * external: async () => {\n * const res = await fetch('https://api.example.com/health');\n * return { status: res.ok ? 'healthy' : 'unhealthy' };\n * },\n * },\n * });\n *\n * app.route('/health', health);\n * // GET /health - Full health check\n * // GET /health/live - Liveness probe\n * // GET /health/ready - Readiness probe\n * ```\n */\nexport function createHealthRouter(options: HealthCheckOptions = {}): HonoApp {\n const router = new Hono<{ Variables: ServerContextVariables }>();\n const { checks = {}, detailed = true } = options;\n\n /**\n * GET /health - Full health check\n * Returns detailed status of all checks\n */\n router.get(\"/\", async (c) => {\n const db = c.get(\"db\");\n const results: Record<string, HealthCheckResult> = {};\n\n // Run database check\n results[\"database\"] = await checkDatabase(db);\n\n // Run custom checks in parallel\n const customCheckResults = await Promise.all(\n Object.entries(checks).map(async ([name, check]) => {\n try {\n const result = await check();\n return [name, result] as const;\n } catch (err) {\n return [\n name,\n {\n status: \"unhealthy\" as const,\n message: err instanceof Error ? err.message : \"Check failed\",\n },\n ] as const;\n }\n })\n );\n\n for (const [name, result] of customCheckResults) {\n results[name] = result;\n }\n\n const overallStatus = aggregateStatus(results);\n const response: HealthResponse = {\n status: overallStatus,\n timestamp: new Date().toISOString(),\n uptime: Math.floor((Date.now() - startTime) / 1000),\n checks: detailed ? results : {},\n };\n\n const statusCode = overallStatus === \"healthy\" ? 200 : overallStatus === \"degraded\" ? 200 : 503;\n\n return c.json(response, statusCode as 200);\n });\n\n /**\n * GET /health/live - Liveness probe\n * Kubernetes liveness probe - returns 200 if server is running\n */\n router.get(\"/live\", (c) => {\n return c.json({\n status: \"ok\",\n timestamp: new Date().toISOString(),\n });\n });\n\n /**\n * GET /health/ready - Readiness probe\n * Kubernetes readiness probe - returns 200 if server can handle traffic\n */\n router.get(\"/ready\", async (c) => {\n const db = c.get(\"db\");\n\n // Check database connection\n const dbHealth = await checkDatabase(db);\n\n if (dbHealth.status === \"unhealthy\") {\n return c.json(\n {\n status: \"not_ready\",\n reason: \"database\",\n timestamp: new Date().toISOString(),\n },\n 503\n );\n }\n\n return c.json({\n status: \"ready\",\n timestamp: new Date().toISOString(),\n });\n });\n\n /**\n * GET /health/startup - Startup probe\n * For slow-starting containers\n */\n router.get(\"/startup\", (c) => {\n return c.json({\n status: \"started\",\n uptime: Math.floor((Date.now() - startTime) / 1000),\n timestamp: new Date().toISOString(),\n });\n });\n\n return router;\n}\n\n/**\n * Simple health endpoint handler\n *\n * @example\n * ```typescript\n * app.get('/health', healthHandler);\n * ```\n */\nexport async function healthHandler(c: import(\"hono\").Context<{ Variables: ServerContextVariables }>) {\n return c.json({\n status: \"ok\",\n timestamp: new Date().toISOString(),\n uptime: Math.floor((Date.now() - startTime) / 1000),\n });\n}\n"],"mappings":";AAKA,SAAS,YAAY;AACrB,SAAS,oBAAoB;;;ACoOtB,SAAS,QAAW,MAAS,MAA4C;AAC9E,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,IACA,MAAM,QAAQ;AAAA,EAChB;AACF;AAKO,SAAS,MACd,MACA,SACA,SACoB;AACpB,SAAO;AAAA,IACL,SAAS;AAAA,IACT,OAAO,EAAE,MAAM,SAAS,SAAS,WAAW,OAAU;AAAA,EACxD;AACF;AAKO,SAAS,oBAA4B;AAC1C,SAAO,OAAO,WAAW;AAC3B;;;ADzNO,SAAS,aAAa,SAAuC;AAClE,QAAM,MAAM,IAAI,KAA4C;AAAA,IAC1D,QAAQ,QAAQ,UAAU;AAAA,EAC5B,CAAC;AAED,QAAM,SAAS,QAAQ,UAAU,aAAa,EAAE,MAAM,cAAc,CAAC;AAGrE,MAAI,IAAI,KAAK,OAAO,GAAG,SAAS;AAE9B,MAAE,IAAI,MAAM,QAAQ,QAAQ;AAC5B,MAAE,IAAI,UAAU,OAAO;AACvB,MAAE,IAAI,UAAU,MAAM;AACtB,MAAE,IAAI,kBAAkB,oBAAI,IAAY,CAAC;AACzC,MAAE,IAAI,gBAAgB,QAAQ,YAAY;AAC1C,MAAE,IAAI,UAAU,QAAQ,UAAU,CAAC,CAAC;AAGpC,QAAI,QAAQ,cAAc,OAAO;AAC/B,YAAM,YAAY,EAAE,IAAI,OAAO,cAAc,KAAK,kBAAkB;AACpE,QAAE,IAAI,aAAa,SAAS;AAC5B,QAAE,OAAO,gBAAgB,SAAS;AAAA,IACpC;AAEA,UAAM,KAAK;AAAA,EACb,CAAC;AAED,SAAO;AACT;AAqBO,SAAS,eAAwB;AACtC,SAAO,IAAI,KAA4C;AACzD;AAaO,SAAS,sBAAsB,SAA0B;AAC9D,QAAM,SAAS,IAAI,KAA4C;AAG/D,QAAM,kBAAkB,IAAI,KAA4C;AACxE,kBAAgB,MAAM,IAAI,OAAO,IAAI,MAAM;AAE3C,SAAO;AACT;AAiBO,SAAS,mBACd,YACA,SAIS;AACT,QAAM,eAAe,IAAI,KAA4C;AAGrE,MAAI,QAAQ,YAAY;AACtB,eAAW,MAAM,QAAQ,YAAY;AACnC,mBAAa,IAAI,KAAK,EAAE;AAAA,IAC1B;AAAA,EACF;AAGA,UAAQ,OAAO,YAAY;AAG3B,QAAM,gBAAgB,IAAI,KAA4C;AACtE,gBAAc,MAAM,IAAI,UAAU,IAAI,YAAY;AAElD,SAAO;AACT;;;AExJA,SAAS,QAAAA,aAAY;AACrB,SAAS,YAAY;AACrB,SAAS,gBAAAC,qBAAiC;AAkDnC,IAAM,eAAN,MAAmB;AAAA,EAChB;AAAA,EACA;AAAA,EACA,iBAA8B,oBAAI,IAAI;AAAA,EACtC,iBAA8C,oBAAI,IAAI;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EAEtB,YAAY,SAA8B;AACxC,SAAK,SAAS,QAAQ;AACtB,SAAK,KAAK,QAAQ,OAAO;AACzB,SAAK,eAAe,QAAQ;AAC5B,SAAK,SAAS,QAAQ,UAAUC,cAAa,EAAE,MAAM,eAAe,CAAC;AAGrE,SAAK,MAAM,IAAIC,MAA4C;AAE3D,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAA4B;AAChC,QAAI,KAAK,aAAa;AACpB,WAAK,OAAO,KAAK,kCAAkC;AACnD;AAAA,IACF;AAEA,SAAK,OAAO,KAAK,8BAA8B;AAG/C,QAAI;AACF,UAAI,KAAK,GAAG,MAAM;AAChB,cAAM,KAAK,MAAM,KAAK,GAAG,KAAK;AAC9B,YAAI,CAAC,GAAI,OAAM,IAAI,MAAM,8BAA8B;AAAA,MACzD,OAAO;AACL,cAAM,KAAK,GAAG,QAAQ,UAAU;AAAA,MAClC;AACA,WAAK,OAAO,KAAK,yBAAyB;AAAA,IAC5C,SAASC,QAAO;AACd,WAAK,OAAO,MAAM,8BAA8BA,MAAK;AACrD,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AAEA,SAAK,cAAc;AACnB,SAAK,OAAO,KAAK,uCAAuC;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAwB;AAE9B,SAAK,IAAI,IAAI,KAAK,OAAO,GAAG,SAAS;AACnC,YAAM,YAAY,kBAAkB;AACpC,YAAMC,iBAAgB,KAAK,OAAO,MAAM,EAAE,UAAU,CAAC;AAGrD,QAAE,IAAI,MAAM,KAAK,EAAE;AACnB,QAAE,IAAI,UAAU,KAAK,MAAM;AAC3B,QAAE,IAAI,kBAAkB,KAAK,cAAc;AAC3C,QAAE,IAAI,UAAUA,cAAa;AAC7B,QAAE,IAAI,aAAa,SAAS;AAC5B,QAAE,IAAI,gBAAgB,KAAK,YAAY;AACvC,QAAE,IAAI,UAAU,KAAK,OAAO,UAAU,CAAC,CAAC;AACxC,QAAE,IAAI,QAAQ,MAAS;AACvB,QAAE,IAAI,UAAU,MAAS;AAEzB,YAAM,QAAQ,KAAK,IAAI;AAEvB,YAAM,KAAK;AAEX,YAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,MAAAA,eAAc,MAAM,qBAAqB;AAAA,QACvC,QAAQ,EAAE,IAAI;AAAA,QACd,MAAM,EAAE,IAAI;AAAA,QACZ,QAAQ,EAAE,IAAI;AAAA,QACd,YAAY;AAAA,MACd,CAAC;AAAA,IACH,CAAC;AAGD,QAAI,KAAK,OAAO,MAAM;AACpB,WAAK,IAAI,IAAI,KAAK,KAAK,KAAK,oBAAoB,KAAK,OAAO,IAAI,CAAC,CAAC;AAAA,IACpE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAoB,QAAgD;AAC1E,UAAM,SAAqC;AAAA,MACzC,QAAQ,OAAO,OAAO,WAAW,aAC7B,CAAC,WAAY,OAAO,OAAuC,MAAM,IAAI,SAAS,OAC9E,OAAO;AAAA,IACb;AAEA,QAAI,OAAO,gBAAgB,QAAW;AACpC,aAAO,cAAc,OAAO;AAAA,IAC9B;AACA,QAAI,OAAO,YAAY,QAAW;AAChC,aAAO,eAAe,OAAO;AAAA,IAC/B;AACA,QAAI,OAAO,mBAAmB,QAAW;AACvC,aAAO,eAAe,OAAO;AAAA,IAC/B;AACA,QAAI,OAAO,mBAAmB,QAAW;AACvC,aAAO,gBAAgB,OAAO;AAAA,IAChC;AACA,QAAI,OAAO,WAAW,QAAW;AAC/B,aAAO,SAAS,OAAO;AAAA,IACzB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAwB;AAC9B,UAAM,WAAW,KAAK,OAAO,YAAY;AAGzC,SAAK,IAAI,IAAI,WAAW,CAAC,MAAM;AAC7B,aAAO,EAAE,KAAK;AAAA,QACZ,QAAQ;AAAA,QACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAAA,IACH,CAAC;AAGD,SAAK,IAAI,IAAI,mBAAmB,OAAO,MAAM;AAC3C,UAAI,WAAW;AACf,UAAI;AACF,YAAI,KAAK,GAAG,MAAM;AAChB,qBAAY,MAAM,KAAK,GAAG,KAAK,IAAK,OAAO;AAAA,QAC7C,OAAO;AACL,gBAAM,KAAK,GAAG,QAAQ,UAAU;AAChC,qBAAW;AAAA,QACb;AAAA,MACF,QAAQ;AACN,mBAAW;AAAA,MACb;AAEA,aAAO,EAAE,KAAK;AAAA,QACZ,QAAQ,aAAa,OAAO,OAAO;AAAA,QACnC,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC,UAAU;AAAA,UACR,UAAU;AAAA,QACZ;AAAA,QACA,SAAS;AAAA,UACP,SAAS,MAAM,KAAK,KAAK,cAAc;AAAA,UACvC,YAAY,MAAM,KAAK,KAAK,eAAe,KAAK,CAAC;AAAA,QACnD;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAGD,SAAK,IAAI,IAAI,UAAU,CAAC,MAAM;AAC5B,YAAM,YAAoC;AAAA,QACxC,QAAQ;AAAA,QACR,UAAU,GAAG,QAAQ;AAAA,MACvB;AAGA,iBAAW,cAAc,KAAK,gBAAgB;AAC5C,kBAAU,UAAU,IAAI,GAAG,QAAQ,IAAI,UAAU;AAAA,MACnD;AAEA,aAAO,EAAE,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,SAAS;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAGD,SAAK,IAAI,IAAI,GAAG,QAAQ,aAAa,CAAC,MAAM;AAC1C,YAAM,WAAW,MAAM,KAAK,KAAK,cAAc,EAAE,IAAI,CAAC,SAAS;AAC7D,cAAM,SAAS,KAAK,eAAe,IAAI,IAAI;AAC3C,eAAO;AAAA,UACL;AAAA,UACA,SAAS,QAAQ,WAAW;AAAA,UAC5B,aAAa,QAAQ,eAAe;AAAA,UACpC,aAAa,QAAQ,eAAe,CAAC;AAAA,QACvC;AAAA,MACF,CAAC;AAED,aAAO,EAAE,KAAK;AAAA,QACZ,SAAS,MAAM,KAAK,KAAK,cAAc;AAAA,QACvC;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,UAAgC;AAC7C,QAAI,KAAK,eAAe,IAAI,SAAS,IAAI,GAAG;AAC1C,WAAK,OAAO,KAAK,8BAA8B,SAAS,IAAI,EAAE;AAC9D;AAAA,IACF;AAEA,SAAK,eAAe,IAAI,SAAS,MAAM,QAAQ;AAC/C,SAAK,OAAO,KAAK,sBAAsB,SAAS,IAAI,EAAE;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,YAAsC;AACvD,UAAM,SAAS,KAAK,eAAe,IAAI,UAAU;AAEjD,QAAI,CAAC,QAAQ;AACX,WAAK,OAAO,MAAM,qBAAqB,UAAU,EAAE;AACnD,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,eAAe,IAAI,UAAU,GAAG;AACvC,WAAK,OAAO,KAAK,2BAA2B,UAAU,EAAE;AACxD,aAAO;AAAA,IACT;AAGA,QAAI,OAAO,cAAc;AACvB,iBAAW,OAAO,OAAO,cAAc;AACrC,YAAI,CAAC,KAAK,eAAe,IAAI,GAAG,GAAG;AACjC,eAAK,OAAO;AAAA,YACV,UAAU,UAAU,aAAa,GAAG;AAAA,UACtC;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,WAAK,OAAO,KAAK,oBAAoB,UAAU,EAAE;AAGjD,UAAI,OAAO,UAAU;AACnB,cAAM,OAAO,SAAS;AAAA,MACxB;AAGA,aAAO,eAAe,KAAK,GAAG;AAG9B,WAAK,eAAe,IAAI,UAAU;AAElC,WAAK,OAAO,KAAK,mBAAmB,UAAU,EAAE;AAChD,aAAO;AAAA,IACT,SAASD,QAAO;AACd,WAAK,OAAO,MAAM,2BAA2B,UAAU,IAAIA,MAAK;AAChE,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,YAAsC;AACxD,QAAI,CAAC,KAAK,eAAe,IAAI,UAAU,GAAG;AACxC,WAAK,OAAO,KAAK,uBAAuB,UAAU,EAAE;AACpD,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,KAAK,eAAe,IAAI,UAAU;AACjD,QAAI,CAAC,QAAQ;AACX,WAAK,OAAO,MAAM,qBAAqB,UAAU,EAAE;AACnD,aAAO;AAAA,IACT;AAGA,eAAW,CAAC,MAAM,CAAC,KAAK,KAAK,gBAAgB;AAC3C,UAAI,KAAK,eAAe,IAAI,IAAI,KAAK,EAAE,cAAc,SAAS,UAAU,GAAG;AACzE,aAAK,OAAO;AAAA,UACV,kBAAkB,UAAU,KAAK,IAAI;AAAA,QACvC;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAEA,QAAI;AAEF,UAAI,OAAO,WAAW;AACpB,cAAM,OAAO,UAAU;AAAA,MACzB;AAIA,WAAK,eAAe,OAAO,UAAU;AAErC,WAAK,OAAO,KAAK,oBAAoB,UAAU,EAAE;AACjD,aAAO;AAAA,IACT,SAASA,QAAO;AACd,WAAK,OAAO,MAAM,4BAA4B,UAAU,IAAIA,MAAK;AACjE,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,SAAkB;AAChB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,oBAA8B;AAC5B,WAAO,MAAM,KAAK,KAAK,cAAc;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAiC;AAC/B,WAAO,MAAM,KAAK,KAAK,eAAe,KAAK,CAAC;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,YAA6B;AAC3C,WAAO,KAAK,eAAe,IAAI,UAAU;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,YAA6B;AAC9C,WAAO,KAAK,eAAe,IAAI,UAAU;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,cAA+B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,YAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AACF;AAKO,SAAS,mBAAmB,SAA4C;AAC7E,SAAO,IAAI,aAAa,OAAO;AACjC;AAKO,SAAS,aAAa,UAA0C;AACrE,SAAO;AACT;;;ACnZA,IAAM,qBAA0C;AAAA,EAC9C,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,SAAS;AACX;AAwBO,IAAM,aAAN,MAAiB;AAAA,EAGtB,YACU,IACR,SAAoB,CAAC,GACrB;AAFQ;AAGR,SAAK,SAAS,EAAE,GAAG,oBAAoB,GAAG,OAAO;AAAA,EACnD;AAAA,EAPQ;AAAA;AAAA;AAAA;AAAA;AAAA,EAaR,MAAM,YAAY,UAAiC;AACjD,QAAI,CAAC,KAAK,OAAO,QAAS;AAE1B,QAAI;AAGF,YAAM,kBAAkB,SAAS,QAAQ,MAAM,IAAI;AACnD,YAAM,KAAK,GAAG,QAAQ,OAAO,KAAK,OAAO,eAAe,OAAO,eAAe,GAAG;AAAA,IACnF,SAASE,QAAO;AACd,cAAQ,MAAM,oCAAoCA,MAAK;AACvD,YAAM,IAAI,SAAS,gCAAgC,kBAAkBA,MAAK;AAAA,IAC5E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAA+B;AACnC,QAAI,CAAC,KAAK,OAAO,QAAS;AAE1B,QAAI;AACF,YAAM,KAAK,GAAG,QAAQ,SAAS,KAAK,OAAO,eAAe,EAAE;AAAA,IAC9D,SAASA,QAAO;AACd,cAAQ,MAAM,sCAAsCA,MAAK;AACzD,YAAM,IAAI,SAAS,kCAAkC,oBAAoBA,MAAK;AAAA,IAChF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAc,UAAkB,WAAyC;AAC7E,UAAM,KAAK,YAAY,QAAQ;AAC/B,QAAI;AACF,aAAO,MAAM,UAAU;AAAA,IACzB,UAAE;AACA,YAAM,KAAK,cAAc;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAqB;AACnB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,YAAiC;AAC/B,WAAO,EAAE,GAAG,KAAK,OAAO;AAAA,EAC1B;AACF;AAKO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAClC,YACE,SACgB,MACA,OAChB;AACA,UAAM,OAAO;AAHG;AACA;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAKO,SAAS,iBAAiB,IAAqB,QAAgC;AACpF,SAAO,IAAI,WAAW,IAAI,MAAM;AAClC;AAWO,SAAS,cAAc,QAAgC;AAC5D,SAAO,OAAO,GAAgB,SAA6C;AACzE,UAAM,OAAO,EAAE,IAAI,MAAM;AACzB,UAAM,KAAK,EAAE,IAAI,IAAI;AAGrB,QAAI,CAAC,MAAM,YAAY,CAAC,IAAI;AAC1B,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,MAAM,IAAI,WAAW,IAAI,MAAM;AAErC,QAAI;AACF,YAAM,IAAI,YAAY,KAAK,QAAQ;AACnC,YAAM,KAAK;AAAA,IACb,UAAE;AACA,YAAM,IAAI,cAAc;AAAA,IAC1B;AAAA,EACF;AACF;AAaO,SAAS,kBACd,WACA,UAKI,CAAC,GACG;AACR,QAAM;AAAA,IACJ,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,aAAa,GAAG,SAAS;AAAA,IACzB,WAAW;AAAA,EACb,IAAI;AAEJ,SAAO;AAAA;AAAA,cAEK,SAAS;AAAA;AAAA;AAAA,cAGT,SAAS;AAAA;AAAA;AAAA,wBAGC,UAAU,OAAO,SAAS;AAAA,gBAClC,UAAU,OAAO,SAAS;AAAA;AAAA,WAE/B,cAAc,uBAAuB,eAAe,aAAa,QAAQ;AAAA,EAClF,KAAK;AACP;AAKO,SAAS,mBAAmB,WAA2B;AAC5D,SAAO;AAAA,cACK,SAAS;AAAA,cACT,SAAS;AAAA,EACrB,KAAK;AACP;;;ACxNA,SAAS,gBAAgB,yBAAyB;AA8B3C,IAAM,eAAN,MAAgD;AAAA,EAC7C,kBAA4C,oBAAI,IAAI;AAAA,EACpD,YAAsC,oBAAI,IAAI;AAAA,EAC9C,kBAA4C,oBAAI,IAAI;AAAA,EACpD,gBAA0C,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA,EAK1D,gBAAgB,QAAgB,YAA0B;AACxD,QAAI,CAAC,KAAK,gBAAgB,IAAI,MAAM,GAAG;AACrC,WAAK,gBAAgB,IAAI,QAAQ,oBAAI,IAAI,CAAC;AAAA,IAC5C;AACA,SAAK,gBAAgB,IAAI,MAAM,EAAG,IAAI,UAAU;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,QAAgB,YAA0B;AACzD,SAAK,gBAAgB,IAAI,MAAM,GAAG,OAAO,UAAU;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,QAAgB,MAAoB;AAC7C,QAAI,CAAC,KAAK,UAAU,IAAI,MAAM,GAAG;AAC/B,WAAK,UAAU,IAAI,QAAQ,oBAAI,IAAI,CAAC;AAAA,IACtC;AACA,SAAK,UAAU,IAAI,MAAM,EAAG,IAAI,IAAI;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,QAAgB,MAAoB;AAC7C,SAAK,UAAU,IAAI,MAAM,GAAG,OAAO,IAAI;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,UAAkB,aAA6B;AACxD,SAAK,gBAAgB,IAAI,UAAU,IAAI,IAAI,WAAW,CAAC;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,UAAkB,QAAsB;AACtD,QAAI,CAAC,KAAK,cAAc,IAAI,QAAQ,GAAG;AACrC,WAAK,cAAc,IAAI,UAAU,oBAAI,IAAI,CAAC;AAAA,IAC5C;AACA,SAAK,cAAc,IAAI,QAAQ,EAAG,IAAI,MAAM;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,UAAkB,QAAsB;AACzD,SAAK,cAAc,IAAI,QAAQ,GAAG,OAAO,MAAM;AAAA,EACjD;AAAA;AAAA,EAIA,MAAM,mBAAmB,QAAgB,WAAuC;AAC9E,UAAM,cAAc,oBAAI,IAAY;AAGpC,UAAM,SAAS,KAAK,gBAAgB,IAAI,MAAM;AAC9C,QAAI,QAAQ;AACV,aAAO,QAAQ,CAAC,MAAM,YAAY,IAAI,CAAC,CAAC;AAAA,IAC1C;AAGA,UAAM,QAAQ,KAAK,UAAU,IAAI,MAAM;AACvC,QAAI,OAAO;AACT,YAAM,QAAQ,CAAC,SAAS;AACtB,cAAM,YAAY,KAAK,gBAAgB,IAAI,IAAI;AAC/C,YAAI,WAAW;AACb,oBAAU,QAAQ,CAAC,MAAM,YAAY,IAAI,CAAC,CAAC;AAAA,QAC7C;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO,MAAM,KAAK,WAAW;AAAA,EAC/B;AAAA,EAEA,MAAM,aAAa,QAAgB,WAAuC;AACxE,WAAO,MAAM,KAAK,KAAK,UAAU,IAAI,MAAM,KAAK,CAAC,CAAC;AAAA,EACpD;AAAA,EAEA,MAAM,cACJ,QACA,OACA,UACkB;AAClB,UAAM,cAAc,MAAM,KAAK,mBAAmB,QAAQ,QAAQ;AAClE,UAAM,iBAAiB,GAAG,MAAM,QAAQ,IAAI,MAAM,MAAM;AAGxD,QAAI,YAAY,SAAS,cAAc,GAAG;AACxC,aAAO;AAAA,IACT;AAMA,eAAW,QAAQ,aAAa;AAC9B,UAAI,SAAS,IAAK,QAAO;AACzB,UAAI,SAAS,GAAG,MAAM,QAAQ,KAAM,QAAO;AAC3C,UAAI,SAAS,KAAK,MAAM,MAAM,GAAI,QAAO;AAAA,IAC3C;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,eAAe,QAAgB,UAAoC;AACvE,WAAO,KAAK,cAAc,IAAI,QAAQ,GAAG,IAAI,MAAM,KAAK;AAAA,EAC1D;AACF;AAKO,IAAM,cAAN,MAAkB;AAAA,EACvB,YAAoB,SAA4B;AAA5B;AAAA,EAA6B;AAAA;AAAA;AAAA;AAAA,EAKjD,MAAM,mBAAmB,QAAgB,UAAsC;AAC7E,WAAO,KAAK,QAAQ,mBAAmB,QAAQ,QAAQ;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,QAAgB,UAAsC;AACvE,WAAO,KAAK,QAAQ,aAAa,QAAQ,QAAQ;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cACJ,QACA,OACA,UACkB;AAClB,WAAO,KAAK,QAAQ,cAAc,QAAQ,OAAO,QAAQ;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBACJ,QACA,QACA,UACkB;AAClB,eAAW,SAAS,QAAQ;AAC1B,UAAI,MAAM,KAAK,cAAc,QAAQ,OAAO,QAAQ,GAAG;AACrD,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kBACJ,QACA,QACA,UACkB;AAClB,eAAW,SAAS,QAAQ;AAC1B,UAAI,CAAE,MAAM,KAAK,cAAc,QAAQ,OAAO,QAAQ,GAAI;AACxD,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,QAAgB,UAAoC;AACvE,WAAO,KAAK,QAAQ,eAAe,QAAQ,QAAQ;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,QAAgB,MAAc,UAAqC;AAC/E,UAAM,QAAQ,MAAM,KAAK,aAAa,QAAQ,QAAQ;AACtD,WAAO,MAAM,SAAS,IAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,QAAgB,OAAiB,UAAqC;AACrF,UAAM,YAAY,MAAM,KAAK,aAAa,QAAQ,QAAQ;AAC1D,WAAO,MAAM,KAAK,CAAC,SAAS,UAAU,SAAS,IAAI,CAAC;AAAA,EACtD;AACF;AAKO,SAAS,qBAAmE;AACjF,QAAM,UAAU,IAAI,aAAa;AACjC,QAAM,OAAO,IAAI,YAAY,OAAO;AACpC,SAAO,EAAE,MAAM,QAAQ;AACzB;AAKO,SAAS,kBAAkB,SAAyC;AACzE,SAAO,IAAI,YAAY,OAAO;AAChC;AASO,SAAS,cAA0B;AACxC,SAAO,OAAO,GAAgB,SAA6C;AACzE,UAAM,OAAO,EAAE,IAAI,MAAM;AAEzB,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,kBAAkB,yBAAyB;AAAA,IACvD;AAEA,WAAO,KAAK;AAAA,EACd;AACF;AAWO,SAAS,kBACd,UACA,QACA,UAAgF,CAAC,GACrE;AACZ,SAAO,OAAO,GAAgB,SAA6C;AACzE,UAAM,OAAO,EAAE,IAAI,MAAM;AAEzB,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,kBAAkB,yBAAyB;AAAA,IACvD;AAEA,UAAM,QAAyB;AAAA,MAC7B;AAAA,MACA;AAAA,MACA,OAAO,QAAQ,SAAS;AAAA,IAC1B;AAGA,QAAI,gBAAgB;AAEpB,QAAI,QAAQ,SAAS;AACnB,sBAAgB,MAAM,QAAQ,QAAQ,cAAc,KAAK,IAAI,OAAO,KAAK,QAAQ;AAAA,IACnF,OAAO;AAEL,sBAAgB,oBAAoB,MAAM,KAAK;AAAA,IACjD;AAEA,QAAI,CAAC,eAAe;AAClB,YAAM,IAAI,eAAe,sBAAsB,QAAQ,IAAI,MAAM,EAAE;AAAA,IACrE;AAEA,WAAO,KAAK;AAAA,EACd;AACF;AAKO,SAAS,qBACd,aACA,UAA2C,CAAC,GAChC;AACZ,SAAO,OAAO,GAAgB,SAA6C;AACzE,UAAM,OAAO,EAAE,IAAI,MAAM;AAEzB,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,kBAAkB,yBAAyB;AAAA,IACvD;AAEA,QAAI,SAAS;AAEb,eAAW,QAAQ,aAAa;AAC9B,YAAM,QAAyB,EAAE,UAAU,KAAK,UAAU,QAAQ,KAAK,OAAO;AAE9E,UAAI,QAAQ,SAAS;AACnB,YAAI,MAAM,QAAQ,QAAQ,cAAc,KAAK,IAAI,OAAO,KAAK,QAAQ,GAAG;AACtE,mBAAS;AACT;AAAA,QACF;AAAA,MACF,OAAO;AACL,YAAI,oBAAoB,MAAM,KAAK,GAAG;AACpC,mBAAS;AACT;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,eAAe,0BAA0B;AAAA,IACrD;AAEA,WAAO,KAAK;AAAA,EACd;AACF;AAKO,SAAS,YAAY,MAA0B;AACpD,SAAO,OAAO,GAAgB,SAA6C;AACzE,UAAM,OAAO,EAAE,IAAI,MAAM;AAEzB,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,kBAAkB,yBAAyB;AAAA,IACvD;AAEA,QAAI,KAAK,SAAS,MAAM;AACtB,YAAM,IAAI,eAAe,kBAAkB,IAAI,EAAE;AAAA,IACnD;AAEA,WAAO,KAAK;AAAA,EACd;AACF;AAKO,SAAS,eAAe,OAA6B;AAC1D,SAAO,OAAO,GAAgB,SAA6C;AACzE,UAAM,OAAO,EAAE,IAAI,MAAM;AAEzB,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,kBAAkB,yBAAyB;AAAA,IACvD;AAEA,QAAI,CAAC,KAAK,QAAQ,CAAC,MAAM,SAAS,KAAK,IAAI,GAAG;AAC5C,YAAM,IAAI,eAAe,gCAAgC,MAAM,KAAK,IAAI,CAAC,EAAE;AAAA,IAC7E;AAEA,WAAO,KAAK;AAAA,EACd;AACF;AAKO,SAAS,oBAAoB,cAAmC;AACrE,SAAO,OAAO,GAAgB,SAA6C;AACzE,UAAM,OAAO,EAAE,IAAI,MAAM;AACzB,UAAM,SAAS,EAAE,IAAI,QAAQ;AAE7B,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,kBAAkB,yBAAyB;AAAA,IACvD;AAEA,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,eAAe,yBAAyB;AAAA,IACpD;AAEA,QAAI,KAAK,aAAa,OAAO,IAAI;AAC/B,YAAM,IAAI,eAAe,6BAA6B;AAAA,IACxD;AAEA,QAAI,gBAAgB,KAAK,SAAS,cAAc;AAC9C,YAAM,IAAI,eAAe,4BAA4B,YAAY,EAAE;AAAA,IACrE;AAEA,WAAO,KAAK;AAAA,EACd;AACF;AAKA,SAAS,oBAAoB,MAAmB,OAAiC;AAC/E,QAAM,iBAAiB,GAAG,MAAM,QAAQ,IAAI,MAAM,MAAM;AAExD,aAAW,QAAQ,KAAK,aAAa;AACnC,QAAI,SAAS,eAAgB,QAAO;AACpC,QAAI,SAAS,IAAK,QAAO;AACzB,QAAI,SAAS,GAAG,MAAM,QAAQ,KAAM,QAAO;AAC3C,QAAI,SAAS,KAAK,MAAM,MAAM,GAAI,QAAO;AAAA,EAC3C;AAEA,SAAO;AACT;AASO,SAAS,gBAAgB,YAAqC;AACnE,QAAM,CAAC,UAAU,MAAM,IAAI,WAAW,MAAM,GAAG;AAC/C,MAAI,CAAC,YAAY,CAAC,QAAQ;AACxB,UAAM,IAAI,MAAM,8BAA8B,UAAU,EAAE;AAAA,EAC5D;AACA,SAAO,EAAE,UAAU,OAAO;AAC5B;AAKO,SAAS,iBAAiB,UAAkB,QAAwB;AACzE,SAAO,GAAG,QAAQ,IAAI,MAAM;AAC9B;AAKO,SAAS,gBAAgB,UAA0C;AACxE,SAAO;AAAA,IACL,EAAE,MAAM,GAAG,QAAQ,WAAW,UAAU,QAAQ,SAAS;AAAA,IACzD,EAAE,MAAM,GAAG,QAAQ,SAAS,UAAU,QAAQ,OAAO;AAAA,IACrD,EAAE,MAAM,GAAG,QAAQ,WAAW,UAAU,QAAQ,SAAS;AAAA,IACzD,EAAE,MAAM,GAAG,QAAQ,WAAW,UAAU,QAAQ,SAAS;AAAA,IACzD,EAAE,MAAM,GAAG,QAAQ,SAAS,UAAU,QAAQ,OAAO;AAAA,EACvD;AACF;AAKO,IAAM,gBAAgD;AAAA,EAC3D,OAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,CAAC,GAAG;AAAA,IACjB,UAAU;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,CAAC,UAAU,YAAY,YAAY,QAAQ;AAAA,IACxD,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,CAAC,UAAU,QAAQ;AAAA,IAChC,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,CAAC,UAAU,QAAQ;AAAA,IAChC,UAAU;AAAA,EACZ;AACF;;;ACvfO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAClC,YACkB,YACA,MAChB,SACgB,SAChB;AACA,UAAM,OAAO;AALG;AACA;AAEA;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,aAAa;AACX,WAAO,MAAc,KAAK,MAAM,KAAK,SAAS,KAAK,OAAO;AAAA,EAC5D;AACF;AAKO,IAAM,kBAAN,cAA8B,SAAS;AAAA,EAC5C,YAAY,UAAU,eAAe,SAAmC;AACtE,UAAM,KAAK,eAAe,SAAS,OAAO;AAC1C,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAMC,qBAAN,cAAgC,SAAS;AAAA,EAC9C,YAAY,UAAU,gBAAgB,SAAmC;AACvE,UAAM,KAAK,gBAAgB,SAAS,OAAO;AAC3C,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAMC,kBAAN,cAA6B,SAAS;AAAA,EAC3C,YAAY,UAAU,aAAa,SAAmC;AACpE,UAAM,KAAK,aAAa,SAAS,OAAO;AACxC,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,gBAAN,cAA4B,SAAS;AAAA,EAC1C,YAAY,UAAU,aAAa,SAAmC;AACpE,UAAM,KAAK,aAAa,SAAS,OAAO;AACxC,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,gBAAN,cAA4B,SAAS;AAAA,EAC1C,YAAY,UAAU,YAAY,SAAmC;AACnE,UAAM,KAAK,YAAY,SAAS,OAAO;AACvC,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,kBAAN,cAA8B,SAAS;AAAA,EAC5C,YAAY,UAAU,qBAAqB,SAAmC;AAC5E,UAAM,KAAK,oBAAoB,SAAS,OAAO;AAC/C,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,iBAAN,cAA6B,SAAS;AAAA,EAC3C,YACE,UAAU,qBACM,YAChB;AACA,UAAM,KAAK,uBAAuB,SAAS,EAAE,WAAW,CAAC;AAFzC;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,gBAAN,cAA4B,SAAS;AAAA,EAC1C,YAAY,UAAU,yBAAyB,SAAmC;AAChF,UAAM,KAAK,kBAAkB,SAAS,OAAO;AAC7C,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,0BAAN,cAAsC,SAAS;AAAA,EACpD,YAAY,UAAU,uBAAuB,SAAmC;AAC9E,UAAM,KAAK,uBAAuB,SAAS,OAAO;AAClD,SAAK,OAAO;AAAA,EACd;AACF;AAwDO,SAAS,aAAa,UAA+B,CAAC,GAAG;AAC9D,QAAM;AAAA,IACJ,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,IACnB;AAAA,EACF,IAAI;AAEJ,SAAO,OAAO,GAAgB,SAAmB;AAC/C,QAAI;AACF,YAAM,KAAK;AAAA,IACb,SAAS,KAAK;AACZ,YAAMC,SAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAGhE,YAAM,aAAaA,kBAAiB,WAAWA,OAAM,aAAa;AAGlE,UAAI,SAAS;AACX,gBAAQA,QAAO,CAAC;AAAA,MAClB,OAAO;AACL,cAAM,SAAS,EAAE,IAAI,QAAQ;AAC7B,YAAI,QAAQ;AACV,iBAAO,MAAM,iBAAiB;AAAA,YAC5B,WAAW,EAAE,IAAI,WAAW;AAAA,YAC5B,OAAOA,OAAM;AAAA,YACb,OAAOA,OAAM;AAAA,UACf,CAAC;AAAA,QACH;AAAA,MACF;AAGA,UAAI,gBAAgB;AAClB,cAAM,qBAAqB,gBACvB,cAAcA,QAAO,UAAU,IAC/B,oBAAoB,cAAc;AAEtC,YAAI,oBAAoB;AACtB,gBAAM,OAAO,EAAE,IAAI,MAAM;AACzB,gBAAM,SAAS,EAAE,IAAI,QAAQ;AAG7B,gBAAM,eAA6B;AAAA,YACjC,WAAW,EAAE,IAAI,WAAW;AAAA,YAC5B,MAAM;AAAA,cACJ,MAAM,EAAE,IAAI;AAAA,cACZ,QAAQ,EAAE,IAAI;AAAA,cACd,YAAY,OAAO,UAAU;AAAA,YAC/B;AAAA,UACF;AAEA,cAAI,MAAM,IAAI;AACZ,yBAAa,SAAS,KAAK;AAAA,UAC7B;AACA,cAAI,QAAQ,IAAI;AACd,yBAAa,WAAW,OAAO;AAAA,UACjC;AAGA,gBAAM,QAAiC;AAAA,YACrC,OAAO,EAAE,IAAI,MAAM;AAAA,UACrB;AACA,cAAIA,kBAAiB,UAAU;AAC7B,kBAAM,WAAW,IAAIA,OAAM;AAAA,UAC7B;AACA,uBAAa,QAAQ;AAGrB,kBAAQ;AAAA,YACN,eAAe,iBAAiBA,QAAO,YAAY;AAAA,UACrD,EAAE,MAAM,MAAM;AAAA,UAEd,CAAC;AAAA,QACH;AAAA,MACF;AAGA,UAAIA,kBAAiB,UAAU;AAC7B,eAAO,EAAE,KAAKA,OAAM,WAAW,GAAGA,OAAM,UAAiB;AAAA,MAC3D;AAGA,YAAM,UAAmC,CAAC;AAE1C,UAAI,gBAAgBA,OAAM,OAAO;AAC/B,gBAAQ,OAAO,IAAIA,OAAM;AAAA,MAC3B;AAEA,aAAO,EAAE;AAAA,QACP,MAAc,kBAAkB,gCAAgC,OAAO;AAAA,QACvE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAUO,SAAS,gBAAgB,GAAgB;AAC9C,SAAO,EAAE;AAAA,IACP,MAAc,aAAa,SAAS,EAAE,IAAI,MAAM,IAAI,EAAE,IAAI,IAAI,YAAY;AAAA,IAC1E;AAAA,EACF;AACF;;;AC7OA,SAAS,aACP,GACA,QACA,QACA,QACe;AAEf,QAAM,aAAa,EAAE,IAAI,OAAO,MAAM;AACtC,MAAI,YAAY;AACd,QAAI,UAAU,WAAW,WAAW,GAAG,MAAM,GAAG,GAAG;AACjD,aAAO,WAAW,MAAM,OAAO,SAAS,CAAC;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAGA,MAAI,QAAQ;AACV,UAAM,eAAe,EAAE,IAAI,OAAO,QAAQ;AAC1C,QAAI,cAAc;AAChB,YAAM,UAAU,aAAa,MAAM,GAAG,EAAE,IAAI,CAACC,OAAMA,GAAE,KAAK,CAAC;AAC3D,iBAAWA,MAAK,SAAS;AACvB,cAAM,CAAC,KAAK,GAAG,UAAU,IAAIA,GAAE,MAAM,GAAG;AACxC,YAAI,QAAQ,QAAQ;AAClB,iBAAO,WAAW,KAAK,GAAG;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAuBO,SAAS,KAAK,SAAgC;AACnD,QAAM;AAAA,IACJ;AAAA,IACA,SAAS;AAAA,IACT,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,UAAU;AAAA,EACZ,IAAI;AAEJ,SAAO,OAAO,GAAgB,SAAmB;AAE/C,QAAI,OAAO,CAAC,GAAG;AACb,aAAO,KAAK;AAAA,IACd;AAGA,UAAM,QAAQ,aAAa,GAAG,QAAQ,QAAQ,MAAM;AAEpD,QAAI,CAAC,OAAO;AACV,YAAM,IAAIC,mBAAkB,OAAO;AAAA,IACrC;AAGA,UAAM,UAAU,MAAM,OAAO,KAAK;AAElC,QAAI,CAAC,SAAS;AACZ,YAAM,IAAIA,mBAAkB,0BAA0B;AAAA,IACxD;AAGA,UAAM,OAAoB;AAAA,MACxB,IAAI,QAAQ;AAAA,MACZ,OAAO,QAAQ;AAAA,MACf,UAAU,QAAQ;AAAA,MAClB,MAAM,QAAQ;AAAA,MACd,aAAa,QAAQ,eAAe,CAAC;AAAA,IACvC;AAEA,MAAE,IAAI,QAAQ,IAAI;AAElB,UAAM,KAAK;AAAA,EACb;AACF;AAkBO,SAAS,aAAa,SAAiD;AAC5E,QAAM,EAAE,QAAQ,SAAS,iBAAiB,SAAS,UAAU,QAAQ,KAAK,IAAI;AAE9E,SAAO,OAAO,GAAgB,SAAmB;AAE/C,QAAI,OAAO,CAAC,GAAG;AACb,aAAO,KAAK;AAAA,IACd;AAGA,UAAM,QAAQ,aAAa,GAAG,QAAQ,QAAQ,MAAM;AAEpD,QAAI,OAAO;AACT,UAAI;AACF,cAAM,UAAU,MAAM,OAAO,KAAK;AAElC,YAAI,SAAS;AAEX,gBAAM,OAAoB;AAAA,YACxB,IAAI,QAAQ;AAAA,YACZ,OAAO,QAAQ;AAAA,YACf,UAAU,QAAQ;AAAA,YAClB,MAAM,QAAQ;AAAA,YACd,aAAa,QAAQ,eAAe,CAAC;AAAA,UACvC;AAEA,YAAE,IAAI,QAAQ,IAAI;AAAA,QACpB;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,KAAK;AAAA,EACb;AACF;AAkBO,SAAS,qBACd,aACA;AACA,SAAO;AAAA,IACL,MAAM,CAAC,YACL,KAAK,EAAE,GAAG,aAAa,GAAG,QAAQ,CAAC;AAAA,IACrC,cAAc,CAAC,YACb,aAAa,EAAE,GAAG,aAAa,GAAG,QAAQ,CAAC;AAAA,EAC/C;AACF;;;ACtNA,IAAM,oBAAgC;AAAA,EACpC,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,SAAS,CAAC,OAAO,QAAQ,OAAO,SAAS,UAAU,SAAS;AAAA,EAC5D,gBAAgB,CAAC,gBAAgB,iBAAiB,gBAAgB,cAAc;AAAA,EAChF,gBAAgB,CAAC,gBAAgB,eAAe;AAAA,EAChD,QAAQ;AAAA;AACV;AAKA,SAAS,gBAAgB,QAAgB,QAA6B;AACpE,MAAI,OAAO,WAAW,IAAK,QAAO;AAElC,MAAI,OAAO,OAAO,WAAW,UAAU;AACrC,WAAO,WAAW,OAAO;AAAA,EAC3B;AAEA,MAAI,MAAM,QAAQ,OAAO,MAAM,GAAG;AAChC,WAAO,OAAO,OAAO,SAAS,MAAM;AAAA,EACtC;AAEA,MAAI,OAAO,OAAO,WAAW,YAAY;AACvC,WAAO,OAAO,OAAO,MAAM;AAAA,EAC7B;AAEA,SAAO;AACT;AAaO,SAASC,MAAK,QAA4F;AAC/G,QAAMC,cAAa,EAAE,GAAG,mBAAmB,GAAG,OAAO;AAErD,SAAO,OAAO,GAAgB,SAA6C;AACzE,UAAM,SAAS,EAAE,IAAI,OAAO,QAAQ,KAAK;AAGzC,QAAI,EAAE,IAAI,WAAW,WAAW;AAC9B,YAAM,WAAW,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;AAEnD,UAAI,gBAAgB,QAAQA,WAAU,GAAG;AACvC,iBAAS,QAAQ,IAAI,+BAA+B,UAAU,GAAG;AAAA,MACnE;AAEA,UAAIA,YAAW,aAAa;AAC1B,iBAAS,QAAQ,IAAI,oCAAoC,MAAM;AAAA,MACjE;AAEA,UAAIA,YAAW,SAAS;AACtB,iBAAS,QAAQ;AAAA,UACf;AAAA,UACAA,YAAW,QAAQ,KAAK,IAAI;AAAA,QAC9B;AAAA,MACF;AAEA,UAAIA,YAAW,gBAAgB;AAC7B,iBAAS,QAAQ;AAAA,UACf;AAAA,UACAA,YAAW,eAAe,KAAK,IAAI;AAAA,QACrC;AAAA,MACF;AAEA,UAAIA,YAAW,QAAQ;AACrB,iBAAS,QAAQ,IAAI,0BAA0B,OAAOA,YAAW,MAAM,CAAC;AAAA,MAC1E;AAEA,aAAO;AAAA,IACT;AAGA,UAAM,KAAK;AAGX,QAAI,gBAAgB,QAAQA,WAAU,GAAG;AACvC,QAAE,OAAO,+BAA+B,UAAU,GAAG;AAAA,IACvD;AAEA,QAAIA,YAAW,aAAa;AAC1B,QAAE,OAAO,oCAAoC,MAAM;AAAA,IACrD;AAEA,QAAIA,YAAW,gBAAgB;AAC7B,QAAE,OAAO,iCAAiCA,YAAW,eAAe,KAAK,IAAI,CAAC;AAAA,IAChF;AAAA,EACF;AACF;;;ACrEA,SAAS,sBAA8B;AACrC,QAAM,QAAQ,IAAI,WAAW,EAAE;AAC/B,SAAO,gBAAgB,KAAK;AAC5B,SAAO,MAAM,KAAK,KAAK,EACpB,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AACZ;AAKA,SAAS,UAAU,GAAgB,MAAkC;AACnE,QAAM,eAAe,EAAE,IAAI,OAAO,QAAQ;AAC1C,MAAI,CAAC,aAAc,QAAO;AAE1B,QAAM,UAAU,aAAa,MAAM,GAAG,EAAE,IAAI,CAACC,OAAMA,GAAE,KAAK,CAAC;AAC3D,aAAW,UAAU,SAAS;AAC5B,UAAM,CAAC,KAAK,GAAG,UAAU,IAAI,OAAO,MAAM,GAAG;AAC7C,QAAI,QAAQ,MAAM;AAChB,aAAO,WAAW,KAAK,GAAG;AAAA,IAC5B;AAAA,EACF;AACA,SAAO;AACT;AAuBO,SAAS,KAAK,UAAuB,CAAC,GAAG;AAC9C,QAAM;AAAA,IACJ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU,CAAC,QAAQ,OAAO,SAAS,QAAQ;AAAA,IAC3C,eAAe,CAAC;AAAA,IAChB;AAAA,IACA,gBAAgB;AAAA,IAChB,SAAS,CAAC;AAAA,EACZ,IAAI;AAEJ,QAAM,gBAAgB;AAAA,IACpB,QAAQ,OAAO,UAAU;AAAA,IACzB,UAAU,OAAO,YAAY;AAAA,IAC7B,UAAU,OAAO,YAAa;AAAA,IAC9B,MAAM,OAAO,QAAQ;AAAA,IACrB,QAAQ,OAAO,UAAU;AAAA;AAAA,EAC3B;AAEA,SAAO,OAAO,GAAgB,SAAmB;AAE/C,QAAI,OAAO,CAAC,GAAG;AACb,aAAO,KAAK;AAAA,IACd;AAGA,UAAM,OAAO,EAAE,IAAI;AACnB,QAAI,aAAa,KAAK,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,GAAG;AAChD,aAAO,KAAK;AAAA,IACd;AAGA,QAAI,QAAQ,UAAU,GAAG,UAAU;AAEnC,QAAI,CAAC,OAAO;AAEV,cAAQ,cAAc;AAGtB,YAAM,cAAc;AAAA,QAClB,GAAG,UAAU,IAAI,KAAK;AAAA,QACtB,QAAQ,cAAc,IAAI;AAAA,QAC1B,WAAW,cAAc,MAAM;AAAA,QAC/B,cAAc,YAAY,YAAY,cAAc,QAAQ;AAAA,QAC5D,cAAc,UAAU;AAAA,QACxB,cAAc,YAAY;AAAA,MAC5B,EACG,OAAO,OAAO,EACd,KAAK,IAAI;AAEZ,QAAE,OAAO,cAAc,WAAW;AAAA,IACpC;AAGA,IAAC,EAA0C,IAAI,aAAsB,KAAc;AAGnF,QAAI,QAAQ,SAAS,EAAE,IAAI,MAAM,GAAG;AAClC,YAAM,cAAc,EAAE,IAAI,OAAO,UAAU;AAC3C,YAAM,YAAY,MAAM,aAAa,CAAC;AAEtC,YAAM,gBAAgB,eAAe;AAErC,UAAI,CAAC,iBAAiB,kBAAkB,OAAO;AAC7C,cAAM,IAAIC,gBAAe,oBAAoB;AAAA,MAC/C;AAAA,IACF;AAEA,UAAM,KAAK;AAAA,EACb;AACF;AAKA,eAAe,aAAa,GAA6C;AACvE,MAAI;AACF,UAAM,cAAc,EAAE,IAAI,OAAO,cAAc,KAAK;AAEpD,QAAI,YAAY,SAAS,kBAAkB,GAAG;AAC5C,YAAM,OAAQ,MAAM,EAAE,IAAI,KAAK;AAC/B,aAAQ,KAAK,OAAO,KAAK,KAAK,WAAW,KAAK,KAAK,YAAY;AAAA,IACjE;AAEA,QAAI,YAAY,SAAS,mCAAmC,GAAG;AAC7D,YAAM,OAAO,MAAM,EAAE,IAAI,UAAU;AACnC,aAAO,KAAK,OAAO;AAAA,IACrB;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAMO,SAAS,mBAAmB,UAAuB,CAAC,GAAG;AAC5D,SAAO,KAAK;AAAA,IACV,GAAG;AAAA,IACH,QAAQ;AAAA,MACN,GAAG,QAAQ;AAAA,MACX,UAAU;AAAA;AAAA,IACZ;AAAA,EACF,CAAC;AACH;;;ACrKO,IAAM,yBAAN,MAAyD;AAAA,EACtD,QAAQ,oBAAI,IAAgD;AAAA,EAEpE,MAAM,IAAI,KAA8B;AACtC,UAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAChC,QAAI,CAAC,SAAS,MAAM,UAAU,KAAK,IAAI,GAAG;AACxC,aAAO;AAAA,IACT;AACA,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,MAAM,UAAU,KAAa,UAAmC;AAC9D,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAEhC,QAAI,CAAC,SAAS,MAAM,UAAU,KAAK;AAEjC,WAAK,MAAM,IAAI,KAAK,EAAE,OAAO,GAAG,SAAS,MAAM,SAAS,CAAC;AACzD,aAAO;AAAA,IACT;AAGA,UAAM;AACN,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,MAAM,MAAM,KAA4B;AACtC,SAAK,MAAM,OAAO,GAAG;AAAA,EACvB;AAAA;AAAA,EAGA,UAAgB;AACd,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,CAAC,KAAK,KAAK,KAAK,KAAK,OAAO;AACrC,UAAI,MAAM,UAAU,KAAK;AACvB,aAAK,MAAM,OAAO,GAAG;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACF;AAyBA,IAAI,iBAA0C;AAK9C,SAAS,oBAAsC;AAC7C,MAAI,CAAC,gBAAgB;AACnB,qBAAiB,IAAI,uBAAuB;AAAA,EAC9C;AACA,SAAO;AACT;AA2BO,SAAS,UAAU,UAA4B,CAAC,GAAG;AACxD,QAAM;AAAA,IACJ,WAAW,KAAK;AAAA;AAAA,IAChB,MAAM;AAAA,IACN,eAAe;AAAA,IACf;AAAA,IACA,UAAU,kBAAkB;AAAA,IAC5B,UAAU;AAAA,IACV,UAAU;AAAA,IACV;AAAA,EACF,IAAI;AAEJ,SAAO,OAAO,GAAgB,SAAmB;AAE/C,QAAI,OAAO,CAAC,GAAG;AACb,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,MAAM,aAAa,aAAa,CAAC,CAAC;AACxC,UAAM,UAAU,MAAM,QAAQ,UAAU,KAAK,QAAQ;AAGrD,QAAI,SAAS;AACX,QAAE,OAAO,qBAAqB,OAAO,GAAG,CAAC;AACzC,QAAE,OAAO,yBAAyB,OAAO,KAAK,IAAI,GAAG,MAAM,OAAO,CAAC,CAAC;AACpE,QAAE,OAAO,qBAAqB,OAAO,KAAK,MAAM,KAAK,IAAI,IAAI,YAAY,GAAI,CAAC,CAAC;AAAA,IACjF;AAGA,QAAI,UAAU,KAAK;AACjB,UAAI,gBAAgB;AAClB,uBAAe,GAAG,GAAG;AAAA,MACvB;AAEA,YAAM,aAAa,KAAK,KAAK,WAAW,GAAI;AAC5C,QAAE,OAAO,eAAe,OAAO,UAAU,CAAC;AAE1C,YAAM,IAAI,eAAe,SAAS,UAAU;AAAA,IAC9C;AAEA,UAAM,KAAK;AAAA,EACb;AACF;AAKA,SAAS,oBAAoB,GAAwB;AACnD,SACE,EAAE,IAAI,OAAO,iBAAiB,GAAG,MAAM,GAAG,EAAE,CAAC,GAAG,KAAK,KACrD,EAAE,IAAI,OAAO,WAAW,KACxB,EAAE,IAAI,OAAO,kBAAkB,KAC/B;AAEJ;AAkBO,SAAS,kBAAkB,UAA4B,CAAC,GAAG;AAChE,QAAM,UAAU,QAAQ,WAAW,kBAAkB;AAErD,SAAO;AAAA,IACL,YAAY,UAAU,EAAE,GAAG,SAAS,QAAQ,CAAC;AAAA,IAC7C;AAAA,IACA,OAAO,CAAC,QAAgB,QAAQ,MAAM,aAAa,GAAG,EAAE;AAAA,IACxD,KAAK,CAAC,QAAgB,QAAQ,IAAI,aAAa,GAAG,EAAE;AAAA,EACtD;AACF;;;ACpLA,SAAS,YAAY,OAAuB;AAC1C,MAAI,QAAQ,KAAM,QAAO,GAAG,KAAK;AACjC,MAAI,QAAQ,OAAO,KAAM,QAAO,IAAI,QAAQ,MAAM,QAAQ,CAAC,CAAC;AAC5D,SAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,CAAC,CAAC;AAC9C;AAaO,SAAS,cAAc,UAAgC,CAAC,GAAG;AAChE,QAAM;AAAA,IACJ;AAAA,IACA,SAAS;AAAA,IACT,cAAc;AAAA,IACd,gBAAgB;AAAA,EAClB,IAAI;AAEJ,SAAO,OAAO,GAAgB,SAAmB;AAE/C,QAAI,OAAO,CAAC,GAAG;AACb,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,QAAQ,KAAK,IAAI;AACvB,UAAM,SAAS,EAAE,IAAI,QAAQ;AAC7B,UAAM,YAAY,EAAE,IAAI,WAAW;AAGnC,UAAM,SAAS,EAAE,IAAI;AACrB,UAAM,OAAO,EAAE,IAAI;AACnB,UAAM,QAAQ,EAAE,IAAI,MAAM;AAC1B,UAAM,YAAY,EAAE,IAAI,OAAO,YAAY;AAC3C,UAAM,KAAK,EAAE,IAAI,OAAO,iBAAiB,KAAK,EAAE,IAAI,OAAO,WAAW,KAAK;AAG3E,QAAI,WAAW,QAAQ;AACrB,cAAQ,MAAM,mBAAmB;AAAA,QAC/B;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,OAAO,KAAK,KAAK,EAAE,SAAS,IAAI,QAAQ;AAAA,QAC/C;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAGA,QAAI;AACJ,QAAI,eAAe,CAAC,QAAQ,OAAO,OAAO,EAAE,SAAS,MAAM,GAAG;AAC5D,UAAI;AACF,cAAM,cAAc,EAAE,IAAI,OAAO,cAAc,KAAK;AACpD,YAAI,YAAY,SAAS,kBAAkB,GAAG;AAC5C,gBAAM,OAAO,MAAM,EAAE,IAAI,KAAK;AAC9B,wBAAc,KAAK,SAAS,gBACxB,KAAK,UAAU,GAAG,aAAa,IAAI,QACnC;AAAA,QACN;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAGA,UAAM,KAAK;AAGX,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,UAAMC,UAAS,EAAE,IAAI;AAGrB,UAAM,gBAAgB,EAAE,IAAI,QAAQ,IAAI,gBAAgB;AACxD,UAAM,OAAO,gBAAgB,SAAS,eAAe,EAAE,IAAI;AAG3D,QAAI,WAAW,QAAQ;AACrB,YAAM,UAAmC;AAAA,QACvC;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAAA;AAAA,QACA,UAAU,GAAG,QAAQ;AAAA,QACrB,MAAM,YAAY,IAAI;AAAA,MACxB;AAEA,UAAI,aAAa;AACf,gBAAQ,aAAa,IAAI;AAAA,MAC3B;AAGA,UAAIA,WAAU,KAAK;AACjB,gBAAQ,MAAM,qBAAqB,OAAO;AAAA,MAC5C,WAAWA,WAAU,KAAK;AACxB,gBAAQ,KAAK,qBAAqB,OAAO;AAAA,MAC3C,OAAO;AACL,gBAAQ,KAAK,qBAAqB,OAAO;AAAA,MAC3C;AAAA,IACF,WAAW,WAAW,YAAY;AAEhC,YAAM,MAAM,GAAG,EAAE,UAAS,oBAAI,KAAK,GAAE,YAAY,CAAC,MAAM,MAAM,IAAI,IAAI,KAAKA,OAAM,IAAI,IAAI,SAAS,SAAS,KAAK,QAAQ;AACxH,cAAQ,IAAI,GAAG;AAAA,IACjB,OAAO;AAEL,YAAM,MAAM,GAAG,MAAM,IAAI,IAAI,IAAIA,OAAM,IAAI,QAAQ;AACnD,cAAQ,IAAI,GAAG;AAAA,IACjB;AAAA,EACF;AACF;;;ACXO,SAAS,cAAc,SAA+B;AAC3D,QAAM;AAAA,IACJ;AAAA,IACA,aAAa;AAAA,IACb,WAAW;AAAA,IACX;AAAA,IACA,UAAU;AAAA,IACV,cAAc;AAAA,IACd,gBAAgB,CAAC,MAAM,EAAE,IAAI,MAAM,GAAG;AAAA,IACtC,cAAc,CAAC,MAAM,EAAE,IAAI,QAAQ,GAAG,MAAM,EAAE,IAAI,MAAM,GAAG;AAAA,IAC3D;AAAA,IACA,kBAAkB;AAAA,IAClB;AAAA,EACF,IAAI;AAEJ,SAAO,OAAO,GAAgB,SAAmB;AAE/C,QAAI,YAAY,WAAW;AACzB,YAAM,WAAW,CAAC;AAClB,aAAO,KAAK;AAAA,IACd;AAGA,UAAM,KAAK;AAGX,QAAI,OAAO,CAAC,EAAG;AAGf,QAAI,eAAe,EAAE,IAAI,UAAU,IAAK;AAExC,UAAM,WAAW,CAAC;AAAA,EACpB;AAEA,iBAAe,WAAW,GAAgB;AACxC,UAAM,aAAa,cAAc,CAAC;AAClC,UAAM,WAAW,YAAY,CAAC;AAG9B,QAAI,CAAC,cAAc,CAAC,SAAU;AAE9B,UAAM,qBACJ,OAAO,eAAe,aAAa,WAAW,CAAC,IAAI;AAErD,UAAM,mBACJ,OAAO,aAAa,aAAa,SAAS,CAAC,IAAI;AAEjD,UAAM,WAAW,kBACb;AAAA,MACE,MAAM,EAAE,IAAI;AAAA,MACZ,QAAQ,EAAE,IAAI;AAAA,MACd,YAAY,EAAE,IAAI;AAAA,MAClB,WAAW,EAAE,IAAI,OAAO,YAAY;AAAA,IACtC,IACA;AAEJ,QAAI;AAEF,YAAM,eAQF;AAAA,QACF;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QACZ,UAAU;AAAA,MACZ;AAEA,YAAM,iBAAiB,oBAAoB,CAAC;AAC5C,UAAI,mBAAmB,QAAW;AAChC,qBAAa,iBAAiB;AAAA,MAChC;AAEA,UAAI,aAAa,QAAW;AAC1B,qBAAa,WAAW;AAAA,MAC1B;AAEA,YAAM,iBAAiB,oBAAoB,CAAC;AAC5C,UAAI,mBAAmB,QAAW;AAChC,qBAAa,iBAAiB;AAAA,MAChC;AAEA,YAAM,aAAa,WAAW,YAAY;AAAA,IAC5C,SAASC,QAAO;AAEd,YAAM,SAAS,EAAE,IAAI,QAAQ;AAC7B,UAAI,QAAQ;AACV,eAAO,MAAM,yBAAyB;AAAA,UACpC,OAAOA,kBAAiB,QAAQA,OAAM,UAAU,OAAOA,MAAK;AAAA,UAC5D;AAAA,UACA,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,oBAAoB,aAAmC;AACrE,SAAO,CAAC,cAA8C;AACpD,WAAO,cAAc,EAAE,GAAG,aAAa,GAAG,UAAU,CAAC;AAAA,EACvD;AACF;;;ACtMO,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAI5C,YACkB,YACA,OACA,cACA,oBAA4B,GAC5C;AACA;AAAA,MACE,uBAAuB,UAAU,MAAM,YAAY,IAAI,SAAS,WAAW;AAAA,IAC7E;AAPgB;AACA;AACA;AACA;AAKhB,SAAK,OAAO;AAAA,EACd;AAAA,EAbgB,aAAa;AAAA,EACb,OAAO;AAazB;AAwGO,SAAS,iBAAiB,SAAkC;AACjE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,gBAAgB,CAAC,MAAM,EAAE,IAAI,MAAM,GAAG;AAAA,IACtC,iBAAiB;AAAA,IACjB;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,EACF,IAAI;AAEJ,SAAO,OAAO,GAAgB,SAAmB;AAE/C,QAAI,OAAO,CAAC,GAAG;AACb,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,aAAa,cAAc,CAAC;AAGlC,QAAI,CAAC,YAAY;AACf,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,qBACJ,OAAO,eAAe,aAAa,WAAW,CAAC,IAAI;AAErD,UAAM,mBACJ,OAAO,aAAa,aAAa,SAAS,CAAC,IAAI;AAEjD,QAAI;AACF,YAAM,SAAS,MAAM,aAAa;AAAA,QAChC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAGA,UAAI,gBAAgB;AAClB,UAAE,OAAO,iBAAiB,OAAO,OAAO,SAAS,WAAW,CAAC;AAC7D,UAAE,OAAO,qBAAqB,OAAO,OAAO,aAAa,WAAW,CAAC;AACrE,UAAE,OAAO,gBAAgB,OAAO,OAAO,YAAY,CAAC;AAEpD,YAAI,OAAO,iBAAiB,MAAM;AAChC,YAAE,OAAO,mBAAmB,OAAO,OAAO,YAAY,CAAC;AAAA,QACzD;AAAA,MACF;AAGA,UACE,OAAO,iBAAiB,QACxB,OAAO,gBAAgB,MACvB,gBACA;AACA,uBAAe,GAAG,QAAQ,kBAAkB;AAAA,MAC9C;AAGA,UAAI,CAAC,OAAO,WAAW,CAAC,WAAW;AAEjC,YAAI,iBAAiB;AACnB,gBAAM,WAAW,gBAAgB,GAAG,QAAQ,kBAAkB;AAC9D,cAAI,SAAU,QAAO;AAAA,QACvB;AAGA,cAAM,IAAI;AAAA,UACR;AAAA,UACA,OAAO;AAAA,UACP,OAAO;AAAA,UACP;AAAA,QACF;AAAA,MACF;AAGA,YAAM,KAAK;AAAA,IACb,SAASC,QAAO;AAEd,UAAIA,kBAAiB,oBAAoB;AACvC,cAAMA;AAAA,MACR;AAGA,YAAM,SAAS,EAAE,IAAI,QAAQ;AAC7B,UAAI,QAAQ;AACV,eAAO,MAAM,sBAAsB;AAAA,UACjC,OAAOA,kBAAiB,QAAQA,OAAM,UAAU,OAAOA,MAAK;AAAA,UAC5D;AAAA,UACA,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAGA,YAAM,KAAK;AAAA,IACb;AAAA,EACF;AACF;AAKO,SAAS,uBACd,aACA;AACA,SAAO,CAAC,eAAsD;AAC5D,WAAO,iBAAiB,EAAE,GAAG,aAAa,WAAW,CAAC;AAAA,EACxD;AACF;AAMO,SAAS,sBACd,SAMA;AACA,QAAM,EAAE,SAAS,IAAI;AAErB,SAAO,OAAO,GAAgB,SAAmB;AAC/C,UAAM,cAAc,QAAQ,kBAAkB,CAAC,QAAQ,IAAI,IAAI,MAAM,GAAG,KAAK,CAAC;AAE9E,QAAI,CAAC,cAAc,QAAQ,OAAO,CAAC,GAAG;AACpC,aAAO,KAAK;AAAA,IACd;AAGA,eAAW,WAAW,UAAU;AAC9B,YAAM,mBACJ,OAAO,QAAQ,aAAa,aACxB,QAAQ,SAAS,CAAC,IAClB,QAAQ,YAAY;AAE1B,YAAM,SAAS,MAAM,QAAQ,aAAa;AAAA,QACxC;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,MACF;AAEA,UAAI,CAAC,OAAO,WAAW,CAAC,QAAQ,WAAW;AACzC,YAAI,QAAQ,iBAAiB;AAC3B,gBAAM,WAAW,QAAQ,gBAAgB,GAAG,QAAQ,QAAQ,UAAU;AACtE,cAAI,SAAU,QAAO;AAAA,QACvB;AAEA,cAAM,IAAI;AAAA,UACR,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,OAAO;AAAA,UACP;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,KAAK;AAAA,EACb;AACF;;;ACvTA;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAiCK;AAEP,SAAS,QAAAC,OAAM,gBAAgB,uBAAuB;AAuRtD;AAAA,EACe,aAAbC;AAAA,EACmB,mBAAnBC;AAAA,EACe,eAAfC;AAAA,EACkB,kBAAlBC;AAAA,OACK;AAnQP,SAAS,uBAAuB,QAA+C;AAC7E,QAAM,YAAY,gBAAgB,MAAM;AACxC,QAAM,SAAmC,CAAC;AAE1C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,SAAS,GAAG;AACpD,WAAO,GAAG,IAAI,CAAC,KAAK;AAAA,EACtB;AAEA,SAAO;AACT;AAqBO,SAAS,aAA6B,QAAW,UAA2B,CAAC,GAAG;AACrF,SAAO,OAAO,GAAgB,SAAkC;AAC9D,QAAI;AAEJ,QAAI;AACF,aAAO,MAAM,EAAE,IAAI,KAAK;AAAA,IAC1B,QAAQ;AACN,YAAM,IAAI,gBAAgB,mBAAmB;AAAA,IAC/C;AAEA,UAAM,SAAS,OAAO,IAAI;AAE1B,QAAI,kBAAkBJ,MAAK,QAAQ;AACjC,YAAM,IAAI;AAAA,QACR,QAAQ,iBAAiB;AAAA,QACzB,EAAE,QAAQ,uBAAuB,MAAM,EAAE;AAAA,MAC3C;AAAA,IACF;AAGA,IAAC,EAAkD,IAAI,iBAA0B,MAAe;AAEhG,UAAM,KAAK;AAAA,EACb;AACF;AAkBO,SAAS,cAA8B,QAAW,UAA2B,CAAC,GAAG;AACtF,SAAO,OAAO,GAAgB,SAAkC;AAC9D,UAAM,QAAQ,EAAE,IAAI,MAAM;AAC1B,UAAM,SAAS,OAAO,KAAK;AAE3B,QAAI,kBAAkBA,MAAK,QAAQ;AACjC,YAAM,IAAI;AAAA,QACR,QAAQ,iBAAiB;AAAA,QACzB,EAAE,QAAQ,uBAAuB,MAAM,EAAE;AAAA,MAC3C;AAAA,IACF;AAEA,IAAC,EAAmD,IAAI,kBAA2B,MAAe;AAElG,UAAM,KAAK;AAAA,EACb;AACF;AAgBO,SAAS,eAA+B,QAAW,UAA2B,CAAC,GAAG;AACvF,SAAO,OAAO,GAAgB,SAAkC;AAC9D,UAAM,SAAS,EAAE,IAAI,MAAM;AAC3B,UAAM,SAAS,OAAO,MAAM;AAE5B,QAAI,kBAAkBA,MAAK,QAAQ;AACjC,YAAM,IAAI;AAAA,QACR,QAAQ,iBAAiB;AAAA,QACzB,EAAE,QAAQ,uBAAuB,MAAM,EAAE;AAAA,MAC3C;AAAA,IACF;AAEA,IAAC,EAAoD,IAAI,mBAA4B,MAAe;AAEpG,UAAM,KAAK;AAAA,EACb;AACF;AAcO,SAAS,gBAAgC,QAAW,UAA2B,CAAC,GAAG;AACxF,SAAO,OAAO,GAAgB,SAAkC;AAE9D,UAAM,UAAkC,CAAC;AACzC,MAAE,IAAI,IAAI,QAAQ,QAAQ,CAAC,OAAO,QAAQ;AACxC,cAAQ,IAAI,YAAY,CAAC,IAAI;AAAA,IAC/B,CAAC;AAED,UAAM,SAAS,OAAO,OAAO;AAE7B,QAAI,kBAAkBA,MAAK,QAAQ;AACjC,YAAM,IAAI;AAAA,QACR,QAAQ,iBAAiB;AAAA,QACzB,EAAE,QAAQ,uBAAuB,MAAM,EAAE;AAAA,MAC3C;AAAA,IACF;AAEA,IAAC,EAAqD,IAAI,oBAA6B,MAAe;AAEtG,UAAM,KAAK;AAAA,EACb;AACF;AAqBO,SAAS,SAKd,SAKC;AACD,SAAO,OAAO,GAAgB,SAAkC;AAE9D,QAAI,QAAQ,QAAQ;AAClB,YAAM,SAAS,EAAE,IAAI,MAAM;AAC3B,YAAM,SAAS,QAAQ,OAAO,MAAM;AACpC,UAAI,kBAAkBA,MAAK,QAAQ;AACjC,cAAM,IAAI,gBAAgB,4BAA4B;AAAA,UACpD,QAAQ,uBAAuB,MAAM;AAAA,QACvC,CAAC;AAAA,MACH;AACA,MAAC,EAAiD,IAAI,mBAA4B,MAAe;AAAA,IACnG;AAGA,QAAI,QAAQ,OAAO;AACjB,YAAM,QAAQ,EAAE,IAAI,MAAM;AAC1B,YAAM,SAAS,QAAQ,MAAM,KAAK;AAClC,UAAI,kBAAkBA,MAAK,QAAQ;AACjC,cAAM,IAAI,gBAAgB,4BAA4B;AAAA,UACpD,QAAQ,uBAAuB,MAAM;AAAA,QACvC,CAAC;AAAA,MACH;AACA,MAAC,EAAgD,IAAI,kBAA2B,MAAe;AAAA,IACjG;AAGA,QAAI,QAAQ,SAAS;AACnB,YAAM,UAAkC,CAAC;AACzC,QAAE,IAAI,IAAI,QAAQ,QAAQ,CAAC,OAAO,QAAQ;AACxC,gBAAQ,IAAI,YAAY,CAAC,IAAI;AAAA,MAC/B,CAAC;AACD,YAAM,SAAS,QAAQ,QAAQ,OAAO;AACtC,UAAI,kBAAkBA,MAAK,QAAQ;AACjC,cAAM,IAAI,gBAAgB,mBAAmB;AAAA,UAC3C,QAAQ,uBAAuB,MAAM;AAAA,QACvC,CAAC;AAAA,MACH;AACA,MAAC,EAAkD,IAAI,oBAA6B,MAAe;AAAA,IACrG;AAGA,QAAI,QAAQ,MAAM;AAChB,UAAI;AACJ,UAAI;AACF,eAAO,MAAM,EAAE,IAAI,KAAK;AAAA,MAC1B,QAAQ;AACN,cAAM,IAAI,gBAAgB,mBAAmB;AAAA,MAC/C;AACA,YAAM,SAAS,QAAQ,KAAK,IAAI;AAChC,UAAI,kBAAkBA,MAAK,QAAQ;AACjC,cAAM,IAAI,gBAAgB,qBAAqB;AAAA,UAC7C,QAAQ,uBAAuB,MAAM;AAAA,QACvC,CAAC;AAAA,MACH;AACA,MAAC,EAA+C,IAAI,iBAA0B,MAAe;AAAA,IAC/F;AAEA,UAAM,KAAK;AAAA,EACb;AACF;;;ACjTA,IAAM,iBAA8C;AAAA,EAClD,cAAc;AAAA,EACd,UAAU;AAAA,EACV,WAAW;AAAA,EACX,YAAY;AACd;AAqBO,SAAS,gBACd,GACA,UAA6B,CAAC,GACZ;AAClB,QAAM,OAAO,EAAE,GAAG,gBAAgB,GAAG,QAAQ;AAE7C,QAAM,UAAU,EAAE,IAAI,MAAM,KAAK,SAAS;AAC1C,QAAM,WAAW,EAAE,IAAI,MAAM,KAAK,UAAU;AAE5C,MAAI,OAAO,UAAU,SAAS,SAAS,EAAE,IAAI;AAC7C,MAAI,QAAQ,WAAW,SAAS,UAAU,EAAE,IAAI,KAAK;AAGrD,MAAI,MAAM,IAAI,KAAK,OAAO,EAAG,QAAO;AACpC,MAAI,MAAM,KAAK,KAAK,QAAQ,EAAG,SAAQ,KAAK;AAC5C,MAAI,QAAQ,KAAK,SAAU,SAAQ,KAAK;AAExC,QAAM,UAAU,OAAO,KAAK;AAE5B,SAAO,EAAE,MAAM,OAAO,OAAO;AAC/B;AAKO,SAAS,qBAAqB,QAIlB;AACjB,QAAM,EAAE,MAAM,OAAO,MAAM,IAAI;AAC/B,QAAM,aAAa,KAAK,KAAK,QAAQ,KAAK;AAE1C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,OAAO;AAAA,IAChB,SAAS,OAAO;AAAA,EAClB;AACF;AAaO,SAAS,SACd,MACA,QACsB;AACtB,SAAO;AAAA,IACL;AAAA,IACA,YAAY,qBAAqB,MAAM;AAAA,EACzC;AACF;AAgDO,SAAS,sBACd,GACA,UAA6B,CAAC,GACN;AACxB,QAAM,OAAO,EAAE,GAAG,gBAAgB,GAAG,QAAQ;AAE7C,QAAM,SAAS,EAAE,IAAI,MAAM,QAAQ,KAAK;AACxC,QAAM,WAAW,EAAE,IAAI,MAAM,KAAK,UAAU;AAC5C,QAAM,YAAY,EAAE,IAAI,MAAM,WAAW,MAAM,aAAa,aAAa;AAEzE,MAAI,QAAQ,WAAW,SAAS,UAAU,EAAE,IAAI,KAAK;AACrD,MAAI,MAAM,KAAK,KAAK,QAAQ,EAAG,SAAQ,KAAK;AAC5C,MAAI,QAAQ,KAAK,SAAU,SAAQ,KAAK;AAExC,SAAO,EAAE,QAAQ,OAAO,UAAU;AACpC;AAYO,SAAS,eACd,MACA,QAC4B;AAC5B,QAAM,EAAE,QAAQ,MAAM,IAAI;AAC1B,QAAM,UAAU,KAAK,SAAS;AAG9B,QAAM,QAAQ,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;AAE/C,QAAM,WAAW,MAAM,MAAM,SAAS,CAAC;AACvC,QAAM,YAAY,MAAM,CAAC;AAEzB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,MACV;AAAA,MACA,YAAY,WAAW,WAAW,SAAS,KAAK;AAAA,MAChD,YAAY,UAAU,YAAY,UAAU,KAAK;AAAA,MACjD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,qBACd,GACA,MACM;AACN,IAAE,OAAO,iBAAiB,OAAO,KAAK,KAAK,CAAC;AAC5C,IAAE,OAAO,iBAAiB,OAAO,KAAK,UAAU,CAAC;AACjD,IAAE,OAAO,UAAU,OAAO,KAAK,IAAI,CAAC;AACpC,IAAE,OAAO,cAAc,OAAO,KAAK,KAAK,CAAC;AACzC,IAAE,OAAO,cAAc,OAAO,KAAK,OAAO,CAAC;AAC3C,IAAE,OAAO,cAAc,OAAO,KAAK,OAAO,CAAC;AAC7C;;;ACxOO,SAAS,KAAQ,GAAgB,MAASK,UAAS,KAAe;AACvE,SAAO,EAAE,KAAK,QAAQ,IAAI,GAAGA,OAAa;AAC5C;AAaO,SAAS,aACd,GACA,MACA,MACAA,UAAS,KACC;AACV,SAAO,EAAE,KAAK,QAAQ,MAAM,IAAI,GAAGA,OAAa;AAClD;AAgBO,SAAS,UACd,GACA,MACA,SACAA,UAAS,KACT,SACU;AACV,SAAO,EAAE,KAAK,MAAM,MAAM,SAAS,OAAO,GAAGA,OAAa;AAC5D;AAKO,SAAS,QAAW,GAAgB,MAAS,UAA6B;AAC/E,MAAI,UAAU;AACZ,MAAE,OAAO,YAAY,QAAQ;AAAA,EAC/B;AACA,SAAO,EAAE,KAAK,QAAQ,IAAI,GAAG,GAAG;AAClC;AAKO,SAAS,UAAU,IAA2B;AACnD,SAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;AAC3C;AAKO,SAAS,SAAY,GAAgB,MAAoB;AAC9D,MAAI,MAAM;AACR,WAAO,EAAE,KAAK,QAAQ,IAAI,GAAG,GAAG;AAAA,EAClC;AACA,SAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;AAC3C;AAKO,SAAS,SAAS,GAAgBC,MAAaD,UAAsC,KAAe;AACzG,SAAO,EAAE,SAASC,MAAKD,OAAM;AAC/B;AAiBO,SAAS,OACd,IACA,UACA,UAGI,CAAC,GACK;AACV,QAAM,UAAU,IAAI,YAAY;AAEhC,QAAM,iBAAiB,IAAI,eAAe;AAAA,IACxC,MAAM,MAAM,YAAY;AACtB,YAAM,QAAQ,OAAO,UAAkB;AACrC,mBAAW,QAAQ,QAAQ,OAAO,KAAK,CAAC;AAAA,MAC1C;AAEA,UAAI;AACF,cAAM,SAAS,KAAK;AAAA,MACtB,UAAE;AACA,mBAAW,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,IAAI,SAAS,gBAAgB;AAAA,IAClC,SAAS;AAAA,MACP,gBAAgB,QAAQ,eAAe;AAAA,MACvC,iBAAiB;AAAA,MACjB,YAAY;AAAA,MACZ,GAAG,QAAQ;AAAA,IACb;AAAA,EACF,CAAC;AACH;AAgBO,SAAS,IACd,GACA,UAGU;AACV,SAAO,OAAO,GAAG,OAAO,UAAU;AAChC,UAAM,OAAO,OAAO,UAA0E;AAC5F,UAAI,UAAU;AAEd,UAAI,MAAM,IAAI;AACZ,mBAAW,OAAO,MAAM,EAAE;AAAA;AAAA,MAC5B;AAEA,UAAI,MAAM,OAAO;AACf,mBAAW,UAAU,MAAM,KAAK;AAAA;AAAA,MAClC;AAEA,UAAI,MAAM,OAAO;AACf,mBAAW,UAAU,MAAM,KAAK;AAAA;AAAA,MAClC;AAEA,YAAM,OAAO,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO,KAAK,UAAU,MAAM,IAAI;AACpF,iBAAW,SAAS,IAAI;AAAA;AAAA;AAExB,YAAM,MAAM,OAAO;AAAA,IACrB;AAEA,UAAM,SAAS,IAAI;AAAA,EACrB,CAAC;AACH;AAKO,SAAS,SACd,GACA,MACA,UACA,cAAc,4BACJ;AACV,IAAE,OAAO,uBAAuB,yBAAyB,QAAQ,GAAG;AACpE,IAAE,OAAO,gBAAgB,WAAW;AAEpC,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,EAAE,KAAK,IAAI;AAAA,EACpB;AAEA,SAAO,IAAI,SAAS,MAAM;AAAA,IACxB,SAAS,EAAE,IAAI;AAAA,EACjB,CAAC;AACH;;;AClNA,SAAS,QAAAE,aAAY;AA2CrB,IAAM,YAAY,KAAK,IAAI;AAK3B,eAAe,cAAc,IAAmE;AAC9F,QAAM,QAAQ,KAAK,IAAI;AAEvB,MAAI;AACF,QAAI,GAAG,MAAM;AACX,YAAM,GAAG,KAAK;AAAA,IAChB;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,KAAK,IAAI,IAAI;AAAA,IACxB;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,eAAe,QAAQ,IAAI,UAAU;AAAA,MAC9C,SAAS,KAAK,IAAI,IAAI;AAAA,IACxB;AAAA,EACF;AACF;AAKA,SAAS,gBAAgB,QAAyD;AAChF,QAAM,WAAW,OAAO,OAAO,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM;AAE1D,MAAI,SAAS,KAAK,CAAC,MAAM,MAAM,WAAW,GAAG;AAC3C,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,KAAK,CAAC,MAAM,MAAM,UAAU,GAAG;AAC1C,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AA0BO,SAAS,mBAAmB,UAA8B,CAAC,GAAY;AAC5E,QAAM,SAAS,IAAIA,MAA4C;AAC/D,QAAM,EAAE,SAAS,CAAC,GAAG,WAAW,KAAK,IAAI;AAMzC,SAAO,IAAI,KAAK,OAAO,MAAM;AAC3B,UAAM,KAAK,EAAE,IAAI,IAAI;AACrB,UAAM,UAA6C,CAAC;AAGpD,YAAQ,UAAU,IAAI,MAAM,cAAc,EAAE;AAG5C,UAAM,qBAAqB,MAAM,QAAQ;AAAA,MACvC,OAAO,QAAQ,MAAM,EAAE,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;AAClD,YAAI;AACF,gBAAM,SAAS,MAAM,MAAM;AAC3B,iBAAO,CAAC,MAAM,MAAM;AAAA,QACtB,SAAS,KAAK;AACZ,iBAAO;AAAA,YACL;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,SAAS,eAAe,QAAQ,IAAI,UAAU;AAAA,YAChD;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,eAAW,CAAC,MAAM,MAAM,KAAK,oBAAoB;AAC/C,cAAQ,IAAI,IAAI;AAAA,IAClB;AAEA,UAAM,gBAAgB,gBAAgB,OAAO;AAC7C,UAAM,WAA2B;AAAA,MAC/B,QAAQ;AAAA,MACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,QAAQ,KAAK,OAAO,KAAK,IAAI,IAAI,aAAa,GAAI;AAAA,MAClD,QAAQ,WAAW,UAAU,CAAC;AAAA,IAChC;AAEA,UAAM,aAAa,kBAAkB,YAAY,MAAM,kBAAkB,aAAa,MAAM;AAE5F,WAAO,EAAE,KAAK,UAAU,UAAiB;AAAA,EAC3C,CAAC;AAMD,SAAO,IAAI,SAAS,CAAC,MAAM;AACzB,WAAO,EAAE,KAAK;AAAA,MACZ,QAAQ;AAAA,MACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,CAAC;AAAA,EACH,CAAC;AAMD,SAAO,IAAI,UAAU,OAAO,MAAM;AAChC,UAAM,KAAK,EAAE,IAAI,IAAI;AAGrB,UAAM,WAAW,MAAM,cAAc,EAAE;AAEvC,QAAI,SAAS,WAAW,aAAa;AACnC,aAAO,EAAE;AAAA,QACP;AAAA,UACE,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,KAAK;AAAA,MACZ,QAAQ;AAAA,MACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,CAAC;AAAA,EACH,CAAC;AAMD,SAAO,IAAI,YAAY,CAAC,MAAM;AAC5B,WAAO,EAAE,KAAK;AAAA,MACZ,QAAQ;AAAA,MACR,QAAQ,KAAK,OAAO,KAAK,IAAI,IAAI,aAAa,GAAI;AAAA,MAClD,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AACT;AAUA,eAAsB,cAAc,GAAkE;AACpG,SAAO,EAAE,KAAK;AAAA,IACZ,QAAQ;AAAA,IACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,QAAQ,KAAK,OAAO,KAAK,IAAI,IAAI,aAAa,GAAI;AAAA,EACpD,CAAC;AACH;","names":["Hono","createLogger","createLogger","Hono","error","requestLogger","error","UnauthorizedError","ForbiddenError","error","c","UnauthorizedError","cors","corsConfig","c","ForbiddenError","status","error","error","type","uuidParam","paginationQuery","searchQuery","dateRangeQuery","status","url","Hono"]}
|