@spfn/core 0.1.0-alpha.8 β†’ 0.1.0-alpha.82

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.
Files changed (61) hide show
  1. package/README.md +169 -195
  2. package/dist/auto-loader-JFaZ9gON.d.ts +80 -0
  3. package/dist/cache/index.d.ts +211 -0
  4. package/dist/cache/index.js +1013 -0
  5. package/dist/cache/index.js.map +1 -0
  6. package/dist/client/index.d.ts +131 -92
  7. package/dist/client/index.js +93 -85
  8. package/dist/client/index.js.map +1 -1
  9. package/dist/codegen/generators/index.d.ts +19 -0
  10. package/dist/codegen/generators/index.js +1521 -0
  11. package/dist/codegen/generators/index.js.map +1 -0
  12. package/dist/codegen/index.d.ts +76 -60
  13. package/dist/codegen/index.js +1506 -735
  14. package/dist/codegen/index.js.map +1 -1
  15. package/dist/database-errors-BNNmLTJE.d.ts +86 -0
  16. package/dist/db/index.d.ts +844 -44
  17. package/dist/db/index.js +1281 -1307
  18. package/dist/db/index.js.map +1 -1
  19. package/dist/env/index.d.ts +508 -0
  20. package/dist/env/index.js +1127 -0
  21. package/dist/env/index.js.map +1 -0
  22. package/dist/errors/index.d.ts +136 -0
  23. package/dist/errors/index.js +172 -0
  24. package/dist/errors/index.js.map +1 -0
  25. package/dist/index-DHiAqhKv.d.ts +101 -0
  26. package/dist/index.d.ts +3 -374
  27. package/dist/index.js +2424 -2178
  28. package/dist/index.js.map +1 -1
  29. package/dist/logger/index.d.ts +94 -0
  30. package/dist/logger/index.js +795 -0
  31. package/dist/logger/index.js.map +1 -0
  32. package/dist/middleware/index.d.ts +60 -0
  33. package/dist/middleware/index.js +918 -0
  34. package/dist/middleware/index.js.map +1 -0
  35. package/dist/route/index.d.ts +21 -53
  36. package/dist/route/index.js +1259 -219
  37. package/dist/route/index.js.map +1 -1
  38. package/dist/server/index.d.ts +18 -0
  39. package/dist/server/index.js +2419 -2059
  40. package/dist/server/index.js.map +1 -1
  41. package/dist/types/index.d.ts +121 -0
  42. package/dist/types/index.js +38 -0
  43. package/dist/types/index.js.map +1 -0
  44. package/dist/types-BXibIEyj.d.ts +60 -0
  45. package/package.json +67 -17
  46. package/dist/auto-loader-C44TcLmM.d.ts +0 -125
  47. package/dist/bind-pssq1NRT.d.ts +0 -34
  48. package/dist/postgres-errors-CY_Es8EJ.d.ts +0 -1703
  49. package/dist/scripts/index.d.ts +0 -24
  50. package/dist/scripts/index.js +0 -1201
  51. package/dist/scripts/index.js.map +0 -1
  52. package/dist/scripts/templates/api-index.template.txt +0 -10
  53. package/dist/scripts/templates/api-tag.template.txt +0 -11
  54. package/dist/scripts/templates/contract.template.txt +0 -87
  55. package/dist/scripts/templates/entity-type.template.txt +0 -31
  56. package/dist/scripts/templates/entity.template.txt +0 -19
  57. package/dist/scripts/templates/index.template.txt +0 -10
  58. package/dist/scripts/templates/repository.template.txt +0 -37
  59. package/dist/scripts/templates/routes-id.template.txt +0 -59
  60. package/dist/scripts/templates/routes-index.template.txt +0 -44
  61. package/dist/types-SlzTr8ZO.d.ts +0 -143
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/route/auto-loader.ts","../../src/errors/database-errors.ts","../../src/route/bind.ts","../../src/route/create-app.ts","../../src/route/types.ts"],"names":["relativePath"],"mappings":"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","file":"index.js","sourcesContent":["import { readdir, stat } from 'fs/promises';\nimport { join, relative } from 'path';\nimport type { Hono } from 'hono';\n\n/**\n * Extend Hono Context to support skipMiddlewares metadata\n */\ndeclare module 'hono' {\n interface ContextVariableMap {\n _skipMiddlewares?: string[];\n }\n}\n\n/**\n * AutoRouteLoader: Simplified File-based Routing System\n *\n * ## Features\n * - πŸ“ Auto-discovery: Scans routes directory and auto-registers\n * - πŸ”„ Dynamic routes: [id] β†’ :id, [...slug] β†’ *\n * - πŸ“Š Statistics: Route registration stats for dashboard\n * - 🏷️ Grouping: Natural grouping by directory structure\n *\n * ## Usage\n * ```typescript\n * const app = new Hono();\n * await loadRoutes(app);\n * ```\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type RouteInfo = {\n /** URL path (e.g., /users/:id) */\n path: string;\n /** File path relative to routes dir */\n file: string;\n /** Route metadata from export */\n meta?: {\n description?: string;\n tags?: string[];\n auth?: boolean;\n [key: string]: unknown;\n };\n /** Priority (1=static, 2=dynamic, 3=catch-all) */\n priority: number;\n};\n\nexport type RouteStats = {\n total: number;\n byPriority: {\n static: number;\n dynamic: number;\n catchAll: number;\n };\n byTag: Record<string, number>;\n routes: RouteInfo[];\n};\n\n// ============================================================================\n// Main Loader Class\n// ============================================================================\n\nexport class AutoRouteLoader\n{\n private routes: RouteInfo[] = [];\n private registeredRoutes = new Map<string, string>(); // normalized path β†’ file\n private debug: boolean;\n private readonly middlewares: Array<{ name: string; handler: any }>;\n\n constructor(\n private routesDir: string,\n debug = false,\n middlewares: Array<{ name: string; handler: any }> = []\n )\n {\n this.debug = debug;\n this.middlewares = middlewares;\n }\n\n /**\n * Load all routes from directory\n */\n async load(app: Hono): Promise<RouteStats>\n {\n const startTime = Date.now();\n\n // 1. Scan files\n const files = await this.scanFiles(this.routesDir);\n\n if (files.length === 0)\n {\n console.warn('⚠️ No route files found');\n return this.getStats();\n }\n\n // 2. Calculate priorities for all files\n const filesWithPriority = files.map(file => ({\n path: file,\n priority: this.calculatePriority(relative(this.routesDir, file)),\n }));\n\n // 3. Sort by priority (static=1, dynamic=2, catch-all=3)\n filesWithPriority.sort((a, b) => a.priority - b.priority);\n\n if (this.debug)\n {\n console.log(`\\nπŸ“‹ Route Registration Order:`);\n console.log(` Priority 1 (Static): ${filesWithPriority.filter(f => f.priority === 1).length} routes`);\n console.log(` Priority 2 (Dynamic): ${filesWithPriority.filter(f => f.priority === 2).length} routes`);\n console.log(` Priority 3 (Catch-all): ${filesWithPriority.filter(f => f.priority === 3).length} routes\\n`);\n }\n\n // 4. Load and register routes in priority order\n let successCount = 0;\n let failureCount = 0;\n\n for (const { path } of filesWithPriority)\n {\n const success = await this.loadRoute(app, path);\n if (success)\n {\n successCount++;\n }\n else\n {\n failureCount++;\n }\n }\n\n // 5. Log stats\n const elapsed = Date.now() - startTime;\n const stats = this.getStats();\n\n if (this.debug)\n {\n this.logStats(stats, elapsed);\n }\n\n if (failureCount > 0)\n {\n console.warn(`⚠️ ${failureCount} route(s) failed to load`);\n }\n\n return stats;\n }\n\n /**\n * Get route statistics\n */\n getStats(): RouteStats\n {\n const stats: RouteStats = {\n total: this.routes.length,\n byPriority: { static: 0, dynamic: 0, catchAll: 0 },\n byTag: {},\n routes: this.routes,\n };\n\n for (const route of this.routes)\n {\n // Count by priority\n if (route.priority === 1) stats.byPriority.static++;\n else if (route.priority === 2) stats.byPriority.dynamic++;\n else if (route.priority === 3) stats.byPriority.catchAll++;\n\n // Count by tag\n if (route.meta?.tags)\n {\n for (const tag of route.meta.tags)\n {\n stats.byTag[tag] = (stats.byTag[tag] || 0) + 1;\n }\n }\n }\n\n return stats;\n }\n\n // ========================================================================\n // Private Methods\n // ========================================================================\n\n /**\n * Recursively scan directory for .ts files\n */\n private async scanFiles(dir: string, files: string[] = []): Promise<string[]>\n {\n const entries = await readdir(dir);\n\n for (const entry of entries)\n {\n const fullPath = join(dir, entry);\n const fileStat = await stat(fullPath);\n\n if (fileStat.isDirectory())\n {\n // Recurse into subdirectories\n await this.scanFiles(fullPath, files);\n }\n else if (this.isValidRouteFile(entry))\n {\n files.push(fullPath);\n }\n }\n\n return files;\n }\n\n /**\n * Check if file is a valid route file\n */\n private isValidRouteFile(fileName: string): boolean\n {\n return (\n fileName.endsWith('.ts') &&\n !fileName.endsWith('.test.ts') &&\n !fileName.endsWith('.spec.ts') &&\n !fileName.endsWith('.d.ts') &&\n fileName !== 'contract.ts'\n );\n }\n\n /**\n * Load and register a single route\n * Returns true if successful, false if failed\n */\n private async loadRoute(app: Hono, absolutePath: string): Promise<boolean>\n {\n const relativePath = relative(this.routesDir, absolutePath);\n\n try\n {\n // Import module\n const module = await import(absolutePath);\n\n if (!module.default)\n {\n console.error(`❌ ${relativePath}: Must export Hono instance as default`);\n return false;\n }\n\n // Validate that it's actually a Hono instance\n if (typeof module.default.route !== 'function')\n {\n console.error(`❌ ${relativePath}: Default export is not a Hono instance`);\n return false;\n }\n\n // Convert file path to URL path\n const urlPath = this.fileToPath(relativePath);\n const priority = this.calculatePriority(relativePath);\n\n // Check for route conflicts\n const normalizedPath = this.normalizePath(urlPath);\n const existingFile = this.registeredRoutes.get(normalizedPath);\n\n if (existingFile)\n {\n console.warn(`⚠️ Route conflict detected:`);\n console.warn(` Path: ${urlPath} (normalized: ${normalizedPath})`);\n console.warn(` Already registered by: ${existingFile}`);\n console.warn(` Attempted by: ${relativePath}`);\n console.warn(` β†’ Skipping duplicate registration`);\n return false;\n }\n\n // Track registration\n this.registeredRoutes.set(normalizedPath, relativePath);\n\n // Check if module uses contract-based routing (createApp)\n const hasContractMetas = module.default._contractMetas && module.default._contractMetas.size > 0;\n\n if (hasContractMetas)\n {\n // Contract-based routing: method-level skipMiddlewares\n // Use wildcard pattern to match all sub-paths (e.g., /test/* matches /test/public, /test/private)\n const middlewarePath = urlPath === '/' ? '/*' : `${urlPath}/*`;\n\n // 1. Register meta-setting middleware first\n app.use(middlewarePath, (c, next) =>\n {\n const method = c.req.method;\n const requestPath = new URL(c.req.url).pathname;\n\n // Calculate relative path by removing the route base path\n // E.g., if urlPath = '/test' and requestPath = '/test/public', then relativePath = '/public'\n const relativePath = requestPath.startsWith(urlPath)\n ? requestPath.slice(urlPath.length) || '/'\n : requestPath;\n\n const key = `${method} ${relativePath}`;\n const meta = module.default._contractMetas?.get(key);\n\n if (meta?.skipMiddlewares)\n {\n c.set('_skipMiddlewares', meta.skipMiddlewares);\n }\n\n return next();\n });\n\n // 2. Wrap global middlewares to check skipMiddlewares\n for (const middleware of this.middlewares)\n {\n app.use(middlewarePath, async (c, next) =>\n {\n const skipList = c.get('_skipMiddlewares') || [];\n\n if (skipList.includes(middleware.name))\n {\n return next(); // Skip this middleware\n }\n\n return middleware.handler(c, next); // Execute middleware\n });\n }\n }\n else\n {\n // File-based routing: file-level skipMiddlewares (fallback)\n const skipList = module.meta?.skipMiddlewares || [];\n const activeMiddlewares = this.middlewares\n .filter(m => !skipList.includes(m.name));\n\n for (const middleware of activeMiddlewares)\n {\n app.use(urlPath, middleware.handler);\n }\n }\n\n // Register route\n app.route(urlPath, module.default);\n\n // Store route info\n this.routes.push({\n path: urlPath,\n file: relativePath,\n meta: module.meta,\n priority,\n });\n\n if (this.debug)\n {\n const icon = priority === 1 ? 'πŸ”Ή' : priority === 2 ? 'πŸ”Έ' : '⭐';\n console.log(` ${icon} ${urlPath.padEnd(40)} β†’ ${relativePath}`);\n }\n\n return true;\n }\n catch (error)\n {\n const err = error as Error;\n\n // Categorize error types and provide helpful messages\n if (err.message.includes('Cannot find module') || err.message.includes('MODULE_NOT_FOUND'))\n {\n console.error(`❌ ${relativePath}: Missing dependency`);\n console.error(` ${err.message}`);\n console.error(` β†’ Run: npm install`);\n }\n else if (err.message.includes('SyntaxError') || err.stack?.includes('SyntaxError'))\n {\n console.error(`❌ ${relativePath}: Syntax error`);\n console.error(` ${err.message}`);\n\n if (this.debug && err.stack)\n {\n console.error(` Stack trace (first 5 lines):`);\n const stackLines = err.stack.split('\\n').slice(0, 5);\n stackLines.forEach(line => console.error(` ${line}`));\n }\n }\n else if (err.message.includes('Unexpected token'))\n {\n console.error(`❌ ${relativePath}: Parse error`);\n console.error(` ${err.message}`);\n console.error(` β†’ Check for syntax errors or invalid TypeScript`);\n }\n else\n {\n console.error(`❌ ${relativePath}: ${err.message}`);\n\n if (this.debug && err.stack)\n {\n console.error(` Stack: ${err.stack}`);\n }\n }\n\n return false;\n }\n }\n\n /**\n * Convert file path to URL path\n *\n * Examples:\n * - users/index.ts β†’ /users\n * - users/[id].ts β†’ /users/:id\n * - posts/[...slug].ts β†’ /posts/*\n */\n private fileToPath(filePath: string): string\n {\n // Remove .ts extension\n let path = filePath.replace(/\\.ts$/, '');\n\n // Split into segments\n const segments = path.split('/');\n\n // Remove 'index' if it's the last segment\n if (segments[segments.length - 1] === 'index')\n {\n segments.pop();\n }\n\n // Transform segments: [id] β†’ :id, [...slug] β†’ *\n const transformed = segments.map(seg =>\n {\n // Catch-all: [...slug] β†’ *\n if (/^\\[\\.\\.\\.[\\w-]+]$/.test(seg))\n {\n return '*';\n }\n // Dynamic: [id] β†’ :id\n if (/^\\[[\\w-]+]$/.test(seg))\n {\n return ':' + seg.slice(1, -1);\n }\n // Skip 'index' segments (index/index.ts β†’ /, posts/index/index.ts β†’ /posts)\n if (seg === 'index')\n {\n return null;\n }\n // Static: users β†’ users\n return seg;\n }).filter(seg => seg !== null);\n\n // Join and ensure leading slash\n const result = '/' + transformed.join('/');\n return result.replace(/\\/+/g, '/').replace(/\\/$/, '') || '/';\n }\n\n /**\n * Calculate route priority\n * 1 = static, 2 = dynamic, 3 = catch-all\n */\n private calculatePriority(path: string): number\n {\n if (/\\[\\.\\.\\.[\\w-]+]/.test(path)) return 3; // Catch-all\n if (/\\[[\\w-]+]/.test(path)) return 2; // Dynamic\n return 1; // Static\n }\n\n /**\n * Normalize path for conflict detection\n *\n * Converts dynamic parameter names to generic placeholders:\n * - /users/:id β†’ /users/:param\n * - /users/:userId β†’ /users/:param (conflict!)\n * - /posts/* β†’ /posts/* (unchanged)\n *\n * This allows detection of routes with different param names\n * that would match the same URL patterns.\n */\n private normalizePath(path: string): string\n {\n // Replace all dynamic params (:xxx) with :param\n // This allows us to detect conflicts like /users/:id and /users/:userId\n return path.replace(/:\\w+/g, ':param');\n }\n\n /**\n * Log statistics\n */\n private logStats(stats: RouteStats, elapsed: number): void\n {\n console.log(`\\nπŸ“Š Route Statistics:`);\n console.log(` Total: ${stats.total} routes`);\n console.log(\n ` Priority: ${stats.byPriority.static} static, ` +\n `${stats.byPriority.dynamic} dynamic, ` +\n `${stats.byPriority.catchAll} catch-all`\n );\n\n if (Object.keys(stats.byTag).length > 0)\n {\n const tagCounts = Object.entries(stats.byTag)\n .map(([tag, count]) => `${tag}(${count})`)\n .join(', ');\n console.log(` Tags: ${tagCounts}`);\n }\n\n console.log(`\\nβœ… Routes loaded in ${elapsed}ms\\n`);\n }\n}\n\n// ============================================================================\n// Convenience Function\n// ============================================================================\n\n/**\n * Load routes from default location (src/server/routes)\n */\nexport async function loadRoutes(\n app: Hono,\n options?: {\n routesDir?: string;\n debug?: boolean;\n middlewares?: Array<{ name: string; handler: any }>;\n }\n): Promise<RouteStats>\n{\n const routesDir = options?.routesDir ?? join(process.cwd(), 'src', 'server', 'routes');\n const debug = options?.debug ?? false;\n const middlewares = options?.middlewares ?? [];\n\n const loader = new AutoRouteLoader(routesDir, debug, middlewares);\n return loader.load(app);\n}","/**\n * Database Error Classes\n *\n * Type-safe error handling with custom error class hierarchy\n * Mapped to HTTP status codes for API responses\n */\n\n/**\n * Base Database Error\n *\n * Base class for all database-related errors\n */\nexport class DatabaseError<TDetails extends Record<string, unknown> = Record<string, unknown>> extends Error\n{\n public readonly statusCode: number;\n public readonly details?: TDetails;\n public readonly timestamp: Date;\n\n constructor(\n message: string,\n statusCode: number = 500,\n details?: TDetails\n )\n {\n super(message);\n this.name = 'DatabaseError';\n this.statusCode = statusCode;\n this.details = details;\n this.timestamp = new Date();\n Error.captureStackTrace(this, this.constructor);\n }\n\n /**\n * Serialize error for API response\n */\n toJSON()\n {\n return {\n name: this.name,\n message: this.message,\n statusCode: this.statusCode,\n details: this.details,\n timestamp: this.timestamp.toISOString()\n };\n }\n}\n\n/**\n * Connection Error (503 Service Unavailable)\n *\n * Database connection failure, connection pool exhaustion, etc.\n */\nexport class ConnectionError extends DatabaseError\n{\n constructor(message: string, details?: Record<string, any>)\n {\n super(message, 503, details);\n this.name = 'ConnectionError';\n }\n}\n\n/**\n * Query Error (500 Internal Server Error)\n *\n * SQL query execution failure, syntax errors, etc.\n */\nexport class QueryError extends DatabaseError\n{\n constructor(message: string, statusCode: number = 500, details?: Record<string, any>)\n {\n super(message, statusCode, details);\n this.name = 'QueryError';\n }\n}\n\n/**\n * Not Found Error (404 Not Found)\n *\n * Requested resource does not exist\n */\nexport class NotFoundError extends QueryError\n{\n constructor(resource: string, id: string | number)\n {\n super(`${resource} with id ${id} not found`, 404, { resource, id });\n this.name = 'NotFoundError';\n }\n}\n\n/**\n * Validation Error (400 Bad Request)\n *\n * Input data validation failure\n */\nexport class ValidationError extends QueryError\n{\n constructor(message: string, details?: Record<string, any>)\n {\n super(message, 400, details);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * Transaction Error (500 Internal Server Error)\n *\n * Transaction start/commit/rollback failure\n */\nexport class TransactionError extends DatabaseError\n{\n constructor(message: string, statusCode: number = 500, details?: Record<string, any>)\n {\n super(message, statusCode, details);\n this.name = 'TransactionError';\n }\n}\n\n/**\n * Deadlock Error (409 Conflict)\n *\n * Database deadlock detected\n */\nexport class DeadlockError extends TransactionError\n{\n constructor(message: string, details?: Record<string, any>)\n {\n super(message, 409, details);\n this.name = 'DeadlockError';\n }\n}\n\n/**\n * Duplicate Entry Error (409 Conflict)\n *\n * Unique constraint violation (e.g., duplicate email)\n */\nexport class DuplicateEntryError extends QueryError\n{\n constructor(field: string, value: string | number)\n {\n super(`${field} '${value}' already exists`, 409, { field, value });\n this.name = 'DuplicateEntryError';\n }\n}","import type { Context } from 'hono';\nimport { Value } from '@sinclair/typebox/value';\nimport type { RouteContract, RouteContext, InferContract } from './types.js';\nimport { ValidationError } from '../errors/database-errors.js';\n\n/**\n * Contract-based Route Handler Wrapper\n *\n * Binds a contract to a route handler, providing automatic validation\n * and type-safe context creation.\n *\n * ## Features\n * - βœ… Automatic params/query/body validation using TypeBox\n * - βœ… Type-safe RouteContext with contract-based inference\n * - βœ… Clean separation: bind() for validation, Hono for middleware\n *\n * ## Usage\n *\n * ```typescript\n * // Basic usage\n * export const GET = bind(contract, async (c) => {\n * return c.json({ data: 'public' });\n * });\n *\n * // For middleware, use Hono's app-level or route-level middleware:\n * // app.use('/api/*', authMiddleware);\n * // app.get('/users/:id', authMiddleware, bind(contract, handler));\n * ```\n *\n * @param contract - Route contract defining params, query, body, response schemas\n * @param handler - Route handler function\n * @returns Hono-compatible handler function\n */\nexport function bind<TContract extends RouteContract>(\n contract: TContract,\n handler: (c: RouteContext<TContract>) => Response | Promise<Response>\n)\n{\n return async (rawContext: Context) =>\n {\n // ============================================================\n // 1. Validate params\n // ============================================================\n const params = rawContext.req.param();\n if (contract.params)\n {\n const errors = [...Value.Errors(contract.params, params)];\n if (errors.length > 0)\n {\n throw new ValidationError(\n 'Invalid path parameters',\n {\n fields: errors.map(e => ({\n path: e.path,\n message: e.message,\n value: e.value,\n }))\n }\n );\n }\n }\n\n // ============================================================\n // 2. Validate query\n // ============================================================\n const url = new URL(rawContext.req.url);\n const query: Record<string, string | string[]> = {};\n url.searchParams.forEach((v, k) =>\n {\n const existing = query[k];\n if (existing)\n {\n // Convert to array or append to existing array\n query[k] = Array.isArray(existing) ? [...existing, v] : [existing, v];\n }\n else\n {\n query[k] = v;\n }\n });\n\n if (contract.query)\n {\n const errors = [...Value.Errors(contract.query, query)];\n if (errors.length > 0)\n {\n throw new ValidationError(\n 'Invalid query parameters',\n {\n fields: errors.map(e => ({\n path: e.path,\n message: e.message,\n value: e.value,\n }))\n }\n );\n }\n }\n\n // ============================================================\n // 3. Create RouteContext\n // ============================================================\n const routeContext: RouteContext<TContract> = {\n params: params as InferContract<TContract>['params'],\n query: query as InferContract<TContract>['query'],\n\n // data() - validates and returns body\n data: async () =>\n {\n const body = await rawContext.req.json();\n if (contract.body)\n {\n const errors = [...Value.Errors(contract.body, body)];\n if (errors.length > 0)\n {\n throw new ValidationError(\n 'Invalid request body',\n {\n fields: errors.map(e => ({\n path: e.path,\n message: e.message,\n value: e.value,\n }))\n }\n );\n }\n }\n return body as InferContract<TContract>['body'];\n },\n\n // json() - returns typed response\n json: (data, status, headers) =>\n {\n return rawContext.json(data, status, headers);\n },\n\n // raw Hono context for advanced usage\n raw: rawContext,\n };\n\n // ============================================================\n // 4. Execute handler\n // ============================================================\n return handler(routeContext);\n };\n}","/**\n * Create App - Hono Wrapper for Contract-based Routing\n *\n * Provides a cleaner API for registering routes with contracts\n */\n\nimport { Hono } from 'hono';\nimport type { MiddlewareHandler } from 'hono';\nimport { bind } from './bind.js';\nimport type { RouteContract, RouteHandler } from './types.js';\n\n/**\n * Extended Hono app with bind() method\n */\nexport type SPFNApp = Hono & {\n /**\n * Bind a contract to a handler with optional middlewares\n *\n * @example\n * ```ts\n * // Handler only\n * app.bind(getUserContract, async (c) => {\n * return c.json({ id: c.params.id });\n * });\n *\n * // With middlewares\n * app.bind(createUserContract, [authMiddleware, logMiddleware], async (c) => {\n * const body = await c.data();\n * return c.json({ id: '123' });\n * });\n * ```\n */\n bind<TContract extends RouteContract>(\n contract: TContract,\n handler: RouteHandler\n ): void;\n\n bind<TContract extends RouteContract>(\n contract: TContract,\n middlewares: MiddlewareHandler[],\n handler: RouteHandler\n ): void;\n\n /**\n * Contract metadata storage\n * Map<\"METHOD /path\", RouteMeta>\n * @internal\n */\n _contractMetas?: Map<string, RouteContract['meta']>;\n};\n\n/**\n * Create SPFN app instance\n *\n * Wraps Hono with contract-based routing support\n *\n * @example\n * ```ts\n * import { createApp } from '@spfn/core/route';\n * import { getUserContract, createUserContract } from '@/server/contracts/users';\n *\n * const app = createApp();\n *\n * // Register routes using contracts\n * app.bind(getUserContract, async (c) => {\n * return c.json({ id: c.params.id });\n * });\n *\n * app.bind(createUserContract, [authMiddleware], async (c) => {\n * const body = await c.data();\n * return c.json({ id: '123' });\n * });\n *\n * export default app;\n * ```\n */\nexport function createApp(): SPFNApp\n{\n const hono = new Hono();\n\n // Add bind method\n const app = hono as SPFNApp;\n\n // Initialize contract metadata storage\n app._contractMetas = new Map();\n\n app.bind = function <TContract extends RouteContract>(\n contract: TContract,\n ...args: [RouteHandler] | [MiddlewareHandler[], RouteHandler]\n )\n {\n const method = contract.method.toLowerCase();\n const path = contract.path;\n\n // Extract middlewares and handler\n const [middlewares, handler] = args.length === 1\n ? [[], args[0]]\n : [args[0], args[1]];\n\n // Store contract metadata for auto-loader\n if (contract.meta)\n {\n const key = `${contract.method} ${path}`;\n app._contractMetas!.set(key, contract.meta);\n }\n\n // Register with Hono using bind() for validation\n const boundHandler = bind(contract, handler);\n\n // Build handler array\n const handlers = middlewares.length > 0\n ? [...middlewares, boundHandler]\n : [boundHandler];\n\n // Register based on HTTP method\n switch (method)\n {\n case 'get':\n hono.get(path, ...handlers);\n break;\n case 'post':\n hono.post(path, ...handlers);\n break;\n case 'put':\n hono.put(path, ...handlers);\n break;\n case 'patch':\n hono.patch(path, ...handlers);\n break;\n case 'delete':\n hono.delete(path, ...handlers);\n break;\n default:\n throw new Error(`Unsupported HTTP method: ${contract.method}`);\n }\n };\n\n return app;\n}","import type { Context } from 'hono';\nimport type { ContentfulStatusCode } from 'hono/utils/http-status';\nimport type { TSchema, Static } from '@sinclair/typebox';\n\n/**\n * Header record type compatible with Hono's c.json headers parameter\n */\nexport type HeaderRecord = Record<string, string | string[]>;\n\n/**\n * File-based Routing System Type Definitions\n *\n * ## Type Flow\n * ```\n * RouteFile (scan)\n * ↓\n * RouteModule (dynamic import + contracts)\n * ↓\n * RouteDefinition (transformation + validation)\n * ↓\n * Hono App (registration)\n * ```\n *\n * ## Core Types\n * 1. **RouteContract**: TypeBox-based contract definition for type safety and validation\n * 2. **RouteContext**: Extended Context for route handlers (params, query, data)\n * 3. **RouteHandler**: Next.js App Router style handler function type\n * 4. **RouteFile**: File system scan result (Scanner output)\n * 5. **RouteModule**: Dynamic import result (Mapper input)\n * 6. **RouteDefinition**: Transformed route definition (Mapper output, Registry storage)\n * 7. **RouteMeta**: Route metadata (auth, tags, description, etc.)\n * 8. **RoutePriority**: Priority enum (STATIC, DYNAMIC, CATCH_ALL)\n * 9. **ScanOptions**: Scanner configuration options\n *\n * ## Applied Improvements\n * βœ… **HTTP Method Types**: Added HttpMethod union type\n * βœ… **Route Grouping**: Added RouteGroup, RouteStats types\n * βœ… **Type Guards**: isRouteFile, isRouteDefinition, isHttpMethod, hasHttpMethodHandlers\n * βœ… **Contract-based Types**: RouteContract, InferContract for end-to-end type safety\n * βœ… **Generic RouteContext**: RouteContext<TContract> for typed params, query, body, response\n */\n\n// ============================================================================\n// Contract Types\n// ============================================================================\n\n/**\n * Route metadata for additional configuration\n */\nexport type RouteMeta = {\n /** Public route (skip authentication) - default: false */\n public?: boolean;\n /** Skip specific global middlewares by name */\n skipMiddlewares?: string[];\n /** OpenAPI tags for grouping */\n tags?: string[];\n /** Route description for documentation */\n description?: string;\n /** Deprecated flag */\n deprecated?: boolean;\n};\n\n/**\n * Route Contract: TypeBox-based type-safe route definition\n *\n * Defines the shape of request/response for a route endpoint\n *\n * Note: params and query are always Record<string, string> from URL,\n * but can be validated and transformed via TypeBox schemas\n */\nexport type RouteContract = {\n /** HTTP method (GET, POST, PUT, etc.) */\n method: HttpMethod;\n /** Route path (e.g., /users/:id) */\n path: string;\n /** Path parameters schema (optional) - input is always Record<string, string> */\n params?: TSchema;\n /** Query parameters schema (optional) - input is always Record<string, string | string[]> */\n query?: TSchema;\n /** Request body schema (optional) */\n body?: TSchema;\n /** Response schema (required) */\n response: TSchema;\n /** Route metadata (optional) */\n meta?: RouteMeta;\n};\n\n/**\n * Infer types from RouteContract\n *\n * Extracts TypeScript types from TypeBox schemas\n */\nexport type InferContract<TContract extends RouteContract> = {\n params: TContract['params'] extends TSchema\n ? Static<TContract['params']>\n : Record<string, never>;\n query: TContract['query'] extends TSchema\n ? Static<TContract['query']>\n : Record<string, never>;\n body: TContract['body'] extends TSchema\n ? Static<TContract['body']>\n : Record<string, never>;\n response: TContract['response'] extends TSchema\n ? Static<TContract['response']>\n : unknown;\n};\n\n/**\n * RouteContext: Route Handler Dedicated Context\n *\n * Generic version with contract-based type inference\n *\n * Convenience methods provided:\n * - params: Path parameters (typed via contract)\n * - query: Query parameters (typed via contract)\n * - data(): Request Body parsing helper (typed via contract)\n * - json(): JSON response helper (typed via contract)\n * - raw: Original Hono Context (advanced features: raw.req, raw.get(), raw.set(), etc.)\n */\nexport type RouteContext<TContract extends RouteContract = any> = {\n /**\n * Path parameters (typed via contract)\n */\n params: InferContract<TContract>['params'];\n\n /**\n * Query parameters (typed via contract)\n */\n query: InferContract<TContract>['query'];\n\n /**\n * Request Body parsing helper (typed via contract)\n */\n data(): Promise<InferContract<TContract>['body']>;\n\n /**\n * JSON response helper (typed via contract)\n */\n json(\n data: InferContract<TContract>['response'],\n status?: ContentfulStatusCode,\n headers?: HeaderRecord\n ): Response;\n\n /**\n * Original Hono Context (for advanced features when needed)\n * - raw.req: Request object (headers, cookies, etc.)\n * - raw.get(): Read context variables (middleware data)\n * - raw.set(): Set context variables\n */\n raw: Context;\n};\n\n/**\n * HTTP method type (common REST API methods)\n */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\n/**\n * Next.js App Router Style Route Handler\n *\n * Function that receives RouteContext and returns Response\n */\nexport type RouteHandler = (c: RouteContext) => Response | Promise<Response>;\n\n/**\n * HttpMethod type guard\n */\nexport function isHttpMethod(value: unknown): value is HttpMethod\n{\n return (\n typeof value === 'string' &&\n ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].includes(value)\n );\n}"]}
1
+ {"version":3,"sources":["../../src/logger/adapters/pino.ts","../../src/logger/types.ts","../../src/logger/formatters.ts","../../src/logger/logger.ts","../../src/logger/transports/console.ts","../../src/logger/transports/file.ts","../../src/logger/config.ts","../../src/logger/adapters/custom.ts","../../src/logger/adapter-factory.ts","../../src/logger/index.ts","../../src/route/function-routes.ts","../../src/route/auto-loader.ts","../../src/errors/http-errors.ts","../../src/route/bind.ts","../../src/middleware/error-handler.ts","../../src/middleware/request-logger.ts","../../src/route/create-app.ts","../../src/types/api-response.ts","../../src/route/types.ts"],"names":["newPath","existsSync","mkdirSync","join","unlinkSync","init_logger","routeLogger","discoverFunctionRoutes"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Pino Logger Adapter\n *\n * High-performance logger adapter using Pino with pretty-print for development and JSON for production.\n */\n\nimport pino from 'pino';\nimport type { LoggerAdapter, AdapterConfig, LogLevel } from './types';\n\n/**\n * Pino Logger Adapter\n */\nexport class PinoAdapter implements LoggerAdapter\n{\n private logger: pino.Logger;\n\n constructor(config: AdapterConfig)\n {\n const isProduction = process.env.NODE_ENV === 'production';\n const isDevelopment = process.env.NODE_ENV === 'development';\n\n // Try to use pino-pretty in development if available (optional dependency)\n const transport = isDevelopment ? {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'HH:MM:ss.l',\n ignore: 'pid,hostname',\n singleLine: false,\n messageFormat: '{module} {msg}',\n errorLikeObjectKeys: ['err', 'error'],\n },\n } : undefined;\n\n // Development: pretty print (if pino-pretty available) or JSON\n // Production: JSON output\n try\n {\n this.logger = pino({\n level: config.level,\n\n // κΈ°λ³Έ ν•„λ“œ\n base: config.module ? { module: config.module } : undefined,\n\n // Transport (pretty print in development if available)\n transport,\n });\n }\n catch (error)\n {\n // Fallback: pino-pretty not available, use plain JSON\n this.logger = pino({\n level: config.level,\n base: config.module ? { module: config.module } : undefined,\n });\n }\n }\n\n child(module: string): LoggerAdapter\n {\n const childLogger = new PinoAdapter({ level: this.logger.level as LogLevel, module });\n childLogger.logger = this.logger.child({ module });\n return childLogger;\n }\n\n debug(message: string, context?: Record<string, unknown>): void\n {\n this.logger.debug(context || {}, message);\n }\n\n info(message: string, context?: Record<string, unknown>): void\n {\n this.logger.info(context || {}, message);\n }\n\n warn(message: string, errorOrContext?: Error | Record<string, unknown>, context?: Record<string, unknown>): void\n {\n if (errorOrContext instanceof Error)\n {\n this.logger.warn({ err: errorOrContext, ...context }, message);\n }\n else\n {\n this.logger.warn(errorOrContext || {}, message);\n }\n }\n\n error(message: string, errorOrContext?: Error | Record<string, unknown>, context?: Record<string, unknown>): void\n {\n if (errorOrContext instanceof Error)\n {\n this.logger.error({ err: errorOrContext, ...context }, message);\n }\n else\n {\n this.logger.error(errorOrContext || {}, message);\n }\n }\n\n fatal(message: string, errorOrContext?: Error | Record<string, unknown>, context?: Record<string, unknown>): void\n {\n if (errorOrContext instanceof Error)\n {\n this.logger.fatal({ err: errorOrContext, ...context }, message);\n }\n else\n {\n this.logger.fatal(errorOrContext || {}, message);\n }\n }\n\n async close(): Promise<void>\n {\n // PinoλŠ” μžλ™μœΌλ‘œ flush됨\n // ν•„μš”μ‹œ pino.final() μ‚¬μš© κ°€λŠ₯\n }\n}","/**\n * Logger Type Definitions\n *\n * λ‘œκΉ… μ‹œμŠ€ν…œ νƒ€μž… μ •μ˜\n *\n * βœ… κ΅¬ν˜„ μ™„λ£Œ:\n * - LogLevel νƒ€μž… μ •μ˜\n * - LogMetadata μΈν„°νŽ˜μ΄μŠ€\n * - Transport μΈν„°νŽ˜μ΄μŠ€\n * - ν™˜κ²½λ³„ μ„€μ • νƒ€μž…\n *\n * πŸ”— κ΄€λ ¨ 파일:\n * - src/logger/logger.ts (Logger 클래슀)\n * - src/logger/transports/ (Transport κ΅¬ν˜„μ²΄)\n * - src/logger/config.ts (μ„€μ •)\n */\n\n/**\n * 둜그 레벨\n * debug < info < warn < error < fatal\n */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';\n\n/**\n * 둜그 레벨 μš°μ„ μˆœμœ„\n */\nexport const LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n fatal: 4,\n};\n\n/**\n * 둜그 메타데이터\n */\nexport interface LogMetadata\n{\n timestamp: Date;\n level: LogLevel;\n message: string;\n module?: string;\n error?: Error;\n context?: Record<string, unknown>;\n}\n\n/**\n * Transport μΈν„°νŽ˜μ΄μŠ€\n * λͺ¨λ“  TransportλŠ” 이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•΄μ•Ό 함\n */\nexport interface Transport\n{\n /**\n * Transport 이름\n */\n name: string;\n\n /**\n * μ΅œμ†Œ 둜그 레벨 (이 레벨 μ΄μƒλ§Œ 처리)\n */\n level: LogLevel;\n\n /**\n * ν™œμ„±ν™” μ—¬λΆ€\n */\n enabled: boolean;\n\n /**\n * 둜그 처리 ν•¨μˆ˜\n */\n log(metadata: LogMetadata): Promise<void>;\n\n /**\n * Transport μ’…λ£Œ (λ¦¬μ†ŒμŠ€ 정리)\n */\n close?(): Promise<void>;\n}\n\n/**\n * Logger μ„€μ •\n */\nexport interface LoggerConfig\n{\n /**\n * κΈ°λ³Έ 둜그 레벨\n */\n level: LogLevel;\n\n /**\n * λͺ¨λ“ˆλͺ… (context)\n */\n module?: string;\n\n /**\n * Transport 리슀트\n */\n transports: Transport[];\n}\n\n/**\n * Transport μ„€μ • (곡톡)\n */\nexport interface TransportConfig\n{\n level: LogLevel;\n enabled: boolean;\n}\n\n/**\n * Console Transport μ„€μ •\n */\nexport interface ConsoleTransportConfig extends TransportConfig\n{\n colorize?: boolean;\n}\n\n/**\n * File Transport μ„€μ •\n */\nexport interface FileTransportConfig extends TransportConfig\n{\n logDir: string;\n maxFileSize?: number; // bytes\n maxFiles?: number; // μ΅œλŒ€ 둜그 파일 개수\n}\n\n/**\n * Slack Transport μ„€μ •\n */\nexport interface SlackTransportConfig extends TransportConfig\n{\n webhookUrl: string;\n channel?: string;\n username?: string;\n}\n\n/**\n * Email Transport μ„€μ •\n */\nexport interface EmailTransportConfig extends TransportConfig\n{\n from: string;\n to: string[];\n smtpHost: string;\n smtpPort: number;\n smtpUser?: string;\n smtpPassword?: string;\n}","/**\n * Logger Formatters\n *\n * Log formatting utilities for console, JSON, Slack, and Email 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 *\n * @param data - 원본 데이터\n * @returns λ§ˆμŠ€ν‚Ήλœ 데이터\n */\nexport function maskSensitiveData(data: unknown): unknown\n{\n // null, undefined 처리\n if (data === null || data === undefined)\n {\n return data;\n }\n\n // λ°°μ—΄ 처리\n if (Array.isArray(data))\n {\n return data.map(item => maskSensitiveData(item));\n }\n\n // 객체 처리\n if (typeof data === 'object')\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 // μ€‘μ²©λœ κ°μ²΄λŠ” μž¬κ·€ 처리\n masked[key] = maskSensitiveData(value);\n }\n else\n {\n // 일반 값은 κ·ΈλŒ€λ‘œ μœ μ§€\n masked[key] = value;\n }\n }\n\n return masked;\n }\n\n // κΈ°λ³Έ νƒ€μž…μ€ κ·ΈλŒ€λ‘œ λ°˜ν™˜\n return data;\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 // [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 const valueStr = typeof value === 'string' ? value : String(value);\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 * Slack λ©”μ‹œμ§€ 포맷\n */\nexport function formatSlack(metadata: LogMetadata): string\n{\n const emoji = {\n debug: ':bug:',\n info: ':information_source:',\n warn: ':warning:',\n error: ':x:',\n fatal: ':fire:',\n };\n\n const parts: string[] = [];\n\n parts.push(`${emoji[metadata.level]} *${metadata.level.toUpperCase()}*`);\n\n if (metadata.module)\n {\n parts.push(`\\`[${metadata.module}]\\``);\n }\n\n parts.push(metadata.message);\n\n let message = parts.join(' ');\n\n if (metadata.context)\n {\n message += '\\n```\\n' + JSON.stringify(metadata.context, null, 2) + '\\n```';\n }\n\n if (metadata.error)\n {\n message += '\\n```\\n' + formatError(metadata.error) + '\\n```';\n }\n\n return message;\n}\n\n/**\n * Email 제λͺ© 생성\n */\nexport function formatEmailSubject(metadata: LogMetadata): string\n{\n const prefix = `[${metadata.level.toUpperCase()}]`;\n const module = metadata.module ? `[${metadata.module}]` : '';\n\n return `${prefix}${module} ${metadata.message}`;\n}\n\n/**\n * Email λ³Έλ¬Έ 생성 (HTML)\n */\nexport function formatEmailBody(metadata: LogMetadata): string\n{\n const parts: string[] = [];\n\n parts.push('<html>');\n parts.push('<body style=\"font-family: monospace; padding: 20px;\">');\n\n // 헀더\n parts.push(`<h2 style=\"color: ${getEmailColor(metadata.level)};\">`);\n parts.push(`${metadata.level.toUpperCase()}`);\n parts.push('</h2>');\n\n // μ‹œκ°„\n parts.push('<p>');\n parts.push(`<strong>Timestamp:</strong> ${formatTimestamp(metadata.timestamp)}`);\n parts.push('</p>');\n\n // λͺ¨λ“ˆ\n if (metadata.module)\n {\n parts.push('<p>');\n parts.push(`<strong>Module:</strong> ${metadata.module}`);\n parts.push('</p>');\n }\n\n // λ©”μ‹œμ§€\n parts.push('<p>');\n parts.push(`<strong>Message:</strong> ${metadata.message}`);\n parts.push('</p>');\n\n // Context\n if (metadata.context)\n {\n parts.push('<h3>Context</h3>');\n parts.push('<pre style=\"background: #f4f4f4; padding: 10px; border-radius: 4px;\">');\n parts.push(JSON.stringify(metadata.context, null, 2));\n parts.push('</pre>');\n }\n\n // μ—λŸ¬\n if (metadata.error)\n {\n parts.push('<h3>Error Stack Trace</h3>');\n parts.push('<pre style=\"background: #fff0f0; padding: 10px; border-radius: 4px;\">');\n parts.push(formatError(metadata.error));\n parts.push('</pre>');\n }\n\n parts.push('</body>');\n parts.push('</html>');\n\n return parts.join('\\n');\n}\n\n/**\n * Email λ ˆλ²¨λ³„ 컬러\n */\nfunction getEmailColor(level: LogLevel): string\n{\n const colors: Record<LogLevel, string> = {\n debug: '#00BCD4',\n info: '#4CAF50',\n warn: '#FF9800',\n error: '#F44336',\n fatal: '#9C27B0',\n };\n\n return colors[level];\n}","/**\n * Logger Class\n *\n * Central logging class with multiple transports, child loggers, and sensitive data masking.\n */\n\nimport type { LogLevel, LogMetadata, LoggerConfig, Transport } from './types';\nimport { LOG_LEVEL_PRIORITY } from './types';\nimport { maskSensitiveData } from './formatters';\n\n/**\n * Logger class\n */\nexport class Logger\n{\n private readonly config: LoggerConfig;\n private readonly module?: string;\n\n constructor(config: LoggerConfig)\n {\n this.config = config;\n this.module = config.module;\n }\n\n /**\n * Get current log level\n */\n get level(): LogLevel\n {\n return this.config.level;\n }\n\n /**\n * Create child logger (per module)\n */\n child(module: string): Logger\n {\n return new Logger({\n ...this.config,\n module,\n });\n }\n\n /**\n * Debug log\n */\n debug(message: string, context?: Record<string, unknown>): void\n {\n this.log('debug', message, undefined, context);\n }\n\n /**\n * Info log\n */\n info(message: string, context?: Record<string, unknown>): void\n {\n this.log('info', message, undefined, context);\n }\n\n /**\n * Warn log\n */\n warn(message: string, context?: Record<string, unknown>): void;\n warn(message: string, error: Error, context?: Record<string, unknown>): void;\n warn(message: string, errorOrContext?: Error | Record<string, unknown>, context?: Record<string, unknown>): void\n {\n if (errorOrContext instanceof Error)\n {\n this.log('warn', message, errorOrContext, context);\n }\n else\n {\n this.log('warn', message, undefined, errorOrContext);\n }\n }\n\n /**\n * Error log\n */\n error(message: string, context?: Record<string, unknown>): void;\n error(message: string, error: Error, context?: Record<string, unknown>): void;\n error(message: string, errorOrContext?: Error | Record<string, unknown>, context?: Record<string, unknown>): void\n {\n if (errorOrContext instanceof Error)\n {\n this.log('error', message, errorOrContext, context);\n }\n else\n {\n this.log('error', message, undefined, errorOrContext);\n }\n }\n\n /**\n * Fatal log\n */\n fatal(message: string, context?: Record<string, unknown>): void;\n fatal(message: string, error: Error, context?: Record<string, unknown>): void;\n fatal(message: string, errorOrContext?: Error | Record<string, unknown>, context?: Record<string, unknown>): void\n {\n if (errorOrContext instanceof Error)\n {\n this.log('fatal', message, errorOrContext, context);\n }\n else\n {\n this.log('fatal', message, undefined, errorOrContext);\n }\n }\n\n /**\n * Log processing (internal)\n */\n private log(level: LogLevel, message: string, error?: Error, context?: Record<string, unknown>): void\n {\n // Early return if log level is below configured level\n // This prevents unnecessary metadata creation and processing\n if (LOG_LEVEL_PRIORITY[level] < LOG_LEVEL_PRIORITY[this.config.level])\n {\n return;\n }\n\n const metadata: LogMetadata = {\n timestamp: new Date(),\n level,\n message,\n module: this.module,\n error,\n // Mask sensitive information in context to prevent credential leaks\n context: context ? maskSensitiveData(context) as Record<string, unknown> : undefined,\n };\n\n // Pass to all enabled Transports\n this.processTransports(metadata);\n }\n\n /**\n * Process Transports\n */\n private processTransports(metadata: LogMetadata): void\n {\n const promises = this.config.transports\n .filter(transport => transport.enabled)\n .map(transport => this.safeTransportLog(transport, metadata));\n\n // Async processing to prevent Transport errors from blocking logs\n Promise.all(promises).catch(error =>\n {\n // Use stderr directly to avoid circular logging\n const errorMessage = error instanceof Error ? error.message : String(error);\n process.stderr.write(`[Logger] Transport error: ${errorMessage}\\n`);\n });\n }\n\n /**\n * Transport log (error-safe)\n */\n private async safeTransportLog(transport: Transport, metadata: LogMetadata): Promise<void>\n {\n try\n {\n await transport.log(metadata);\n }\n catch (error)\n {\n // Use stderr directly to avoid circular logging\n const errorMessage = error instanceof Error ? error.message : String(error);\n process.stderr.write(`[Logger] Transport \"${transport.name}\" failed: ${errorMessage}\\n`);\n }\n }\n\n /**\n * Close all Transports\n */\n async close(): Promise<void>\n {\n const closePromises = this.config.transports\n .filter(transport => transport.close)\n .map(transport => transport.close!());\n\n await Promise.all(closePromises);\n }\n}","/**\n * Console Transport\n *\n * μ½˜μ†” 좜λ ₯ Transport\n *\n * βœ… κ΅¬ν˜„ μ™„λ£Œ:\n * - μ½˜μ†” 좜λ ₯ (stdout/stderr)\n * - 컬러 좜λ ₯ 지원\n * - 둜그 λ ˆλ²¨λ³„ 슀트림 뢄리 (warn/error/fatal β†’ stderr)\n *\n * πŸ”— κ΄€λ ¨ 파일:\n * - src/logger/types.ts (Transport μΈν„°νŽ˜μ΄μŠ€)\n * - src/logger/formatters.ts (포맷터)\n * - src/logger/config.ts (μ„€μ •)\n */\n\nimport type { Transport, LogMetadata, LogLevel, ConsoleTransportConfig } from '../types';\nimport { LOG_LEVEL_PRIORITY } from '../types';\nimport { formatConsole } from '../formatters';\n\n/**\n * Console Transport\n */\nexport class ConsoleTransport implements Transport\n{\n public readonly name = 'console';\n public readonly level: LogLevel;\n public readonly enabled: boolean;\n\n private colorize: boolean;\n\n constructor(config: ConsoleTransportConfig)\n {\n this.level = config.level;\n this.enabled = config.enabled;\n this.colorize = config.colorize ?? true;\n }\n\n async log(metadata: LogMetadata): Promise<void>\n {\n // Enabled μƒνƒœ 체크\n if (!this.enabled)\n {\n return;\n }\n\n // 둜그 레벨 체크\n if (LOG_LEVEL_PRIORITY[metadata.level] < LOG_LEVEL_PRIORITY[this.level])\n {\n return;\n }\n\n // ν¬λ§·νŒ…\n const message = formatConsole(metadata, this.colorize);\n\n // warn/error/fatal은 stderr둜, λ‚˜λ¨Έμ§€λŠ” stdout으둜\n if (metadata.level === 'warn' || metadata.level === 'error' || metadata.level === 'fatal')\n {\n console.error(message);\n }\n else\n {\n console.log(message);\n }\n }\n}","/**\n * File Transport\n *\n * File output transport with date and size-based rotation, automatic cleanup.\n */\n\nimport { createWriteStream, existsSync, mkdirSync, statSync, readdirSync, unlinkSync, renameSync } from 'fs';\nimport type { WriteStream } from 'fs';\nimport { join } from 'path';\nimport type { Transport, LogMetadata, LogLevel, FileTransportConfig } from '../types';\nimport { LOG_LEVEL_PRIORITY } from '../types';\nimport { formatJSON } from '../formatters';\n\n/**\n * File Transport\n */\nexport class FileTransport implements Transport\n{\n public readonly name = 'file';\n public readonly level: LogLevel;\n public readonly enabled: boolean;\n\n private readonly logDir: string;\n private readonly maxFileSize: number;\n private readonly maxFiles: number;\n private currentStream: WriteStream | null = null;\n private currentFilename: string | null = null;\n\n constructor(config: FileTransportConfig)\n {\n this.level = config.level;\n this.enabled = config.enabled;\n this.logDir = config.logDir;\n this.maxFileSize = config.maxFileSize ?? 10 * 1024 * 1024; // 10MB\n this.maxFiles = config.maxFiles ?? 10;\n\n // 둜그 디렉토리가 μ—†μœΌλ©΄ 생성\n if (!existsSync(this.logDir))\n {\n mkdirSync(this.logDir, { recursive: true });\n }\n }\n\n async log(metadata: LogMetadata): Promise<void>\n {\n // Enabled μƒνƒœ 체크\n if (!this.enabled)\n {\n return;\n }\n\n // 둜그 레벨 체크\n if (LOG_LEVEL_PRIORITY[metadata.level] < LOG_LEVEL_PRIORITY[this.level])\n {\n return;\n }\n\n // JSON 포맷으둜 λ³€ν™˜\n const message = formatJSON(metadata);\n\n // 파일λͺ…: YYYY-MM-DD.log\n const filename = this.getLogFilename(metadata.timestamp);\n\n // λ‚ μ§œκ°€ λ³€κ²½λ˜λ©΄ 슀트림 ꡐ체\n if (this.currentFilename !== filename)\n {\n await this.rotateStream(filename);\n await this.cleanOldFiles(); // 였래된 파일 정리\n }\n // 파일 크기 체크 및 λ‘œν…Œμ΄μ…˜\n else if (this.currentFilename)\n {\n await this.checkAndRotateBySize();\n }\n\n // μŠ€νŠΈλ¦Όμ— μ“°κΈ°\n if (this.currentStream)\n {\n return new Promise((resolve, reject) =>\n {\n this.currentStream!.write(message + '\\n', 'utf-8', (error: Error | null | undefined) =>\n {\n if (error)\n {\n // 파일 μ“°κΈ° μ‹€νŒ¨ μ‹œ stderr둜 좜λ ₯ (fallback)\n process.stderr.write(`[FileTransport] Failed to write log: ${error.message}\\n`);\n reject(error);\n }\n else\n {\n resolve();\n }\n });\n });\n }\n }\n\n /**\n * 슀트림 ꡐ체 (λ‚ μ§œ λ³€κ²½ μ‹œ)\n */\n private async rotateStream(filename: string): Promise<void>\n {\n // κΈ°μ‘΄ 슀트림 λ‹«κΈ°\n if (this.currentStream)\n {\n await this.closeStream();\n }\n\n // μƒˆ 슀트림 생성\n const filepath = join(this.logDir, filename);\n\n this.currentStream = createWriteStream(filepath, {\n flags: 'a', // append mode\n encoding: 'utf-8',\n });\n\n this.currentFilename = filename;\n\n // 슀트림 μ—λŸ¬ 핸듀링\n this.currentStream.on('error', (error) =>\n {\n process.stderr.write(`[FileTransport] Stream error: ${error.message}\\n`);\n // μ—λŸ¬ λ°œμƒ μ‹œ 슀트림 μ΄ˆκΈ°ν™”\n this.currentStream = null;\n this.currentFilename = null;\n });\n }\n\n /**\n * ν˜„μž¬ 슀트림 λ‹«κΈ°\n */\n private async closeStream(): Promise<void>\n {\n if (!this.currentStream)\n {\n return;\n }\n\n return new Promise((resolve, reject) =>\n {\n this.currentStream!.end((error: Error | null | undefined) =>\n {\n if (error)\n {\n reject(error);\n }\n else\n {\n this.currentStream = null;\n this.currentFilename = null;\n resolve();\n }\n });\n });\n }\n\n /**\n * 파일 크기 체크 및 크기 기반 λ‘œν…Œμ΄μ…˜\n */\n private async checkAndRotateBySize(): Promise<void>\n {\n if (!this.currentFilename)\n {\n return;\n }\n\n const filepath = join(this.logDir, this.currentFilename);\n\n // 파일이 μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄ μŠ€ν‚΅\n if (!existsSync(filepath))\n {\n return;\n }\n\n try\n {\n const stats = statSync(filepath);\n\n // 파일 크기가 maxFileSizeλ₯Ό μ΄ˆκ³Όν•˜λ©΄ λ‘œν…Œμ΄μ…˜\n if (stats.size >= this.maxFileSize)\n {\n await this.rotateBySize();\n }\n }\n catch (error)\n {\n // 파일 stat μ‹€νŒ¨ μ‹œ λ¬΄μ‹œ\n const errorMessage = error instanceof Error ? error.message : String(error);\n process.stderr.write(`[FileTransport] Failed to check file size: ${errorMessage}\\n`);\n }\n }\n\n /**\n * 크기 기반 λ‘œν…Œμ΄μ…˜ μˆ˜ν–‰\n * 예: 2025-01-01.log -> 2025-01-01.1.log, 2025-01-01.1.log -> 2025-01-01.2.log\n */\n private async rotateBySize(): Promise<void>\n {\n if (!this.currentFilename)\n {\n return;\n }\n\n // κΈ°μ‘΄ 슀트림 λ‹«κΈ°\n await this.closeStream();\n\n const baseName = this.currentFilename.replace(/\\.log$/, '');\n const files = readdirSync(this.logDir);\n\n // ν˜„μž¬ λ‚ μ§œμ˜ 둜그 νŒŒμΌλ“€ μ°ΎκΈ° (예: 2025-01-01.log, 2025-01-01.1.log, ...)\n const relatedFiles = files\n .filter(file => file.startsWith(baseName) && file.endsWith('.log'))\n .sort()\n .reverse(); // μ—­μˆœ μ •λ ¬λ‘œ 높은 λ²ˆν˜ΈλΆ€ν„° 처리\n\n // κΈ°μ‘΄ νŒŒμΌλ“€μ„ 번호 μ¦κ°€μ‹œμΌœ 이동 (예: .1.log -> .2.log)\n for (const file of relatedFiles)\n {\n const match = file.match(/\\.(\\d+)\\.log$/);\n if (match)\n {\n const oldNum = parseInt(match[1], 10);\n const newNum = oldNum + 1;\n const oldPath = join(this.logDir, file);\n const newPath = join(this.logDir, `${baseName}.${newNum}.log`);\n\n try\n {\n renameSync(oldPath, newPath);\n }\n catch (error)\n {\n const errorMessage = error instanceof Error ? error.message : String(error);\n process.stderr.write(`[FileTransport] Failed to rotate file: ${errorMessage}\\n`);\n }\n }\n }\n\n // ν˜„μž¬ νŒŒμΌμ„ .1.log둜 이동\n const currentPath = join(this.logDir, this.currentFilename);\n const newPath = join(this.logDir, `${baseName}.1.log`);\n\n try\n {\n if (existsSync(currentPath))\n {\n renameSync(currentPath, newPath);\n }\n }\n catch (error)\n {\n const errorMessage = error instanceof Error ? error.message : String(error);\n process.stderr.write(`[FileTransport] Failed to rotate current file: ${errorMessage}\\n`);\n }\n\n // μƒˆ 슀트림 생성 (λ™μΌν•œ 파일λͺ…μœΌλ‘œ)\n await this.rotateStream(this.currentFilename);\n }\n\n /**\n * 였래된 둜그 파일 정리\n * maxFiles 개수λ₯Ό μ΄ˆκ³Όν•˜λŠ” 둜그 파일 μ‚­μ œ\n */\n private async cleanOldFiles(): Promise<void>\n {\n try\n {\n // 디렉토리가 μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄ μŠ€ν‚΅\n if (!existsSync(this.logDir))\n {\n return;\n }\n\n const files = readdirSync(this.logDir);\n\n // .log둜 λλ‚˜λŠ” 파일만 필터링 ν›„ μˆ˜μ • μ‹œκ°„ κΈ°μ€€ μ •λ ¬\n const logFiles = files\n .filter(file => file.endsWith('.log'))\n .map(file =>\n {\n const filepath = join(this.logDir, file);\n const stats = statSync(filepath);\n return { file, mtime: stats.mtime };\n })\n .sort((a, b) => b.mtime.getTime() - a.mtime.getTime()); // μ΅œμ‹  파일이 μ•žμœΌλ‘œ\n\n // maxFilesλ₯Ό μ΄ˆκ³Όν•˜λŠ” 였래된 νŒŒμΌλ“€ μ‚­μ œ\n if (logFiles.length > this.maxFiles)\n {\n const filesToDelete = logFiles.slice(this.maxFiles);\n\n for (const { file } of filesToDelete)\n {\n const filepath = join(this.logDir, file);\n try\n {\n unlinkSync(filepath);\n }\n catch (error)\n {\n const errorMessage = error instanceof Error ? error.message : String(error);\n process.stderr.write(`[FileTransport] Failed to delete old file \"${file}\": ${errorMessage}\\n`);\n }\n }\n }\n }\n catch (error)\n {\n const errorMessage = error instanceof Error ? error.message : String(error);\n process.stderr.write(`[FileTransport] Failed to clean old files: ${errorMessage}\\n`);\n }\n }\n\n /**\n * λ‚ μ§œλ³„ 둜그 파일λͺ… 생성\n */\n private getLogFilename(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\n return `${year}-${month}-${day}.log`;\n }\n\n async close(): Promise<void>\n {\n // 슀트림 정리\n await this.closeStream();\n }\n}","/**\n * Logger Configuration\n *\n * Environment-based logger configuration with validation for console, file, Slack, and Email transports.\n */\n\nimport { existsSync, accessSync, constants, mkdirSync, writeFileSync, unlinkSync } from 'fs';\nimport { join } from 'path';\nimport type {\n LogLevel,\n ConsoleTransportConfig,\n FileTransportConfig,\n SlackTransportConfig,\n EmailTransportConfig,\n} from './types';\n\n/**\n * Check if file logging is enabled (for self-hosted)\n */\nexport function isFileLoggingEnabled(): boolean\n{\n return process.env.LOGGER_FILE_ENABLED === 'true';\n}\n\n/**\n * Get default log level by environment\n */\nexport function getDefaultLogLevel(): LogLevel\n{\n const isProduction = process.env.NODE_ENV === 'production';\n const isDevelopment = process.env.NODE_ENV === 'development';\n\n if (isDevelopment)\n {\n return 'debug';\n }\n\n if (isProduction)\n {\n return 'info';\n }\n\n // Test environment\n return 'warn';\n}\n\n/**\n * Console Transport configuration\n */\nexport function getConsoleConfig(): ConsoleTransportConfig\n{\n const isProduction = process.env.NODE_ENV === 'production';\n\n return {\n level: 'debug',\n enabled: true,\n colorize: !isProduction, // Dev: colored output, Production: plain text\n };\n}\n\n/**\n * File Transport configuration\n */\nexport function getFileConfig(): FileTransportConfig\n{\n const isProduction = process.env.NODE_ENV === 'production';\n\n return {\n level: 'info',\n enabled: isProduction, // File logging in production only\n logDir: process.env.LOG_DIR || './logs',\n maxFileSize: 10 * 1024 * 1024, // 10MB\n maxFiles: 10,\n };\n}\n\n/**\n * Slack Transport configuration\n */\nexport function getSlackConfig(): SlackTransportConfig | null\n{\n const webhookUrl = process.env.SLACK_WEBHOOK_URL;\n\n if (!webhookUrl)\n {\n return null; // Disabled if not configured\n }\n\n const isProduction = process.env.NODE_ENV === 'production';\n\n return {\n level: 'error', // Send error and above to Slack\n enabled: isProduction, // Enabled in production only\n webhookUrl,\n channel: process.env.SLACK_CHANNEL,\n username: process.env.SLACK_USERNAME || 'Logger Bot',\n };\n}\n\n/**\n * Email Transport configuration\n */\nexport function getEmailConfig(): EmailTransportConfig | null\n{\n const smtpHost = process.env.SMTP_HOST;\n const smtpPort = process.env.SMTP_PORT;\n const emailFrom = process.env.EMAIL_FROM;\n const emailTo = process.env.EMAIL_TO;\n\n // Disabled if required settings are missing\n if (!smtpHost || !smtpPort || !emailFrom || !emailTo)\n {\n return null;\n }\n\n const isProduction = process.env.NODE_ENV === 'production';\n\n return {\n level: 'fatal', // Send fatal level only via email\n enabled: isProduction, // Enabled in production only\n from: emailFrom,\n to: emailTo.split(',').map(email => email.trim()),\n smtpHost,\n smtpPort: parseInt(smtpPort, 10),\n smtpUser: process.env.SMTP_USER,\n smtpPassword: process.env.SMTP_PASSWORD,\n };\n}\n\n/**\n * Validate directory path and write permissions\n */\nfunction validateDirectoryWritable(dirPath: string): void\n{\n // Check if directory exists\n if (!existsSync(dirPath))\n {\n // Try to create directory\n try\n {\n mkdirSync(dirPath, { recursive: true });\n }\n catch (error)\n {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to create log directory \"${dirPath}\": ${errorMessage}`);\n }\n }\n\n // Check write permission\n try\n {\n accessSync(dirPath, constants.W_OK);\n }\n catch\n {\n throw new Error(`Log directory \"${dirPath}\" is not writable. Please check permissions.`);\n }\n\n // Try to write a test file\n const testFile = join(dirPath, '.logger-write-test');\n try\n {\n writeFileSync(testFile, 'test', 'utf-8');\n unlinkSync(testFile);\n }\n catch (error)\n {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Cannot write to log directory \"${dirPath}\": ${errorMessage}`);\n }\n}\n\n/**\n * Validate file transport configuration\n */\nfunction validateFileConfig(): void\n{\n if (!isFileLoggingEnabled())\n {\n return; // File logging disabled, skip validation\n }\n\n const logDir = process.env.LOG_DIR;\n\n // Check if LOG_DIR is set\n if (!logDir)\n {\n throw new Error(\n 'LOG_DIR environment variable is required when LOGGER_FILE_ENABLED=true. ' +\n 'Example: LOG_DIR=/var/log/myapp'\n );\n }\n\n // Validate directory\n validateDirectoryWritable(logDir);\n}\n\n/**\n * Validate Slack transport configuration\n */\nfunction validateSlackConfig(): void\n{\n const webhookUrl = process.env.SLACK_WEBHOOK_URL;\n\n if (!webhookUrl)\n {\n return; // Slack disabled, skip validation\n }\n\n // Validate webhook URL format\n if (!webhookUrl.startsWith('https://hooks.slack.com/'))\n {\n throw new Error(\n `Invalid SLACK_WEBHOOK_URL: \"${webhookUrl}\". ` +\n 'Slack webhook URLs must start with \"https://hooks.slack.com/\"'\n );\n }\n}\n\n/**\n * Validate Email transport configuration\n */\nfunction validateEmailConfig(): void\n{\n const smtpHost = process.env.SMTP_HOST;\n const smtpPort = process.env.SMTP_PORT;\n const emailFrom = process.env.EMAIL_FROM;\n const emailTo = process.env.EMAIL_TO;\n\n // If any email config is set, all required fields must be present\n const hasAnyEmailConfig = smtpHost || smtpPort || emailFrom || emailTo;\n if (!hasAnyEmailConfig)\n {\n return; // Email disabled, skip validation\n }\n\n // Validate all required fields\n const missingFields: string[] = [];\n if (!smtpHost) missingFields.push('SMTP_HOST');\n if (!smtpPort) missingFields.push('SMTP_PORT');\n if (!emailFrom) missingFields.push('EMAIL_FROM');\n if (!emailTo) missingFields.push('EMAIL_TO');\n\n if (missingFields.length > 0)\n {\n throw new Error(\n `Email transport configuration incomplete. Missing: ${missingFields.join(', ')}. ` +\n 'Either set all required fields or remove all email configuration.'\n );\n }\n\n // Validate SMTP port is a number\n const port = parseInt(smtpPort!, 10);\n if (isNaN(port) || port < 1 || port > 65535)\n {\n throw new Error(\n `Invalid SMTP_PORT: \"${smtpPort}\". Must be a number between 1 and 65535.`\n );\n }\n\n // Validate email format (basic check)\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(emailFrom!))\n {\n throw new Error(`Invalid EMAIL_FROM format: \"${emailFrom}\"`);\n }\n\n // Validate email recipients\n const recipients = emailTo!.split(',').map(e => e.trim());\n for (const email of recipients)\n {\n if (!emailRegex.test(email))\n {\n throw new Error(`Invalid email address in EMAIL_TO: \"${email}\"`);\n }\n }\n}\n\n/**\n * Validate environment variables\n */\nfunction validateEnvironment(): void\n{\n const nodeEnv = process.env.NODE_ENV;\n\n if (!nodeEnv)\n {\n process.stderr.write(\n '[Logger] Warning: NODE_ENV is not set. Defaulting to test environment.\\n'\n );\n }\n // Allow any NODE_ENV value (development, production, test, staging, local, etc.)\n // No validation needed - users can use custom environments\n}\n\n/**\n * Validate all logger configuration\n * Throws an error if configuration is invalid\n */\nexport function validateConfig(): void\n{\n try\n {\n validateEnvironment();\n validateFileConfig();\n validateSlackConfig();\n validateEmailConfig();\n }\n catch (error)\n {\n if (error instanceof Error)\n {\n throw new Error(`[Logger] Configuration validation failed: ${error.message}`);\n }\n throw error;\n }\n}","/**\n * Custom Logger Adapter\n *\n * 자체 κ΅¬ν˜„ν•œ Loggerλ₯Ό μ‚¬μš©ν•˜λŠ” Adapter\n *\n * βœ… κ΅¬ν˜„ μ™„λ£Œ:\n * - κΈ°μ‘΄ Logger 클래슀 λž˜ν•‘\n * - Transport μ‹œμŠ€ν…œ (Console, File)\n * - Child logger 지원\n *\n * πŸ’‘ μš©λ„:\n * - Pino μ˜μ‘΄μ„± 제거 ν•„μš”μ‹œ\n * - μ»€μŠ€ν…€ Transport ν•„μš”μ‹œ\n * - μ™„μ „ν•œ μ œμ–΄κ°€ ν•„μš”ν•œ 경우\n *\n * πŸ”— κ΄€λ ¨ 파일:\n * - src/logger/logger.ts (Logger 클래슀)\n * - src/logger/transports/ (Transport κ΅¬ν˜„)\n * - src/logger/adapters/types.ts (μΈν„°νŽ˜μ΄μŠ€)\n */\n\nimport { Logger } from '../logger';\nimport { ConsoleTransport } from '../transports/console';\nimport { FileTransport } from '../transports/file';\nimport { getConsoleConfig, getFileConfig } from '../config';\nimport type { LoggerAdapter, AdapterConfig } from './types';\nimport type { Transport } from '../types';\n\n/**\n * Transport μ΄ˆκΈ°ν™”\n */\nfunction initializeTransports(): Transport[]\n{\n const transports: Transport[] = [];\n\n // Console Transport (항상 ν™œμ„±ν™”)\n const consoleConfig = getConsoleConfig();\n transports.push(new ConsoleTransport(consoleConfig));\n\n // File Transport (ν”„λ‘œλ•μ…˜μ—μ„œλ§Œ ν™œμ„±ν™”)\n const fileConfig = getFileConfig();\n if (fileConfig.enabled)\n {\n transports.push(new FileTransport(fileConfig));\n }\n\n return transports;\n}\n\n/**\n * Custom Logger Adapter\n */\nexport class CustomAdapter implements LoggerAdapter\n{\n private logger: Logger;\n\n constructor(config: AdapterConfig)\n {\n this.logger = new Logger({\n level: config.level,\n module: config.module,\n transports: initializeTransports(),\n });\n }\n\n child(module: string): LoggerAdapter\n {\n const adapter = new CustomAdapter({ level: this.logger.level, module });\n adapter.logger = this.logger.child(module);\n return adapter;\n }\n\n debug(message: string, context?: Record<string, unknown>): void\n {\n this.logger.debug(message, context);\n }\n\n info(message: string, context?: Record<string, unknown>): void\n {\n this.logger.info(message, context);\n }\n\n warn(message: string, errorOrContext?: Error | Record<string, unknown>, context?: Record<string, unknown>): void\n {\n if (errorOrContext instanceof Error)\n {\n this.logger.warn(message, errorOrContext, context);\n }\n else\n {\n this.logger.warn(message, errorOrContext);\n }\n }\n\n error(message: string, errorOrContext?: Error | Record<string, unknown>, context?: Record<string, unknown>): void\n {\n if (errorOrContext instanceof Error)\n {\n this.logger.error(message, errorOrContext, context);\n }\n else\n {\n this.logger.error(message, errorOrContext);\n }\n }\n\n fatal(message: string, errorOrContext?: Error | Record<string, unknown>, context?: Record<string, unknown>): void\n {\n if (errorOrContext instanceof Error)\n {\n this.logger.fatal(message, errorOrContext, context);\n }\n else\n {\n this.logger.fatal(message, errorOrContext);\n }\n }\n\n async close(): Promise<void>\n {\n await this.logger.close();\n }\n}","/**\n * Logger Adapter Factory\n *\n * Adapter creation and initialization logic\n */\n\nimport { PinoAdapter } from './adapters/pino.js';\nimport { CustomAdapter } from './adapters/custom.js';\nimport { getDefaultLogLevel, validateConfig } from './config.js';\nimport type { LoggerAdapter } from './adapters/types.js';\n\n/**\n * Adapter type\n */\ntype AdapterType = 'pino' | 'custom';\n\n/**\n * Create adapter instance\n */\nfunction createAdapter(type: AdapterType): LoggerAdapter\n{\n const level = getDefaultLogLevel();\n\n switch (type)\n {\n case 'pino':\n return new PinoAdapter({ level });\n\n case 'custom':\n return new CustomAdapter({ level });\n\n default:\n return new PinoAdapter({ level });\n }\n}\n\n/**\n * Read adapter type from environment variable\n */\nfunction getAdapterType(): AdapterType\n{\n const adapterEnv = process.env.LOGGER_ADAPTER as AdapterType;\n\n if (adapterEnv === 'custom' || adapterEnv === 'pino')\n {\n return adapterEnv;\n }\n\n // Default: pino\n return 'pino';\n}\n\n/**\n * Initialize logger with configuration validation\n */\nfunction initializeLogger(): LoggerAdapter\n{\n // Validate configuration before creating logger\n validateConfig();\n\n // Create and return logger instance\n return createAdapter(getAdapterType());\n}\n\n/**\n * Singleton Logger instance\n */\nexport const logger: LoggerAdapter = initializeLogger();","/**\n * Logger Module Exports\n *\n * Entry point for logger module (Pure re-export only)\n *\n * πŸ’‘ Usage examples:\n * ```typescript\n * import { logger } from '@spfn/core';\n *\n * // Basic usage\n * logger.info('Application started');\n * logger.error('Connection failed', error);\n *\n * // Create module-specific logger\n * const dbLogger = logger.child('database');\n * dbLogger.debug('Connecting to database...');\n *\n * // Add context\n * logger.warn('Retry attempt', { attempt: 3, delay: 1000 });\n * ```\n *\n * πŸ’‘ Adapter switching:\n * - Environment variable: LOGGER_ADAPTER=pino (default) or custom\n * - Pino: High performance, production-proven\n * - Custom: Full control, no Pino dependency\n */\n\n// Logger Instance\nexport { logger } from './adapter-factory.js';\n\n// Types\nexport type { LogLevel, LoggerAdapter } from './adapters/types.js';\n","/**\n * Function Route Discovery\n *\n * Automatically discovers and loads routes from SPFN functions\n *\n * NOTE: Contract-based routing - routes use absolute paths defined in contracts\n * No basePath needed - each contract defines its own absolute path (e.g., '/cms/labels')\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { logger } from '../logger';\n\nconst routeLogger = logger.child('function-routes');\n\nexport type FunctionRouteInfo = {\n packageName: string;\n routesDir: string;\n packagePath: string;\n prefix?: string; // From package.json spfn.prefix\n};\n\n/**\n * Discover SPFN functions with route declarations\n *\n * Scans node_modules for packages that declare routes in package.json\n *\n * Example package.json:\n * ```json\n * {\n * \"name\": \"@spfn/cms\",\n * \"spfn\": {\n * \"routes\": {\n * \"dir\": \"./dist/routes\"\n * }\n * }\n * }\n * ```\n */\nexport function discoverFunctionRoutes(cwd: string = process.cwd()): FunctionRouteInfo[]\n{\n const functions: FunctionRouteInfo[] = [];\n const nodeModulesPath = join(cwd, 'node_modules');\n\n try\n {\n // Read package.json to get dependencies\n const projectPkgPath = join(cwd, 'package.json');\n const projectPkg = JSON.parse(readFileSync(projectPkgPath, 'utf-8'));\n\n const dependencies = {\n ...projectPkg.dependencies,\n ...projectPkg.devDependencies,\n };\n\n // Scan each dependency for spfn.routes\n for (const [packageName] of Object.entries(dependencies))\n {\n // Only scan @spfn/* and packages starting with spfn-\n if (!packageName.startsWith('@spfn/') && !packageName.startsWith('spfn-'))\n {\n continue;\n }\n\n try\n {\n const pkgPath = join(nodeModulesPath, ...packageName.split('/'), 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n\n if (pkg.spfn?.routes?.dir)\n {\n const { dir } = pkg.spfn.routes;\n const prefix = pkg.spfn.prefix; // Read prefix from package.json\n const packagePath = dirname(pkgPath);\n const routesDir = join(packagePath, dir);\n\n functions.push({\n packageName,\n routesDir,\n packagePath,\n prefix, // Include prefix in function info\n });\n\n routeLogger.debug('Discovered function routes', {\n package: packageName,\n dir,\n prefix: prefix || '(none)',\n });\n }\n }\n catch (error)\n {\n // Silently skip packages that don't exist or can't be read\n // This is normal for optional dependencies or workspace links\n }\n }\n }\n catch (error)\n {\n routeLogger.warn('Failed to discover function routes', {\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n\n return functions;\n}","import { readdir, stat } from 'fs/promises';\nimport { join, relative } from 'path';\nimport { Hono } from 'hono';\nimport type { MiddlewareHandler } from 'hono';\nimport { logger } from '../logger';\n\nconst routeLogger = logger.child('route');\n\ndeclare module 'hono'\n{\n interface ContextVariableMap\n {\n _skipMiddlewares?: string[];\n }\n}\n\n/**\n * AutoRouteLoader: Simplified File-based Routing System\n *\n * Features:\n * - Auto-discovery: Scans routes directory and auto-registers\n * - Dynamic routes: [id] β†’ :id, [...slug] β†’ *\n * - Statistics: Route registration stats for dashboard\n * - Grouping: Natural grouping by directory structure\n */\n\nexport type RouteInfo = {\n path: string;\n file: string;\n meta?: {\n description?: string;\n tags?: string[];\n auth?: boolean;\n [key: string]: unknown;\n };\n priority: number;\n};\n\nexport type RouteStats = {\n total: number;\n byPriority: {\n static: number;\n dynamic: number;\n catchAll: number;\n };\n byTag: Record<string, number>;\n routes: RouteInfo[];\n};\n\ntype RouteModule = {\n default: Hono & {\n _contractMetas?: Map<string, any>;\n };\n meta?: {\n description?: string;\n tags?: string[];\n skipMiddlewares?: string[];\n [key: string]: unknown;\n };\n};\n\nexport class AutoRouteLoader\n{\n private routes: RouteInfo[] = [];\n private readonly debug: boolean;\n private readonly middlewares: Array<{ name: string; handler: MiddlewareHandler }>;\n\n constructor(\n private routesDir: string,\n debug = false,\n middlewares: Array<{ name: string; handler: MiddlewareHandler }> = []\n ) {\n this.debug = debug;\n this.middlewares = middlewares;\n }\n\n async load(app: Hono): Promise<RouteStats>\n {\n const startTime = Date.now();\n\n const files = await this.scanFiles(this.routesDir);\n\n if (files.length === 0)\n {\n routeLogger.warn('No route files found');\n return this.getStats();\n }\n\n let successCount = 0;\n let failureCount = 0;\n\n for (const file of files)\n {\n const success = await this.loadRoute(app, file);\n if (success)\n {\n successCount++;\n }\n else\n {\n failureCount++;\n }\n }\n\n const elapsed = Date.now() - startTime;\n const stats = this.getStats();\n\n if (this.debug)\n {\n this.logStats(stats, elapsed);\n }\n\n if (failureCount > 0)\n {\n routeLogger.warn('Some routes failed to load', { failureCount });\n }\n\n return stats;\n }\n\n /**\n * Load routes from an external directory (e.g., from SPFN function packages)\n * Reads package.json spfn.prefix and mounts routes under that prefix\n *\n * @param app - Hono app instance\n * @param routesDir - Directory containing route handlers\n * @param packageName - Name of the package (for logging)\n * @param prefix - Optional prefix to mount routes under (from package.json spfn.prefix)\n * @returns Route statistics\n */\n async loadExternalRoutes(app: Hono, routesDir: string, packageName: string, prefix?: string): Promise<RouteStats>\n {\n const startTime = Date.now();\n const tempRoutesDir = this.routesDir;\n this.routesDir = routesDir;\n\n const files = await this.scanFiles(routesDir);\n\n if (files.length === 0)\n {\n routeLogger.warn('No route files found', { dir: routesDir, package: packageName });\n this.routesDir = tempRoutesDir;\n return this.getStats();\n }\n\n let successCount = 0;\n let failureCount = 0;\n\n // Load routes with prefix if provided (from package.json spfn.prefix)\n for (const file of files)\n {\n const success = await this.loadRoute(app, file, prefix);\n if (success)\n {\n successCount++;\n }\n else\n {\n failureCount++;\n }\n }\n\n const elapsed = Date.now() - startTime;\n\n if (this.debug)\n {\n routeLogger.info('External routes loaded', {\n package: packageName,\n prefix: prefix || '/',\n total: successCount,\n failed: failureCount,\n elapsed: `${elapsed}ms`,\n });\n }\n\n this.routesDir = tempRoutesDir;\n return this.getStats();\n }\n\n getStats(): RouteStats\n {\n const stats: RouteStats = {\n total: this.routes.length,\n byPriority: { static: 0, dynamic: 0, catchAll: 0 },\n byTag: {},\n routes: this.routes,\n };\n\n for (const route of this.routes)\n {\n if (route.priority === 1) stats.byPriority.static++;\n else if (route.priority === 2) stats.byPriority.dynamic++;\n else if (route.priority === 3) stats.byPriority.catchAll++;\n\n if (route.meta?.tags)\n {\n for (const tag of route.meta.tags)\n {\n stats.byTag[tag] = (stats.byTag[tag] || 0) + 1;\n }\n }\n }\n\n return stats;\n }\n\n private async scanFiles(dir: string, files: string[] = []): Promise<string[]>\n {\n const entries = await readdir(dir);\n\n for (const entry of entries)\n {\n const fullPath = join(dir, entry);\n const fileStat = await stat(fullPath);\n\n if (fileStat.isDirectory())\n {\n await this.scanFiles(fullPath, files);\n }\n else if (this.isValidRouteFile(entry))\n {\n files.push(fullPath);\n }\n }\n\n return files;\n }\n\n private isValidRouteFile(fileName: string): boolean\n {\n // Strict convention: Only index.ts, index.js, or index.mjs files are route handlers\n // This prevents accidental loading of utility files, helpers, types, etc.\n return fileName === 'index.ts' || fileName === 'index.js' || fileName === 'index.mjs';\n }\n\n private async loadRoute(app: Hono, absolutePath: string, prefix?: string): Promise<boolean>\n {\n const relativePath = relative(this.routesDir, absolutePath);\n\n try\n {\n const module = await import(absolutePath) as RouteModule;\n\n if (!this.validateModule(module, relativePath))\n {\n return false;\n }\n\n // Contract-based routing: Use contract paths directly\n const hasContractMetas = module.default._contractMetas && module.default._contractMetas.size > 0;\n\n if (!hasContractMetas)\n {\n routeLogger.error('Route must use contract-based routing', {\n file: relativePath,\n hint: 'Export contracts using satisfies RouteContract and use app.bind()'\n });\n return false;\n }\n\n // Extract paths from contract metas for logging and stats\n const contractPaths = this.extractContractPaths(module);\n\n // Validate contract paths against prefix (if prefix is provided)\n if (prefix)\n {\n const invalidPaths = contractPaths.filter(path => !path.startsWith(prefix));\n if (invalidPaths.length > 0)\n {\n routeLogger.error('Contract paths must include the package prefix', {\n file: relativePath,\n prefix,\n invalidPaths,\n hint: `Contract paths should start with \"${prefix}\". Example: path: \"${prefix}/labels\"`\n });\n return false;\n }\n }\n\n // Register contract-based middlewares\n this.registerContractBasedMiddlewares(app, contractPaths, module);\n\n // Mount directly (contracts already include full path with prefix)\n app.route('/', module.default);\n\n // Track routes for stats\n contractPaths.forEach(path => {\n this.routes.push({\n path: path, // Use contract path as-is (already includes prefix)\n file: relativePath,\n meta: module.meta,\n priority: this.calculateContractPriority(path),\n });\n\n if (this.debug)\n {\n const icon = path.includes('*') ? '⭐' : path.includes(':') ? 'πŸ”Έ' : 'πŸ”Ή';\n routeLogger.debug(`Registered route: ${path}`, { icon, file: relativePath });\n }\n });\n\n return true;\n }\n catch (error)\n {\n this.categorizeAndLogError(error as Error, relativePath);\n return false;\n }\n }\n\n private extractContractPaths(module: RouteModule): string[]\n {\n const paths = new Set<string>();\n\n if (module.default._contractMetas)\n {\n for (const key of module.default._contractMetas.keys())\n {\n // key format: \"GET /teams/:id\"\n const path = key.split(' ')[1];\n if (path)\n {\n paths.add(path);\n }\n }\n }\n\n return Array.from(paths);\n }\n\n private calculateContractPriority(path: string): number\n {\n if (path.includes('*')) return 3; // Catch-all\n if (path.includes(':')) return 2; // Dynamic\n return 1; // Static\n }\n\n private validateModule(module: RouteModule, relativePath: string): boolean\n {\n if (!module.default)\n {\n routeLogger.error('Route must export Hono instance as default', { file: relativePath });\n return false;\n }\n\n if (typeof module.default.route !== 'function')\n {\n routeLogger.error('Default export is not a Hono instance', { file: relativePath });\n return false;\n }\n\n return true;\n }\n\n private registerContractBasedMiddlewares(app: Hono, contractPaths: string[], module: RouteModule): void\n {\n // Register middleware checker for all contract paths\n app.use('*', (c, next) =>\n {\n const method = c.req.method;\n const requestPath = new URL(c.req.url).pathname;\n\n const key = `${method} ${requestPath}`;\n const meta = module.default._contractMetas?.get(key);\n\n if (meta?.skipMiddlewares)\n {\n c.set('_skipMiddlewares', meta.skipMiddlewares);\n }\n\n return next();\n });\n\n // Register middlewares for each contract path\n for (const contractPath of contractPaths)\n {\n const middlewarePath = contractPath === '/' ? '/*' : `${contractPath}/*`;\n\n for (const middleware of this.middlewares)\n {\n app.use(middlewarePath, async (c, next) =>\n {\n const skipList = c.get('_skipMiddlewares') || [];\n\n if (skipList.includes(middleware.name))\n {\n return next();\n }\n\n return middleware.handler(c, next);\n });\n }\n }\n }\n\n private categorizeAndLogError(error: Error, relativePath: string): void\n {\n const message = error.message;\n const stack = error.stack;\n\n if (message.includes('Cannot find module') || message.includes('MODULE_NOT_FOUND'))\n {\n routeLogger.error('Missing dependency', {\n file: relativePath,\n error: message,\n hint: 'Run: npm install',\n });\n }\n else if (message.includes('SyntaxError') || stack?.includes('SyntaxError'))\n {\n routeLogger.error('Syntax error', {\n file: relativePath,\n error: message,\n ...(this.debug && stack && {\n stack: stack.split('\\n').slice(0, 5).join('\\n')\n }),\n });\n }\n else if (message.includes('Unexpected token'))\n {\n routeLogger.error('Parse error', {\n file: relativePath,\n error: message,\n hint: 'Check for syntax errors or invalid TypeScript',\n });\n }\n else\n {\n routeLogger.error('Route loading failed', {\n file: relativePath,\n error: message,\n ...(this.debug && stack && { stack }),\n });\n }\n }\n\n private logStats(stats: RouteStats, elapsed: number): void\n {\n const tagCounts = Object.entries(stats.byTag)\n .map(([tag, count]) => `${tag}(${count})`)\n .join(', ');\n\n routeLogger.info('Routes loaded successfully', {\n total: stats.total,\n priority: {\n static: stats.byPriority.static,\n dynamic: stats.byPriority.dynamic,\n catchAll: stats.byPriority.catchAll,\n },\n ...(tagCounts && { tags: tagCounts }),\n elapsed: `${elapsed}ms`,\n });\n }\n}\n\nexport async function loadRoutes(\n app: Hono,\n options?: {\n routesDir?: string;\n debug?: boolean;\n middlewares?: Array<{ name: string; handler: MiddlewareHandler }>;\n includeFunctionRoutes?: boolean;\n }\n): Promise<RouteStats>\n{\n const routesDir = options?.routesDir ?? join(process.cwd(), 'src', 'server', 'routes');\n const debug = options?.debug ?? false;\n const middlewares = options?.middlewares ?? [];\n const includeFunctionRoutes = options?.includeFunctionRoutes ?? true; // Default: true\n\n const loader = new AutoRouteLoader(routesDir, debug, middlewares);\n const stats = await loader.load(app);\n\n // Load function routes if enabled\n if (includeFunctionRoutes)\n {\n const { discoverFunctionRoutes } = await import('./function-routes.js');\n const functionRoutes = discoverFunctionRoutes();\n\n if (functionRoutes.length > 0)\n {\n routeLogger.info('Loading function routes', { count: functionRoutes.length });\n\n for (const func of functionRoutes)\n {\n try\n {\n await loader.loadExternalRoutes(app, func.routesDir, func.packageName, func.prefix);\n routeLogger.info('Function routes loaded', {\n package: func.packageName,\n routesDir: func.routesDir,\n prefix: func.prefix || '/',\n });\n }\n catch (error)\n {\n routeLogger.error('Failed to load function routes', {\n package: func.packageName,\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n }\n }\n\n return stats;\n}","/**\n * HTTP Error Classes\n *\n * Standard HTTP error classes for API responses\n * Covers common HTTP status codes beyond database errors\n */\n\n/**\n * Base HTTP Error\n *\n * Base class for all HTTP-related errors\n */\nexport class HttpError<TDetails extends Record<string, unknown> = Record<string, unknown>> extends Error\n{\n public readonly statusCode: number;\n public readonly details?: TDetails;\n public readonly timestamp: Date;\n\n constructor(\n message: string,\n statusCode: number,\n details?: TDetails\n )\n {\n super(message);\n this.name = 'HttpError';\n this.statusCode = statusCode;\n this.details = details;\n this.timestamp = new Date();\n Error.captureStackTrace(this, this.constructor);\n }\n\n /**\n * Serialize error for API response\n */\n toJSON()\n {\n return {\n name: this.name,\n message: this.message,\n statusCode: this.statusCode,\n details: this.details,\n timestamp: this.timestamp.toISOString()\n };\n }\n}\n\n/**\n * Bad Request Error (400)\n *\n * Generic bad request - malformed syntax, invalid parameters, etc.\n */\nexport class BadRequestError extends HttpError\n{\n constructor(message: string = 'Bad request', details?: Record<string, any>)\n {\n super(message, 400, details);\n this.name = 'BadRequestError';\n }\n}\n\n/**\n * Validation Error (400)\n *\n * Input validation failure (request params, query, body)\n * Used by contract-based routing for automatic validation\n */\nexport class ValidationError extends HttpError\n{\n constructor(message: string, details?: Record<string, any>)\n {\n super(message, 400, details);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * Unauthorized Error (401)\n *\n * Authentication required or authentication failed\n */\nexport class UnauthorizedError extends HttpError\n{\n constructor(message: string = 'Authentication required', details?: Record<string, any>)\n {\n super(message, 401, details);\n this.name = 'UnauthorizedError';\n }\n}\n\n/**\n * Forbidden Error (403)\n *\n * Authenticated but lacks permission to access resource\n */\nexport class ForbiddenError extends HttpError\n{\n constructor(message: string = 'Access forbidden', details?: Record<string, any>)\n {\n super(message, 403, details);\n this.name = 'ForbiddenError';\n }\n}\n\n/**\n * Not Found Error (404)\n *\n * Requested resource does not exist\n * Generic HTTP 404 error (for database-specific NotFoundError, see database-errors.ts)\n */\nexport class NotFoundError extends HttpError\n{\n constructor(message: string = 'Resource not found', details?: Record<string, any>)\n {\n super(message, 404, details);\n this.name = 'NotFoundError';\n }\n}\n\n/**\n * Conflict Error (409)\n *\n * Generic conflict - resource state conflict, concurrent modification, etc.\n * More general than DuplicateEntryError\n */\nexport class ConflictError extends HttpError\n{\n constructor(message: string = 'Resource conflict', details?: Record<string, any>)\n {\n super(message, 409, details);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * Too Many Requests Error (429)\n *\n * Rate limit exceeded\n */\nexport class TooManyRequestsError extends HttpError\n{\n constructor(\n message: string = 'Too many requests',\n retryAfter?: number,\n details?: Record<string, any>\n )\n {\n const fullDetails = retryAfter\n ? { ...details, retryAfter }\n : details;\n\n super(message, 429, fullDetails);\n this.name = 'TooManyRequestsError';\n }\n}\n\n/**\n * Internal Server Error (500)\n *\n * Generic server error when no specific error type applies\n */\nexport class InternalServerError extends HttpError\n{\n constructor(message: string = 'Internal server error', details?: Record<string, any>)\n {\n super(message, 500, details);\n this.name = 'InternalServerError';\n }\n}\n\n/**\n * Unprocessable Entity Error (422)\n *\n * Request is well-formed but contains semantic errors\n */\nexport class UnprocessableEntityError extends HttpError\n{\n constructor(message: string = 'Unprocessable entity', details?: Record<string, any>)\n {\n super(message, 422, details);\n this.name = 'UnprocessableEntityError';\n }\n}\n\n/**\n * Service Unavailable Error (503)\n *\n * Service temporarily unavailable (maintenance, overload, etc.)\n */\nexport class ServiceUnavailableError extends HttpError\n{\n constructor(\n message: string = 'Service unavailable',\n retryAfter?: number,\n details?: Record<string, any>\n )\n {\n const fullDetails = retryAfter\n ? { ...details, retryAfter }\n : details;\n\n super(message, 503, fullDetails);\n this.name = 'ServiceUnavailableError';\n }\n}","import type { Context } from 'hono';\nimport type { ContentfulStatusCode } from 'hono/utils/http-status';\nimport { Value } from '@sinclair/typebox/value';\nimport type { RouteContract, RouteContext, InferContract } from './types.js';\nimport { ValidationError } from '../errors';\nimport type { ApiSuccessResponse } from './api-response.js';\n\n/**\n * Contract-based Route Handler Wrapper\n *\n * Binds a contract to a route handler, providing automatic validation\n * and type-safe context creation.\n *\n * Features:\n * - Automatic params/query/body validation using TypeBox\n * - Type-safe RouteContext with contract-based inference\n * - Clean separation: bind() for validation, Hono for middleware\n */\nexport function bind<TContract extends RouteContract>(\n contract: TContract,\n handler: (c: RouteContext<TContract>) => Response | Promise<Response>\n) {\n return async (rawContext: Context) =>\n {\n let params = rawContext.req.param();\n if (contract.params)\n {\n // Convert types (e.g., string \"123\" -> number 123)\n params = Value.Convert(contract.params, params) as typeof params;\n\n // Then validate\n const errors = [...Value.Errors(contract.params, params)];\n if (errors.length > 0)\n {\n throw new ValidationError(\n 'Invalid path parameters',\n {\n fields: errors.map(e => ({\n path: e.path,\n message: e.message,\n value: e.value,\n }))\n }\n );\n }\n }\n\n const url = new URL(rawContext.req.url);\n let query: Record<string, string | string[]> = {};\n url.searchParams.forEach((v, k) =>\n {\n const existing = query[k];\n if (existing)\n {\n query[k] = Array.isArray(existing) ? [...existing, v] : [existing, v];\n }\n else\n {\n query[k] = v;\n }\n });\n\n if (contract.query)\n {\n // Convert types (e.g., string \"123\" -> number 123, \"true\" -> boγ…‡olean true)\n query = Value.Convert(contract.query, query) as typeof query;\n\n // Then validate\n const errors = [...Value.Errors(contract.query, query)];\n if (errors.length > 0)\n {\n throw new ValidationError(\n 'Invalid query parameters',\n {\n fields: errors.map(e => ({\n path: e.path,\n message: e.message,\n value: e.value,\n }))\n }\n );\n }\n }\n\n const routeContext: RouteContext<TContract> =\n {\n params: params as InferContract<TContract>['params'],\n query: query as InferContract<TContract>['query'],\n\n data: async () =>\n {\n let body = await rawContext.req.json();\n if (contract.body)\n {\n // Convert types (e.g., handle nested objects, arrays, etc.)\n body = Value.Convert(contract.body, body) as any;\n\n // Then validate\n const errors = [...Value.Errors(contract.body, body)];\n if (errors.length > 0)\n {\n throw new ValidationError(\n 'Invalid request body',\n {\n fields: errors.map(e => ({\n path: e.path,\n message: e.message,\n value: e.value,\n }))\n }\n );\n }\n }\n\n return body as InferContract<TContract>['body'];\n },\n\n json: (data, status, headers) =>\n {\n // Warn if ErrorHandler is enabled but response doesn't follow standard format\n const errorHandlerEnabled = rawContext.get('errorHandlerEnabled');\n if (errorHandlerEnabled && process.env.NODE_ENV !== 'production')\n {\n const hasSuccessField = data && typeof data === 'object' && 'success' in data;\n if (!hasSuccessField)\n {\n console.warn(\n '[SPFN] Warning: ErrorHandler is enabled but c.json() is being used with non-standard response format.\\n' +\n 'Consider using c.success() for consistent API responses, or disable ErrorHandler if you prefer custom formats.'\n );\n }\n }\n\n return rawContext.json(data, status, headers);\n },\n\n success: <T>(data: T, meta?: ApiSuccessResponse<T>['meta'], status: ContentfulStatusCode | undefined = 200) =>\n {\n const response: ApiSuccessResponse<T> = {\n success: true,\n data,\n };\n\n if (meta)\n {\n response.meta = meta;\n }\n\n return rawContext.json(response, status);\n },\n\n paginated: <T>(data: T[], page: number, limit: number, total: number) =>\n {\n const response: ApiSuccessResponse<T[]> = {\n success: true,\n data,\n meta: {\n pagination: {\n page,\n limit,\n total,\n totalPages: Math.ceil(total / limit),\n },\n },\n };\n\n return rawContext.json(response, 200 as ContentfulStatusCode);\n },\n\n raw: rawContext,\n };\n\n return handler(routeContext);\n };\n}","/**\n * Error Handler Middleware\n *\n * Generic middleware that converts errors with statusCode to HTTP responses\n */\nimport type { Context } from 'hono';\nimport type { ContentfulStatusCode } from 'hono/utils/http-status';\nimport { logger } from '../logger';\nimport type { ErrorResponse } from '../types/api-response.js';\n\nconst errorLogger = logger.child('error-handler');\n\nexport interface ErrorHandlerOptions\n{\n /**\n * Include stack trace in response\n * @default process.env.NODE_ENV !== 'production'\n */\n includeStack?: boolean;\n\n /**\n * Enable error logging\n * @default true\n */\n enableLogging?: boolean;\n}\n\ninterface ErrorWithStatusCode extends Error\n{\n statusCode?: number;\n details?: any;\n}\n\n/**\n * Standard error response format\n *\n * Re-exported from @spfn/core/types for convenience\n */\nexport type { ErrorResponse } from '../types/api-response.js';\n\n/**\n * Error handler middleware\n *\n * Used in Hono's onError hook\n */\nexport function ErrorHandler(options: ErrorHandlerOptions = {}): (err: Error, c: Context) => Response | Promise<Response>\n{\n const {\n includeStack = process.env.NODE_ENV !== 'production',\n enableLogging = true,\n } = options;\n\n return (err: Error, c: Context) =>\n {\n const errorWithCode = err as ErrorWithStatusCode;\n const statusCode = errorWithCode.statusCode || 500;\n const errorType = err.name || 'Error';\n\n if (enableLogging)\n {\n const logLevel = statusCode >= 500 ? 'error' : 'warn';\n\n const logData: Record<string, any> = {\n type: errorType,\n message: err.message,\n statusCode,\n path: c.req.path,\n method: c.req.method,\n };\n\n // Include details if available\n if (errorWithCode.details)\n {\n logData.details = errorWithCode.details;\n }\n\n // Include stack trace for 500 errors in development\n if (statusCode >= 500 && includeStack)\n {\n logData.stack = err.stack;\n }\n\n errorLogger[logLevel]('Error occurred', logData);\n }\n\n const response: ErrorResponse = {\n success: false,\n error: {\n message: err.message || 'Internal Server Error',\n type: errorType,\n statusCode,\n },\n };\n\n if (errorWithCode.details)\n {\n response.error.details = errorWithCode.details;\n }\n\n if (includeStack)\n {\n response.error.stack = err.stack;\n }\n\n return c.json(response, statusCode as ContentfulStatusCode);\n };\n}\n","/**\n * Request Logger Middleware\n *\n * Automatic API request/response logging with performance monitoring\n */\nimport type { Context, Next } from 'hono';\nimport { randomBytes } from 'crypto';\nimport { logger } from '../logger';\n\nexport interface RequestLoggerConfig\n{\n /**\n * Paths to exclude from logging (health checks, etc.)\n */\n excludePaths?: string[];\n\n /**\n * Field names to mask for sensitive data\n */\n sensitiveFields?: string[];\n\n /**\n * Slow request threshold (ms)\n */\n slowRequestThreshold?: number;\n}\n\nconst DEFAULT_CONFIG: Required<RequestLoggerConfig> = {\n excludePaths: ['/health', '/ping', '/favicon.ico'],\n sensitiveFields: ['password', 'token', 'apiKey', 'secret', 'authorization'],\n slowRequestThreshold: 1000,\n};\n\n/**\n * Generate cryptographically secure request ID\n */\nfunction generateRequestId(): string\n{\n const timestamp = Date.now();\n const randomPart = randomBytes(6).toString('hex');\n return `req_${timestamp}_${randomPart}`;\n}\n\n/**\n * Mask sensitive data with circular reference handling\n */\nexport function maskSensitiveData(\n obj: any,\n sensitiveFields: string[],\n seen = new WeakSet()\n): any\n{\n if (!obj || typeof obj !== 'object') return obj;\n\n if (seen.has(obj)) return '[Circular]';\n seen.add(obj);\n\n const lowerFields = sensitiveFields.map(f => f.toLowerCase());\n const masked = Array.isArray(obj) ? [...obj] : { ...obj };\n\n for (const key in masked)\n {\n const lowerKey = key.toLowerCase();\n\n if (lowerFields.some(field => lowerKey.includes(field)))\n {\n masked[key] = '***MASKED***';\n }\n else if (typeof masked[key] === 'object' && masked[key] !== null)\n {\n masked[key] = maskSensitiveData(masked[key], sensitiveFields, seen);\n }\n }\n\n return masked;\n}\n\n/**\n * Request Logger middleware\n */\nexport function RequestLogger(config?: RequestLoggerConfig)\n{\n const cfg = { ...DEFAULT_CONFIG, ...config };\n const apiLogger = logger.child('api');\n\n return async (c: Context, next: Next) =>\n {\n const path = new URL(c.req.url).pathname;\n\n if (cfg.excludePaths.includes(path))\n {\n return next();\n }\n\n const requestId = generateRequestId();\n c.set('requestId', requestId);\n\n const method = c.req.method;\n const userAgent = c.req.header('user-agent');\n const ip = c.req.header('x-forwarded-for') || c.req.header('x-real-ip') || 'unknown';\n\n const startTime = Date.now();\n\n apiLogger.info('Request received', {\n requestId,\n method,\n path,\n ip,\n userAgent,\n });\n\n try\n {\n await next();\n\n const duration = Date.now() - startTime;\n const status = c.res.status;\n\n const logLevel = status >= 400 ? 'warn' : 'info';\n const isSlowRequest = duration >= cfg.slowRequestThreshold;\n\n const logData: Record<string, any> = {\n requestId,\n method,\n path,\n status,\n duration,\n };\n\n if (isSlowRequest)\n {\n logData.slow = true;\n }\n\n apiLogger[logLevel]('Request completed', logData);\n }\n catch (error)\n {\n const duration = Date.now() - startTime;\n\n apiLogger.error('Request failed', error as Error, {\n requestId,\n method,\n path,\n duration,\n });\n\n throw error;\n }\n };\n}","/**\n * Create App - Hono Wrapper for Contract-based Routing\n *\n * Provides a cleaner API for registering routes with contracts\n */\n\nimport { Hono } from 'hono';\nimport type { MiddlewareHandler } from 'hono';\nimport { bind } from './bind.js';\nimport type { RouteContract, RouteHandler } from './types.js';\nimport { ErrorHandler } from '../middleware';\n\nexport type SPFNApp = Hono & {\n bind<TContract extends RouteContract>(\n contract: TContract,\n handler: RouteHandler<TContract>\n ): void;\n\n bind<TContract extends RouteContract>(\n contract: TContract,\n middlewares: MiddlewareHandler[],\n handler: RouteHandler<TContract>\n ): void;\n\n _contractMetas?: Map<string, RouteContract['meta']>;\n};\n\n/**\n * Create SPFN app instance\n *\n * Wraps Hono with contract-based routing support\n */\nexport function createApp(): SPFNApp\n{\n const hono = new Hono();\n const app = hono as SPFNApp;\n\n app._contractMetas = new Map();\n\n // Register default error handler\n app.onError(ErrorHandler());\n\n const methodMap = new Map<string, (path: string, handlers: any[]) => void>([\n ['get', (path, handlers) => hono.get(path, ...handlers)],\n ['post', (path, handlers) => hono.post(path, ...handlers)],\n ['put', (path, handlers) => hono.put(path, ...handlers)],\n ['patch', (path, handlers) => hono.patch(path, ...handlers)],\n ['delete', (path, handlers) => hono.delete(path, ...handlers)],\n ]);\n\n app.bind = function <TContract extends RouteContract>(\n contract: TContract,\n ...args: [RouteHandler<TContract>] | [MiddlewareHandler[], RouteHandler<TContract>]\n )\n {\n const method = contract.method.toLowerCase();\n const path = contract.path;\n\n const [middlewares, handler] = args.length === 1\n ? [[], args[0]]\n : [args[0], args[1]];\n\n // Always register contract (even without meta) so auto-loader can detect contract-based routing\n const key = `${contract.method} ${path}`;\n app._contractMetas!.set(key, contract.meta || {});\n\n const boundHandler = bind(contract, handler);\n const handlers = middlewares.length > 0\n ? [...middlewares, boundHandler]\n : [boundHandler];\n\n const registerMethod = methodMap.get(method);\n if (!registerMethod)\n {\n throw new Error(`Unsupported HTTP method: ${contract.method}`);\n }\n\n registerMethod(path, handlers);\n };\n\n return app;\n}","/**\n * Standard API Response Types & Schemas\n *\n * Pure TypeBox schemas and type definitions for API responses.\n * Can be used in both server and client code.\n */\n\nimport type { TSchema } from '@sinclair/typebox';\nimport { Type } from '@sinclair/typebox';\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Standard error response format\n *\n * Used by ErrorHandler middleware for all error responses.\n * Compatible with ApiResponse pattern for consistent API responses.\n */\nexport interface ErrorResponse\n{\n success: false;\n error: {\n message: string;\n type: string;\n statusCode: number;\n stack?: string;\n details?: any;\n };\n}\n\n/**\n * Success response wrapper\n */\nexport interface ApiSuccessResponse<T = any>\n{\n success: true;\n data: T;\n meta?: {\n timestamp?: string;\n requestId?: string;\n pagination?: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n };\n [key: string]: any;\n };\n}\n\n/**\n * Error response type (alias for ErrorResponse)\n */\nexport type ApiErrorResponse = ErrorResponse;\n\n/**\n * Unified API response type\n */\nexport type ApiResponse<T = any> = ApiSuccessResponse<T> | ApiErrorResponse;\n\n// ============================================================================\n// TypeBox Schema Helpers\n// ============================================================================\n\n/**\n * Creates a TypeBox schema for ApiSuccessResponse<T>\n *\n * @example\n * ```ts\n * const UserSchema = Type.Object({\n * id: Type.String(),\n * name: Type.String(),\n * });\n *\n * const contract = {\n * response: ApiSuccessSchema(UserSchema),\n * };\n * ```\n */\nexport function ApiSuccessSchema<T extends TSchema>(dataSchema: T)\n{\n return Type.Object({\n success: Type.Literal(true),\n data: dataSchema,\n meta: Type.Optional(Type.Object({\n timestamp: Type.Optional(Type.String()),\n requestId: Type.Optional(Type.String()),\n pagination: Type.Optional(Type.Object({\n page: Type.Number(),\n limit: Type.Number(),\n total: Type.Number(),\n totalPages: Type.Number(),\n })),\n })),\n });\n}\n\n/**\n * Creates a TypeBox schema for ApiErrorResponse\n */\nexport function ApiErrorSchema()\n{\n return Type.Object({\n success: Type.Literal(false),\n error: Type.Object({\n message: Type.String(),\n type: Type.String(),\n statusCode: Type.Number(),\n stack: Type.Optional(Type.String()),\n details: Type.Optional(Type.Any()),\n }),\n });\n}\n\n/**\n * Creates a TypeBox schema for ApiSuccessResponse<T>\n *\n * Use this in your route contract's response field for standardized responses.\n * Note: ContractClient throws ApiClientError on failure, so only success type is needed.\n *\n * @example\n * ```ts\n * const contract = {\n * method: 'GET',\n * path: '/users/:id',\n * response: ApiResponseSchema(Type.Object({\n * id: Type.String(),\n * name: Type.String(),\n * })),\n * };\n * ```\n */\nexport function ApiResponseSchema<T extends TSchema>(dataSchema: T)\n{\n return ApiSuccessSchema(dataSchema);\n}\n","import type { Context } from 'hono';\nimport type { ContentfulStatusCode } from 'hono/utils/http-status';\nimport type { TSchema, Static } from '@sinclair/typebox';\nimport type { ApiSuccessResponse } from './api-response.js';\n\n/**\n * File-based Routing System Type Definitions\n */\n\nexport type HeaderRecord = Record<string, string | string[]>;\n\nexport type RouteMeta = {\n public?: boolean;\n skipMiddlewares?: string[];\n tags?: string[];\n description?: string;\n deprecated?: boolean;\n};\n\n/**\n * Route Contract: TypeBox-based type-safe route definition\n *\n * Defines the shape of request/response for a route endpoint\n */\nexport type RouteContract = {\n method: HttpMethod;\n path: string;\n params?: TSchema;\n query?: TSchema;\n body?: TSchema;\n response: TSchema;\n meta?: RouteMeta;\n};\n\n/**\n * Infer types from RouteContract\n *\n * Extracts TypeScript types from TypeBox schemas\n */\nexport type InferContract<TContract extends RouteContract> = {\n params: TContract['params'] extends TSchema\n ? Static<TContract['params']>\n : Record<string, never>;\n query: TContract['query'] extends TSchema\n ? Static<TContract['query']>\n : Record<string, never>;\n body: TContract['body'] extends TSchema\n ? Static<TContract['body']>\n : Record<string, never>;\n response: TContract['response'] extends TSchema\n ? Static<TContract['response']>\n : unknown;\n};\n\n/**\n * RouteContext: Route Handler Dedicated Context\n *\n * Generic version with contract-based type inference\n */\nexport type RouteContext<TContract extends RouteContract = any> = {\n params: InferContract<TContract>['params'];\n query: InferContract<TContract>['query'];\n data(): Promise<InferContract<TContract>['body']>;\n json(\n data: InferContract<TContract>['response'],\n status?: ContentfulStatusCode,\n headers?: HeaderRecord\n ): Response;\n success<T>(\n data: T,\n meta?: ApiSuccessResponse<T>['meta'],\n status?: number\n ): Response;\n paginated<T>(\n data: T[],\n page: number,\n limit: number,\n total: number\n ): Response;\n raw: Context;\n};\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\nexport type RouteHandler<TContract extends RouteContract = any> =\n (c: RouteContext<TContract>) => Response | Promise<Response>;\n\nexport function isHttpMethod(value: unknown): value is HttpMethod\n{\n return (\n typeof value === 'string' &&\n ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].includes(value)\n );\n}"]}
@@ -280,6 +280,17 @@ interface ServerInstance {
280
280
  close: () => Promise<void>;
281
281
  }
282
282
 
283
+ /**
284
+ * Create Hono Server
285
+ *
286
+ * Creates and configures a Hono application instance.
287
+ */
288
+
289
+ declare module 'hono' {
290
+ interface ContextVariableMap {
291
+ errorHandlerEnabled?: boolean;
292
+ }
293
+ }
283
294
  /**
284
295
  * Create Hono app with automatic configuration
285
296
  *
@@ -289,6 +300,13 @@ interface ServerInstance {
289
300
  * 3. app.ts -> Full control (no auto config)
290
301
  */
291
302
  declare function createServer(config?: ServerConfig): Promise<Hono>;
303
+
304
+ /**
305
+ * Start SPFN Server
306
+ *
307
+ * Starts and configures the SPFN HTTP server with graceful shutdown.
308
+ */
309
+
292
310
  /**
293
311
  * Start SPFN server
294
312
  *