@spfn/core 0.2.0-beta.5 → 0.2.0-beta.8
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/README.md +260 -1175
- package/dist/{boss-BO8ty33K.d.ts → boss-DI1r4kTS.d.ts} +24 -7
- package/dist/codegen/index.d.ts +47 -2
- package/dist/codegen/index.js +143 -5
- package/dist/codegen/index.js.map +1 -1
- package/dist/db/index.d.ts +13 -0
- package/dist/db/index.js +40 -6
- package/dist/db/index.js.map +1 -1
- package/dist/job/index.d.ts +23 -8
- package/dist/job/index.js +43 -3
- package/dist/job/index.js.map +1 -1
- package/dist/nextjs/index.d.ts +2 -2
- package/dist/nextjs/index.js +35 -3
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/server.d.ts +61 -14
- package/dist/nextjs/server.js +98 -32
- package/dist/nextjs/server.js.map +1 -1
- package/dist/route/index.d.ts +136 -2
- package/dist/route/index.js +209 -11
- package/dist/route/index.js.map +1 -1
- package/dist/server/index.d.ts +72 -1
- package/dist/server/index.js +41 -0
- package/dist/server/index.js.map +1 -1
- package/dist/{types-D_N_U-Py.d.ts → types-BOPTApC2.d.ts} +15 -0
- package/docs/cache.md +133 -0
- package/docs/codegen.md +74 -0
- package/docs/database.md +346 -0
- package/docs/entity.md +539 -0
- package/docs/env.md +477 -0
- package/docs/errors.md +319 -0
- package/docs/event.md +116 -0
- package/docs/file-upload.md +717 -0
- package/docs/job.md +131 -0
- package/docs/logger.md +108 -0
- package/docs/middleware.md +337 -0
- package/docs/nextjs.md +241 -0
- package/docs/repository.md +496 -0
- package/docs/route.md +497 -0
- package/docs/server.md +307 -0
- package/package.json +1 -1
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/logger/formatters.ts","../../src/server/dotenv-loader.ts","../../src/event/sse/handler.ts","../../src/server/helpers.ts","../../src/server/logger.ts","../../src/server/create-server.ts","../../src/job/boss.ts","../../src/job/job-router.ts","../../src/job/register-jobs.ts","../../src/server/banner.ts","../../src/server/validation.ts","../../src/server/start-server.ts","../../src/server/config-builder.ts"],"names":["config","logger","existsSync","jobLogger","job","join","env","resolve","formatUnhandledRejection","cors"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Logger Formatters\n *\n * Log formatting utilities for console and JSON outputs with sensitive data masking.\n */\n\nimport type { LogLevel, LogMetadata } from './types';\n\n/**\n * 민감 정보로 간주되는 키 목록\n * 이 키들을 포함하는 필드는 자동으로 마스킹됨\n */\nconst SENSITIVE_KEYS = [\n 'password',\n 'passwd',\n 'pwd',\n 'secret',\n 'token',\n 'apikey',\n 'api_key',\n 'accesstoken',\n 'access_token',\n 'refreshtoken',\n 'refresh_token',\n 'authorization',\n 'auth',\n 'cookie',\n 'session',\n 'sessionid',\n 'session_id',\n 'privatekey',\n 'private_key',\n 'creditcard',\n 'credit_card',\n 'cardnumber',\n 'card_number',\n 'cvv',\n 'ssn',\n 'pin',\n];\n\n/**\n * 마스킹된 값\n */\nconst MASKED_VALUE = '***MASKED***';\n\n/**\n * 키가 민감 정보를 포함하는지 확인\n */\nfunction isSensitiveKey(key: string): boolean\n{\n const lowerKey = key.toLowerCase();\n return SENSITIVE_KEYS.some(sensitive => lowerKey.includes(sensitive));\n}\n\n/**\n * 민감 정보 마스킹\n * Context 객체에서 민감한 정보(비밀번호, 토큰 등)를 마스킹\n * Circular reference를 안전하게 처리\n *\n * @param data - 원본 데이터\n * @param seen - 순환 참조 감지용 WeakSet (내부 사용)\n * @returns 마스킹된 데이터\n */\nexport function maskSensitiveData(data: unknown, seen = new WeakSet<object>()): unknown\n{\n // null, undefined 처리\n if (data === null || data === undefined)\n {\n return data;\n }\n\n // 기본 타입은 그대로 반환\n if (typeof data !== 'object')\n {\n return data;\n }\n\n // Circular reference 감지\n if (seen.has(data as object))\n {\n return '[Circular]';\n }\n seen.add(data as object);\n\n // 배열 처리\n if (Array.isArray(data))\n {\n return data.map(item => maskSensitiveData(item, seen));\n }\n\n // 객체 처리\n const masked: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data))\n {\n if (isSensitiveKey(key))\n {\n // 민감 정보 키는 마스킹\n masked[key] = MASKED_VALUE;\n }\n else if (typeof value === 'object' && value !== null)\n {\n // 중첩된 객체는 재귀 처리 (seen 전달)\n masked[key] = maskSensitiveData(value, seen);\n }\n else\n {\n // 일반 값은 그대로 유지\n masked[key] = value;\n }\n }\n\n return masked;\n}\n\n/**\n * ANSI 컬러 코드\n */\nconst COLORS = {\n reset: '\\x1b[0m',\n bright: '\\x1b[1m',\n dim: '\\x1b[2m',\n\n // 로그 레벨 컬러\n debug: '\\x1b[36m', // cyan\n info: '\\x1b[32m', // green\n warn: '\\x1b[33m', // yellow\n error: '\\x1b[31m', // red\n fatal: '\\x1b[35m', // magenta\n\n // 추가 컬러\n gray: '\\x1b[90m',\n};\n\n/**\n * 로그 레벨을 컬러 문자열로 변환\n */\nexport function colorizeLevel(level: LogLevel): string\n{\n const color = COLORS[level];\n const levelStr = level.toUpperCase().padEnd(5);\n return `${color}${levelStr}${COLORS.reset}`;\n}\n\n/**\n * 타임스탬프 포맷 (ISO 8601)\n */\nexport function formatTimestamp(date: Date): string\n{\n return date.toISOString();\n}\n\n/**\n * 타임스탬프 포맷 (사람이 읽기 쉬운 형식)\n */\nexport function formatTimestampHuman(date: Date): string\n{\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n const seconds = String(date.getSeconds()).padStart(2, '0');\n const ms = String(date.getMilliseconds()).padStart(3, '0');\n\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${ms}`;\n}\n\n/**\n * 에러 객체를 문자열로 변환 (스택 트레이스 포함)\n */\nexport function formatError(error: Error): string\n{\n const lines: string[] = [];\n\n lines.push(`${error.name}: ${error.message}`);\n\n if (error.stack)\n {\n const stackLines = error.stack.split('\\n').slice(1);\n lines.push(...stackLines);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Context 객체를 문자열로 변환\n */\nexport function formatContext(context: Record<string, unknown>): string\n{\n try\n {\n return JSON.stringify(context, null, 2);\n }\n catch (error)\n {\n return '[Context serialization failed]';\n }\n}\n\n/**\n * 콘솔용 컬러 포맷\n */\nexport function formatConsole(metadata: LogMetadata, colorize = true): string\n{\n const parts: string[] = [];\n\n // [타임스탬프]\n const timestamp = formatTimestampHuman(metadata.timestamp);\n if (colorize)\n {\n parts.push(`${COLORS.gray}[${timestamp}]${COLORS.reset}`);\n }\n else\n {\n parts.push(`[${timestamp}]`);\n }\n\n // [pid=12345]\n const pid = process.pid;\n if (colorize)\n {\n parts.push(`${COLORS.dim}[pid=${pid}]${COLORS.reset}`);\n }\n else\n {\n parts.push(`[pid=${pid}]`);\n }\n\n // [module=value]\n if (metadata.module)\n {\n if (colorize)\n {\n parts.push(`${COLORS.dim}[module=${metadata.module}]${COLORS.reset}`);\n }\n else\n {\n parts.push(`[module=${metadata.module}]`);\n }\n }\n\n // Context를 각각 [key=value] 형태로 추가\n if (metadata.context && Object.keys(metadata.context).length > 0)\n {\n Object.entries(metadata.context).forEach(([key, value]) =>\n {\n let valueStr: string;\n if (typeof value === 'string')\n {\n valueStr = value;\n }\n else if (typeof value === 'object' && value !== null)\n {\n try\n {\n valueStr = JSON.stringify(value);\n }\n catch (error)\n {\n valueStr = '[circular]';\n }\n }\n else\n {\n valueStr = String(value);\n }\n\n if (colorize)\n {\n parts.push(`${COLORS.dim}[${key}=${valueStr}]${COLORS.reset}`);\n }\n else\n {\n parts.push(`[${key}=${valueStr}]`);\n }\n });\n }\n\n // (LEVEL):\n const levelStr = metadata.level.toUpperCase();\n if (colorize)\n {\n const color = COLORS[metadata.level];\n parts.push(`${color}(${levelStr})${COLORS.reset}:`);\n }\n else\n {\n parts.push(`(${levelStr}):`);\n }\n\n // 메시지\n if (colorize)\n {\n parts.push(`${COLORS.bright}${metadata.message}${COLORS.reset}`);\n }\n else\n {\n parts.push(metadata.message);\n }\n\n let output = parts.join(' ');\n\n // 에러는 별도 줄로 추가\n if (metadata.error)\n {\n output += '\\n' + formatError(metadata.error);\n }\n\n return output;\n}\n\n/**\n * JSON 포맷 (파일 저장 및 전송용)\n */\nexport function formatJSON(metadata: LogMetadata): string\n{\n const obj: Record<string, unknown> = {\n timestamp: formatTimestamp(metadata.timestamp),\n level: metadata.level,\n message: metadata.message,\n };\n\n if (metadata.module)\n {\n obj.module = metadata.module;\n }\n\n if (metadata.context)\n {\n obj.context = metadata.context;\n }\n\n if (metadata.error)\n {\n obj.error = {\n name: metadata.error.name,\n message: metadata.error.message,\n stack: metadata.error.stack,\n };\n }\n\n return JSON.stringify(obj);\n}\n\n/**\n * Drizzle ORM 에러에서 쿼리 정보 추출\n *\n * Drizzle ORM은 에러 메시지에 다음 형식으로 정보를 포함:\n * - \"Failed query: <QUERY>\\nparams: <PARAMS>\"\n * - \"Query: <QUERY>\"\n *\n * @param error - Error 객체\n * @returns 쿼리 정보 (query, params, table)\n */\nexport function extractQueryInfo(error: Error): {\n query?: string;\n params?: unknown;\n table?: string;\n} | null\n{\n const message = error.message;\n\n if (!message) return null;\n\n const result: {\n query?: string;\n params?: unknown;\n table?: string;\n } = {};\n\n // Extract query from \"Failed query: ...\" or \"Query: ...\"\n const queryMatch = message.match(/(?:Failed query:|Query:)\\s*([^\\n]+)/);\n if (queryMatch)\n {\n result.query = queryMatch[1].trim();\n\n // Extract table name from query (e.g., UPDATE \"table_name\" or INSERT INTO \"table_name\")\n const tableMatch = result.query.match(/(?:UPDATE|INSERT INTO|DELETE FROM|FROM)\\s+\"?([a-zA-Z_][a-zA-Z0-9_]*)\"?\\.\"?([a-zA-Z_][a-zA-Z0-9_]*)\"?|(?:UPDATE|INSERT INTO|DELETE FROM|FROM)\\s+\"?([a-zA-Z_][a-zA-Z0-9_]*)\"?/i);\n if (tableMatch)\n {\n // Schema.Table or just Table\n result.table = tableMatch[2] || tableMatch[3] || tableMatch[1];\n }\n }\n\n // Extract params from \"params: ...\"\n const paramsMatch = message.match(/params:\\s*(.+?)(?:\\n|$)/);\n if (paramsMatch)\n {\n const paramsStr = paramsMatch[1].trim();\n try\n {\n // Try to parse as comma-separated values\n result.params = paramsStr.split(',').map(p => p.trim());\n }\n catch (e)\n {\n result.params = paramsStr;\n }\n }\n\n return Object.keys(result).length > 0 ? result : null;\n}\n\n/**\n * Promise rejection의 호출 스택에서 실제 발생 위치 추출\n *\n * 스택 트레이스에서 다음 정보를 추출:\n * - 실제 에러 발생 파일 경로\n * - 라인 번호\n * - 함수명/메서드명\n * - Repository 정보 (있는 경우)\n *\n * @param error - Error 객체\n * @returns Promise context 정보\n */\nexport function extractPromiseContext(error: Error): Record<string, unknown>\n{\n const context: Record<string, unknown> = {};\n\n if (!error.stack) return context;\n\n const stackLines = error.stack.split('\\n');\n\n // Skip first line (error message) and find first meaningful stack frame\n // Ignore node_modules and internal Node.js paths\n for (let i = 1; i < stackLines.length; i++)\n {\n const line = stackLines[i].trim();\n\n // Skip node_modules and node internals\n if (line.includes('node_modules') || line.includes('node:internal')) continue;\n\n // Extract file, line number, and function name\n // Format: \"at ClassName.methodName (file.ts:line:col)\"\n // or: \"at functionName (file.ts:line:col)\"\n // or: \"at file.ts:line:col\"\n\n const match = line.match(/at\\s+(?:([a-zA-Z_$][\\w$]*(?:\\.[a-zA-Z_$][\\w$]*)*)\\s+)?\\(?([^)]+):(\\d+):(\\d+)\\)?/);\n\n if (match)\n {\n const [, functionName, filePath, lineNumber, columnNumber] = match;\n\n // Extract just the filename from the full path\n const fileNameMatch = filePath.match(/([^/\\\\]+)$/);\n const fileName = fileNameMatch ? fileNameMatch[1] : filePath;\n\n context.file = fileName;\n context.line = parseInt(lineNumber, 10);\n context.column = parseInt(columnNumber, 10);\n\n if (functionName)\n {\n // Check if it's a class method (e.g., \"ClassName.methodName\")\n const methodMatch = functionName.match(/^(.+)\\.([^.]+)$/);\n if (methodMatch)\n {\n const [, className, methodName] = methodMatch;\n\n context.class = className;\n context.method = methodName;\n\n // Check if it's a Repository\n if (className.includes('Repository'))\n {\n context.repository = className;\n }\n }\n else\n {\n context.function = functionName;\n }\n }\n\n // Found first relevant frame, stop here\n break;\n }\n }\n\n return context;\n}\n\n/**\n * Unhandled rejection 에러를 상세하게 포맷팅\n *\n * Promise context와 DB 쿼리 정보를 자동으로 추출하여\n * 에러 발생 위치와 원인을 명확하게 파악할 수 있도록 함\n *\n * @param reason - Rejection 원인 (Error 또는 기타)\n * @param promise - Promise 객체\n * @returns 상세 context 정보\n */\nexport function formatUnhandledRejection(reason: unknown, promise: Promise<unknown>): {\n error: Error;\n context: Record<string, unknown>;\n}\n{\n // Convert reason to Error if not already\n let error: Error;\n if (reason instanceof Error)\n {\n error = reason;\n }\n else if (typeof reason === 'string')\n {\n error = new Error(reason);\n }\n else\n {\n error = new Error(JSON.stringify(reason));\n }\n\n const context: Record<string, unknown> = {\n promise: String(promise),\n };\n\n // Extract promise context (file, line, function, etc.)\n const promiseContext = extractPromiseContext(error);\n if (Object.keys(promiseContext).length > 0)\n {\n context.promiseContext = promiseContext;\n }\n\n // Extract DB query info if available\n const queryInfo = extractQueryInfo(error);\n if (queryInfo)\n {\n context.queryInfo = queryInfo;\n }\n\n return { error, context };\n}","import { config } from \"dotenv\";\nimport { existsSync } from \"fs\";\nimport { resolve } from \"path\";\n\n/**\n * Load environment files for SPFN server\n *\n * Priority (high → low, later files don't override):\n * 1. .env.server.local - Server-only secrets (gitignored)\n * 2. .env.server - Server-only defaults\n * 3. .env.{NODE_ENV}.local\n * 4. .env.local - Local overrides (gitignored)\n * 5. .env.{NODE_ENV}\n * 6. .env - Defaults\n */\nexport function loadEnvFiles()\n{\n const cwd = process.cwd();\n const nodeEnv = process.env.NODE_ENV || 'development';\n\n // Build list of .env files to load (in priority order, high → low)\n // dotenv won't override existing vars, so load high-priority files first\n const envFiles: string[] = [\n '.env.server.local',\n '.env.server',\n `.env.${nodeEnv}.local`,\n nodeEnv !== 'test' ? '.env.local' : null,\n `.env.${nodeEnv}`,\n '.env',\n ].filter((file): file is string => file !== null);\n\n // Load each file if it exists\n for (const file of envFiles)\n {\n const filePath = resolve(cwd, file);\n if (existsSync(filePath))\n {\n config({ path: filePath });\n }\n }\n}","/**\n * SSE Handler for Hono\n *\n * Creates SSE stream endpoint for event subscription\n *\n * @example\n * ```typescript\n * import { Hono } from 'hono';\n * import { createSSEHandler } from '@spfn/core/event/sse';\n * import { eventRouter } from './events';\n *\n * const app = new Hono();\n *\n * // GET /events/stream?events=userCreated,orderPlaced\n * app.get('/events/stream', createSSEHandler(eventRouter));\n * ```\n */\n\nimport type { Context } from 'hono';\nimport { streamSSE } from 'hono/streaming';\nimport { logger } from '@spfn/core/logger';\nimport type { EventRouterDef, InferEventNames } from '../router';\nimport type { SSEHandlerConfig } from './types';\n\nconst sseLogger = logger.child('@spfn/core:sse');\n\n/**\n * Create SSE handler for Hono\n *\n * Query parameters:\n * - events: Comma-separated list of event names to subscribe\n *\n * @example\n * ```typescript\n * app.get('/events/stream', createSSEHandler(eventRouter, {\n * pingInterval: 30000,\n * }));\n * ```\n */\nexport function createSSEHandler<TRouter extends EventRouterDef<any>>(\n router: TRouter,\n config: SSEHandlerConfig = {}\n)\n{\n const {\n pingInterval = 30000,\n // headers: customHeaders = {}, // Reserved for future use\n } = config;\n\n return async (c: Context) =>\n {\n // Parse events from query parameter\n const eventsParam = c.req.query('events');\n\n if (!eventsParam)\n {\n return c.json({ error: 'Missing events parameter' }, 400);\n }\n\n const requestedEvents = eventsParam.split(',').map(e => e.trim());\n\n // Validate event names\n const validEventNames = router.eventNames as string[];\n const invalidEvents = requestedEvents.filter(e => !validEventNames.includes(e));\n\n if (invalidEvents.length > 0)\n {\n return c.json({\n error: 'Invalid event names',\n invalidEvents,\n validEvents: validEventNames,\n }, 400);\n }\n\n sseLogger.debug('SSE connection requested', {\n events: requestedEvents,\n clientIp: c.req.header('x-forwarded-for') || c.req.header('x-real-ip'),\n });\n\n // Start SSE stream\n return streamSSE(c, async (stream) =>\n {\n const unsubscribes: (() => void)[] = [];\n let messageId = 0;\n\n // Subscribe to each requested event\n for (const eventName of requestedEvents as InferEventNames<TRouter>[])\n {\n const eventDef = router.events[eventName];\n\n if (!eventDef)\n {\n continue;\n }\n\n const unsubscribe = eventDef.subscribe((payload: unknown) =>\n {\n messageId++;\n\n const message = {\n event: eventName,\n data: payload,\n };\n\n sseLogger.debug('SSE sending event', {\n event: eventName,\n messageId,\n });\n\n // Fire-and-forget in sync callback\n void stream.writeSSE({\n id: String(messageId),\n event: eventName as string,\n data: JSON.stringify(message),\n });\n });\n\n unsubscribes.push(unsubscribe);\n }\n\n sseLogger.info('SSE connection established', {\n events: requestedEvents,\n subscriptionCount: unsubscribes.length,\n });\n\n // Send initial connection message\n await stream.writeSSE({\n event: 'connected',\n data: JSON.stringify({\n subscribedEvents: requestedEvents,\n timestamp: Date.now(),\n }),\n });\n\n // Keep-alive ping\n const pingTimer = setInterval(() =>\n {\n // Fire-and-forget in sync callback\n void stream.writeSSE({\n event: 'ping',\n data: JSON.stringify({ timestamp: Date.now() }),\n });\n }, pingInterval);\n\n // Wait for client disconnect using abort signal\n const abortSignal = c.req.raw.signal;\n\n while (!abortSignal.aborted)\n {\n await stream.sleep(pingInterval);\n }\n\n // Cleanup\n clearInterval(pingTimer);\n unsubscribes.forEach(fn => fn());\n\n sseLogger.info('SSE connection closed', {\n events: requestedEvents,\n });\n }, async (err: Error) =>\n {\n sseLogger.error('SSE stream error', {\n error: err.message,\n });\n });\n };\n}\n\n","import type { Hono, Handler, MiddlewareHandler } from 'hono';\nimport type { Server } from 'http';\nimport { getDatabase } from '@spfn/core/db';\nimport { getCache } from '@spfn/core/cache';\nimport { env } from '@spfn/core/config';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface ServiceStatus\n{\n status: string;\n error?: string;\n}\n\ninterface HealthCheckResponse\n{\n status: 'ok' | 'degraded';\n timestamp: string;\n services?: {\n database: ServiceStatus;\n redis: ServiceStatus;\n };\n}\n\ninterface StartupConfig\n{\n middleware: {\n logger: boolean;\n cors: boolean;\n errorHandler: boolean;\n custom: number;\n };\n healthCheck: {\n enabled: boolean;\n path?: string;\n detailed?: boolean;\n };\n hooks: {\n beforeRoutes: boolean;\n afterRoutes: boolean;\n };\n timeout: {\n request: string;\n keepAlive: string;\n headers: string;\n };\n shutdown: {\n timeout: string;\n };\n}\n\n// ============================================================================\n// Functions\n// ============================================================================\n\nexport function createHealthCheckHandler(detailed: boolean): Handler\n{\n return async (c) =>\n {\n const response: HealthCheckResponse = {\n status: 'ok',\n timestamp: new Date().toISOString(),\n };\n\n if (detailed)\n {\n let dbStatus: string = 'unknown';\n let dbError: string | undefined;\n\n // Try to get database instance\n try\n {\n const db = getDatabase();\n try\n {\n await db.execute('SELECT 1');\n dbStatus = 'connected';\n }\n catch (error)\n {\n dbStatus = 'error';\n dbError = error instanceof Error ? error.message : String(error);\n }\n }\n catch (error)\n {\n // Database not initialized\n dbStatus = 'not_initialized';\n dbError = 'Database not available';\n }\n\n const redis = getCache();\n let redisStatus: string = redis ? 'unknown' : 'not_initialized';\n let redisError: string | undefined;\n if (redis)\n {\n try\n {\n await redis.ping();\n redisStatus = 'connected';\n }\n catch (error)\n {\n redisStatus = 'error';\n redisError = error instanceof Error ? error.message : String(error);\n }\n }\n\n response.services = {\n database: {\n status: dbStatus,\n ...(dbError && { error: dbError }),\n },\n redis: {\n status: redisStatus,\n ...(redisError && { error: redisError }),\n },\n };\n\n const hasErrors =\n (dbStatus === 'error' || dbStatus === 'not_initialized') ||\n (redisStatus === 'error');\n response.status = hasErrors ? 'degraded' : 'ok';\n }\n\n const statusCode = response.status === 'ok' ? 200 : 503;\n return c.json(response, statusCode);\n };\n}\n\nexport function applyServerTimeouts(\n server: Server,\n timeouts: {\n request: number;\n keepAlive: number;\n headers: number;\n }\n): void\n{\n if ('timeout' in server)\n {\n server.timeout = timeouts.request;\n server.keepAliveTimeout = timeouts.keepAlive;\n server.headersTimeout = timeouts.headers;\n }\n}\n\nexport function getTimeoutConfig(config?: {\n request?: number;\n keepAlive?: number;\n headers?: number;\n}): {\n request: number;\n keepAlive: number;\n headers: number;\n}\n{\n return {\n request: config?.request ?? env.SERVER_TIMEOUT,\n keepAlive: config?.keepAlive ?? env.SERVER_KEEPALIVE_TIMEOUT,\n headers: config?.headers ?? env.SERVER_HEADERS_TIMEOUT,\n };\n}\n\nexport function getShutdownTimeout(config?: { timeout?: number }): number\n{\n return config?.timeout ?? env.SHUTDOWN_TIMEOUT;\n}\n\nexport function buildMiddlewareOrder(config: {\n middleware?: {\n logger?: boolean;\n cors?: boolean;\n errorHandler?: boolean;\n };\n use?: MiddlewareHandler[];\n beforeRoutes?: (app: Hono) => void | Promise<void>;\n afterRoutes?: (app: Hono) => void | Promise<void>;\n}): string[]\n{\n const order: string[] = [];\n const middlewareConfig = config.middleware ?? {};\n const enableLogger = middlewareConfig.logger !== false;\n const enableCors = middlewareConfig.cors !== false;\n const enableErrorHandler = middlewareConfig.errorHandler !== false;\n\n if (enableLogger) order.push('RequestLogger');\n if (enableCors) order.push('CORS');\n config.use?.forEach((_, i) => order.push(`Custom[${i}]`));\n if (config.beforeRoutes) order.push('beforeRoutes hook');\n order.push('Routes');\n if (config.afterRoutes) order.push('afterRoutes hook');\n if (enableErrorHandler) order.push('ErrorHandler');\n\n return order;\n}\n\nexport function buildStartupConfig(\n config: {\n middleware?: {\n logger?: boolean;\n cors?: boolean;\n errorHandler?: boolean;\n };\n use?: MiddlewareHandler[];\n healthCheck?: {\n enabled?: boolean;\n path?: string;\n detailed?: boolean;\n };\n beforeRoutes?: (app: Hono) => void | Promise<void>;\n afterRoutes?: (app: Hono) => void | Promise<void>;\n shutdown?: {\n timeout?: number;\n };\n },\n timeouts: {\n request: number;\n keepAlive: number;\n headers: number;\n }\n): StartupConfig\n{\n const middlewareConfig = config.middleware ?? {};\n const healthCheckConfig = config.healthCheck ?? {};\n const healthCheckEnabled = healthCheckConfig.enabled !== false;\n const healthCheckPath = healthCheckConfig.path ?? '/health';\n const healthCheckDetailed = healthCheckConfig.detailed ?? (env.NODE_ENV === 'development');\n\n return {\n middleware: {\n logger: middlewareConfig.logger !== false,\n cors: middlewareConfig.cors !== false,\n errorHandler: middlewareConfig.errorHandler !== false,\n custom: config.use?.length ?? 0,\n },\n healthCheck: healthCheckEnabled ? {\n enabled: true,\n path: healthCheckPath,\n detailed: healthCheckDetailed,\n } : { enabled: false },\n hooks: {\n beforeRoutes: !!config.beforeRoutes,\n afterRoutes: !!config.afterRoutes,\n },\n timeout: {\n request: `${timeouts.request}ms`,\n keepAlive: `${timeouts.keepAlive}ms`,\n headers: `${timeouts.headers}ms`,\n },\n shutdown: {\n timeout: `${config.shutdown?.timeout ?? env.SHUTDOWN_TIMEOUT}ms`,\n },\n };\n}\n","import { logger } from \"@spfn/core/logger\";\n\nexport const serverLogger = logger.child('@spfn/core:server');","/**\n * Create Hono Server\n *\n * Creates and configures a Hono application instance.\n */\n\nimport { Hono } from 'hono';\nimport { cors } from 'hono/cors';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\n\nimport { registerRoutes, type RegisteredRoute } from '@spfn/core/route';\nimport { ErrorHandler, RequestLogger } from '@spfn/core/middleware';\nimport { createSSEHandler } from '../event/sse/handler';\nimport { createHealthCheckHandler } from './helpers';\nimport { serverLogger } from './logger';\n\nimport type { ServerConfig, AppFactory } from './types';\n\n// Extend Hono context with error handler flag\ndeclare module 'hono'\n{\n interface ContextVariableMap\n {\n errorHandlerEnabled?: boolean;\n }\n}\n\n/**\n * Create Hono app with automatic configuration\n *\n * Levels:\n * 1. No app.ts -> Full auto config\n * 2. server.config.ts -> Partial customization\n * 3. app.ts -> Full control (no auto config)\n */\nexport async function createServer(config?: ServerConfig): Promise<Hono>\n{\n const cwd = process.cwd();\n const appPath = join(cwd, 'src', 'server', 'app.ts');\n const appJsPath = join(cwd, 'src', 'server', 'app');\n\n // Level 3: Full control with app.ts\n if (existsSync(appPath) || existsSync(appJsPath))\n {\n return await loadCustomApp(appPath, appJsPath, config);\n }\n\n // Level 1 & 2: Auto config\n return await createAutoConfiguredApp(config);\n}\n\nasync function loadCustomApp(\n appPath: string,\n appJsPath: string,\n config?: ServerConfig\n): Promise<Hono>\n{\n // Determine which path exists to avoid duplicate checks\n const actualPath = existsSync(appPath) ? appPath : appJsPath;\n const appModule = await import(actualPath);\n const appFactory: AppFactory = appModule.default;\n\n if (!appFactory)\n {\n throw new Error('app.ts must export a default function that returns a Hono app');\n }\n\n const app = await appFactory();\n\n // Register routes (if provided via config)\n if (config?.routes)\n {\n const routes = registerRoutes(app, config.routes, config.middlewares);\n logRegisteredRoutes(routes, config?.debug ?? false);\n }\n\n return app;\n}\n\nasync function createAutoConfiguredApp(config?: ServerConfig): Promise<Hono>\n{\n const app = new Hono();\n\n const middlewareConfig = config?.middleware ?? {};\n const enableLogger = middlewareConfig.logger !== false;\n const enableCors = middlewareConfig.cors !== false;\n const enableErrorHandler = middlewareConfig.errorHandler !== false;\n\n // 1. Set error handler flag in context\n if (enableErrorHandler)\n {\n app.use('*', async (c, next) =>\n {\n c.set('errorHandlerEnabled', true);\n await next();\n });\n }\n\n // 2. Default middleware\n applyDefaultMiddleware(app, config, enableLogger, enableCors);\n\n // 3. Custom middleware\n if (Array.isArray(config?.use))\n {\n config.use.forEach(mw => app.use('*', mw));\n }\n\n // 4. Health check endpoint\n registerHealthCheckEndpoint(app, config);\n\n // 5. beforeRoutes hook from config\n await executeBeforeRoutesHook(app, config);\n\n // 6. Load routes\n await loadAppRoutes(app, config);\n\n // 7. Register SSE endpoint (if events router provided)\n registerSSEEndpoint(app, config);\n\n // 8. afterRoutes hook from config\n await executeAfterRoutesHook(app, config);\n\n // 9. Error handler\n if (enableErrorHandler)\n {\n app.onError(ErrorHandler());\n }\n\n return app;\n}\n\nfunction applyDefaultMiddleware(\n app: Hono,\n config: ServerConfig | undefined,\n enableLogger: boolean,\n enableCors: boolean\n): void\n{\n if (enableLogger)\n {\n app.use('*', RequestLogger());\n }\n\n if (enableCors)\n {\n // Only apply cors if config.cors is not explicitly false\n // This handles both config.cors = undefined and config.cors = {...options}\n const corsOptions = config?.cors !== false ? config?.cors : undefined;\n app.use('*', cors(corsOptions));\n }\n}\n\nfunction registerHealthCheckEndpoint(app: Hono, config?: ServerConfig): void\n{\n const healthCheckConfig = config?.healthCheck ?? {};\n const healthCheckEnabled = healthCheckConfig.enabled !== false;\n const healthCheckPath = healthCheckConfig.path ?? '/health';\n const healthCheckDetailed = healthCheckConfig.detailed\n ?? process.env.NODE_ENV === 'development';\n\n if (healthCheckEnabled)\n {\n app.get(healthCheckPath, createHealthCheckHandler(healthCheckDetailed));\n serverLogger.debug(`Health check endpoint enabled at ${healthCheckPath}`);\n }\n}\n\nasync function executeBeforeRoutesHook(app: Hono, config?: ServerConfig): Promise<void>\n{\n if (config?.lifecycle?.beforeRoutes)\n {\n await config.lifecycle.beforeRoutes(app);\n }\n}\n\nasync function loadAppRoutes(app: Hono, config?: ServerConfig): Promise<void>\n{\n const debug = isDebugMode(config);\n\n // Register define-route based routes (if provided)\n if (config?.routes)\n {\n const routes = registerRoutes(app, config.routes, config.middlewares);\n logRegisteredRoutes(routes, debug);\n }\n else if (debug)\n {\n serverLogger.warn('⚠️ No routes configured. Use defineServerConfig().routes() to register routes.');\n }\n}\n\n/**\n * Log registered routes in a formatted table\n */\nfunction logRegisteredRoutes(routes: RegisteredRoute[], debug: boolean): void\n{\n if (routes.length === 0)\n {\n if (debug)\n {\n serverLogger.warn('⚠️ No routes registered');\n }\n return;\n }\n\n // Sort routes by path for better readability\n const sortedRoutes = [...routes].sort((a, b) => a.path.localeCompare(b.path));\n\n // Calculate max method length for alignment\n const maxMethodLen = Math.max(...sortedRoutes.map(r => r.method.length));\n\n // Build route list string\n const routeLines = sortedRoutes.map(r =>\n ` ${r.method.padEnd(maxMethodLen)} ${r.path}`\n ).join('\\n');\n\n serverLogger.info(`✓ Routes registered (${routes.length}):\\n${routeLines}`);\n}\n\nasync function executeAfterRoutesHook(app: Hono, config?: ServerConfig): Promise<void>\n{\n if (config?.lifecycle?.afterRoutes)\n {\n await config.lifecycle.afterRoutes(app);\n }\n}\n\n/**\n * Register SSE endpoint for event streaming\n */\nfunction registerSSEEndpoint(app: Hono, config?: ServerConfig): void\n{\n if (!config?.events)\n {\n return;\n }\n\n const eventsConfig = config.eventsConfig ?? {};\n const path = eventsConfig.path ?? '/events/stream';\n const debug = isDebugMode(config);\n\n // Register SSE handler\n app.get(path, createSSEHandler(config.events, eventsConfig));\n\n if (debug)\n {\n const eventNames = config.events.eventNames as string[];\n serverLogger.info(`✓ SSE endpoint registered at ${path}`, {\n events: eventNames,\n });\n }\n}\n\n/**\n * Determine if debug mode is enabled\n */\nfunction isDebugMode(config?: ServerConfig): boolean\n{\n return config?.debug ?? process.env.NODE_ENV === 'development';\n}","/**\n * pg-boss Wrapper\n *\n * Manages pg-boss instance lifecycle\n */\n\nimport PgBoss from 'pg-boss';\nimport { logger } from '@spfn/core/logger';\n\nconst jobLogger = logger.child('@spfn/core:job');\n\n/**\n * Global pg-boss instance\n */\nlet bossInstance: PgBoss | null = null;\n\n/**\n * Stored config for access during registration\n */\nlet bossConfig: BossConfig | null = null;\n\n/**\n * Options for pg-boss initialization\n *\n * @example\n * ```typescript\n * await initBoss({\n * connectionString: process.env.DATABASE_URL,\n * schema: 'spfn_queue',\n * clearOnStart: process.env.NODE_ENV === 'development',\n * });\n * ```\n */\nexport interface BossOptions\n{\n /**\n * PostgreSQL connection string\n *\n * @example 'postgresql://user:password@localhost:5432/mydb'\n */\n connectionString: string;\n\n /**\n * Schema name for pg-boss tables\n *\n * pg-boss creates its own tables in this schema.\n *\n * @default 'spfn_queue'\n */\n schema?: string;\n\n /**\n * Maintenance interval in seconds\n *\n * pg-boss runs maintenance tasks (cleanup, archiving) at this interval.\n *\n * @default 120\n */\n maintenanceIntervalSeconds?: number;\n\n /**\n * Monitor state changes interval in seconds\n *\n * When set, pg-boss emits state change events at this interval.\n *\n * @default undefined (disabled)\n */\n monitorIntervalSeconds?: number;\n\n /**\n * Clear all pending/scheduled jobs on startup\n *\n * Useful for development mode to start with a clean queue.\n * Should be false in production.\n *\n * @default false\n */\n clearOnStart?: boolean;\n}\n\n/**\n * @deprecated Use BossOptions instead\n */\nexport type BossConfig = BossOptions;\n\n/**\n * Initialize pg-boss with the given configuration\n *\n * Must be called before registerJobs(). Typically handled by defineServerConfig().\n *\n * @param options - pg-boss configuration options\n * @returns The pg-boss instance\n *\n * @example\n * ```typescript\n * const boss = await initBoss({\n * connectionString: process.env.DATABASE_URL!,\n * schema: 'spfn_queue',\n * });\n * ```\n */\nexport async function initBoss(options: BossOptions): Promise<PgBoss>\n{\n if (bossInstance)\n {\n jobLogger.warn('pg-boss already initialized, returning existing instance');\n return bossInstance;\n }\n\n jobLogger.info('Initializing pg-boss...');\n\n bossConfig = options;\n\n const pgBossOptions: PgBoss.ConstructorOptions = {\n connectionString: options.connectionString,\n schema: options.schema ?? 'spfn_queue',\n maintenanceIntervalSeconds: options.maintenanceIntervalSeconds ?? 120,\n };\n\n // Only set monitorIntervalSeconds if explicitly provided (must be >= 1)\n if (options.monitorIntervalSeconds !== undefined && options.monitorIntervalSeconds >= 1)\n {\n pgBossOptions.monitorIntervalSeconds = options.monitorIntervalSeconds;\n }\n\n bossInstance = new PgBoss(pgBossOptions);\n\n // Event handlers\n bossInstance.on('error', (error) =>\n {\n jobLogger.error('pg-boss error:', error);\n });\n\n await bossInstance.start();\n\n jobLogger.info('pg-boss started successfully');\n\n return bossInstance;\n}\n\n/**\n * Get the current pg-boss instance\n */\nexport function getBoss(): PgBoss | null\n{\n return bossInstance;\n}\n\n/**\n * Stop pg-boss gracefully\n */\nexport async function stopBoss(): Promise<void>\n{\n if (!bossInstance)\n {\n return;\n }\n\n jobLogger.info('Stopping pg-boss...');\n\n try\n {\n await bossInstance.stop({ graceful: true, timeout: 30000 });\n jobLogger.info('pg-boss stopped gracefully');\n }\n catch (error)\n {\n jobLogger.error('Error stopping pg-boss:', error);\n throw error;\n }\n finally\n {\n bossInstance = null;\n bossConfig = null;\n }\n}\n\n/**\n * Check if pg-boss is initialized and running\n */\nexport function isBossRunning(): boolean\n{\n return bossInstance !== null;\n}\n\n/**\n * Check if jobs should be cleared on start\n */\nexport function shouldClearOnStart(): boolean\n{\n return bossConfig?.clearOnStart ?? false;\n}\n","/**\n * Job Router\n *\n * Groups job definitions for registration with the server\n */\n\nimport type { JobDef, JobRouter, JobRouterEntry } from './types';\n\n/**\n * Type guard to check if value is a JobDef\n */\nexport function isJobDef(value: unknown): value is JobDef<any>\n{\n return (\n value !== null &&\n typeof value === 'object' &&\n 'name' in value &&\n 'handler' in value &&\n 'send' in value &&\n 'run' in value\n );\n}\n\n/**\n * Type guard to check if value is a JobRouter\n */\nexport function isJobRouter(value: unknown): value is JobRouter<any>\n{\n return (\n value !== null &&\n typeof value === 'object' &&\n 'jobs' in value &&\n '_jobs' in value\n );\n}\n\n/**\n * Define a job router to group jobs together\n *\n * @example\n * ```typescript\n * // Flat structure\n * export const jobRouter = defineJobRouter({\n * sendWelcomeEmail,\n * dailyReport,\n * initCache,\n * });\n *\n * // Nested structure\n * export const jobRouter = defineJobRouter({\n * email: defineJobRouter({\n * sendWelcome: sendWelcomeEmailJob,\n * sendReset: sendResetPasswordJob,\n * }),\n * reports: defineJobRouter({\n * daily: dailyReportJob,\n * weekly: weeklyReportJob,\n * }),\n * });\n *\n * // Mixed\n * export const jobRouter = defineJobRouter({\n * initCache, // flat\n * email: defineJobRouter({ ... }), // nested\n * });\n * ```\n */\nexport function defineJobRouter<\n TJobs extends Record<string, JobRouterEntry>\n>(jobs: TJobs): JobRouter<TJobs>\n{\n return {\n jobs,\n _jobs: jobs,\n };\n}\n\n/**\n * Collect all JobDefs from a JobRouter (including nested)\n */\nexport function collectJobs(\n router: JobRouter<any>,\n prefix = ''\n): JobDef<any>[]\n{\n const jobs: JobDef<any>[] = [];\n\n for (const [key, value] of Object.entries(router.jobs))\n {\n const name = prefix ? `${prefix}.${key}` : key;\n\n if (isJobRouter(value))\n {\n // Nested router - recurse\n jobs.push(...collectJobs(value, name));\n }\n else if (isJobDef(value))\n {\n jobs.push(value);\n }\n }\n\n return jobs;\n}\n","/**\n * Job Registration\n *\n * Registers jobs with pg-boss\n */\n\nimport type PgBoss from 'pg-boss';\nimport { logger } from '@spfn/core/logger';\nimport type { JobDef, JobOptions, JobRouter } from './types';\nimport type { EventDef } from '@spfn/core/event';\nimport { collectJobs } from './job-router';\nimport { getBoss, shouldClearOnStart } from './boss';\n\nconst jobLogger = logger.child('@spfn/core:job');\n\n/**\n * Get the pg-boss queue name for an event\n */\nexport function getEventQueueName(eventName: string): string\n{\n return `event:${eventName}`;\n}\n\n/**\n * Build default pg-boss options for a job\n */\nfunction getDefaultJobOptions(options?: JobOptions): PgBoss.SendOptions\n{\n return {\n retryLimit: options?.retryLimit ?? 3,\n retryDelay: options?.retryDelay ?? 1000,\n expireInSeconds: options?.expireInSeconds ?? 300,\n };\n}\n\n/**\n * Register all jobs from a JobRouter with pg-boss\n *\n * This function:\n * 1. Collects all jobs from the router (including nested routers)\n * 2. Optionally clears existing jobs (if clearOnStart is enabled)\n * 3. Registers each job's worker handler with pg-boss\n * 4. Sets up cron schedules for scheduled jobs\n * 5. Queues runOnce jobs\n * 6. Connects event subscriptions to job queues\n *\n * @param router - JobRouter containing job definitions\n *\n * @example\n * ```typescript\n * // Define jobs\n * const sendEmail = job('send-email')\n * .input(Type.Object({ to: Type.String() }))\n * .handler(async (input) => { ... });\n *\n * const dailyReport = job('daily-report')\n * .cron('0 9 * * *')\n * .handler(async () => { ... });\n *\n * // Create router\n * const jobRouter = defineJobRouter({ sendEmail, dailyReport });\n *\n * // Initialize pg-boss first\n * await initBoss({ connectionString: process.env.DATABASE_URL! });\n *\n * // Register jobs\n * await registerJobs(jobRouter);\n * ```\n */\nexport async function registerJobs(router: JobRouter<any>): Promise<void>\n{\n const boss = getBoss();\n if (!boss)\n {\n throw new Error(\n 'pg-boss not initialized. Call initBoss() before registerJobs()'\n );\n }\n\n const jobs = collectJobs(router);\n const clearOnStart = shouldClearOnStart();\n\n jobLogger.info(`Registering ${jobs.length} job(s)...`);\n\n // Clear existing jobs if requested (useful for development)\n if (clearOnStart)\n {\n jobLogger.info('Clearing existing jobs before registration...');\n for (const job of jobs)\n {\n // Clear job queue\n await boss.deleteAllJobs(job.name);\n\n // Also clear event queue if subscribed\n if (job.subscribedEvent)\n {\n const eventQueue = getEventQueueName(job.subscribedEvent);\n await boss.deleteAllJobs(eventQueue);\n }\n }\n jobLogger.info('Existing jobs cleared');\n }\n\n for (const job of jobs)\n {\n await registerJob(job);\n }\n\n jobLogger.info('All jobs registered successfully');\n}\n\n/**\n * Create queue if not exists (required for pg-boss v11+)\n */\nasync function ensureQueue(boss: PgBoss, queueName: string): Promise<void>\n{\n await boss.createQueue(queueName);\n}\n\n/**\n * Register worker handler for a job\n */\nasync function registerWorker(\n boss: PgBoss,\n job: JobDef<any>,\n queueName: string\n): Promise<void>\n{\n // Ensure queue exists before registering worker\n await ensureQueue(boss, queueName);\n\n await boss.work(\n queueName,\n { batchSize: 1 },\n async (jobs) =>\n {\n for (const pgBossJob of jobs)\n {\n jobLogger.debug(`[Job:${job.name}] Executing...`, { jobId: pgBossJob.id });\n\n const startTime = Date.now();\n\n try\n {\n if (job.inputSchema)\n {\n await (job.handler as (input: unknown) => Promise<void>)(pgBossJob.data);\n }\n else\n {\n await (job.handler as () => Promise<void>)();\n }\n\n const duration = Date.now() - startTime;\n jobLogger.info(`[Job:${job.name}] Completed in ${duration}ms`, {\n jobId: pgBossJob.id,\n duration,\n });\n }\n catch (error)\n {\n const duration = Date.now() - startTime;\n jobLogger.error(`[Job:${job.name}] Failed after ${duration}ms`, {\n jobId: pgBossJob.id,\n duration,\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }\n }\n );\n}\n\n/**\n * Connect event to pg-boss queue\n */\nfunction connectEventToQueue(\n boss: PgBoss,\n job: JobDef<any>,\n queueName: string\n): void\n{\n if (!job._subscribedEventDef)\n {\n return;\n }\n\n const eventDef = job._subscribedEventDef as EventDef<any>;\n eventDef._registerJobQueue(queueName, async (queue, payload) =>\n {\n await boss.send(queue, payload as object, getDefaultJobOptions(job.options));\n });\n\n jobLogger.debug(`[Job:${job.name}] Connected to event: ${job.subscribedEvent}`);\n}\n\n/**\n * Register cron schedule for a job\n */\nasync function registerCronSchedule(boss: PgBoss, job: JobDef<any>): Promise<void>\n{\n if (!job.cronExpression)\n {\n return;\n }\n\n jobLogger.debug(`[Job:${job.name}] Scheduling cron: ${job.cronExpression}`);\n\n // Ensure queue exists for cron jobs (uses job.name as queue)\n await ensureQueue(boss, job.name);\n\n await boss.schedule(\n job.name,\n job.cronExpression,\n {},\n getDefaultJobOptions(job.options)\n );\n\n jobLogger.info(`[Job:${job.name}] Cron scheduled: ${job.cronExpression}`);\n}\n\n/**\n * Queue a runOnce job\n */\nasync function queueRunOnceJob(boss: PgBoss, job: JobDef<any>): Promise<void>\n{\n if (!job.runOnce)\n {\n return;\n }\n\n jobLogger.debug(`[Job:${job.name}] Queuing runOnce job`);\n\n // Ensure queue exists for runOnce jobs (uses job.name as queue)\n await ensureQueue(boss, job.name);\n\n await boss.send(\n job.name,\n {},\n {\n ...getDefaultJobOptions(job.options),\n singletonKey: `runOnce:${job.name}`,\n }\n );\n\n jobLogger.info(`[Job:${job.name}] runOnce job queued`);\n}\n\n/**\n * Register a single job with pg-boss\n */\nasync function registerJob(job: JobDef<any>): Promise<void>\n{\n const boss = getBoss();\n if (!boss)\n {\n throw new Error('pg-boss not initialized');\n }\n\n const queueName = job.subscribedEvent\n ? getEventQueueName(job.subscribedEvent)\n : job.name;\n\n jobLogger.debug(`Registering job: ${job.name}`, {\n queueName,\n subscribedEvent: job.subscribedEvent,\n });\n\n await registerWorker(boss, job, queueName);\n connectEventToQueue(boss, job, queueName);\n await registerCronSchedule(boss, job);\n await queueRunOnceJob(boss, job);\n\n jobLogger.debug(`Job registered: ${job.name}`);\n}\n","/**\n * Server Startup Banner\n *\n * Displays SPFN logo and server information at startup.\n */\n\nimport { networkInterfaces } from 'os';\n\n/**\n * Get local network IP address\n */\nfunction getNetworkAddress(): string | null\n{\n const nets = networkInterfaces();\n\n for (const name of Object.keys(nets))\n {\n const netGroup = nets[name];\n if (!netGroup) continue;\n\n for (const net of netGroup)\n {\n // IPv4, non-internal address\n if (net.family === 'IPv4' && !net.internal)\n {\n return net.address;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Print server startup banner\n */\nexport function printBanner(options: {\n mode: string;\n host: string;\n port: number;\n}): void\n{\n const { mode, host, port } = options;\n\n console.log('');\n console.log(' _____ ____ ______ _ _');\n console.log(' / ____| _ \\\\| ____| \\\\ | |');\n console.log(' | (___ | |_) | |__ | \\\\| |');\n console.log(' \\\\___ \\\\| __/| __| | . ` |');\n console.log(' ____) | | | | | |\\\\ |');\n console.log(' |_____/|_| |_| |_| \\\\_|');\n console.log('');\n console.log(` Mode: ${mode}`);\n\n // Show Local and Network addresses like Next.js\n if (host === '0.0.0.0')\n {\n const networkIP = getNetworkAddress();\n console.log(` ▲ Local: http://localhost:${port}`);\n if (networkIP)\n {\n console.log(` ▲ Network: http://${networkIP}:${port}`);\n }\n }\n else\n {\n console.log(` ▲ Local: http://${host}:${port}`);\n }\n\n console.log('');\n}\n","/**\n * Server Configuration Validation\n *\n * Validates server configuration to catch errors early with clear messages.\n */\n\nimport type { ServerConfig } from './types';\n\n/**\n * Validate server configuration\n * Throws descriptive errors for invalid configurations\n */\nexport function validateServerConfig(config: ServerConfig): void\n{\n // Port validation\n if (config.port !== undefined)\n {\n if (!Number.isInteger(config.port) || config.port < 0 || config.port > 65535)\n {\n throw new Error(\n `Invalid port: ${config.port}. Port must be an integer between 0 and 65535.`\n );\n }\n }\n\n // Timeout validation\n if (config.timeout)\n {\n const { request, keepAlive, headers } = config.timeout;\n\n if (request !== undefined && (request < 0 || !Number.isFinite(request)))\n {\n throw new Error(`Invalid timeout.request: ${request}. Must be a positive number.`);\n }\n\n if (keepAlive !== undefined && (keepAlive < 0 || !Number.isFinite(keepAlive)))\n {\n throw new Error(`Invalid timeout.keepAlive: ${keepAlive}. Must be a positive number.`);\n }\n\n if (headers !== undefined && (headers < 0 || !Number.isFinite(headers)))\n {\n throw new Error(`Invalid timeout.headers: ${headers}. Must be a positive number.`);\n }\n\n // Logical validation\n if (headers && request && headers > request)\n {\n throw new Error(\n `Invalid timeout configuration: headers timeout (${headers}ms) cannot exceed request timeout (${request}ms).`\n );\n }\n }\n\n // Shutdown timeout validation\n if (config.shutdown?.timeout !== undefined)\n {\n const timeout = config.shutdown.timeout;\n if (timeout < 0 || !Number.isFinite(timeout))\n {\n throw new Error(`Invalid shutdown.timeout: ${timeout}. Must be a positive number.`);\n }\n }\n\n // Health check path validation\n if (config.healthCheck?.path)\n {\n if (!config.healthCheck.path.startsWith('/'))\n {\n throw new Error(\n `Invalid healthCheck.path: \"${config.healthCheck.path}\". Must start with \"/\".`\n );\n }\n }\n}","/**\n * Start SPFN Server\n *\n * Starts and configures the SPFN HTTP server with graceful shutdown.\n */\n\nimport { serve } from '@hono/node-server';\nimport { existsSync } from 'fs';\nimport type { Hono } from 'hono';\nimport type { Server } from 'http';\nimport { join } from 'path';\n\nimport { closeCache, initCache } from '@spfn/core/cache';\nimport { closeDatabase, initDatabase } from '@spfn/core/db';\nimport { initBoss, stopBoss, registerJobs } from '../job';\nimport { serverLogger } from './logger';\nimport { printBanner } from './banner';\nimport { createServer } from './create-server';\nimport { loadEnvFiles } from \"./dotenv-loader\";\nimport {\n applyServerTimeouts,\n buildMiddlewareOrder,\n buildStartupConfig,\n getShutdownTimeout,\n getTimeoutConfig,\n} from './helpers';\n\nimport type { ServerConfig, ServerInstance } from './types';\nimport { validateServerConfig } from './validation';\nimport { env } from '@spfn/core/config';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_MAX_LISTENERS = 15;\n\nconst TIMEOUTS = {\n SERVER_CLOSE: 5000,\n DATABASE_CLOSE: 5000,\n REDIS_CLOSE: 5000,\n PRODUCTION_ERROR_SHUTDOWN: 10000,\n} as const;\n\nconst CONFIG_FILE_PATHS = [\n '.spfn/server/server.config.mjs',\n '.spfn/server/server.config',\n 'src/server/server.config',\n 'src/server/server.config.ts',\n] as const;\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface InfrastructureConfig\n{\n database: boolean;\n redis: boolean;\n}\n\n/**\n * Shutdown state manager to prevent race conditions\n */\ninterface ShutdownState\n{\n isShuttingDown: boolean;\n}\n\n// ============================================================================\n// Module State\n// ============================================================================\n\n/**\n * Track whether process-level shutdown handlers have been registered\n * Process handlers should only be registered once\n */\nlet processHandlersRegistered = false;\n\n// ============================================================================\n// Main Entry Point\n// ============================================================================\n\n/**\n * Start SPFN server\n *\n * Automatically loads server.config.ts if exists\n * Automatically initializes Database and Redis from environment\n * Sets up graceful shutdown handlers for SIGTERM and SIGINT\n *\n * @returns ServerInstance with server, app, config, and close() method\n */\nexport async function startServer(config?: ServerConfig): Promise<ServerInstance>\n{\n loadEnvFiles();\n\n const finalConfig = await loadAndMergeConfig(config);\n const { host, port, debug } = finalConfig;\n\n validateServerConfig(finalConfig);\n\n // Validate required config values\n if (!host || !port)\n {\n throw new Error('Server host and port are required');\n }\n\n if (debug)\n {\n logMiddlewareOrder(finalConfig);\n }\n\n // Create shutdown state for this server instance\n const shutdownState: ShutdownState = {\n isShuttingDown: false,\n };\n\n try\n {\n await initializeInfrastructure(finalConfig);\n\n const app = await createServer(finalConfig);\n const server = startHttpServer(app, host, port);\n\n const timeouts = getTimeoutConfig(finalConfig.timeout);\n applyServerTimeouts(server as Server, timeouts);\n\n logServerTimeouts(timeouts);\n printBanner({\n mode: debug ? 'Development' : 'Production',\n host,\n port,\n });\n\n logServerStarted(debug, host, port, finalConfig, timeouts);\n\n const shutdownServer = createShutdownHandler(server as Server, finalConfig, shutdownState);\n const shutdown = createGracefulShutdown(shutdownServer, finalConfig, shutdownState);\n\n // Register process-level handlers\n registerProcessHandlers(shutdown);\n\n const serverInstance: ServerInstance = {\n server,\n app,\n config: finalConfig,\n close: async () =>\n {\n serverLogger.info('Manual server shutdown requested');\n\n // Prevent re-entry for manual close\n if (shutdownState.isShuttingDown)\n {\n serverLogger.warn('Shutdown already in progress, ignoring manual close request');\n return;\n }\n\n shutdownState.isShuttingDown = true;\n await shutdownServer();\n },\n };\n\n // Execute afterStart hook from config\n if (finalConfig.lifecycle?.afterStart)\n {\n serverLogger.debug('Executing afterStart hook...');\n try\n {\n await finalConfig.lifecycle.afterStart(serverInstance);\n }\n catch (error)\n {\n serverLogger.error('afterStart hook failed', error as Error);\n // Don't throw - server is already running\n // Just log the error and continue\n }\n }\n\n return serverInstance;\n }\n catch (error)\n {\n const err = error as Error;\n serverLogger.error('Server initialization failed', err);\n\n await cleanupOnFailure(finalConfig);\n\n throw error;\n }\n}\n\n// ============================================================================\n// Configuration Loading\n// ============================================================================\n\nasync function loadAndMergeConfig(config?: ServerConfig): Promise<ServerConfig>\n{\n const cwd = process.cwd();\n let fileConfig: ServerConfig = {};\n let loadedConfigPath: string | null = null;\n\n // Try loading config files in priority order\n for (const configPath of CONFIG_FILE_PATHS)\n {\n const fullPath = join(cwd, configPath);\n if (existsSync(fullPath))\n {\n try\n {\n const configModule = await import(fullPath);\n fileConfig = configModule.default ?? {};\n loadedConfigPath = configPath;\n break;\n }\n catch (error)\n {\n serverLogger.error(`Failed to load config from ${configPath} - file exists but import failed`, error as Error);\n // Continue trying other config files instead of failing\n }\n }\n }\n\n if (loadedConfigPath)\n {\n serverLogger.debug(`Loaded configuration from ${loadedConfigPath}`);\n }\n else\n {\n serverLogger.debug('No configuration file found, using defaults');\n }\n\n return {\n ...fileConfig,\n ...config,\n port: config?.port ?? fileConfig?.port ?? env.PORT,\n host: config?.host ?? fileConfig?.host ?? env.HOST,\n };\n}\n\n// ============================================================================\n// Infrastructure Management\n// ============================================================================\n\n/**\n * Determine which infrastructure components should be initialized\n */\nfunction getInfrastructureConfig(config: ServerConfig): InfrastructureConfig\n{\n return {\n database: config.infrastructure?.database !== false,\n redis: config.infrastructure?.redis !== false,\n };\n}\n\nasync function initializeInfrastructure(config: ServerConfig): Promise<void>\n{\n if (config.lifecycle?.beforeInfrastructure)\n {\n serverLogger.debug('Executing beforeInfrastructure hook...');\n await config.lifecycle.beforeInfrastructure(config);\n }\n\n const infraConfig = getInfrastructureConfig(config);\n\n if (infraConfig.database)\n {\n serverLogger.debug('Initializing database...');\n await initDatabase(config.database);\n }\n else\n {\n serverLogger.debug('Database initialization disabled');\n }\n\n if (infraConfig.redis)\n {\n serverLogger.debug('Initializing Redis...');\n await initCache();\n }\n else\n {\n serverLogger.debug('Redis initialization disabled');\n }\n\n if (config.lifecycle?.afterInfrastructure)\n {\n serverLogger.debug('Executing afterInfrastructure hook...');\n await config.lifecycle.afterInfrastructure();\n }\n\n // Initialize jobs if configured\n if (config.jobs)\n {\n const dbUrl = env.DATABASE_URL;\n if (!dbUrl)\n {\n throw new Error(\n 'Jobs require database connection. ' +\n 'Ensure DATABASE_URL is set or database is enabled.'\n );\n }\n\n serverLogger.debug('Initializing pg-boss...');\n await initBoss({\n connectionString: dbUrl,\n ...config.jobsConfig,\n });\n\n serverLogger.debug('Registering jobs...');\n await registerJobs(config.jobs);\n }\n}\n\n// ============================================================================\n// HTTP Server Management\n// ============================================================================\n\nfunction startHttpServer(app: Hono, host: string, port: number): ReturnType<typeof serve>\n{\n serverLogger.debug(`Starting server on ${host}:${port}...`);\n\n return serve({\n fetch: app.fetch,\n port,\n hostname: host,\n });\n}\n\nfunction logMiddlewareOrder(config: ServerConfig): void\n{\n const middlewareOrder = buildMiddlewareOrder(config);\n serverLogger.debug('Middleware execution order', {\n order: middlewareOrder,\n });\n}\n\nfunction logServerTimeouts(timeouts: {\n request: number;\n keepAlive: number;\n headers: number;\n}): void\n{\n serverLogger.info('Server timeouts configured', {\n request: `${timeouts.request}ms`,\n keepAlive: `${timeouts.keepAlive}ms`,\n headers: `${timeouts.headers}ms`,\n });\n}\n\nfunction logServerStarted(\n debug: boolean | undefined,\n host: string,\n port: number,\n config: ServerConfig,\n timeouts: { request: number; keepAlive: number; headers: number }\n): void\n{\n const startupConfig = buildStartupConfig(config, timeouts);\n\n serverLogger.info('Server started successfully', {\n mode: debug ? 'development' : 'production',\n host,\n port,\n config: startupConfig,\n });\n}\n\n// ============================================================================\n// Graceful Shutdown\n// ============================================================================\n\nfunction createShutdownHandler(\n server: Server,\n config: ServerConfig,\n shutdownState: ShutdownState\n): () => Promise<void>\n{\n return async () =>\n {\n // Prevent re-entry\n if (shutdownState.isShuttingDown)\n {\n serverLogger.debug('Shutdown already in progress for this instance, skipping');\n return;\n }\n\n shutdownState.isShuttingDown = true;\n serverLogger.debug('Closing HTTP server...');\n\n // Close server with timeout to prevent hanging\n let timeoutId: NodeJS.Timeout | undefined;\n\n await Promise.race([\n new Promise<void>((resolve, reject) =>\n {\n server.close((err) =>\n {\n if (timeoutId) clearTimeout(timeoutId);\n\n if (err)\n {\n serverLogger.error('HTTP server close error', err);\n reject(err);\n }\n else\n {\n serverLogger.info('HTTP server closed');\n resolve();\n }\n });\n }),\n new Promise<void>((_, reject) =>\n {\n timeoutId = setTimeout(() =>\n {\n reject(new Error(`HTTP server close timeout after ${TIMEOUTS.SERVER_CLOSE}ms`));\n }, TIMEOUTS.SERVER_CLOSE);\n }),\n ]).catch((error) =>\n {\n if (timeoutId) clearTimeout(timeoutId);\n serverLogger.warn('HTTP server close timeout, forcing shutdown', error as Error);\n // Continue with cleanup even if server.close() times out\n });\n\n // Stop pg-boss if jobs were configured\n if (config.jobs)\n {\n serverLogger.debug('Stopping pg-boss...');\n try\n {\n await stopBoss();\n }\n catch (error)\n {\n serverLogger.error('pg-boss stop failed', error as Error);\n // Continue with shutdown even if stop fails\n }\n }\n\n // Execute beforeShutdown hook from config\n if (config.lifecycle?.beforeShutdown)\n {\n serverLogger.debug('Executing beforeShutdown hook...');\n try\n {\n await config.lifecycle.beforeShutdown();\n }\n catch (error)\n {\n serverLogger.error('beforeShutdown hook failed', error as Error);\n // Continue with shutdown even if hook fails\n }\n }\n\n // Only close resources that were enabled for initialization\n const infraConfig = getInfrastructureConfig(config);\n\n if (infraConfig.database)\n {\n serverLogger.debug('Closing database connections...');\n await closeInfrastructure(closeDatabase, 'Database', TIMEOUTS.DATABASE_CLOSE);\n }\n\n if (infraConfig.redis)\n {\n serverLogger.debug('Closing Redis connections...');\n await closeInfrastructure(closeCache, 'Redis', TIMEOUTS.REDIS_CLOSE);\n }\n\n serverLogger.info('Server shutdown completed');\n };\n}\n\n/**\n * Close infrastructure component with timeout\n */\nasync function closeInfrastructure(\n closeFn: () => Promise<void>,\n name: string,\n timeout: number\n): Promise<void>\n{\n let timeoutId: NodeJS.Timeout | undefined;\n\n try\n {\n await Promise.race([\n closeFn().then(() =>\n {\n if (timeoutId) clearTimeout(timeoutId);\n }),\n new Promise<void>((_, reject) =>\n {\n timeoutId = setTimeout(() =>\n {\n reject(new Error(`${name} close timeout after ${timeout}ms`));\n }, timeout);\n }),\n ]);\n serverLogger.info(`${name} connections closed successfully`);\n }\n catch (error)\n {\n if (timeoutId) clearTimeout(timeoutId);\n serverLogger.error(`${name} close failed or timed out`, error as Error);\n // Continue with shutdown even if close fails\n }\n}\n\nfunction createGracefulShutdown(\n shutdownServer: () => Promise<void>,\n config: ServerConfig,\n shutdownState: ShutdownState\n): (signal: string) => Promise<void>\n{\n return async (signal: string) =>\n {\n // Prevent re-entry\n if (shutdownState.isShuttingDown)\n {\n serverLogger.warn(`${signal} received but shutdown already in progress, ignoring`);\n return;\n }\n\n serverLogger.info(`${signal} received, starting graceful shutdown...`);\n\n const shutdownTimeout = getShutdownTimeout(config.shutdown);\n let timeoutId: NodeJS.Timeout | undefined;\n\n try\n {\n await Promise.race([\n shutdownServer().then(() =>\n {\n if (timeoutId) clearTimeout(timeoutId);\n }),\n new Promise<never>((_, reject) =>\n {\n timeoutId = setTimeout(() =>\n {\n reject(new Error(`Graceful shutdown timeout after ${shutdownTimeout}ms`));\n }, shutdownTimeout);\n }),\n ]);\n\n if (timeoutId) clearTimeout(timeoutId);\n serverLogger.info('Graceful shutdown completed successfully');\n process.exit(0);\n }\n catch (error)\n {\n if (timeoutId) clearTimeout(timeoutId);\n const err = error as Error;\n\n if (err.message && err.message.includes('timeout'))\n {\n serverLogger.error('Graceful shutdown timeout, forcing exit', err);\n }\n else\n {\n serverLogger.error('Error during graceful shutdown', err);\n }\n\n process.exit(1);\n }\n };\n}\n\n// ============================================================================\n// Error Handlers\n// ============================================================================\n\n/**\n * Handle process errors with environment-specific behavior\n */\nfunction handleProcessError(\n errorType: string,\n shutdown: (signal: string) => Promise<void>\n): void\n{\n const isProduction = env.NODE_ENV === 'production';\n const isDevelopment = env.NODE_ENV === 'development';\n\n // In development/watch mode, exit immediately for clean restart\n // In production, attempt graceful shutdown\n if (isDevelopment || process.env.WATCH_MODE === 'true')\n {\n serverLogger.info('Exiting immediately for clean restart');\n process.exit(1);\n }\n else if (isProduction)\n {\n serverLogger.info(`Attempting graceful shutdown after ${errorType}`);\n\n // Set a timeout to force exit if shutdown hangs\n const forceExitTimer = setTimeout(() =>\n {\n serverLogger.error(`Forced exit after ${TIMEOUTS.PRODUCTION_ERROR_SHUTDOWN}ms - graceful shutdown did not complete`);\n process.exit(1);\n }, TIMEOUTS.PRODUCTION_ERROR_SHUTDOWN);\n\n // Don't use await in event handler - handle promise explicitly\n shutdown(errorType)\n .then(() =>\n {\n clearTimeout(forceExitTimer);\n serverLogger.info('Graceful shutdown completed, exiting');\n process.exit(0);\n })\n .catch((shutdownError) =>\n {\n clearTimeout(forceExitTimer);\n serverLogger.error('Graceful shutdown failed', shutdownError as Error);\n process.exit(1);\n });\n }\n else\n {\n // Unknown environment - exit immediately for safety\n serverLogger.info('Exiting immediately');\n process.exit(1);\n }\n}\n\nfunction registerProcessHandlers(\n shutdown: (signal: string) => Promise<void>\n): void\n{\n // Prevent duplicate registration\n if (processHandlersRegistered)\n {\n serverLogger.debug('Process handlers already registered, skipping');\n return;\n }\n\n processHandlersRegistered = true;\n\n // Increase max listeners to prevent warnings in development with hot reload\n const currentMax = process.getMaxListeners();\n if (currentMax < DEFAULT_MAX_LISTENERS)\n {\n process.setMaxListeners(DEFAULT_MAX_LISTENERS);\n }\n\n process.on('SIGTERM', () =>\n {\n shutdown('SIGTERM').catch((error) =>\n {\n serverLogger.error('SIGTERM handler failed', error as Error);\n process.exit(1);\n });\n });\n\n process.on('SIGINT', () =>\n {\n shutdown('SIGINT').catch((error) =>\n {\n serverLogger.error('SIGINT handler failed', error as Error);\n process.exit(1);\n });\n });\n\n process.on('uncaughtException', (error) =>\n {\n // Enhanced logging for EADDRINUSE errors\n if (error.message?.includes('EADDRINUSE'))\n {\n serverLogger.error('Port conflict detected - detailed trace:', error, {\n code: (error as any).code,\n port: (error as any).port,\n address: (error as any).address,\n syscall: (error as any).syscall,\n });\n }\n else\n {\n serverLogger.error('Uncaught exception', error);\n }\n\n handleProcessError('UNCAUGHT_EXCEPTION', shutdown);\n });\n\n process.on('unhandledRejection', (reason, promise) =>\n {\n // Enhanced error logging with promise context extraction\n if (reason instanceof Error)\n {\n // Import formatUnhandledRejection dynamically to avoid circular deps\n import('../logger/formatters').then(({ formatUnhandledRejection }) =>\n {\n const { error, context } = formatUnhandledRejection(reason, promise);\n\n serverLogger.error('Unhandled promise rejection', error, context);\n }).catch(() =>\n {\n // Fallback if formatUnhandledRejection fails\n serverLogger.error('Unhandled promise rejection', reason, {\n promise,\n });\n });\n }\n else\n {\n serverLogger.error('Unhandled promise rejection', {\n reason,\n promise,\n });\n }\n\n handleProcessError('UNHANDLED_REJECTION', shutdown);\n });\n\n serverLogger.debug('Process-level shutdown handlers registered successfully');\n}\n\n// ============================================================================\n// Cleanup\n// ============================================================================\n\nasync function cleanupOnFailure(config: ServerConfig): Promise<void>\n{\n try\n {\n serverLogger.debug('Cleaning up after initialization failure...');\n\n // Only cleanup resources that were enabled for initialization\n const infraConfig = getInfrastructureConfig(config);\n\n if (infraConfig.database)\n {\n await closeInfrastructure(closeDatabase, 'Database', TIMEOUTS.DATABASE_CLOSE);\n }\n\n if (infraConfig.redis)\n {\n await closeInfrastructure(closeCache, 'Redis', TIMEOUTS.REDIS_CLOSE);\n }\n\n serverLogger.debug('Cleanup completed');\n }\n catch (cleanupError)\n {\n serverLogger.error('Cleanup failed', cleanupError as Error);\n }\n}","/**\n * Server Config Builder\n *\n * Provides a fluent API for building server configuration\n */\n\nimport type { MiddlewareHandler } from 'hono';\nimport type { ServerConfig } from './types';\nimport type { Router, NamedMiddleware } from '@spfn/core/route';\nimport type { JobRouter, BossOptions } from '../job';\nimport type { EventRouterDef } from '../event/router';\nimport type { SSEHandlerConfig } from '../event/sse/types';\nimport { serverLogger } from './logger';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ntype Lifecycle = NonNullable<ServerConfig['lifecycle']>;\ntype LifecycleKey = keyof Lifecycle;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction collectHooks<K extends LifecycleKey>(\n lifecycles: Lifecycle[],\n key: K\n): NonNullable<Lifecycle[K]>[]\n{\n return lifecycles\n .map(lc => lc[key])\n .filter((hook): hook is NonNullable<Lifecycle[K]> => hook !== undefined);\n}\n\nfunction createMergedHook<T extends (...args: any[]) => void | Promise<void>>(\n hooks: T[]\n): T | undefined\n{\n if (hooks.length === 0)\n {\n return undefined;\n }\n\n return (async (...args: Parameters<T>) =>\n {\n for (const hook of hooks)\n {\n await hook(...args);\n }\n }) as T;\n}\n\nexport class ServerConfigBuilder\n{\n private config: ServerConfig = {};\n private lifecycles: NonNullable<ServerConfig['lifecycle']>[] = [];\n\n /**\n * Set server port\n */\n port(port: number): this\n {\n this.config.port = port;\n return this;\n }\n\n /**\n * Set server hostname\n */\n host(host: string): this\n {\n this.config.host = host;\n return this;\n }\n\n /**\n * Set CORS configuration\n */\n cors(cors: ServerConfig['cors']): this\n {\n this.config.cors = cors;\n return this;\n }\n\n /**\n * Configure built-in middleware\n */\n middleware(middleware: ServerConfig['middleware']): this\n {\n this.config.middleware = middleware;\n return this;\n }\n\n /**\n * Add custom middleware\n */\n use(handlers: MiddlewareHandler[]): this\n {\n this.config.use = handlers;\n return this;\n }\n\n /**\n * Add named middlewares for route-level skip control\n */\n middlewares(middlewares: ServerConfig['middlewares']): this\n {\n this.config.middlewares = middlewares;\n return this;\n }\n\n /**\n * Register define-route based router\n *\n * Automatically applies:\n * - Global middlewares from router._globalMiddlewares (via .use())\n * - Package routers from router._packageRouters (via .packages())\n *\n * @example\n * ```typescript\n * const appRouter = defineRouter({\n * getUser: route.get('/users/:id')...\n * })\n * .packages([authRouter, cmsAppRouter])\n * .use([authMiddleware]);\n *\n * export default defineServerConfig()\n * .routes(appRouter) // middlewares auto-applied\n * .build();\n * ```\n */\n routes(router: Router<any>): this\n {\n this.config.routes = router;\n\n // Collect all global middlewares from router and package routers\n const allGlobalMiddlewares: NamedMiddleware[] = [];\n\n // Add main router's global middlewares\n if (router._globalMiddlewares?.length > 0)\n {\n allGlobalMiddlewares.push(...router._globalMiddlewares);\n }\n\n // Add package routers' global middlewares\n if (router._packageRouters?.length > 0)\n {\n for (const pkgRouter of router._packageRouters)\n {\n if (pkgRouter._globalMiddlewares?.length > 0)\n {\n allGlobalMiddlewares.push(...pkgRouter._globalMiddlewares);\n }\n }\n }\n\n // Merge with existing middlewares\n if (allGlobalMiddlewares.length > 0)\n {\n this.config.middlewares = [\n ...(this.config.middlewares || []),\n ...allGlobalMiddlewares,\n ];\n }\n\n return this;\n }\n\n /**\n * Register background jobs router\n *\n * @example\n * ```typescript\n * import { job, defineJobRouter } from '@spfn/core/job';\n *\n * const sendEmail = job('send-email')\n * .input(Type.Object({ to: Type.String() }))\n * .handler(async (input) => { ... });\n *\n * const jobRouter = defineJobRouter({ sendEmail });\n *\n * export default defineServerConfig()\n * .routes(appRouter)\n * .jobs(jobRouter)\n * .build();\n * ```\n */\n jobs(router: JobRouter<any>, config?: Omit<BossOptions, 'connectionString'>): this\n {\n this.config.jobs = router;\n if (config)\n {\n this.config.jobsConfig = config;\n }\n return this;\n }\n\n /**\n * Register event router for SSE (Server-Sent Events)\n *\n * Enables real-time event streaming to frontend clients.\n * Events defined with defineEvent() can be subscribed by:\n * - Backend: .subscribe() for internal handlers\n * - Jobs: .on(event) for background processing\n * - Frontend: SSE stream for real-time updates\n *\n * @example\n * ```typescript\n * import { defineEvent, defineEventRouter } from '@spfn/core/event';\n *\n * const userCreated = defineEvent('user.created', Type.Object({\n * userId: Type.String(),\n * }));\n *\n * const eventRouter = defineEventRouter({ userCreated });\n *\n * export default defineServerConfig()\n * .routes(appRouter)\n * .events(eventRouter) // → GET /events/stream\n * .build();\n *\n * // Custom path\n * .events(eventRouter, { path: '/sse' })\n * ```\n */\n events(\n router: EventRouterDef<any>,\n config?: SSEHandlerConfig & { path?: string }\n ): this\n {\n this.config.events = router;\n if (config)\n {\n this.config.eventsConfig = config;\n }\n return this;\n }\n\n /**\n * Enable/disable debug mode\n */\n debug(enabled: boolean): this\n {\n this.config.debug = enabled;\n return this;\n }\n\n /**\n * Configure database settings\n */\n database(database: ServerConfig['database']): this\n {\n this.config.database = database;\n return this;\n }\n\n /**\n * Configure server timeout settings\n */\n timeout(timeout: ServerConfig['timeout']): this\n {\n this.config.timeout = timeout;\n return this;\n }\n\n /**\n * Configure graceful shutdown settings\n */\n shutdown(shutdown: ServerConfig['shutdown']): this\n {\n this.config.shutdown = shutdown;\n return this;\n }\n\n /**\n * Configure health check endpoint\n */\n healthCheck(healthCheck: ServerConfig['healthCheck']): this\n {\n this.config.healthCheck = healthCheck;\n return this;\n }\n\n /**\n * Configure infrastructure initialization\n */\n infrastructure(infrastructure: ServerConfig['infrastructure']): this\n {\n this.config.infrastructure = infrastructure;\n return this;\n }\n\n /**\n * Configure lifecycle hooks\n * Can be called multiple times - hooks will be executed in registration order\n */\n lifecycle(lifecycle: ServerConfig['lifecycle']): this\n {\n if (lifecycle)\n {\n this.lifecycles.push(lifecycle);\n }\n return this;\n }\n\n /**\n * Build and return the final configuration\n */\n build(): ServerConfig\n {\n if (this.lifecycles.length > 0)\n {\n serverLogger.info('Merging lifecycles', { count: this.lifecycles.length });\n this.config.lifecycle = this.mergeLifecycles();\n }\n\n return this.config;\n }\n\n private mergeLifecycles(): Lifecycle\n {\n return {\n beforeInfrastructure: createMergedHook(\n collectHooks(this.lifecycles, 'beforeInfrastructure')\n ),\n afterInfrastructure: createMergedHook(\n collectHooks(this.lifecycles, 'afterInfrastructure')\n ),\n beforeRoutes: createMergedHook(\n collectHooks(this.lifecycles, 'beforeRoutes')\n ),\n afterRoutes: createMergedHook(\n collectHooks(this.lifecycles, 'afterRoutes')\n ),\n afterStart: createMergedHook(\n collectHooks(this.lifecycles, 'afterStart')\n ),\n beforeShutdown: createMergedHook(\n collectHooks(this.lifecycles, 'beforeShutdown')\n ),\n };\n }\n}\n\n/**\n * Create a new server configuration builder\n *\n * @example\n * ```typescript\n * // server.config.ts\n * import { defineServerConfig, route, defineRouter } from '@spfn/core/server';\n * import { Type } from '@sinclair/typebox';\n *\n * const appRouter = defineRouter({\n * getUser: route.get('/users/:id')\n * .input({ params: Type.Object({ id: Type.String() }) })\n * .handler(async (c) => {\n * const { params } = await c.data();\n * return { id: params.id, name: 'John' };\n * }),\n * });\n *\n * export default defineServerConfig()\n * .port(3000)\n * .routes(appRouter)\n * .middleware({ logger: true, cors: true })\n * .debug(true)\n * .build();\n * ```\n */\nexport function defineServerConfig(): ServerConfigBuilder\n{\n return new ServerConfigBuilder();\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../src/logger/formatters.ts","../../src/server/dotenv-loader.ts","../../src/event/sse/handler.ts","../../src/server/helpers.ts","../../src/server/logger.ts","../../src/server/create-server.ts","../../src/job/boss.ts","../../src/job/job-router.ts","../../src/job/register-jobs.ts","../../src/server/banner.ts","../../src/server/validation.ts","../../src/server/start-server.ts","../../src/server/config-builder.ts"],"names":["config","logger","existsSync","jobLogger","job","join","env","infraConfig","getDatabase","resolve","formatUnhandledRejection","cors"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Logger Formatters\n *\n * Log formatting utilities for console and JSON outputs with sensitive data masking.\n */\n\nimport type { LogLevel, LogMetadata } from './types';\n\n/**\n * 민감 정보로 간주되는 키 목록\n * 이 키들을 포함하는 필드는 자동으로 마스킹됨\n */\nconst SENSITIVE_KEYS = [\n 'password',\n 'passwd',\n 'pwd',\n 'secret',\n 'token',\n 'apikey',\n 'api_key',\n 'accesstoken',\n 'access_token',\n 'refreshtoken',\n 'refresh_token',\n 'authorization',\n 'auth',\n 'cookie',\n 'session',\n 'sessionid',\n 'session_id',\n 'privatekey',\n 'private_key',\n 'creditcard',\n 'credit_card',\n 'cardnumber',\n 'card_number',\n 'cvv',\n 'ssn',\n 'pin',\n];\n\n/**\n * 마스킹된 값\n */\nconst MASKED_VALUE = '***MASKED***';\n\n/**\n * 키가 민감 정보를 포함하는지 확인\n */\nfunction isSensitiveKey(key: string): boolean\n{\n const lowerKey = key.toLowerCase();\n return SENSITIVE_KEYS.some(sensitive => lowerKey.includes(sensitive));\n}\n\n/**\n * 민감 정보 마스킹\n * Context 객체에서 민감한 정보(비밀번호, 토큰 등)를 마스킹\n * Circular reference를 안전하게 처리\n *\n * @param data - 원본 데이터\n * @param seen - 순환 참조 감지용 WeakSet (내부 사용)\n * @returns 마스킹된 데이터\n */\nexport function maskSensitiveData(data: unknown, seen = new WeakSet<object>()): unknown\n{\n // null, undefined 처리\n if (data === null || data === undefined)\n {\n return data;\n }\n\n // 기본 타입은 그대로 반환\n if (typeof data !== 'object')\n {\n return data;\n }\n\n // Circular reference 감지\n if (seen.has(data as object))\n {\n return '[Circular]';\n }\n seen.add(data as object);\n\n // 배열 처리\n if (Array.isArray(data))\n {\n return data.map(item => maskSensitiveData(item, seen));\n }\n\n // 객체 처리\n const masked: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data))\n {\n if (isSensitiveKey(key))\n {\n // 민감 정보 키는 마스킹\n masked[key] = MASKED_VALUE;\n }\n else if (typeof value === 'object' && value !== null)\n {\n // 중첩된 객체는 재귀 처리 (seen 전달)\n masked[key] = maskSensitiveData(value, seen);\n }\n else\n {\n // 일반 값은 그대로 유지\n masked[key] = value;\n }\n }\n\n return masked;\n}\n\n/**\n * ANSI 컬러 코드\n */\nconst COLORS = {\n reset: '\\x1b[0m',\n bright: '\\x1b[1m',\n dim: '\\x1b[2m',\n\n // 로그 레벨 컬러\n debug: '\\x1b[36m', // cyan\n info: '\\x1b[32m', // green\n warn: '\\x1b[33m', // yellow\n error: '\\x1b[31m', // red\n fatal: '\\x1b[35m', // magenta\n\n // 추가 컬러\n gray: '\\x1b[90m',\n};\n\n/**\n * 로그 레벨을 컬러 문자열로 변환\n */\nexport function colorizeLevel(level: LogLevel): string\n{\n const color = COLORS[level];\n const levelStr = level.toUpperCase().padEnd(5);\n return `${color}${levelStr}${COLORS.reset}`;\n}\n\n/**\n * 타임스탬프 포맷 (ISO 8601)\n */\nexport function formatTimestamp(date: Date): string\n{\n return date.toISOString();\n}\n\n/**\n * 타임스탬프 포맷 (사람이 읽기 쉬운 형식)\n */\nexport function formatTimestampHuman(date: Date): string\n{\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n const seconds = String(date.getSeconds()).padStart(2, '0');\n const ms = String(date.getMilliseconds()).padStart(3, '0');\n\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${ms}`;\n}\n\n/**\n * 에러 객체를 문자열로 변환 (스택 트레이스 포함)\n */\nexport function formatError(error: Error): string\n{\n const lines: string[] = [];\n\n lines.push(`${error.name}: ${error.message}`);\n\n if (error.stack)\n {\n const stackLines = error.stack.split('\\n').slice(1);\n lines.push(...stackLines);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Context 객체를 문자열로 변환\n */\nexport function formatContext(context: Record<string, unknown>): string\n{\n try\n {\n return JSON.stringify(context, null, 2);\n }\n catch (error)\n {\n return '[Context serialization failed]';\n }\n}\n\n/**\n * 콘솔용 컬러 포맷\n */\nexport function formatConsole(metadata: LogMetadata, colorize = true): string\n{\n const parts: string[] = [];\n\n // [타임스탬프]\n const timestamp = formatTimestampHuman(metadata.timestamp);\n if (colorize)\n {\n parts.push(`${COLORS.gray}[${timestamp}]${COLORS.reset}`);\n }\n else\n {\n parts.push(`[${timestamp}]`);\n }\n\n // [pid=12345]\n const pid = process.pid;\n if (colorize)\n {\n parts.push(`${COLORS.dim}[pid=${pid}]${COLORS.reset}`);\n }\n else\n {\n parts.push(`[pid=${pid}]`);\n }\n\n // [module=value]\n if (metadata.module)\n {\n if (colorize)\n {\n parts.push(`${COLORS.dim}[module=${metadata.module}]${COLORS.reset}`);\n }\n else\n {\n parts.push(`[module=${metadata.module}]`);\n }\n }\n\n // Context를 각각 [key=value] 형태로 추가\n if (metadata.context && Object.keys(metadata.context).length > 0)\n {\n Object.entries(metadata.context).forEach(([key, value]) =>\n {\n let valueStr: string;\n if (typeof value === 'string')\n {\n valueStr = value;\n }\n else if (typeof value === 'object' && value !== null)\n {\n try\n {\n valueStr = JSON.stringify(value);\n }\n catch (error)\n {\n valueStr = '[circular]';\n }\n }\n else\n {\n valueStr = String(value);\n }\n\n if (colorize)\n {\n parts.push(`${COLORS.dim}[${key}=${valueStr}]${COLORS.reset}`);\n }\n else\n {\n parts.push(`[${key}=${valueStr}]`);\n }\n });\n }\n\n // (LEVEL):\n const levelStr = metadata.level.toUpperCase();\n if (colorize)\n {\n const color = COLORS[metadata.level];\n parts.push(`${color}(${levelStr})${COLORS.reset}:`);\n }\n else\n {\n parts.push(`(${levelStr}):`);\n }\n\n // 메시지\n if (colorize)\n {\n parts.push(`${COLORS.bright}${metadata.message}${COLORS.reset}`);\n }\n else\n {\n parts.push(metadata.message);\n }\n\n let output = parts.join(' ');\n\n // 에러는 별도 줄로 추가\n if (metadata.error)\n {\n output += '\\n' + formatError(metadata.error);\n }\n\n return output;\n}\n\n/**\n * JSON 포맷 (파일 저장 및 전송용)\n */\nexport function formatJSON(metadata: LogMetadata): string\n{\n const obj: Record<string, unknown> = {\n timestamp: formatTimestamp(metadata.timestamp),\n level: metadata.level,\n message: metadata.message,\n };\n\n if (metadata.module)\n {\n obj.module = metadata.module;\n }\n\n if (metadata.context)\n {\n obj.context = metadata.context;\n }\n\n if (metadata.error)\n {\n obj.error = {\n name: metadata.error.name,\n message: metadata.error.message,\n stack: metadata.error.stack,\n };\n }\n\n return JSON.stringify(obj);\n}\n\n/**\n * Drizzle ORM 에러에서 쿼리 정보 추출\n *\n * Drizzle ORM은 에러 메시지에 다음 형식으로 정보를 포함:\n * - \"Failed query: <QUERY>\\nparams: <PARAMS>\"\n * - \"Query: <QUERY>\"\n *\n * @param error - Error 객체\n * @returns 쿼리 정보 (query, params, table)\n */\nexport function extractQueryInfo(error: Error): {\n query?: string;\n params?: unknown;\n table?: string;\n} | null\n{\n const message = error.message;\n\n if (!message) return null;\n\n const result: {\n query?: string;\n params?: unknown;\n table?: string;\n } = {};\n\n // Extract query from \"Failed query: ...\" or \"Query: ...\"\n const queryMatch = message.match(/(?:Failed query:|Query:)\\s*([^\\n]+)/);\n if (queryMatch)\n {\n result.query = queryMatch[1].trim();\n\n // Extract table name from query (e.g., UPDATE \"table_name\" or INSERT INTO \"table_name\")\n const tableMatch = result.query.match(/(?:UPDATE|INSERT INTO|DELETE FROM|FROM)\\s+\"?([a-zA-Z_][a-zA-Z0-9_]*)\"?\\.\"?([a-zA-Z_][a-zA-Z0-9_]*)\"?|(?:UPDATE|INSERT INTO|DELETE FROM|FROM)\\s+\"?([a-zA-Z_][a-zA-Z0-9_]*)\"?/i);\n if (tableMatch)\n {\n // Schema.Table or just Table\n result.table = tableMatch[2] || tableMatch[3] || tableMatch[1];\n }\n }\n\n // Extract params from \"params: ...\"\n const paramsMatch = message.match(/params:\\s*(.+?)(?:\\n|$)/);\n if (paramsMatch)\n {\n const paramsStr = paramsMatch[1].trim();\n try\n {\n // Try to parse as comma-separated values\n result.params = paramsStr.split(',').map(p => p.trim());\n }\n catch (e)\n {\n result.params = paramsStr;\n }\n }\n\n return Object.keys(result).length > 0 ? result : null;\n}\n\n/**\n * Promise rejection의 호출 스택에서 실제 발생 위치 추출\n *\n * 스택 트레이스에서 다음 정보를 추출:\n * - 실제 에러 발생 파일 경로\n * - 라인 번호\n * - 함수명/메서드명\n * - Repository 정보 (있는 경우)\n *\n * @param error - Error 객체\n * @returns Promise context 정보\n */\nexport function extractPromiseContext(error: Error): Record<string, unknown>\n{\n const context: Record<string, unknown> = {};\n\n if (!error.stack) return context;\n\n const stackLines = error.stack.split('\\n');\n\n // Skip first line (error message) and find first meaningful stack frame\n // Ignore node_modules and internal Node.js paths\n for (let i = 1; i < stackLines.length; i++)\n {\n const line = stackLines[i].trim();\n\n // Skip node_modules and node internals\n if (line.includes('node_modules') || line.includes('node:internal')) continue;\n\n // Extract file, line number, and function name\n // Format: \"at ClassName.methodName (file.ts:line:col)\"\n // or: \"at functionName (file.ts:line:col)\"\n // or: \"at file.ts:line:col\"\n\n const match = line.match(/at\\s+(?:([a-zA-Z_$][\\w$]*(?:\\.[a-zA-Z_$][\\w$]*)*)\\s+)?\\(?([^)]+):(\\d+):(\\d+)\\)?/);\n\n if (match)\n {\n const [, functionName, filePath, lineNumber, columnNumber] = match;\n\n // Extract just the filename from the full path\n const fileNameMatch = filePath.match(/([^/\\\\]+)$/);\n const fileName = fileNameMatch ? fileNameMatch[1] : filePath;\n\n context.file = fileName;\n context.line = parseInt(lineNumber, 10);\n context.column = parseInt(columnNumber, 10);\n\n if (functionName)\n {\n // Check if it's a class method (e.g., \"ClassName.methodName\")\n const methodMatch = functionName.match(/^(.+)\\.([^.]+)$/);\n if (methodMatch)\n {\n const [, className, methodName] = methodMatch;\n\n context.class = className;\n context.method = methodName;\n\n // Check if it's a Repository\n if (className.includes('Repository'))\n {\n context.repository = className;\n }\n }\n else\n {\n context.function = functionName;\n }\n }\n\n // Found first relevant frame, stop here\n break;\n }\n }\n\n return context;\n}\n\n/**\n * Unhandled rejection 에러를 상세하게 포맷팅\n *\n * Promise context와 DB 쿼리 정보를 자동으로 추출하여\n * 에러 발생 위치와 원인을 명확하게 파악할 수 있도록 함\n *\n * @param reason - Rejection 원인 (Error 또는 기타)\n * @param promise - Promise 객체\n * @returns 상세 context 정보\n */\nexport function formatUnhandledRejection(reason: unknown, promise: Promise<unknown>): {\n error: Error;\n context: Record<string, unknown>;\n}\n{\n // Convert reason to Error if not already\n let error: Error;\n if (reason instanceof Error)\n {\n error = reason;\n }\n else if (typeof reason === 'string')\n {\n error = new Error(reason);\n }\n else\n {\n error = new Error(JSON.stringify(reason));\n }\n\n const context: Record<string, unknown> = {\n promise: String(promise),\n };\n\n // Extract promise context (file, line, function, etc.)\n const promiseContext = extractPromiseContext(error);\n if (Object.keys(promiseContext).length > 0)\n {\n context.promiseContext = promiseContext;\n }\n\n // Extract DB query info if available\n const queryInfo = extractQueryInfo(error);\n if (queryInfo)\n {\n context.queryInfo = queryInfo;\n }\n\n return { error, context };\n}","import { config } from \"dotenv\";\nimport { existsSync } from \"fs\";\nimport { resolve } from \"path\";\n\n/**\n * Load environment files for SPFN server\n *\n * Priority (high → low, later files don't override):\n * 1. .env.server.local - Server-only secrets (gitignored)\n * 2. .env.server - Server-only defaults\n * 3. .env.{NODE_ENV}.local\n * 4. .env.local - Local overrides (gitignored)\n * 5. .env.{NODE_ENV}\n * 6. .env - Defaults\n */\nexport function loadEnvFiles()\n{\n const cwd = process.cwd();\n const nodeEnv = process.env.NODE_ENV || 'development';\n\n // Build list of .env files to load (in priority order, high → low)\n // dotenv won't override existing vars, so load high-priority files first\n const envFiles: string[] = [\n '.env.server.local',\n '.env.server',\n `.env.${nodeEnv}.local`,\n nodeEnv !== 'test' ? '.env.local' : null,\n `.env.${nodeEnv}`,\n '.env',\n ].filter((file): file is string => file !== null);\n\n // Load each file if it exists\n for (const file of envFiles)\n {\n const filePath = resolve(cwd, file);\n if (existsSync(filePath))\n {\n config({ path: filePath });\n }\n }\n}","/**\n * SSE Handler for Hono\n *\n * Creates SSE stream endpoint for event subscription\n *\n * @example\n * ```typescript\n * import { Hono } from 'hono';\n * import { createSSEHandler } from '@spfn/core/event/sse';\n * import { eventRouter } from './events';\n *\n * const app = new Hono();\n *\n * // GET /events/stream?events=userCreated,orderPlaced\n * app.get('/events/stream', createSSEHandler(eventRouter));\n * ```\n */\n\nimport type { Context } from 'hono';\nimport { streamSSE } from 'hono/streaming';\nimport { logger } from '@spfn/core/logger';\nimport type { EventRouterDef, InferEventNames } from '../router';\nimport type { SSEHandlerConfig } from './types';\n\nconst sseLogger = logger.child('@spfn/core:sse');\n\n/**\n * Create SSE handler for Hono\n *\n * Query parameters:\n * - events: Comma-separated list of event names to subscribe\n *\n * @example\n * ```typescript\n * app.get('/events/stream', createSSEHandler(eventRouter, {\n * pingInterval: 30000,\n * }));\n * ```\n */\nexport function createSSEHandler<TRouter extends EventRouterDef<any>>(\n router: TRouter,\n config: SSEHandlerConfig = {}\n)\n{\n const {\n pingInterval = 30000,\n // headers: customHeaders = {}, // Reserved for future use\n } = config;\n\n return async (c: Context) =>\n {\n // Parse events from query parameter\n const eventsParam = c.req.query('events');\n\n if (!eventsParam)\n {\n return c.json({ error: 'Missing events parameter' }, 400);\n }\n\n const requestedEvents = eventsParam.split(',').map(e => e.trim());\n\n // Validate event names\n const validEventNames = router.eventNames as string[];\n const invalidEvents = requestedEvents.filter(e => !validEventNames.includes(e));\n\n if (invalidEvents.length > 0)\n {\n return c.json({\n error: 'Invalid event names',\n invalidEvents,\n validEvents: validEventNames,\n }, 400);\n }\n\n sseLogger.debug('SSE connection requested', {\n events: requestedEvents,\n clientIp: c.req.header('x-forwarded-for') || c.req.header('x-real-ip'),\n });\n\n // Start SSE stream\n return streamSSE(c, async (stream) =>\n {\n const unsubscribes: (() => void)[] = [];\n let messageId = 0;\n\n // Subscribe to each requested event\n for (const eventName of requestedEvents as InferEventNames<TRouter>[])\n {\n const eventDef = router.events[eventName];\n\n if (!eventDef)\n {\n continue;\n }\n\n const unsubscribe = eventDef.subscribe((payload: unknown) =>\n {\n messageId++;\n\n const message = {\n event: eventName,\n data: payload,\n };\n\n sseLogger.debug('SSE sending event', {\n event: eventName,\n messageId,\n });\n\n // Fire-and-forget in sync callback\n void stream.writeSSE({\n id: String(messageId),\n event: eventName as string,\n data: JSON.stringify(message),\n });\n });\n\n unsubscribes.push(unsubscribe);\n }\n\n sseLogger.info('SSE connection established', {\n events: requestedEvents,\n subscriptionCount: unsubscribes.length,\n });\n\n // Send initial connection message\n await stream.writeSSE({\n event: 'connected',\n data: JSON.stringify({\n subscribedEvents: requestedEvents,\n timestamp: Date.now(),\n }),\n });\n\n // Keep-alive ping\n const pingTimer = setInterval(() =>\n {\n // Fire-and-forget in sync callback\n void stream.writeSSE({\n event: 'ping',\n data: JSON.stringify({ timestamp: Date.now() }),\n });\n }, pingInterval);\n\n // Wait for client disconnect using abort signal\n const abortSignal = c.req.raw.signal;\n\n while (!abortSignal.aborted)\n {\n await stream.sleep(pingInterval);\n }\n\n // Cleanup\n clearInterval(pingTimer);\n unsubscribes.forEach(fn => fn());\n\n sseLogger.info('SSE connection closed', {\n events: requestedEvents,\n });\n }, async (err: Error) =>\n {\n sseLogger.error('SSE stream error', {\n error: err.message,\n });\n });\n };\n}\n\n","import type { Hono, Handler, MiddlewareHandler } from 'hono';\nimport type { Server } from 'http';\nimport { getDatabase } from '@spfn/core/db';\nimport { getCache } from '@spfn/core/cache';\nimport { env } from '@spfn/core/config';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface ServiceStatus\n{\n status: string;\n error?: string;\n}\n\ninterface HealthCheckResponse\n{\n status: 'ok' | 'degraded';\n timestamp: string;\n services?: {\n database: ServiceStatus;\n redis: ServiceStatus;\n };\n}\n\ninterface StartupConfig\n{\n middleware: {\n logger: boolean;\n cors: boolean;\n errorHandler: boolean;\n custom: number;\n };\n healthCheck: {\n enabled: boolean;\n path?: string;\n detailed?: boolean;\n };\n hooks: {\n beforeRoutes: boolean;\n afterRoutes: boolean;\n };\n timeout: {\n request: string;\n keepAlive: string;\n headers: string;\n };\n shutdown: {\n timeout: string;\n };\n}\n\n// ============================================================================\n// Functions\n// ============================================================================\n\nexport function createHealthCheckHandler(detailed: boolean): Handler\n{\n return async (c) =>\n {\n const response: HealthCheckResponse = {\n status: 'ok',\n timestamp: new Date().toISOString(),\n };\n\n if (detailed)\n {\n let dbStatus: string = 'unknown';\n let dbError: string | undefined;\n\n // Try to get database instance\n try\n {\n const db = getDatabase();\n try\n {\n await db.execute('SELECT 1');\n dbStatus = 'connected';\n }\n catch (error)\n {\n dbStatus = 'error';\n dbError = error instanceof Error ? error.message : String(error);\n }\n }\n catch (error)\n {\n // Database not initialized\n dbStatus = 'not_initialized';\n dbError = 'Database not available';\n }\n\n const redis = getCache();\n let redisStatus: string = redis ? 'unknown' : 'not_initialized';\n let redisError: string | undefined;\n if (redis)\n {\n try\n {\n await redis.ping();\n redisStatus = 'connected';\n }\n catch (error)\n {\n redisStatus = 'error';\n redisError = error instanceof Error ? error.message : String(error);\n }\n }\n\n response.services = {\n database: {\n status: dbStatus,\n ...(dbError && { error: dbError }),\n },\n redis: {\n status: redisStatus,\n ...(redisError && { error: redisError }),\n },\n };\n\n const hasErrors =\n (dbStatus === 'error' || dbStatus === 'not_initialized') ||\n (redisStatus === 'error');\n response.status = hasErrors ? 'degraded' : 'ok';\n }\n\n const statusCode = response.status === 'ok' ? 200 : 503;\n return c.json(response, statusCode);\n };\n}\n\nexport function applyServerTimeouts(\n server: Server,\n timeouts: {\n request: number;\n keepAlive: number;\n headers: number;\n }\n): void\n{\n if ('timeout' in server)\n {\n server.timeout = timeouts.request;\n server.keepAliveTimeout = timeouts.keepAlive;\n server.headersTimeout = timeouts.headers;\n }\n}\n\nexport function getTimeoutConfig(config?: {\n request?: number;\n keepAlive?: number;\n headers?: number;\n}): {\n request: number;\n keepAlive: number;\n headers: number;\n}\n{\n return {\n request: config?.request ?? env.SERVER_TIMEOUT,\n keepAlive: config?.keepAlive ?? env.SERVER_KEEPALIVE_TIMEOUT,\n headers: config?.headers ?? env.SERVER_HEADERS_TIMEOUT,\n };\n}\n\nexport function getShutdownTimeout(config?: { timeout?: number }): number\n{\n return config?.timeout ?? env.SHUTDOWN_TIMEOUT;\n}\n\nexport function buildMiddlewareOrder(config: {\n middleware?: {\n logger?: boolean;\n cors?: boolean;\n errorHandler?: boolean;\n };\n use?: MiddlewareHandler[];\n beforeRoutes?: (app: Hono) => void | Promise<void>;\n afterRoutes?: (app: Hono) => void | Promise<void>;\n}): string[]\n{\n const order: string[] = [];\n const middlewareConfig = config.middleware ?? {};\n const enableLogger = middlewareConfig.logger !== false;\n const enableCors = middlewareConfig.cors !== false;\n const enableErrorHandler = middlewareConfig.errorHandler !== false;\n\n if (enableLogger) order.push('RequestLogger');\n if (enableCors) order.push('CORS');\n config.use?.forEach((_, i) => order.push(`Custom[${i}]`));\n if (config.beforeRoutes) order.push('beforeRoutes hook');\n order.push('Routes');\n if (config.afterRoutes) order.push('afterRoutes hook');\n if (enableErrorHandler) order.push('ErrorHandler');\n\n return order;\n}\n\nexport function buildStartupConfig(\n config: {\n middleware?: {\n logger?: boolean;\n cors?: boolean;\n errorHandler?: boolean;\n };\n use?: MiddlewareHandler[];\n healthCheck?: {\n enabled?: boolean;\n path?: string;\n detailed?: boolean;\n };\n beforeRoutes?: (app: Hono) => void | Promise<void>;\n afterRoutes?: (app: Hono) => void | Promise<void>;\n shutdown?: {\n timeout?: number;\n };\n },\n timeouts: {\n request: number;\n keepAlive: number;\n headers: number;\n }\n): StartupConfig\n{\n const middlewareConfig = config.middleware ?? {};\n const healthCheckConfig = config.healthCheck ?? {};\n const healthCheckEnabled = healthCheckConfig.enabled !== false;\n const healthCheckPath = healthCheckConfig.path ?? '/health';\n const healthCheckDetailed = healthCheckConfig.detailed ?? (env.NODE_ENV === 'development');\n\n return {\n middleware: {\n logger: middlewareConfig.logger !== false,\n cors: middlewareConfig.cors !== false,\n errorHandler: middlewareConfig.errorHandler !== false,\n custom: config.use?.length ?? 0,\n },\n healthCheck: healthCheckEnabled ? {\n enabled: true,\n path: healthCheckPath,\n detailed: healthCheckDetailed,\n } : { enabled: false },\n hooks: {\n beforeRoutes: !!config.beforeRoutes,\n afterRoutes: !!config.afterRoutes,\n },\n timeout: {\n request: `${timeouts.request}ms`,\n keepAlive: `${timeouts.keepAlive}ms`,\n headers: `${timeouts.headers}ms`,\n },\n shutdown: {\n timeout: `${config.shutdown?.timeout ?? env.SHUTDOWN_TIMEOUT}ms`,\n },\n };\n}\n","import { logger } from \"@spfn/core/logger\";\n\nexport const serverLogger = logger.child('@spfn/core:server');","/**\n * Create Hono Server\n *\n * Creates and configures a Hono application instance.\n */\n\nimport { Hono } from 'hono';\nimport { cors } from 'hono/cors';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\n\nimport { registerRoutes, type RegisteredRoute } from '@spfn/core/route';\nimport { ErrorHandler, RequestLogger } from '@spfn/core/middleware';\nimport { createSSEHandler } from '../event/sse/handler';\nimport { createHealthCheckHandler } from './helpers';\nimport { serverLogger } from './logger';\n\nimport type { ServerConfig, AppFactory } from './types';\n\n// Extend Hono context with error handler flag\ndeclare module 'hono'\n{\n interface ContextVariableMap\n {\n errorHandlerEnabled?: boolean;\n }\n}\n\n/**\n * Create Hono app with automatic configuration\n *\n * Levels:\n * 1. No app.ts -> Full auto config\n * 2. server.config.ts -> Partial customization\n * 3. app.ts -> Full control (no auto config)\n */\nexport async function createServer(config?: ServerConfig): Promise<Hono>\n{\n const cwd = process.cwd();\n const appPath = join(cwd, 'src', 'server', 'app.ts');\n const appJsPath = join(cwd, 'src', 'server', 'app');\n\n // Level 3: Full control with app.ts\n if (existsSync(appPath) || existsSync(appJsPath))\n {\n return await loadCustomApp(appPath, appJsPath, config);\n }\n\n // Level 1 & 2: Auto config\n return await createAutoConfiguredApp(config);\n}\n\nasync function loadCustomApp(\n appPath: string,\n appJsPath: string,\n config?: ServerConfig\n): Promise<Hono>\n{\n // Determine which path exists to avoid duplicate checks\n const actualPath = existsSync(appPath) ? appPath : appJsPath;\n const appModule = await import(actualPath);\n const appFactory: AppFactory = appModule.default;\n\n if (!appFactory)\n {\n throw new Error('app.ts must export a default function that returns a Hono app');\n }\n\n const app = await appFactory();\n\n // Register routes (if provided via config)\n if (config?.routes)\n {\n const routes = registerRoutes(app, config.routes, config.middlewares);\n logRegisteredRoutes(routes, config?.debug ?? false);\n }\n\n return app;\n}\n\nasync function createAutoConfiguredApp(config?: ServerConfig): Promise<Hono>\n{\n const app = new Hono();\n\n const middlewareConfig = config?.middleware ?? {};\n const enableLogger = middlewareConfig.logger !== false;\n const enableCors = middlewareConfig.cors !== false;\n const enableErrorHandler = middlewareConfig.errorHandler !== false;\n\n // 1. Set error handler flag in context\n if (enableErrorHandler)\n {\n app.use('*', async (c, next) =>\n {\n c.set('errorHandlerEnabled', true);\n await next();\n });\n }\n\n // 2. Default middleware\n applyDefaultMiddleware(app, config, enableLogger, enableCors);\n\n // 3. Custom middleware\n if (Array.isArray(config?.use))\n {\n config.use.forEach(mw => app.use('*', mw));\n }\n\n // 4. Health check endpoint\n registerHealthCheckEndpoint(app, config);\n\n // 5. beforeRoutes hook from config\n await executeBeforeRoutesHook(app, config);\n\n // 6. Load routes\n await loadAppRoutes(app, config);\n\n // 7. Register SSE endpoint (if events router provided)\n registerSSEEndpoint(app, config);\n\n // 8. afterRoutes hook from config\n await executeAfterRoutesHook(app, config);\n\n // 9. Error handler\n if (enableErrorHandler)\n {\n app.onError(ErrorHandler());\n }\n\n return app;\n}\n\nfunction applyDefaultMiddleware(\n app: Hono,\n config: ServerConfig | undefined,\n enableLogger: boolean,\n enableCors: boolean\n): void\n{\n if (enableLogger)\n {\n app.use('*', RequestLogger());\n }\n\n if (enableCors)\n {\n // Only apply cors if config.cors is not explicitly false\n // This handles both config.cors = undefined and config.cors = {...options}\n const corsOptions = config?.cors !== false ? config?.cors : undefined;\n app.use('*', cors(corsOptions));\n }\n}\n\nfunction registerHealthCheckEndpoint(app: Hono, config?: ServerConfig): void\n{\n const healthCheckConfig = config?.healthCheck ?? {};\n const healthCheckEnabled = healthCheckConfig.enabled !== false;\n const healthCheckPath = healthCheckConfig.path ?? '/health';\n const healthCheckDetailed = healthCheckConfig.detailed\n ?? process.env.NODE_ENV === 'development';\n\n if (healthCheckEnabled)\n {\n app.get(healthCheckPath, createHealthCheckHandler(healthCheckDetailed));\n serverLogger.debug(`Health check endpoint enabled at ${healthCheckPath}`);\n }\n}\n\nasync function executeBeforeRoutesHook(app: Hono, config?: ServerConfig): Promise<void>\n{\n if (config?.lifecycle?.beforeRoutes)\n {\n await config.lifecycle.beforeRoutes(app);\n }\n}\n\nasync function loadAppRoutes(app: Hono, config?: ServerConfig): Promise<void>\n{\n const debug = isDebugMode(config);\n\n // Register define-route based routes (if provided)\n if (config?.routes)\n {\n const routes = registerRoutes(app, config.routes, config.middlewares);\n logRegisteredRoutes(routes, debug);\n }\n else if (debug)\n {\n serverLogger.warn('⚠️ No routes configured. Use defineServerConfig().routes() to register routes.');\n }\n}\n\n/**\n * Log registered routes in a formatted table\n */\nfunction logRegisteredRoutes(routes: RegisteredRoute[], debug: boolean): void\n{\n if (routes.length === 0)\n {\n if (debug)\n {\n serverLogger.warn('⚠️ No routes registered');\n }\n return;\n }\n\n // Sort routes by path for better readability\n const sortedRoutes = [...routes].sort((a, b) => a.path.localeCompare(b.path));\n\n // Calculate max method length for alignment\n const maxMethodLen = Math.max(...sortedRoutes.map(r => r.method.length));\n\n // Build route list string\n const routeLines = sortedRoutes.map(r =>\n ` ${r.method.padEnd(maxMethodLen)} ${r.path}`\n ).join('\\n');\n\n serverLogger.info(`✓ Routes registered (${routes.length}):\\n${routeLines}`);\n}\n\nasync function executeAfterRoutesHook(app: Hono, config?: ServerConfig): Promise<void>\n{\n if (config?.lifecycle?.afterRoutes)\n {\n await config.lifecycle.afterRoutes(app);\n }\n}\n\n/**\n * Register SSE endpoint for event streaming\n */\nfunction registerSSEEndpoint(app: Hono, config?: ServerConfig): void\n{\n if (!config?.events)\n {\n return;\n }\n\n const eventsConfig = config.eventsConfig ?? {};\n const path = eventsConfig.path ?? '/events/stream';\n const debug = isDebugMode(config);\n\n // Register SSE handler\n app.get(path, createSSEHandler(config.events, eventsConfig));\n\n if (debug)\n {\n const eventNames = config.events.eventNames as string[];\n serverLogger.info(`✓ SSE endpoint registered at ${path}`, {\n events: eventNames,\n });\n }\n}\n\n/**\n * Determine if debug mode is enabled\n */\nfunction isDebugMode(config?: ServerConfig): boolean\n{\n return config?.debug ?? process.env.NODE_ENV === 'development';\n}","/**\n * pg-boss Wrapper\n *\n * Manages pg-boss instance lifecycle\n */\n\nimport PgBoss from 'pg-boss';\nimport { logger } from '@spfn/core/logger';\n\nconst jobLogger = logger.child('@spfn/core:job');\n\n/**\n * Global pg-boss instance\n */\nlet bossInstance: PgBoss | null = null;\n\n/**\n * Stored config for access during registration\n */\nlet bossConfig: BossConfig | null = null;\n\n/**\n * Options for pg-boss initialization\n *\n * @example\n * ```typescript\n * await initBoss({\n * connectionString: process.env.DATABASE_URL,\n * schema: 'spfn_queue',\n * clearOnStart: process.env.NODE_ENV === 'development',\n * });\n * ```\n */\nexport interface BossOptions\n{\n /**\n * PostgreSQL connection string\n *\n * @example 'postgresql://user:password@localhost:5432/mydb'\n */\n connectionString: string;\n\n /**\n * Schema name for pg-boss tables\n *\n * pg-boss creates its own tables in this schema.\n *\n * @default 'spfn_queue'\n */\n schema?: string;\n\n /**\n * Maintenance interval in seconds\n *\n * pg-boss runs maintenance tasks (cleanup, archiving) at this interval.\n *\n * @default 120\n */\n maintenanceIntervalSeconds?: number;\n\n /**\n * Monitor state changes interval in seconds\n *\n * When set, pg-boss emits state change events at this interval.\n *\n * @default undefined (disabled)\n */\n monitorIntervalSeconds?: number;\n\n /**\n * Clear all pending/scheduled jobs on startup\n *\n * Useful for development mode to start with a clean queue.\n * Should be false in production.\n *\n * @default false\n */\n clearOnStart?: boolean;\n}\n\n/**\n * @deprecated Use BossOptions instead\n */\nexport type BossConfig = BossOptions;\n\n/**\n * Initialize pg-boss with the given configuration\n *\n * Must be called before registerJobs(). Typically handled by defineServerConfig().\n *\n * @param options - pg-boss configuration options\n * @returns The pg-boss instance\n *\n * @example\n * ```typescript\n * const boss = await initBoss({\n * connectionString: process.env.DATABASE_URL!,\n * schema: 'spfn_queue',\n * });\n * ```\n */\nexport async function initBoss(options: BossOptions): Promise<PgBoss>\n{\n if (bossInstance)\n {\n jobLogger.warn('pg-boss already initialized, returning existing instance');\n return bossInstance;\n }\n\n jobLogger.info('Initializing pg-boss...');\n\n bossConfig = options;\n\n const pgBossOptions: PgBoss.ConstructorOptions = {\n connectionString: options.connectionString,\n schema: options.schema ?? 'spfn_queue',\n maintenanceIntervalSeconds: options.maintenanceIntervalSeconds ?? 120,\n };\n\n // Only set monitorIntervalSeconds if explicitly provided (must be >= 1)\n if (options.monitorIntervalSeconds !== undefined && options.monitorIntervalSeconds >= 1)\n {\n pgBossOptions.monitorIntervalSeconds = options.monitorIntervalSeconds;\n }\n\n bossInstance = new PgBoss(pgBossOptions);\n\n // Event handlers\n bossInstance.on('error', (error) =>\n {\n jobLogger.error('pg-boss error:', error);\n });\n\n await bossInstance.start();\n\n jobLogger.info('pg-boss started successfully');\n\n return bossInstance;\n}\n\n/**\n * Get the current pg-boss instance\n */\nexport function getBoss(): PgBoss | null\n{\n return bossInstance;\n}\n\n/**\n * Stop pg-boss gracefully\n */\nexport async function stopBoss(): Promise<void>\n{\n if (!bossInstance)\n {\n return;\n }\n\n jobLogger.info('Stopping pg-boss...');\n\n try\n {\n await bossInstance.stop({ graceful: true, timeout: 30000 });\n jobLogger.info('pg-boss stopped gracefully');\n }\n catch (error)\n {\n jobLogger.error('Error stopping pg-boss:', error);\n throw error;\n }\n finally\n {\n bossInstance = null;\n bossConfig = null;\n }\n}\n\n/**\n * Check if pg-boss is initialized and running\n */\nexport function isBossRunning(): boolean\n{\n return bossInstance !== null;\n}\n\n/**\n * Check if jobs should be cleared on start\n */\nexport function shouldClearOnStart(): boolean\n{\n return bossConfig?.clearOnStart ?? false;\n}\n","/**\n * Job Router\n *\n * Groups job definitions for registration with the server\n */\n\nimport type { JobDef, JobRouter, JobRouterEntry } from './types';\n\n/**\n * Type guard to check if value is a JobDef\n */\nexport function isJobDef(value: unknown): value is JobDef<any>\n{\n return (\n value !== null &&\n typeof value === 'object' &&\n 'name' in value &&\n 'handler' in value &&\n 'send' in value &&\n 'run' in value\n );\n}\n\n/**\n * Type guard to check if value is a JobRouter\n */\nexport function isJobRouter(value: unknown): value is JobRouter<any>\n{\n return (\n value !== null &&\n typeof value === 'object' &&\n 'jobs' in value &&\n '_jobs' in value\n );\n}\n\n/**\n * Define a job router to group jobs together\n *\n * @example\n * ```typescript\n * // Flat structure\n * export const jobRouter = defineJobRouter({\n * sendWelcomeEmail,\n * dailyReport,\n * initCache,\n * });\n *\n * // Nested structure\n * export const jobRouter = defineJobRouter({\n * email: defineJobRouter({\n * sendWelcome: sendWelcomeEmailJob,\n * sendReset: sendResetPasswordJob,\n * }),\n * reports: defineJobRouter({\n * daily: dailyReportJob,\n * weekly: weeklyReportJob,\n * }),\n * });\n *\n * // Mixed\n * export const jobRouter = defineJobRouter({\n * initCache, // flat\n * email: defineJobRouter({ ... }), // nested\n * });\n * ```\n */\nexport function defineJobRouter<\n TJobs extends Record<string, JobRouterEntry>\n>(jobs: TJobs): JobRouter<TJobs>\n{\n return {\n jobs,\n _jobs: jobs,\n };\n}\n\n/**\n * Collect all JobDefs from a JobRouter (including nested)\n */\nexport function collectJobs(\n router: JobRouter<any>,\n prefix = ''\n): JobDef<any>[]\n{\n const jobs: JobDef<any>[] = [];\n\n for (const [key, value] of Object.entries(router.jobs))\n {\n const name = prefix ? `${prefix}.${key}` : key;\n\n if (isJobRouter(value))\n {\n // Nested router - recurse\n jobs.push(...collectJobs(value, name));\n }\n else if (isJobDef(value))\n {\n jobs.push(value);\n }\n }\n\n return jobs;\n}\n","/**\n * Job Registration\n *\n * Registers jobs with pg-boss\n */\n\nimport type PgBoss from 'pg-boss';\nimport { logger } from '@spfn/core/logger';\nimport type { JobDef, JobOptions, JobRouter } from './types';\nimport type { EventDef } from '@spfn/core/event';\nimport { collectJobs } from './job-router';\nimport { getBoss, shouldClearOnStart } from './boss';\n\nconst jobLogger = logger.child('@spfn/core:job');\n\n/**\n * Get the pg-boss queue name for an event\n */\nexport function getEventQueueName(eventName: string): string\n{\n return `event:${eventName}`;\n}\n\n/**\n * Build default pg-boss options for a job\n */\nfunction getDefaultJobOptions(options?: JobOptions): PgBoss.SendOptions\n{\n return {\n retryLimit: options?.retryLimit ?? 3,\n retryDelay: options?.retryDelay ?? 1000,\n expireInSeconds: options?.expireInSeconds ?? 300,\n };\n}\n\n/**\n * Register all jobs from a JobRouter with pg-boss\n *\n * This function:\n * 1. Collects all jobs from the router (including nested routers)\n * 2. Optionally clears existing jobs (if clearOnStart is enabled)\n * 3. Registers each job's worker handler with pg-boss\n * 4. Sets up cron schedules for scheduled jobs\n * 5. Queues runOnce jobs\n * 6. Connects event subscriptions to job queues\n *\n * @param router - JobRouter containing job definitions\n *\n * @example\n * ```typescript\n * // Define jobs\n * const sendEmail = job('send-email')\n * .input(Type.Object({ to: Type.String() }))\n * .handler(async (input) => { ... });\n *\n * const dailyReport = job('daily-report')\n * .cron('0 9 * * *')\n * .handler(async () => { ... });\n *\n * // Create router\n * const jobRouter = defineJobRouter({ sendEmail, dailyReport });\n *\n * // Initialize pg-boss first\n * await initBoss({ connectionString: process.env.DATABASE_URL! });\n *\n * // Register jobs\n * await registerJobs(jobRouter);\n * ```\n */\nexport async function registerJobs(router: JobRouter<any>): Promise<void>\n{\n const boss = getBoss();\n if (!boss)\n {\n throw new Error(\n 'pg-boss not initialized. Call initBoss() before registerJobs()'\n );\n }\n\n const jobs = collectJobs(router);\n const clearOnStart = shouldClearOnStart();\n\n jobLogger.info(`Registering ${jobs.length} job(s)...`);\n\n // Clear existing jobs if requested (useful for development)\n if (clearOnStart)\n {\n jobLogger.info('Clearing existing jobs before registration...');\n for (const job of jobs)\n {\n // Clear job queue\n await boss.deleteAllJobs(job.name);\n\n // Also clear event queue if subscribed\n if (job.subscribedEvent)\n {\n const eventQueue = getEventQueueName(job.subscribedEvent);\n await boss.deleteAllJobs(eventQueue);\n }\n }\n jobLogger.info('Existing jobs cleared');\n }\n\n for (const job of jobs)\n {\n await registerJob(job);\n }\n\n jobLogger.info('All jobs registered successfully');\n}\n\n/**\n * Create queue if not exists (required for pg-boss v11+)\n */\nasync function ensureQueue(boss: PgBoss, queueName: string): Promise<void>\n{\n await boss.createQueue(queueName);\n}\n\n/**\n * Register worker handler for a job\n */\nasync function registerWorker(\n boss: PgBoss,\n job: JobDef<any>,\n queueName: string\n): Promise<void>\n{\n // Ensure queue exists before registering worker\n await ensureQueue(boss, queueName);\n\n await boss.work(\n queueName,\n { batchSize: 1 },\n async (jobs) =>\n {\n for (const pgBossJob of jobs)\n {\n jobLogger.debug(`[Job:${job.name}] Executing...`, { jobId: pgBossJob.id });\n\n const startTime = Date.now();\n\n try\n {\n if (job.inputSchema)\n {\n await (job.handler as (input: unknown) => Promise<void>)(pgBossJob.data);\n }\n else\n {\n await (job.handler as () => Promise<void>)();\n }\n\n const duration = Date.now() - startTime;\n jobLogger.info(`[Job:${job.name}] Completed in ${duration}ms`, {\n jobId: pgBossJob.id,\n duration,\n });\n }\n catch (error)\n {\n const duration = Date.now() - startTime;\n jobLogger.error(`[Job:${job.name}] Failed after ${duration}ms`, {\n jobId: pgBossJob.id,\n duration,\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }\n }\n );\n}\n\n/**\n * Connect event to pg-boss queue\n */\nfunction connectEventToQueue(\n boss: PgBoss,\n job: JobDef<any>,\n queueName: string\n): void\n{\n if (!job._subscribedEventDef)\n {\n return;\n }\n\n const eventDef = job._subscribedEventDef as EventDef<any>;\n eventDef._registerJobQueue(queueName, async (queue, payload) =>\n {\n await boss.send(queue, payload as object, getDefaultJobOptions(job.options));\n });\n\n jobLogger.debug(`[Job:${job.name}] Connected to event: ${job.subscribedEvent}`);\n}\n\n/**\n * Register cron schedule for a job\n */\nasync function registerCronSchedule(boss: PgBoss, job: JobDef<any>): Promise<void>\n{\n if (!job.cronExpression)\n {\n return;\n }\n\n jobLogger.debug(`[Job:${job.name}] Scheduling cron: ${job.cronExpression}`);\n\n // Ensure queue exists for cron jobs (uses job.name as queue)\n await ensureQueue(boss, job.name);\n\n await boss.schedule(\n job.name,\n job.cronExpression,\n {},\n getDefaultJobOptions(job.options)\n );\n\n jobLogger.info(`[Job:${job.name}] Cron scheduled: ${job.cronExpression}`);\n}\n\n/**\n * Queue a runOnce job\n */\nasync function queueRunOnceJob(boss: PgBoss, job: JobDef<any>): Promise<void>\n{\n if (!job.runOnce)\n {\n return;\n }\n\n jobLogger.debug(`[Job:${job.name}] Queuing runOnce job`);\n\n // Ensure queue exists for runOnce jobs (uses job.name as queue)\n await ensureQueue(boss, job.name);\n\n await boss.send(\n job.name,\n {},\n {\n ...getDefaultJobOptions(job.options),\n singletonKey: `runOnce:${job.name}`,\n }\n );\n\n jobLogger.info(`[Job:${job.name}] runOnce job queued`);\n}\n\n/**\n * Register a single job with pg-boss\n */\nasync function registerJob(job: JobDef<any>): Promise<void>\n{\n const boss = getBoss();\n if (!boss)\n {\n throw new Error('pg-boss not initialized');\n }\n\n const queueName = job.subscribedEvent\n ? getEventQueueName(job.subscribedEvent)\n : job.name;\n\n jobLogger.debug(`Registering job: ${job.name}`, {\n queueName,\n subscribedEvent: job.subscribedEvent,\n });\n\n await registerWorker(boss, job, queueName);\n connectEventToQueue(boss, job, queueName);\n await registerCronSchedule(boss, job);\n await queueRunOnceJob(boss, job);\n\n jobLogger.debug(`Job registered: ${job.name}`);\n}\n","/**\n * Server Startup Banner\n *\n * Displays SPFN logo and server information at startup.\n */\n\nimport { networkInterfaces } from 'os';\n\n/**\n * Get local network IP address\n */\nfunction getNetworkAddress(): string | null\n{\n const nets = networkInterfaces();\n\n for (const name of Object.keys(nets))\n {\n const netGroup = nets[name];\n if (!netGroup) continue;\n\n for (const net of netGroup)\n {\n // IPv4, non-internal address\n if (net.family === 'IPv4' && !net.internal)\n {\n return net.address;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Print server startup banner\n */\nexport function printBanner(options: {\n mode: string;\n host: string;\n port: number;\n}): void\n{\n const { mode, host, port } = options;\n\n console.log('');\n console.log(' _____ ____ ______ _ _');\n console.log(' / ____| _ \\\\| ____| \\\\ | |');\n console.log(' | (___ | |_) | |__ | \\\\| |');\n console.log(' \\\\___ \\\\| __/| __| | . ` |');\n console.log(' ____) | | | | | |\\\\ |');\n console.log(' |_____/|_| |_| |_| \\\\_|');\n console.log('');\n console.log(` Mode: ${mode}`);\n\n // Show Local and Network addresses like Next.js\n if (host === '0.0.0.0')\n {\n const networkIP = getNetworkAddress();\n console.log(` ▲ Local: http://localhost:${port}`);\n if (networkIP)\n {\n console.log(` ▲ Network: http://${networkIP}:${port}`);\n }\n }\n else\n {\n console.log(` ▲ Local: http://${host}:${port}`);\n }\n\n console.log('');\n}\n","/**\n * Server Configuration Validation\n *\n * Validates server configuration to catch errors early with clear messages.\n */\n\nimport type { ServerConfig } from './types';\n\n/**\n * Validate server configuration\n * Throws descriptive errors for invalid configurations\n */\nexport function validateServerConfig(config: ServerConfig): void\n{\n // Port validation\n if (config.port !== undefined)\n {\n if (!Number.isInteger(config.port) || config.port < 0 || config.port > 65535)\n {\n throw new Error(\n `Invalid port: ${config.port}. Port must be an integer between 0 and 65535.`\n );\n }\n }\n\n // Timeout validation\n if (config.timeout)\n {\n const { request, keepAlive, headers } = config.timeout;\n\n if (request !== undefined && (request < 0 || !Number.isFinite(request)))\n {\n throw new Error(`Invalid timeout.request: ${request}. Must be a positive number.`);\n }\n\n if (keepAlive !== undefined && (keepAlive < 0 || !Number.isFinite(keepAlive)))\n {\n throw new Error(`Invalid timeout.keepAlive: ${keepAlive}. Must be a positive number.`);\n }\n\n if (headers !== undefined && (headers < 0 || !Number.isFinite(headers)))\n {\n throw new Error(`Invalid timeout.headers: ${headers}. Must be a positive number.`);\n }\n\n // Logical validation\n if (headers && request && headers > request)\n {\n throw new Error(\n `Invalid timeout configuration: headers timeout (${headers}ms) cannot exceed request timeout (${request}ms).`\n );\n }\n }\n\n // Shutdown timeout validation\n if (config.shutdown?.timeout !== undefined)\n {\n const timeout = config.shutdown.timeout;\n if (timeout < 0 || !Number.isFinite(timeout))\n {\n throw new Error(`Invalid shutdown.timeout: ${timeout}. Must be a positive number.`);\n }\n }\n\n // Health check path validation\n if (config.healthCheck?.path)\n {\n if (!config.healthCheck.path.startsWith('/'))\n {\n throw new Error(\n `Invalid healthCheck.path: \"${config.healthCheck.path}\". Must start with \"/\".`\n );\n }\n }\n}","/**\n * Start SPFN Server\n *\n * Starts and configures the SPFN HTTP server with graceful shutdown.\n */\n\nimport { serve } from '@hono/node-server';\nimport { existsSync } from 'fs';\nimport type { Hono } from 'hono';\nimport type { Server } from 'http';\nimport { join } from 'path';\n\nimport { closeCache, initCache } from '@spfn/core/cache';\nimport { closeDatabase, initDatabase, getDatabase } from '@spfn/core/db';\nimport { initBoss, stopBoss, registerJobs } from '../job';\nimport { serverLogger } from './logger';\nimport { printBanner } from './banner';\nimport { createServer } from './create-server';\nimport { loadEnvFiles } from \"./dotenv-loader\";\nimport {\n applyServerTimeouts,\n buildMiddlewareOrder,\n buildStartupConfig,\n getShutdownTimeout,\n getTimeoutConfig,\n} from './helpers';\n\nimport type { ServerConfig, ServerInstance } from './types';\nimport { validateServerConfig } from './validation';\nimport { env } from '@spfn/core/config';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_MAX_LISTENERS = 15;\n\nconst TIMEOUTS = {\n SERVER_CLOSE: 5000,\n DATABASE_CLOSE: 5000,\n REDIS_CLOSE: 5000,\n PRODUCTION_ERROR_SHUTDOWN: 10000,\n} as const;\n\nconst CONFIG_FILE_PATHS = [\n '.spfn/server/server.config.mjs',\n '.spfn/server/server.config',\n 'src/server/server.config',\n 'src/server/server.config.ts',\n] as const;\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface InfrastructureConfig\n{\n database: boolean;\n redis: boolean;\n}\n\n/**\n * Shutdown state manager to prevent race conditions\n */\ninterface ShutdownState\n{\n isShuttingDown: boolean;\n}\n\n// ============================================================================\n// Module State\n// ============================================================================\n\n/**\n * Track whether process-level shutdown handlers have been registered\n * Process handlers should only be registered once\n */\nlet processHandlersRegistered = false;\n\n// ============================================================================\n// Main Entry Point\n// ============================================================================\n\n/**\n * Start SPFN server\n *\n * Automatically loads server.config.ts if exists\n * Automatically initializes Database and Redis from environment\n * Sets up graceful shutdown handlers for SIGTERM and SIGINT\n *\n * @returns ServerInstance with server, app, config, and close() method\n */\nexport async function startServer(config?: ServerConfig): Promise<ServerInstance>\n{\n loadEnvFiles();\n\n const finalConfig = await loadAndMergeConfig(config);\n const { host, port, debug } = finalConfig;\n\n validateServerConfig(finalConfig);\n\n // Validate required config values\n if (!host || !port)\n {\n throw new Error('Server host and port are required');\n }\n\n if (debug)\n {\n logMiddlewareOrder(finalConfig);\n }\n\n // Create shutdown state for this server instance\n const shutdownState: ShutdownState = {\n isShuttingDown: false,\n };\n\n try\n {\n await initializeInfrastructure(finalConfig);\n\n const app = await createServer(finalConfig);\n const server = startHttpServer(app, host, port);\n\n const timeouts = getTimeoutConfig(finalConfig.timeout);\n applyServerTimeouts(server as Server, timeouts);\n\n logServerTimeouts(timeouts);\n printBanner({\n mode: debug ? 'Development' : 'Production',\n host,\n port,\n });\n\n logServerStarted(debug, host, port, finalConfig, timeouts);\n\n const shutdownServer = createShutdownHandler(server as Server, finalConfig, shutdownState);\n const shutdown = createGracefulShutdown(shutdownServer, finalConfig, shutdownState);\n\n // Register process-level handlers\n registerProcessHandlers(shutdown);\n\n const serverInstance: ServerInstance = {\n server,\n app,\n config: finalConfig,\n close: async () =>\n {\n serverLogger.info('Manual server shutdown requested');\n\n // Prevent re-entry for manual close\n if (shutdownState.isShuttingDown)\n {\n serverLogger.warn('Shutdown already in progress, ignoring manual close request');\n return;\n }\n\n shutdownState.isShuttingDown = true;\n await shutdownServer();\n },\n };\n\n // Execute afterStart hook from config\n if (finalConfig.lifecycle?.afterStart)\n {\n serverLogger.debug('Executing afterStart hook...');\n try\n {\n await finalConfig.lifecycle.afterStart(serverInstance);\n }\n catch (error)\n {\n serverLogger.error('afterStart hook failed', error as Error);\n // Don't throw - server is already running\n // Just log the error and continue\n }\n }\n\n return serverInstance;\n }\n catch (error)\n {\n const err = error as Error;\n serverLogger.error('Server initialization failed', err);\n\n await cleanupOnFailure(finalConfig);\n\n throw error;\n }\n}\n\n// ============================================================================\n// Configuration Loading\n// ============================================================================\n\nasync function loadAndMergeConfig(config?: ServerConfig): Promise<ServerConfig>\n{\n const cwd = process.cwd();\n let fileConfig: ServerConfig = {};\n let loadedConfigPath: string | null = null;\n\n // Try loading config files in priority order\n for (const configPath of CONFIG_FILE_PATHS)\n {\n const fullPath = join(cwd, configPath);\n if (existsSync(fullPath))\n {\n try\n {\n const configModule = await import(fullPath);\n fileConfig = configModule.default ?? {};\n loadedConfigPath = configPath;\n break;\n }\n catch (error)\n {\n serverLogger.error(`Failed to load config from ${configPath} - file exists but import failed`, error as Error);\n // Continue trying other config files instead of failing\n }\n }\n }\n\n if (loadedConfigPath)\n {\n serverLogger.debug(`Loaded configuration from ${loadedConfigPath}`);\n }\n else\n {\n serverLogger.debug('No configuration file found, using defaults');\n }\n\n return {\n ...fileConfig,\n ...config,\n port: config?.port ?? fileConfig?.port ?? env.PORT,\n host: config?.host ?? fileConfig?.host ?? env.HOST,\n };\n}\n\n// ============================================================================\n// Infrastructure Management\n// ============================================================================\n\n/**\n * Determine which infrastructure components should be initialized\n */\nfunction getInfrastructureConfig(config: ServerConfig): InfrastructureConfig\n{\n return {\n database: config.infrastructure?.database !== false,\n redis: config.infrastructure?.redis !== false,\n };\n}\n\nasync function initializeInfrastructure(config: ServerConfig): Promise<void>\n{\n if (config.lifecycle?.beforeInfrastructure)\n {\n serverLogger.debug('Executing beforeInfrastructure hook...');\n await config.lifecycle.beforeInfrastructure(config);\n }\n\n const infraConfig = getInfrastructureConfig(config);\n\n if (infraConfig.database)\n {\n serverLogger.debug('Initializing database...');\n await initDatabase(config.database);\n }\n else\n {\n serverLogger.debug('Database initialization disabled');\n }\n\n if (infraConfig.redis)\n {\n serverLogger.debug('Initializing Redis...');\n await initCache();\n }\n else\n {\n serverLogger.debug('Redis initialization disabled');\n }\n\n if (config.lifecycle?.afterInfrastructure)\n {\n serverLogger.debug('Executing afterInfrastructure hook...');\n await config.lifecycle.afterInfrastructure();\n }\n\n // Initialize jobs if configured\n if (config.jobs)\n {\n const dbUrl = env.DATABASE_URL;\n if (!dbUrl)\n {\n throw new Error(\n 'Jobs require database connection. ' +\n 'Ensure DATABASE_URL is set or database is enabled.'\n );\n }\n\n serverLogger.debug('Initializing pg-boss...');\n await initBoss({\n connectionString: dbUrl,\n ...config.jobsConfig,\n });\n\n serverLogger.debug('Registering jobs...');\n await registerJobs(config.jobs);\n }\n\n // Initialize workflows if configured\n if (config.workflows)\n {\n const infraConfig = getInfrastructureConfig(config);\n if (!infraConfig.database)\n {\n throw new Error(\n 'Workflows require database connection. ' +\n 'Ensure database is enabled in infrastructure config.'\n );\n }\n\n serverLogger.debug('Initializing workflow engine...');\n config.workflows._init(\n getDatabase(),\n config.workflowsConfig\n );\n serverLogger.info('Workflow engine initialized');\n }\n}\n\n// ============================================================================\n// HTTP Server Management\n// ============================================================================\n\nfunction startHttpServer(app: Hono, host: string, port: number): ReturnType<typeof serve>\n{\n serverLogger.debug(`Starting server on ${host}:${port}...`);\n\n return serve({\n fetch: app.fetch,\n port,\n hostname: host,\n });\n}\n\nfunction logMiddlewareOrder(config: ServerConfig): void\n{\n const middlewareOrder = buildMiddlewareOrder(config);\n serverLogger.debug('Middleware execution order', {\n order: middlewareOrder,\n });\n}\n\nfunction logServerTimeouts(timeouts: {\n request: number;\n keepAlive: number;\n headers: number;\n}): void\n{\n serverLogger.info('Server timeouts configured', {\n request: `${timeouts.request}ms`,\n keepAlive: `${timeouts.keepAlive}ms`,\n headers: `${timeouts.headers}ms`,\n });\n}\n\nfunction logServerStarted(\n debug: boolean | undefined,\n host: string,\n port: number,\n config: ServerConfig,\n timeouts: { request: number; keepAlive: number; headers: number }\n): void\n{\n const startupConfig = buildStartupConfig(config, timeouts);\n\n serverLogger.info('Server started successfully', {\n mode: debug ? 'development' : 'production',\n host,\n port,\n config: startupConfig,\n });\n}\n\n// ============================================================================\n// Graceful Shutdown\n// ============================================================================\n\nfunction createShutdownHandler(\n server: Server,\n config: ServerConfig,\n shutdownState: ShutdownState\n): () => Promise<void>\n{\n return async () =>\n {\n // Prevent re-entry\n if (shutdownState.isShuttingDown)\n {\n serverLogger.debug('Shutdown already in progress for this instance, skipping');\n return;\n }\n\n shutdownState.isShuttingDown = true;\n serverLogger.debug('Closing HTTP server...');\n\n // Close server with timeout to prevent hanging\n let timeoutId: NodeJS.Timeout | undefined;\n\n await Promise.race([\n new Promise<void>((resolve, reject) =>\n {\n server.close((err) =>\n {\n if (timeoutId) clearTimeout(timeoutId);\n\n if (err)\n {\n serverLogger.error('HTTP server close error', err);\n reject(err);\n }\n else\n {\n serverLogger.info('HTTP server closed');\n resolve();\n }\n });\n }),\n new Promise<void>((_, reject) =>\n {\n timeoutId = setTimeout(() =>\n {\n reject(new Error(`HTTP server close timeout after ${TIMEOUTS.SERVER_CLOSE}ms`));\n }, TIMEOUTS.SERVER_CLOSE);\n }),\n ]).catch((error) =>\n {\n if (timeoutId) clearTimeout(timeoutId);\n serverLogger.warn('HTTP server close timeout, forcing shutdown', error as Error);\n // Continue with cleanup even if server.close() times out\n });\n\n // Stop pg-boss if jobs were configured\n if (config.jobs)\n {\n serverLogger.debug('Stopping pg-boss...');\n try\n {\n await stopBoss();\n }\n catch (error)\n {\n serverLogger.error('pg-boss stop failed', error as Error);\n // Continue with shutdown even if stop fails\n }\n }\n\n // Execute beforeShutdown hook from config\n if (config.lifecycle?.beforeShutdown)\n {\n serverLogger.debug('Executing beforeShutdown hook...');\n try\n {\n await config.lifecycle.beforeShutdown();\n }\n catch (error)\n {\n serverLogger.error('beforeShutdown hook failed', error as Error);\n // Continue with shutdown even if hook fails\n }\n }\n\n // Only close resources that were enabled for initialization\n const infraConfig = getInfrastructureConfig(config);\n\n if (infraConfig.database)\n {\n serverLogger.debug('Closing database connections...');\n await closeInfrastructure(closeDatabase, 'Database', TIMEOUTS.DATABASE_CLOSE);\n }\n\n if (infraConfig.redis)\n {\n serverLogger.debug('Closing Redis connections...');\n await closeInfrastructure(closeCache, 'Redis', TIMEOUTS.REDIS_CLOSE);\n }\n\n serverLogger.info('Server shutdown completed');\n };\n}\n\n/**\n * Close infrastructure component with timeout\n */\nasync function closeInfrastructure(\n closeFn: () => Promise<void>,\n name: string,\n timeout: number\n): Promise<void>\n{\n let timeoutId: NodeJS.Timeout | undefined;\n\n try\n {\n await Promise.race([\n closeFn().then(() =>\n {\n if (timeoutId) clearTimeout(timeoutId);\n }),\n new Promise<void>((_, reject) =>\n {\n timeoutId = setTimeout(() =>\n {\n reject(new Error(`${name} close timeout after ${timeout}ms`));\n }, timeout);\n }),\n ]);\n serverLogger.info(`${name} connections closed successfully`);\n }\n catch (error)\n {\n if (timeoutId) clearTimeout(timeoutId);\n serverLogger.error(`${name} close failed or timed out`, error as Error);\n // Continue with shutdown even if close fails\n }\n}\n\nfunction createGracefulShutdown(\n shutdownServer: () => Promise<void>,\n config: ServerConfig,\n shutdownState: ShutdownState\n): (signal: string) => Promise<void>\n{\n return async (signal: string) =>\n {\n // Prevent re-entry\n if (shutdownState.isShuttingDown)\n {\n serverLogger.warn(`${signal} received but shutdown already in progress, ignoring`);\n return;\n }\n\n serverLogger.info(`${signal} received, starting graceful shutdown...`);\n\n const shutdownTimeout = getShutdownTimeout(config.shutdown);\n let timeoutId: NodeJS.Timeout | undefined;\n\n try\n {\n await Promise.race([\n shutdownServer().then(() =>\n {\n if (timeoutId) clearTimeout(timeoutId);\n }),\n new Promise<never>((_, reject) =>\n {\n timeoutId = setTimeout(() =>\n {\n reject(new Error(`Graceful shutdown timeout after ${shutdownTimeout}ms`));\n }, shutdownTimeout);\n }),\n ]);\n\n if (timeoutId) clearTimeout(timeoutId);\n serverLogger.info('Graceful shutdown completed successfully');\n process.exit(0);\n }\n catch (error)\n {\n if (timeoutId) clearTimeout(timeoutId);\n const err = error as Error;\n\n if (err.message && err.message.includes('timeout'))\n {\n serverLogger.error('Graceful shutdown timeout, forcing exit', err);\n }\n else\n {\n serverLogger.error('Error during graceful shutdown', err);\n }\n\n process.exit(1);\n }\n };\n}\n\n// ============================================================================\n// Error Handlers\n// ============================================================================\n\n/**\n * Handle process errors with environment-specific behavior\n */\nfunction handleProcessError(\n errorType: string,\n shutdown: (signal: string) => Promise<void>\n): void\n{\n const isProduction = env.NODE_ENV === 'production';\n const isDevelopment = env.NODE_ENV === 'development';\n\n // In development/watch mode, exit immediately for clean restart\n // In production, attempt graceful shutdown\n if (isDevelopment || process.env.WATCH_MODE === 'true')\n {\n serverLogger.info('Exiting immediately for clean restart');\n process.exit(1);\n }\n else if (isProduction)\n {\n serverLogger.info(`Attempting graceful shutdown after ${errorType}`);\n\n // Set a timeout to force exit if shutdown hangs\n const forceExitTimer = setTimeout(() =>\n {\n serverLogger.error(`Forced exit after ${TIMEOUTS.PRODUCTION_ERROR_SHUTDOWN}ms - graceful shutdown did not complete`);\n process.exit(1);\n }, TIMEOUTS.PRODUCTION_ERROR_SHUTDOWN);\n\n // Don't use await in event handler - handle promise explicitly\n shutdown(errorType)\n .then(() =>\n {\n clearTimeout(forceExitTimer);\n serverLogger.info('Graceful shutdown completed, exiting');\n process.exit(0);\n })\n .catch((shutdownError) =>\n {\n clearTimeout(forceExitTimer);\n serverLogger.error('Graceful shutdown failed', shutdownError as Error);\n process.exit(1);\n });\n }\n else\n {\n // Unknown environment - exit immediately for safety\n serverLogger.info('Exiting immediately');\n process.exit(1);\n }\n}\n\nfunction registerProcessHandlers(\n shutdown: (signal: string) => Promise<void>\n): void\n{\n // Prevent duplicate registration\n if (processHandlersRegistered)\n {\n serverLogger.debug('Process handlers already registered, skipping');\n return;\n }\n\n processHandlersRegistered = true;\n\n // Increase max listeners to prevent warnings in development with hot reload\n const currentMax = process.getMaxListeners();\n if (currentMax < DEFAULT_MAX_LISTENERS)\n {\n process.setMaxListeners(DEFAULT_MAX_LISTENERS);\n }\n\n process.on('SIGTERM', () =>\n {\n shutdown('SIGTERM').catch((error) =>\n {\n serverLogger.error('SIGTERM handler failed', error as Error);\n process.exit(1);\n });\n });\n\n process.on('SIGINT', () =>\n {\n shutdown('SIGINT').catch((error) =>\n {\n serverLogger.error('SIGINT handler failed', error as Error);\n process.exit(1);\n });\n });\n\n process.on('uncaughtException', (error) =>\n {\n // Enhanced logging for EADDRINUSE errors\n if (error.message?.includes('EADDRINUSE'))\n {\n serverLogger.error('Port conflict detected - detailed trace:', error, {\n code: (error as any).code,\n port: (error as any).port,\n address: (error as any).address,\n syscall: (error as any).syscall,\n });\n }\n else\n {\n serverLogger.error('Uncaught exception', error);\n }\n\n handleProcessError('UNCAUGHT_EXCEPTION', shutdown);\n });\n\n process.on('unhandledRejection', (reason, promise) =>\n {\n // Enhanced error logging with promise context extraction\n if (reason instanceof Error)\n {\n // Import formatUnhandledRejection dynamically to avoid circular deps\n import('../logger/formatters').then(({ formatUnhandledRejection }) =>\n {\n const { error, context } = formatUnhandledRejection(reason, promise);\n\n serverLogger.error('Unhandled promise rejection', error, context);\n }).catch(() =>\n {\n // Fallback if formatUnhandledRejection fails\n serverLogger.error('Unhandled promise rejection', reason, {\n promise,\n });\n });\n }\n else\n {\n serverLogger.error('Unhandled promise rejection', {\n reason,\n promise,\n });\n }\n\n handleProcessError('UNHANDLED_REJECTION', shutdown);\n });\n\n serverLogger.debug('Process-level shutdown handlers registered successfully');\n}\n\n// ============================================================================\n// Cleanup\n// ============================================================================\n\nasync function cleanupOnFailure(config: ServerConfig): Promise<void>\n{\n try\n {\n serverLogger.debug('Cleaning up after initialization failure...');\n\n // Only cleanup resources that were enabled for initialization\n const infraConfig = getInfrastructureConfig(config);\n\n if (infraConfig.database)\n {\n await closeInfrastructure(closeDatabase, 'Database', TIMEOUTS.DATABASE_CLOSE);\n }\n\n if (infraConfig.redis)\n {\n await closeInfrastructure(closeCache, 'Redis', TIMEOUTS.REDIS_CLOSE);\n }\n\n serverLogger.debug('Cleanup completed');\n }\n catch (cleanupError)\n {\n serverLogger.error('Cleanup failed', cleanupError as Error);\n }\n}","/**\n * Server Config Builder\n *\n * Provides a fluent API for building server configuration\n */\n\nimport type { MiddlewareHandler } from 'hono';\nimport type { ServerConfig } from './types';\nimport type { Router, NamedMiddleware } from '@spfn/core/route';\nimport type { JobRouter, BossOptions } from '../job';\nimport type { EventRouterDef } from '../event/router';\nimport type { SSEHandlerConfig } from '../event/sse/types';\nimport { serverLogger } from './logger';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ntype Lifecycle = NonNullable<ServerConfig['lifecycle']>;\ntype LifecycleKey = keyof Lifecycle;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction collectHooks<K extends LifecycleKey>(\n lifecycles: Lifecycle[],\n key: K\n): NonNullable<Lifecycle[K]>[]\n{\n return lifecycles\n .map(lc => lc[key])\n .filter((hook): hook is NonNullable<Lifecycle[K]> => hook !== undefined);\n}\n\nfunction createMergedHook<T extends (...args: any[]) => void | Promise<void>>(\n hooks: T[]\n): T | undefined\n{\n if (hooks.length === 0)\n {\n return undefined;\n }\n\n return (async (...args: Parameters<T>) =>\n {\n for (const hook of hooks)\n {\n await hook(...args);\n }\n }) as T;\n}\n\nexport class ServerConfigBuilder\n{\n private config: ServerConfig = {};\n private lifecycles: NonNullable<ServerConfig['lifecycle']>[] = [];\n\n /**\n * Set server port\n */\n port(port: number): this\n {\n this.config.port = port;\n return this;\n }\n\n /**\n * Set server hostname\n */\n host(host: string): this\n {\n this.config.host = host;\n return this;\n }\n\n /**\n * Set CORS configuration\n */\n cors(cors: ServerConfig['cors']): this\n {\n this.config.cors = cors;\n return this;\n }\n\n /**\n * Configure built-in middleware\n */\n middleware(middleware: ServerConfig['middleware']): this\n {\n this.config.middleware = middleware;\n return this;\n }\n\n /**\n * Add custom middleware\n */\n use(handlers: MiddlewareHandler[]): this\n {\n this.config.use = handlers;\n return this;\n }\n\n /**\n * Add named middlewares for route-level skip control\n */\n middlewares(middlewares: ServerConfig['middlewares']): this\n {\n this.config.middlewares = middlewares;\n return this;\n }\n\n /**\n * Register define-route based router\n *\n * Automatically applies:\n * - Global middlewares from router._globalMiddlewares (via .use())\n * - Package routers from router._packageRouters (via .packages())\n *\n * @example\n * ```typescript\n * const appRouter = defineRouter({\n * getUser: route.get('/users/:id')...\n * })\n * .packages([authRouter, cmsAppRouter])\n * .use([authMiddleware]);\n *\n * export default defineServerConfig()\n * .routes(appRouter) // middlewares auto-applied\n * .build();\n * ```\n */\n routes(router: Router<any>): this\n {\n this.config.routes = router;\n\n // Collect all global middlewares from router and package routers\n const allGlobalMiddlewares: NamedMiddleware[] = [];\n\n // Add main router's global middlewares\n if (router._globalMiddlewares?.length > 0)\n {\n allGlobalMiddlewares.push(...router._globalMiddlewares);\n }\n\n // Add package routers' global middlewares\n if (router._packageRouters?.length > 0)\n {\n for (const pkgRouter of router._packageRouters)\n {\n if (pkgRouter._globalMiddlewares?.length > 0)\n {\n allGlobalMiddlewares.push(...pkgRouter._globalMiddlewares);\n }\n }\n }\n\n // Merge with existing middlewares\n if (allGlobalMiddlewares.length > 0)\n {\n this.config.middlewares = [\n ...(this.config.middlewares || []),\n ...allGlobalMiddlewares,\n ];\n }\n\n return this;\n }\n\n /**\n * Register background jobs router\n *\n * @example\n * ```typescript\n * import { job, defineJobRouter } from '@spfn/core/job';\n *\n * const sendEmail = job('send-email')\n * .input(Type.Object({ to: Type.String() }))\n * .handler(async (input) => { ... });\n *\n * const jobRouter = defineJobRouter({ sendEmail });\n *\n * export default defineServerConfig()\n * .routes(appRouter)\n * .jobs(jobRouter)\n * .build();\n * ```\n */\n jobs(router: JobRouter<any>, config?: Omit<BossOptions, 'connectionString'>): this\n {\n this.config.jobs = router;\n if (config)\n {\n this.config.jobsConfig = config;\n }\n return this;\n }\n\n /**\n * Register event router for SSE (Server-Sent Events)\n *\n * Enables real-time event streaming to frontend clients.\n * Events defined with defineEvent() can be subscribed by:\n * - Backend: .subscribe() for internal handlers\n * - Jobs: .on(event) for background processing\n * - Frontend: SSE stream for real-time updates\n *\n * @example\n * ```typescript\n * import { defineEvent, defineEventRouter } from '@spfn/core/event';\n *\n * const userCreated = defineEvent('user.created', Type.Object({\n * userId: Type.String(),\n * }));\n *\n * const eventRouter = defineEventRouter({ userCreated });\n *\n * export default defineServerConfig()\n * .routes(appRouter)\n * .events(eventRouter) // → GET /events/stream\n * .build();\n *\n * // Custom path\n * .events(eventRouter, { path: '/sse' })\n * ```\n */\n events(\n router: EventRouterDef<any>,\n config?: SSEHandlerConfig & { path?: string }\n ): this\n {\n this.config.events = router;\n if (config)\n {\n this.config.eventsConfig = config;\n }\n return this;\n }\n\n /**\n * Enable/disable debug mode\n */\n debug(enabled: boolean): this\n {\n this.config.debug = enabled;\n return this;\n }\n\n /**\n * Configure database settings\n */\n database(database: ServerConfig['database']): this\n {\n this.config.database = database;\n return this;\n }\n\n /**\n * Configure server timeout settings\n */\n timeout(timeout: ServerConfig['timeout']): this\n {\n this.config.timeout = timeout;\n return this;\n }\n\n /**\n * Configure graceful shutdown settings\n */\n shutdown(shutdown: ServerConfig['shutdown']): this\n {\n this.config.shutdown = shutdown;\n return this;\n }\n\n /**\n * Configure health check endpoint\n */\n healthCheck(healthCheck: ServerConfig['healthCheck']): this\n {\n this.config.healthCheck = healthCheck;\n return this;\n }\n\n /**\n * Configure infrastructure initialization\n */\n infrastructure(infrastructure: ServerConfig['infrastructure']): this\n {\n this.config.infrastructure = infrastructure;\n return this;\n }\n\n /**\n * Register workflow router for workflow orchestration\n *\n * Automatically initializes the workflow engine after database is ready.\n *\n * @example\n * ```typescript\n * import { defineWorkflowRouter } from '@spfn/workflow';\n *\n * const workflowRouter = defineWorkflowRouter([\n * provisionTenant,\n * deprovisionTenant,\n * ]);\n *\n * export default defineServerConfig()\n * .routes(appRouter)\n * .workflows(workflowRouter)\n * .build();\n * ```\n */\n workflows(\n router: ServerConfig['workflows'],\n config?: ServerConfig['workflowsConfig']\n ): this\n {\n this.config.workflows = router;\n if (config)\n {\n this.config.workflowsConfig = config;\n }\n return this;\n }\n\n /**\n * Configure lifecycle hooks\n * Can be called multiple times - hooks will be executed in registration order\n */\n lifecycle(lifecycle: ServerConfig['lifecycle']): this\n {\n if (lifecycle)\n {\n this.lifecycles.push(lifecycle);\n }\n return this;\n }\n\n /**\n * Build and return the final configuration\n */\n build(): ServerConfig\n {\n if (this.lifecycles.length > 0)\n {\n serverLogger.info('Merging lifecycles', { count: this.lifecycles.length });\n this.config.lifecycle = this.mergeLifecycles();\n }\n\n return this.config;\n }\n\n private mergeLifecycles(): Lifecycle\n {\n return {\n beforeInfrastructure: createMergedHook(\n collectHooks(this.lifecycles, 'beforeInfrastructure')\n ),\n afterInfrastructure: createMergedHook(\n collectHooks(this.lifecycles, 'afterInfrastructure')\n ),\n beforeRoutes: createMergedHook(\n collectHooks(this.lifecycles, 'beforeRoutes')\n ),\n afterRoutes: createMergedHook(\n collectHooks(this.lifecycles, 'afterRoutes')\n ),\n afterStart: createMergedHook(\n collectHooks(this.lifecycles, 'afterStart')\n ),\n beforeShutdown: createMergedHook(\n collectHooks(this.lifecycles, 'beforeShutdown')\n ),\n };\n }\n}\n\n/**\n * Create a new server configuration builder\n *\n * @example\n * ```typescript\n * // server.config.ts\n * import { defineServerConfig, route, defineRouter } from '@spfn/core/server';\n * import { Type } from '@sinclair/typebox';\n *\n * const appRouter = defineRouter({\n * getUser: route.get('/users/:id')\n * .input({ params: Type.Object({ id: Type.String() }) })\n * .handler(async (c) => {\n * const { params } = await c.data();\n * return { id: params.id, name: 'John' };\n * }),\n * });\n *\n * export default defineServerConfig()\n * .port(3000)\n * .routes(appRouter)\n * .middleware({ logger: true, cors: true })\n * .debug(true)\n * .build();\n * ```\n */\nexport function defineServerConfig(): ServerConfigBuilder\n{\n return new ServerConfigBuilder();\n}"]}
|