shokupan 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -1815
- package/dist/{analyzer-CnKnQ5KV.js → analyzer-B0fMzeIo.js} +2 -2
- package/dist/{analyzer-CnKnQ5KV.js.map → analyzer-B0fMzeIo.js.map} +1 -1
- package/dist/{analyzer-BAhvpNY_.cjs → analyzer-BOtveWL-.cjs} +2 -2
- package/dist/{analyzer-BAhvpNY_.cjs.map → analyzer-BOtveWL-.cjs.map} +1 -1
- package/dist/{analyzer.impl-CfpMu4-g.cjs → analyzer.impl-CUDO6vpn.cjs} +82 -7
- package/dist/analyzer.impl-CUDO6vpn.cjs.map +1 -0
- package/dist/{analyzer.impl-DCiqlXI5.js → analyzer.impl-DmHe92Oi.js} +82 -7
- package/dist/analyzer.impl-DmHe92Oi.js.map +1 -0
- package/dist/cli.cjs +1 -1
- package/dist/cli.js +1 -1
- package/dist/context.d.ts +40 -8
- package/dist/index.cjs +2876 -506
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.js +2911 -541
- package/dist/index.js.map +1 -1
- package/dist/plugins/application/api-explorer/static/theme.css +4 -0
- package/dist/plugins/application/auth.d.ts +5 -0
- package/dist/plugins/application/dashboard/fetch-interceptor.d.ts +12 -0
- package/dist/plugins/application/dashboard/plugin.d.ts +9 -0
- package/dist/plugins/application/dashboard/static/requests.js +537 -251
- package/dist/plugins/application/dashboard/static/tabulator.css +23 -3
- package/dist/plugins/application/dashboard/static/theme.css +4 -0
- package/dist/plugins/application/error-view/index.d.ts +14 -0
- package/dist/plugins/application/error-view/monkeypatch.d.ts +9 -0
- package/dist/plugins/application/error-view/util/source-reader.d.ts +10 -0
- package/dist/plugins/application/error-view/views/error.d.ts +2 -0
- package/dist/plugins/application/error-view/views/status.d.ts +2 -0
- package/dist/plugins/application/htmx/index.d.ts +39 -0
- package/dist/plugins/application/mcp-server/plugin.d.ts +38 -0
- package/dist/plugins/application/openapi/analyzer.impl.d.ts +4 -0
- package/dist/plugins/application/openapi/test-setup.d.ts +1 -0
- package/dist/plugins/application/opentelemetry/index.d.ts +33 -0
- package/dist/plugins/middleware/compression.d.ts +12 -2
- package/dist/plugins/middleware/rate-limit.d.ts +5 -0
- package/dist/plugins/middleware/session.d.ts +4 -4
- package/dist/plugins/resilience/decorators.d.ts +23 -0
- package/dist/plugins/resilience/factory.d.ts +5 -0
- package/dist/plugins/resilience/index.d.ts +2 -0
- package/dist/router.d.ts +25 -9
- package/dist/server.d.ts +22 -0
- package/dist/shokupan.d.ts +24 -1
- package/dist/util/adapter/bun.d.ts +8 -0
- package/dist/util/adapter/index.d.ts +4 -0
- package/dist/util/adapter/interface.d.ts +12 -0
- package/dist/util/adapter/node.d.ts +8 -0
- package/dist/util/adapter/wintercg.d.ts +5 -0
- package/dist/util/body-parser.d.ts +30 -0
- package/dist/util/decorators.d.ts +58 -3
- package/dist/util/di.d.ts +3 -8
- package/dist/util/env-loader.d.ts +99 -0
- package/dist/util/mcp-protocol.d.ts +52 -0
- package/dist/util/metadata.d.ts +18 -0
- package/dist/util/promise.d.ts +16 -0
- package/dist/util/request.d.ts +1 -0
- package/dist/util/symbol.d.ts +5 -0
- package/dist/util/types.d.ts +140 -3
- package/package.json +37 -10
- package/dist/analyzer.impl-CfpMu4-g.cjs.map +0 -1
- package/dist/analyzer.impl-DCiqlXI5.js.map +0 -1
- package/dist/plugins/application/dashboard/static/failures.js +0 -85
- package/dist/plugins/application/http-server.d.ts +0 -13
- package/dist/util/adapter/adapters.d.ts +0 -19
- package/dist/util/instrumentation.d.ts +0 -9
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/util/http-status.ts","../src/util/response.ts","../src/util/symbol.ts","../src/context.ts","../src/middleware.ts","../src/util/deep-merge.ts","../src/plugins/application/shared/ast-utils.ts","../src/plugins/application/openapi/openapi.ts","../src/plugins/middleware/serve-static.ts","../src/util/di.ts","../src/util/instrumentation.ts","../src/util/stack.ts","../src/util/types.ts","../src/util/controller-scanner.ts","../src/util/http-error.ts","../src/util/middleware-tracker.ts","../src/util/request.ts","../src/util/trie.ts","../src/router.ts","../src/plugins/application/http-server.ts","../src/util/adapter/adapters.ts","../src/util/adapter/filesystem.ts","../src/util/async-hooks.ts","../src/util/cpu-monitor.ts","../src/util/datastore.ts","../src/shokupan.ts","../src/plugins/middleware/rate-limit.ts","../src/util/decorators.ts","../src/plugins/application/api-explorer/components.tsx","../src/plugins/application/api-explorer/plugin.ts","../src/plugins/application/asyncapi/components.tsx","../src/plugins/application/asyncapi/generator.ts","../src/plugins/application/asyncapi/plugin.ts","../src/plugins/application/auth.ts","../src/plugins/application/cluster.ts","../src/plugins/application/dashboard/components.tsx","../src/plugins/application/dashboard/fetch-interceptor.ts","../src/plugins/application/dashboard/metrics-collector.ts","../src/plugins/application/dashboard/plugin.ts","../src/plugins/application/graphql-apollo.ts","../src/plugins/application/scalar.ts","../src/plugins/middleware/compression.ts","../src/plugins/middleware/cors.ts","../src/plugins/middleware/express.ts","../src/plugins/middleware/validation.ts","../src/plugins/middleware/openapi-validator.ts","../src/plugins/middleware/security-headers.ts","../src/plugins/middleware/session.ts"],"sourcesContent":["/**\n * Common HTTP Status Codes\n * Use these constants instead of magic numbers for better readability\n */\nexport const HTTP_STATUS = {\n // 2xx Success\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NO_CONTENT: 204,\n\n // 3xx Redirection\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n SEE_OTHER: 303,\n NOT_MODIFIED: 304,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n\n // 4xx Client Errors\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n REQUEST_TIMEOUT: 408,\n CONFLICT: 409,\n UNPROCESSABLE_ENTITY: 422,\n TOO_MANY_REQUESTS: 429,\n\n // 5xx Server Errors\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n} as const;\n\nexport const VALID_HTTP_STATUSES = new Set<number>([\n 100, 101, 102, 103,\n 200, 201, 202, 203, 204, 205, 206, 207, 208, 226,\n 300, 301, 302, 303, 304, 305, 306, 307, 308,\n 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 421, 422, 423, 424, 425, 426, 428, 429, 431, 451,\n 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511\n]);\n\nexport const VALID_REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);\n","\n/**\n * Custom response class to handle response state (headers, status) \n * before the actual Response object is created.\n */\nexport class ShokupanResponse {\n private _headers: Headers | null = null;\n private _status = 200;\n\n /**\n * Get the current headers\n */\n get headers() {\n if (!this._headers) this._headers = new Headers();\n return this._headers;\n }\n\n /**\n * Get the current status code\n */\n get status() {\n return this._status;\n }\n\n /**\n * Set the status code\n */\n set status(code: number) {\n this._status = code;\n }\n\n /**\n * Set a response header\n * @param key Header name\n * @param value Header value\n */\n public set(key: string, value: string) {\n if (!this._headers) this._headers = new Headers();\n this._headers.set(key, value);\n return this;\n }\n\n /**\n * Append to a response header\n * @param key Header name\n * @param value Header value\n */\n public append(key: string, value: string) {\n if (!this._headers) this._headers = new Headers();\n this._headers.append(key, value);\n return this;\n }\n\n /**\n * Get a response header value\n * @param key Header name\n */\n public get(key: string) {\n return this._headers?.get(key) || null;\n }\n\n /**\n * Check if a header exists\n * @param key Header name\n */\n public has(key: string) {\n return this._headers?.has(key) || false;\n }\n\n /**\n * Internal: check if headers have been initialized/modified\n */\n public get hasPopulatedHeaders() {\n return this._headers !== null;\n }\n}\n","export const $isApplication = Symbol.for(\"Shokupan.app\");\nexport const $appRoot = Symbol.for(\"Shokupan.app-root\");\nexport const $isMounted = Symbol.for(\"Shokupan.isMounted\");\nexport const $routeMethods = Symbol.for(\"Shokupan.routeMethods\");\nexport const $eventMethods = Symbol.for(\"Shokupan.eventMethods\");\nexport const $routeArgs = Symbol.for(\"Shokupan.routeArgs\");\nexport const $controllerPath = Symbol.for(\"Shokupan.controllerPath\");\nexport const $middleware = Symbol.for(\"Shokupan.middleware\");\nexport const $isRouter = Symbol.for(\"Shokupan.router\");\nexport const $parent = Symbol.for(\"Shokupan.parent\");\nexport const $childRouters = Symbol.for(\"Shokupan.child-routers\");\nexport const $childControllers = Symbol.for(\"Shokupan.child-controllers\");\nexport const $mountPath = Symbol.for(\"Shokupan.mount-path\");\nexport const $dispatch = Symbol.for(\"Shokupan.dispatch\");\nexport const $routes = Symbol.for(\"Shokupan.routes\");\nexport const $routeSpec = Symbol.for(\"Shokupan.routeSpec\");\n\n\n\n///\n/// Context object \"hidden\" props that aren't intended for external use.\n/// We use Symbols to hide them internally.\n///\nexport const $url = Symbol.for(\"Shokupan.ctx.url\");\nexport const $requestId = Symbol.for(\"Shokupan.ctx.requestId\");\nexport const $debug = Symbol.for(\"Shokupan.ctx.debug\");\nexport const $finalResponse = Symbol.for(\"Shokupan.ctx.finalResponse\");\nexport const $rawBody = Symbol.for(\"Shokupan.ctx.rawBody\");\nexport const $cachedBody = Symbol.for(\"Shokupan.ctx.cachedBody\");\nexport const $bodyType = Symbol.for(\"Shokupan.ctx.bodyType\");\nexport const $bodyParsed = Symbol.for(\"Shokupan.ctx.bodyParsed\");\nexport const $bodyParseError = Symbol.for(\"Shokupan.ctx.bodyParseError\");\nexport const $routeMatched = Symbol.for(\"Shokupan.ctx.routeMatched\");\nexport const $cachedHostname = Symbol.for(\"Shokupan.ctx.cachedHostname\");\nexport const $cachedProtocol = Symbol.for(\"Shokupan.ctx.cachedProtocol\");\nexport const $cachedHost = Symbol.for(\"Shokupan.ctx.cachedHost\");\nexport const $cachedOrigin = Symbol.for(\"Shokupan.ctx.cachedOrigin\");\nexport const $cachedQuery = Symbol.for(\"Shokupan.ctx.cachedQuery\");\nexport const $ws = Symbol.for(\"Shokupan.ctx.ws\");\nexport const $socket = Symbol.for(\"Shokupan.ctx.socket\");\nexport const $io = Symbol.for(\"Shokupan.ctx.io\");\n\n","import type { BodyInit, Server, ServerWebSocket } from 'bun';\nimport { nanoid } from 'nanoid';\nimport { readFile } from 'node:fs/promises';\nimport { inspect } from 'node:util';\nimport type { Socket, Server as SocketServer } from 'socket.io';\nimport type { Shokupan } from './shokupan';\nimport { VALID_HTTP_STATUSES, VALID_REDIRECT_STATUSES } from './util/http-status';\nimport type { ShokupanRequest } from './util/request';\nimport { ShokupanResponse } from './util/response';\nimport { $bodyParsed, $bodyParseError, $bodyType, $cachedBody, $cachedHost, $cachedHostname, $cachedOrigin, $cachedProtocol, $cachedQuery, $debug, $finalResponse, $io, $rawBody, $requestId, $routeMatched, $socket, $url, $ws } from './util/symbol';\nimport type { CookieOptions, HeadersInit, JSXRenderer } from './util/types';\n\n/**\n * Security: Validate if a cookie domain is safe to use\n*/\nfunction isValidCookieDomain(domain: string, currentHost: string): boolean {\n // Remove port from current host if present\n const hostWithoutPort = currentHost.split(':')[0];\n\n // Domain must be current host or a parent domain\n if (domain === hostWithoutPort) return true;\n\n // Check if domain is a parent domain (starts with .)\n if (domain.startsWith('.')) {\n const domainWithoutDot = domain.slice(1);\n // Current host must end with the domain\n return hostWithoutPort.endsWith(domainWithoutDot);\n }\n\n return false;\n}\n\n\n\nexport interface HandlerStackItem {\n name: string;\n file: string;\n line: number;\n isBuiltin?: boolean;\n stateChanges?: Record<string, any>;\n startTime?: number;\n duration?: number;\n}\n\nexport interface DebugCollector {\n trackStep(id: string | undefined, type: string, duration: number, status: 'success' | 'error', error?: any): void;\n trackEdge(fromId: string | undefined, toId: string | undefined): void;\n setNode(id: string): void;\n getCurrentNode(): string | undefined;\n}\n\n/**\n * Shokupan Request Context\n * \n * The context object passed to all middleware and route handlers.\n * Provides access to request data, response helpers, and typed state management.\n * \n * @template State - The shape of `ctx.state` for type-safe state access across middleware.\n * @template Params - The shape of `ctx.params` based on the route path pattern.\n * \n * @example Basic Usage\n * ```typescript\n * app.get('/hello', (ctx) => {\n * return ctx.json({ message: 'Hello' });\n * });\n * ```\n * \n * @example Typed State\n * ```typescript\n * interface AppState {\n * userId: string;\n * requestId: string;\n * }\n * \n * const app = new Shokupan<AppState>();\n * \n * app.use((ctx, next) => {\n * ctx.state.requestId = crypto.randomUUID(); // ✓ Type-safe\n * return next();\n * });\n * ```\n * \n * @example Typed Path Parameters\n * ```typescript\n * app.get('/users/:userId/posts/:postId', (ctx) => {\n * // ctx.params is automatically typed as { userId: string; postId: string }\n * const { userId, postId } = ctx.params;\n * return ctx.json({ userId, postId });\n * });\n * ```\n * \n * @example Full Type Safety (State + Params)\n * ```typescript\n * interface RequestState {\n * userId: string;\n * permissions: string[];\n * }\n * \n * const app = new Shokupan<RequestState>();\n * \n * app.get('/admin/users/:userId', (ctx) => {\n * // Both typed!\n * const { userId } = ctx.params; // ✓ From path\n * const { permissions } = ctx.state; // ✓ From state\n * \n * if (!permissions.includes('admin')) {\n * return ctx.json({ error: 'Forbidden' }, 403);\n * }\n * return ctx.json({ userId });\n * });\n * ```\n */\nexport class ShokupanContext<\n State extends Record<string, any> = Record<string, any>,\n Params extends Record<string, string> = Record<string, string>\n> {\n public params: Params = {} as Params; // Router assigns this, but default to empty object\n public state: State;\n public handlerStack: HandlerStackItem[] = [];\n\n public readonly response: ShokupanResponse;\n public [$debug]?: DebugCollector;\n public [$finalResponse]?: Response;\n public [$rawBody]?: string | ArrayBuffer | Uint8Array; // Raw body for compression optimization\n\n // Body caching to avoid double parsing\n private [$url]?: URL;\n private [$cachedBody]?: any;\n private [$bodyType]?: 'json' | 'text' | 'formData' | 'arrayBuffer' | 'blob';\n private [$bodyParsed]: boolean = false;\n private [$bodyParseError]?: Error;\n\n public [$routeMatched]: boolean = false;\n\n\n // Cached URL properties to avoid repeated parsing\n private [$cachedHostname]?: string;\n private [$cachedProtocol]?: string;\n private [$cachedHost]?: string;\n private [$cachedOrigin]?: string;\n private [$cachedQuery]?: Record<string, any>;\n\n private disconnectCallbacks: (() => void | Promise<void>)[] = [];\n\n /**\n * Registers a callback to be executed when the associated WebSocket disconnects.\n * This is only applicable for requests that are part of a WebSocket interaction or upgrade.\n */\n public onSocketDisconnect(callback: () => void | Promise<void>) {\n this.disconnectCallbacks.push(callback);\n }\n\n /**\n * @internal\n * Retrieves registered disconnect callbacks for execution.\n */\n public getDisconnectCallbacks() {\n return this.disconnectCallbacks;\n }\n private [$ws]?: ServerWebSocket;\n private [$socket]?: Socket;\n private [$io]?: SocketServer;\n\n /**\n * JSX Rendering Function\n */\n private renderer?: JSXRenderer;\n setRenderer(renderer: JSXRenderer) {\n this.renderer = renderer;\n }\n\n private [$requestId]: string;\n get requestId() {\n return this[$requestId] ??= (this.app?.applicationConfig?.idGenerator?.() ?? nanoid());\n }\n\n [\n // Only apply a custom inspect symbol in Node.js, Deno, or Bun.\n globalThis.navigator?.userAgent?.match(/Node\\.js|Deno|Bun/)\n ? Symbol.for(\"nodejs.util.inspect.custom\")\n : Symbol.for(\"no-op\")\n ]() {\n const innerString = inspect({\n method: this.request.method,\n url: this.request.url,\n requestHeaders: new Map(this.request.headers),\n sessionId: this.sessionID,\n state: this.state,\n params: this.params,\n response: this[$finalResponse]?.body,\n responseHeaders: new Map(this[$finalResponse]?.headers as any),\n handlerStack: this.handlerStack.map(h => h.name === \"anonymous\" ? (h.file + \":\" + h.line) : h.name)\n }, { depth: null, colors: true, numericSeparator: true, customInspect: true });\n\n return \"Context(\" + this.requestId + \") {\" + innerString.slice(1, -2) + \",\\n ...others\\n}\";\n }\n\n constructor(\n public readonly request: ShokupanRequest<any>,\n public readonly server?: Server<any>,\n state?: State,\n public readonly app?: Shokupan,\n public readonly signal?: AbortSignal, // Optional as it might not be provided in tests or simple creates\n enableMiddlewareTracking: boolean = false,\n requestId?: string\n ) {\n this.state = state || {} as State;\n this[$requestId] = requestId;\n\n if (enableMiddlewareTracking) {\n const self = this;\n this.state = new Proxy(this.state, {\n set(target, p, newValue, receiver) {\n const result = Reflect.set(target, p, newValue, receiver);\n const currentHandler = self.handlerStack[self.handlerStack.length - 1];\n if (currentHandler) {\n if (!currentHandler.stateChanges) currentHandler.stateChanges = {};\n currentHandler.stateChanges[p as string] = newValue;\n }\n return result;\n }\n });\n }\n this.response = new ShokupanResponse();\n }\n\n get url(): URL {\n if (!this[$url]) {\n // WebSocket contexts may have empty request URLs\n const urlString = this.request.url || 'http://localhost/';\n this[$url] = new URL(urlString);\n }\n return this[$url];\n }\n\n /**\n * Base request\n */\n get req() { return this.request; }\n /**\n * HTTP method\n */\n get method() { return this.request.method; }\n /**\n * Request path\n */\n get path() {\n // Optimization: return cached path if url already parsed\n if (this[$url]) return this[$url].pathname;\n\n // Fast path extraction without URL parsing\n const url = this.request.url;\n\n // Handle full URL: http://localhost:3000/foo?bar\n let queryIndex = url.indexOf('?');\n const end = queryIndex === -1 ? url.length : queryIndex;\n\n // Ensure we skip protocol/host\n let start = 0;\n const protocolIndex = url.indexOf('://');\n if (protocolIndex !== -1) {\n const hostStart = protocolIndex + 3;\n // Find first slash after host\n const pathStart = url.indexOf('/', hostStart);\n if (pathStart !== -1 && pathStart < end) {\n start = pathStart;\n } else {\n return '/';\n }\n } else {\n // Relative or simple path\n if (url.charCodeAt(0) === 47) { // '/'\n start = 0;\n }\n }\n\n return url.substring(start, end);\n }\n /**\n * Request query params\n */\n get query() {\n if (this[$cachedQuery]) return this[$cachedQuery];\n\n // Security: Use Object.create(null) to prevent prototype pollution\n const q: Record<string, any> = Object.create(null);\n\n // Security: Blocklist dangerous property names\n const blocklist = ['__proto__', 'constructor', 'prototype'];\n\n this.url.searchParams.forEach((value, key) => {\n // Security: Skip dangerous keys\n if (blocklist.includes(key)) return;\n\n // Use hasOwnProperty to avoid prototype chain issues\n if (Object.prototype.hasOwnProperty.call(q, key)) {\n if (Array.isArray(q[key])) {\n q[key].push(value);\n } else {\n q[key] = [q[key], value];\n }\n } else {\n q[key] = value;\n }\n });\n this[$cachedQuery] = q;\n return q;\n }\n\n /**\n * Client IP address\n */\n get ip() { return this.server?.requestIP(this.request as unknown as Request); }\n\n /**\n * Request hostname (e.g. \"localhost\")\n */\n get hostname() {\n return this[$cachedHostname] ??= this.url.hostname;\n }\n\n /**\n * Request host (e.g. \"localhost:3000\")\n */\n get host() {\n return this[$cachedHost] ??= this.url.host;\n }\n\n /**\n * Request protocol (e.g. \"http:\", \"https:\")\n */\n get protocol() {\n return this[$cachedProtocol] ??= this.url.protocol;\n }\n\n /**\n * Whether request is secure (https)\n */\n get secure() { return this.protocol === 'https:'; }\n\n /**\n * Request origin (e.g. \"http://localhost:3000\")\n */\n get origin() {\n return this[$cachedOrigin] ??= this.url.origin;\n }\n\n /**\n * Request headers\n */\n get headers() { return this.request.headers; }\n\n /**\n * Get a request header\n * @param name Header name\n */\n public get(name: string) { return this.request.headers.get(name); }\n\n /**\n * Base response object\n */\n get res() { return this.response; }\n\n /**\n * Get the raw response body content (if available)\n */\n get responseBody() { return this[$rawBody]; }\n\n /**\n * Raw WebSocket connection\n */\n get ws() { return this[$ws]; }\n\n /**\n * Socket.io socket\n */\n get socket() { return this[$socket]; }\n\n /**\n * Socket.io server\n */\n get io() { return this[$io]; }\n\n /**\n * Helper to set a header on the response\n * @param key Header key\n * @param value Header value\n */\n public set(key: string, value: string) {\n this.response.set(key, value);\n return this;\n }\n\n public isUpgraded: boolean = false;\n\n /**\n * Upgrades the request to a WebSocket connection.\n * @param options Upgrade options\n * @returns true if upgraded, false otherwise\n */\n public upgrade(options?: { data?: any; headers?: HeadersInit; }) {\n if (!this.server) return false;\n const success = this.server.upgrade(this.req as any, options);\n if (success) {\n this.isUpgraded = true;\n }\n return success;\n }\n\n /**\n * Set a cookie\n * @param name Cookie name\n * @param value Cookie value\n * @param options Cookie options\n */\n public setCookie(name: string, value: string, options: CookieOptions = {}) {\n // Security: Validate domain attribute to prevent cookie injection\n if (options.domain) {\n const currentHost = this.hostname;\n if (!isValidCookieDomain(options.domain, currentHost)) {\n throw new Error(`Invalid cookie domain: ${options.domain} for host ${currentHost}`);\n }\n }\n\n // Robust Cookie Serialization\n let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;\n if (options.maxAge) cookie += `; Max-Age=${Math.floor(options.maxAge)}`;\n if (options.domain) cookie += `; Domain=${options.domain}`;\n if (options.path) cookie += `; Path=${options.path || '/'}`;\n if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;\n if (options.httpOnly) cookie += `; HttpOnly`;\n if (options.secure) cookie += `; Secure`;\n\n let sameSite = options.sameSite;\n if (sameSite === true) sameSite = 'Strict';\n if (sameSite === undefined || sameSite === false) {\n // Do not set SameSite if undefined/false? Or Default to Lax?\n // Modern browsers default to Lax.\n // We'll leave it omit unless specified.\n } else {\n const stringSameSite = typeof sameSite === 'string' ? sameSite.toLowerCase() : sameSite;\n switch (stringSameSite) {\n case 'lax': cookie += '; SameSite=Lax'; break;\n case 'strict': cookie += '; SameSite=Strict'; break;\n case 'none': cookie += '; SameSite=None'; break;\n default: cookie += '; SameSite=Lax'; break;\n }\n }\n\n if (options.priority) {\n const p = options.priority.toLowerCase();\n if (p === 'low') cookie += '; Priority=Low';\n else if (p === 'medium') cookie += '; Priority=Medium';\n else if (p === 'high') cookie += '; Priority=High';\n }\n\n this.response.append('Set-Cookie', cookie);\n return this;\n }\n\n private mergeHeaders(headers?: HeadersInit): Headers {\n let h: Headers;\n // Optimization: avoid double allocation if response headers are empty/null\n if (this.response.hasPopulatedHeaders) {\n h = new Headers(this.response.headers);\n } else {\n h = new Headers();\n }\n\n if (headers) {\n // Efficient merge dependent on type\n if (headers instanceof Headers) {\n headers.forEach((v, k) => h.set(k, v));\n } else if (Array.isArray(headers)) {\n headers.forEach(([k, v]) => h.set(k, v));\n } else {\n // Object iteration\n const keys = Object.keys(headers);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const val = (headers as any)[key];\n h.set(key, val);\n }\n }\n }\n return h;\n }\n\n\n /**\n * Read request body with caching to avoid double parsing.\n * The body is only parsed once and cached for subsequent reads.\n */\n async body<T = any>(): Promise<T> {\n // If there was an error during pre-parsing, throw it now\n if (this[$bodyParseError] !== undefined) {\n throw this[$bodyParseError];\n }\n\n // Return cached body if already parsed\n if (this[$bodyParsed] === true) {\n return this[$cachedBody] as T;\n }\n\n const contentType = this.request.headers.get(\"content-type\") || \"\";\n\n if (contentType.includes(\"application/json\") || contentType.includes(\"+json\")) {\n // Use native JSON parser which is significantly faster (C++)\n const parserType = this.app?.applicationConfig?.jsonParser || 'native';\n\n if (parserType === 'native') {\n // Determine if we can use the native request.json() method\n // We can't use it if we've already read the body or if it's a clone\n try {\n this[$cachedBody] = await this.request.json();\n } catch (e) {\n // Fallback for empty body or invalid JSON\n // If body is empty, return empty object/null based on preference, or let it fail\n // But standard behavior for empty JSON request is usually error or empty object\n // Re-throwing to match previous behavior\n throw e;\n }\n } else {\n // For custom parsers, we still need the text\n const rawText = await this.request.text();\n const { getJSONParser } = await import('./util/json-parser');\n const parser = getJSONParser(parserType);\n this[$cachedBody] = parser(rawText);\n }\n\n this[$bodyType] = 'json';\n } else if (contentType.includes(\"multipart/form-data\") || contentType.includes(\"application/x-www-form-urlencoded\")) {\n // FormData still needs Request API as it's more complex to parse manually\n this[$cachedBody] = await this.request.formData();\n this[$bodyType] = 'formData';\n } else {\n // Use native text() method\n this[$cachedBody] = await this.request.text();\n this[$bodyType] = 'text';\n }\n\n this[$bodyParsed] = true;\n return this[$cachedBody] as T;\n }\n\n /**\n * Pre-parse the request body before handler execution.\n * This improves performance and enables Node.js compatibility for large payloads.\n * Errors are deferred until the body is actually accessed in the handler.\n */\n async parseBody(): Promise<void> {\n // Skip if already parsed\n if (this[$bodyParsed]) {\n return;\n }\n\n // Skip for methods that typically don't have bodies\n if (this.request.method === 'GET' || this.request.method === 'HEAD') {\n return;\n }\n\n try {\n await this.body(); // Trigger body parsing and caching\n } catch (error) {\n // Store error for later throwing when body is accessed\n this[$bodyParseError] = error as Error;\n }\n }\n\n /**\n * Read raw body from ReadableStream efficiently.\n * This is much faster than request.text() for large payloads.\n * Also handles the case where body is already a string (e.g., in tests).\n */\n private async readRawBody(): Promise<string> {\n // Handle test case where body is already a string\n if (typeof (this.request as any).body === 'string') {\n return (this.request as any).body;\n }\n\n const reader = this.request.body?.getReader();\n if (!reader) {\n return '';\n }\n\n const chunks: Uint8Array[] = [];\n let totalSize = 0;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n totalSize += value.length;\n }\n } finally {\n reader.releaseLock();\n }\n\n // Efficiently combine chunks into single buffer\n const result = new Uint8Array(totalSize);\n let offset = 0;\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i];\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return new TextDecoder().decode(result);\n }\n\n /**\n * Send a response\n * @param body Response body\n * @param options Response options\n * @returns Response\n */\n send(body?: BodyInit, options?: ResponseInit) {\n const headers = this.mergeHeaders(options?.headers as any);\n const status = options?.status ?? this.response.status ?? 200;\n\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_HTTP_STATUSES.has(status)) {\n throw new Error(`Invalid HTTP status code: ${status}`);\n }\n\n // Store raw body for compression middleware\n if (typeof body === \"string\" || body instanceof ArrayBuffer || body instanceof Uint8Array) {\n this[$rawBody] = body;\n }\n\n // :as any because there are multiple bodyinit providers. What the hell.\n return this[$finalResponse] ??= new Response(body as any, { status, headers });\n }\n\n /**\n * Emit an event to the client (WebSocket only)\n * @param event Event name\n * @param data Event data (Must be JSON serializable)\n */\n emit(event: string, data?: any) {\n if (this[$ws]) {\n this[$ws].send(JSON.stringify({ event, data }));\n } else if (this[$socket]) {\n this[$socket].emit(event, data);\n }\n }\n\n /**\n * Respond with a JSON object\n */\n async json(data: object | Promise<object>, status?: number, headers?: HeadersInit) {\n const finalStatus = status ?? this.response.status ?? 200;\n // Validate redirect status code\n if (!VALID_HTTP_STATUSES.has(finalStatus)) {\n throw new Error(`Invalid HTTP status code: ${finalStatus}`);\n }\n this.response.status = finalStatus;\n\n const jsonString = JSON.stringify(data instanceof Promise ? await data : data);\n\n // Store raw body for compression middleware\n this[$rawBody] = jsonString;\n\n // Fast path: no custom headers and no response headers set\n if (!headers && !this.response.hasPopulatedHeaders) {\n this[$finalResponse] = new Response(jsonString, {\n status: finalStatus,\n headers: { \"content-type\": \"application/json\" }\n });\n return this[$finalResponse];\n }\n\n // Slow path: merge headers\n const finalHeaders = this.mergeHeaders(headers);\n finalHeaders.set(\"content-type\", \"application/json\");\n this[$finalResponse] = new Response(jsonString, { status: finalStatus, headers: finalHeaders });\n return this[$finalResponse];\n }\n\n /**\n * Respond with a text string\n */\n async text(data: string | Promise<string>, status?: number, headers?: HeadersInit) {\n const finalStatus = status ?? this.response.status ?? 200;\n\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_HTTP_STATUSES.has(finalStatus)) {\n throw new Error(`Invalid HTTP status code: ${finalStatus}`);\n }\n this.response.status = finalStatus;\n\n // Store raw body for compression middleware\n this[$rawBody] = data instanceof Promise ? await data : data;\n\n // Fast path: no custom headers and no response headers set\n if (!headers && !this.response.hasPopulatedHeaders) {\n this[$finalResponse] = new Response(this[$rawBody], {\n status: finalStatus,\n headers: { \"content-type\": \"text/plain; charset=utf-8\" }\n });\n return this[$finalResponse];\n }\n\n // Slow path: merge headers\n const finalHeaders = this.mergeHeaders(headers);\n finalHeaders.set(\"content-type\", \"text/plain; charset=utf-8\");\n this[$finalResponse] = new Response(this[$rawBody], { status: finalStatus, headers: finalHeaders });\n return this[$finalResponse];\n }\n\n /**\n * Respond with HTML content\n */\n async html(html: string | Promise<string>, status?: number, headers?: HeadersInit) {\n const finalStatus = status ?? this.response.status ?? 200;\n\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_HTTP_STATUSES.has(finalStatus)) {\n throw new Error(`Invalid HTTP status code: ${finalStatus}`);\n }\n this.response.status = finalStatus;\n\n const finalHeaders = this.mergeHeaders(headers);\n finalHeaders.set(\"content-type\", \"text/html; charset=utf-8\");\n\n // Store raw body for compression middleware\n this[$rawBody] = html instanceof Promise ? await html : html;\n\n this[$finalResponse] = new Response(this[$rawBody], { status: finalStatus, headers: finalHeaders });\n return this[$finalResponse];\n }\n\n /**\n * Respond with a redirect\n */\n async redirect(url: string | Promise<string>, status = 302) {\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_REDIRECT_STATUSES.has(status)) {\n throw new Error(`Invalid redirect status code: ${status}`);\n }\n this.response.status = status;\n\n const finalHeaders = this.mergeHeaders();\n finalHeaders.set('Location', url instanceof Promise ? await url : url);\n\n this[$finalResponse] = new Response(null, { status, headers: finalHeaders });\n return this[$finalResponse];\n }\n\n /**\n * Respond with a status code\n * DOES NOT CHAIN!\n */\n async status(statusCode: number | Promise<number>) {\n const status = statusCode instanceof Promise ? await statusCode : statusCode;\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_HTTP_STATUSES.has(status)) {\n throw new Error(`Invalid HTTP status code: ${status}`);\n }\n this.response.status = status;\n\n const finalHeaders = this.mergeHeaders();\n this[$finalResponse] = new Response(null, { status, headers: finalHeaders });\n return this[$finalResponse];\n }\n\n /**\n * Respond with a file\n */\n public async file(path: string, fileOptions?: BlobPropertyBag, responseOptions?: ResponseInit) {\n const finalHeaders = this.mergeHeaders(responseOptions?.headers as any);\n const status = responseOptions?.status ?? this.response.status;\n\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_HTTP_STATUSES.has(status)) {\n throw new Error(`Invalid HTTP status code: ${status}`);\n }\n // status is optional in file responseOptions, so only update if defined, otherwise keep existing\n if (status) this.response.status = status;\n\n if (typeof Bun !== \"undefined\") {\n this[$finalResponse] = new Response(Bun.file(path, fileOptions), { status, headers: finalHeaders });\n return this[$finalResponse];\n } else {\n // Node.js fallback using fs\n const fileBuffer = await readFile(path);\n\n // Set content-type from fileOptions if provided\n if (fileOptions?.type) {\n finalHeaders.set('content-type', fileOptions.type);\n }\n\n this[$finalResponse] = new Response(fileBuffer, { status, headers: finalHeaders });\n return this[$finalResponse];\n }\n }\n\n /**\n * Render a JSX element\n * @param element JSX Element\n * @param args JSX Element Args/Props\n * @param status HTTP Status\n * @param headers HTTP Headers\n */\n public async jsx(element: any, args?: Parameters<JSXRenderer>[1], status?: number, headers?: HeadersInit) {\n status ??= 200;\n\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_HTTP_STATUSES.has(status)) {\n throw new Error(`Invalid HTTP status code: ${status}`);\n }\n if (!this.renderer) {\n throw new Error(\"No JSX renderer configured\");\n }\n\n const html = await this.renderer(element, args);\n return this.html(html, status, headers); // html() already stores _rawBody\n }\n}\n","import type { ShokupanContext } from \"./context\";\nimport { $debug } from './util/symbol';\nimport type { Middleware, NextFn } from './util/types';\n\n/**\n * Composes a list of middleware into a single function.\n * This is the onion model (Koa-style).\n * \n * CRITICAL: This must build the chain ONCE, not rebuild it on every request.\n */\nexport const compose = (middleware: Middleware[]) => {\n if (!middleware.length) {\n return (context: ShokupanContext<unknown>, next?: NextFn) => {\n return next ? next() : Promise.resolve();\n };\n }\n\n return function dispatch(context: ShokupanContext<unknown>, next?: NextFn): Promise<any> {\n let index = -1;\n\n async function runner(i: number): Promise<any> {\n if (i <= index) return Promise.reject(new Error('next() called multiple times'));\n index = i;\n\n if (i >= middleware.length) {\n return next ? next() : Promise.resolve();\n }\n\n const fn = middleware[i];\n\n // Fast path: No debug tracking\n if (!context[$debug]) {\n return fn(context, () => runner(i + 1));\n }\n\n // Slow path: Debug tracking\n const debug = context[$debug];\n const debugId = (fn as any)._debugId || fn.name || 'anonymous';\n const previousNode = debug.getCurrentNode();\n\n debug.trackEdge(previousNode, debugId);\n debug.setNode(debugId);\n\n const start = performance.now();\n try {\n const res = await Promise.resolve(fn(context, () => runner(i + 1)));\n debug.trackStep(debugId, 'middleware', performance.now() - start, 'success');\n return res;\n } catch (err) {\n debug.trackStep(debugId, 'middleware', performance.now() - start, 'error', err);\n return Promise.reject(err);\n } finally {\n if (previousNode) debug.setNode(previousNode);\n }\n }\n\n return runner(0);\n };\n};\n\n\n","/**\n * Simple object check.\n */\nexport function isObject(item: any): item is Record<string, any> {\n return (item && typeof item === 'object' && !Array.isArray(item));\n}\n\n/**\n * Deep merge two objects.\n * \n * - Arrays are concatenated.\n * - Objects are merged recursively.\n * - Primitives are overwritten.\n */\nexport function deepMerge<T extends Record<string, any>>(target: T, ...sources: Partial<T>[]): T {\n if (!sources.length) return target;\n const source = sources.shift();\n\n if (isObject(target) && isObject(source)) {\n const sourceKeys = Object.keys(source);\n for (let i = 0; i < sourceKeys.length; i++) {\n const key = sourceKeys[i];\n if (isObject(source[key])) {\n if (!target[key]) Object.assign(target, { [key]: {} });\n deepMerge(target[key], source[key]);\n } else if (Array.isArray(source[key])) {\n if (!target[key]) Object.assign(target, { [key]: [] });\n\n if (key === 'tags') {\n // Start fresh if tags are provided in source (overwrite)\n (target as any)[key] = source[key];\n continue;\n }\n\n // Concat then deduplicate primitives\n const mergedArray = (target as any)[key].concat(source[key]);\n\n // If all items are primitives, unique them\n const isPrimitive = (item: any) =>\n typeof item === 'string' ||\n typeof item === 'number' ||\n typeof item === 'boolean';\n\n if (mergedArray.every(isPrimitive)) {\n (target as any)[key] = Array.from(new Set(mergedArray));\n }\n else {\n (target as any)[key] = mergedArray;\n }\n } else {\n Object.assign(target, { [key]: source[key] });\n }\n }\n }\n\n return deepMerge(target, ...sources);\n}\n","\n/**\n * Gets deduped AST routes if available.\n */\nexport async function getAstRoutes(applications: any[], options: { includePrefix?: boolean, pathTransform?: (p: string) => string; } = {}) {\n const { includePrefix = true, pathTransform } = options;\n\n const astRoutes: any[] = [];\n\n const getExpandedRoutes = (app: any, prefix: string = '', seen = new Set<string>(), sourceOverride?: any): any[] => {\n if (seen.has(app.name)) return [];\n const newSeen = new Set(seen);\n newSeen.add(app.name);\n\n const expanded: any[] = [];\n\n let currentPrefix = prefix;\n // Only consider controller prefix if includePrefix is true\n if (includePrefix && app.controllerPrefix) {\n const cleanPrefix = currentPrefix.endsWith('/') ? currentPrefix.slice(0, -1) : currentPrefix;\n const cleanCont = app.controllerPrefix.startsWith('/') ? app.controllerPrefix : '/' + app.controllerPrefix;\n currentPrefix = cleanPrefix + cleanCont;\n }\n\n for (const route of app.routes) {\n let path = route.path;\n\n if (includePrefix) {\n const cleanPrefix = currentPrefix.endsWith('/') ? currentPrefix.slice(0, -1) : currentPrefix;\n const cleanPath = path.startsWith('/') ? path : '/' + path;\n path = cleanPrefix + cleanPath;\n if (path.length > 1 && path.endsWith('/')) {\n path = path.slice(0, -1);\n }\n }\n\n // Apply path transformation if provided (e.g. removing leading slash for events)\n if (pathTransform) {\n path = pathTransform(path);\n }\n // For OpenAPI default (if includePrefix true and no transform), ensure leading slash\n else if (includePrefix && !path.startsWith('/')) {\n path = '/' + path;\n }\n\n const expandedRoute = {\n ...route,\n path: path || '/'\n };\n\n if (sourceOverride) {\n expandedRoute.sourceContext = sourceOverride;\n }\n\n expanded.push(expandedRoute);\n }\n\n if (app.mounted) {\n for (const mount of app.mounted) {\n const targetApp = applications.find(a => a.name === mount.target || a.className === mount.target);\n if (targetApp) {\n let nextPrefix = '';\n\n if (includePrefix) {\n const cleanPrefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;\n const mountPrefix = mount.prefix.startsWith('/') ? mount.prefix : '/' + mount.prefix;\n nextPrefix = cleanPrefix + mountPrefix;\n }\n\n // Check for builtin/external dependency to override source\n let nextSourceOverride = sourceOverride;\n if (mount.dependency || (mount.targetFilePath && mount.targetFilePath.includes('node_modules'))) {\n if (mount.sourceContext) {\n nextSourceOverride = {\n ...mount.sourceContext,\n // Add highlight for the mount line to make it clear\n highlightLines: [mount.sourceContext.startLine, mount.sourceContext.endLine],\n highlights: [{\n startLine: mount.sourceContext.startLine,\n endLine: mount.sourceContext.endLine,\n type: 'return-success' // Use the success color (cyan) for the mount point\n }]\n };\n }\n }\n\n expanded.push(...getExpandedRoutes(targetApp, nextPrefix, newSeen, nextSourceOverride));\n }\n }\n }\n return expanded;\n };\n\n applications.forEach(app => {\n astRoutes.push(...getExpandedRoutes(app));\n });\n\n // Deduplicate routes based on score (only relevant for OpenAPI usually, but safe for all)\n const dedupedRoutes = new Map<string, { route: any, score: number; }>();\n\n for (const route of astRoutes) {\n // Key includes method and path\n const key = `${route.method.toUpperCase()}:${route.path}`;\n let score = 0;\n if (route.responseSchema) score += 10;\n if (route.handlerSource) score += 5;\n\n // If duplicate found, keep the one with higher score (better inference)\n if (!dedupedRoutes.has(key) || score > dedupedRoutes.get(key)!.score) {\n dedupedRoutes.set(key, { route, score });\n }\n }\n\n return Array.from(dedupedRoutes.values()).map(v => v.route);\n}\n","import type { ShokupanRouter } from '../../../router';\nimport { deepMerge } from '../../../util/deep-merge';\nimport { $childControllers, $childRouters, $mountPath, $parent, $routes } from '../../../util/symbol';\nimport type { OpenAPIOptions, ShokupanHandler } from '../../../util/types';\nimport { getAstRoutes } from '../shared/ast-utils';\n\n/**\n * Regex patterns for analyzing handler source code to infer types.\n */\nconst REGEX_PATTERNS = {\n QUERY_INT: /parseInt\\(ctx\\.query\\.(\\w+)\\)/g,\n QUERY_FLOAT: /parseFloat\\(ctx\\.query\\.(\\w+)\\)/g,\n QUERY_NUMBER: /Number\\(ctx\\.query\\.(\\w+)\\)/g,\n QUERY_BOOL: /(?:Boolean\\(ctx\\.query\\.(\\w+)\\)|!+ctx\\.query\\.(\\w+))/g,\n QUERY_GENERIC: /ctx\\.query\\.(\\w+)/g,\n PARAM_INT: /parseInt\\(ctx\\.params\\.(\\w+)\\)/g,\n PARAM_FLOAT: /parseFloat\\(ctx\\.params\\.(\\w+)\\)/g,\n PARAM_GENERIC: /ctx\\.params\\.(\\w+)/,\n HEADER_GET: /ctx\\.get\\(['\"](\\w+)['\"]\\)/g,\n ERROR_STATUS: /ctx\\.(?:json|text|html)\\([^)]+,\\s*(\\d{3,})\\)/g\n};\n\n/**\n * Analyze a handler function to infer request/response types based on source code usage.\n */\nfunction analyzeHandler(handler: ShokupanHandler): { inferredSpec?: any; } {\n const handlerSource = handler.toString();\n const inferredSpec: any = {};\n\n // Detect request body\n if (handlerSource.includes('ctx.body') || handlerSource.includes('await ctx.req.json()')) {\n inferredSpec.requestBody = {\n content: { 'application/json': { schema: { type: 'object' } } }\n };\n }\n\n const queryParams = new Map<string, { type: string; format?: string; }>();\n\n // Helper to process regex matches\n const processMatches = (regex: RegExp, type: string, format?: string) => {\n const matches = Array.from(handlerSource.matchAll(regex));\n for (const match of matches) {\n const name = match[1] || match[2];\n if (name && !queryParams.has(name)) {\n queryParams.set(name, { type, format });\n }\n }\n };\n\n processMatches(REGEX_PATTERNS.QUERY_INT, 'integer', 'int32');\n processMatches(REGEX_PATTERNS.QUERY_FLOAT, 'number', 'float');\n processMatches(REGEX_PATTERNS.QUERY_NUMBER, 'number');\n processMatches(REGEX_PATTERNS.QUERY_BOOL, 'boolean');\n processMatches(REGEX_PATTERNS.QUERY_GENERIC, 'string');\n\n if (queryParams.size > 0) {\n if (!inferredSpec.parameters) inferredSpec.parameters = [];\n queryParams.forEach((schema, paramName) => {\n inferredSpec.parameters.push({\n name: paramName,\n in: 'query',\n schema: { type: schema.type, ...(schema.format ? { format: schema.format } : {}) }\n });\n });\n }\n\n const pathParams = new Map<string, { type: string; format?: string; }>();\n const processPathMatches = (regex: RegExp, type: string, format?: string) => {\n const matches = Array.from(handlerSource.matchAll(regex));\n for (const match of matches) {\n const name = match[1];\n if (name) pathParams.set(name, { type, format });\n }\n };\n\n processPathMatches(REGEX_PATTERNS.PARAM_INT, 'integer', 'int32');\n processPathMatches(REGEX_PATTERNS.PARAM_FLOAT, 'number', 'float');\n\n if (pathParams.size > 0) {\n if (!inferredSpec.parameters) inferredSpec.parameters = [];\n pathParams.forEach((schema, paramName) => {\n inferredSpec.parameters.push({\n name: paramName,\n in: 'path',\n required: true,\n schema: { type: schema.type, ...(schema.format ? { format: schema.format } : {}) }\n });\n });\n }\n\n // Detect Headers\n const headerMatches = Array.from(handlerSource.matchAll(REGEX_PATTERNS.HEADER_GET));\n for (const match of headerMatches) {\n if (match[1]) {\n if (!inferredSpec.parameters) inferredSpec.parameters = [];\n inferredSpec.parameters.push({\n name: match[1],\n in: 'header',\n schema: { type: 'string' }\n });\n }\n }\n\n // Detect response formats\n const responses: any = {};\n\n if (handlerSource.includes('ctx.json(')) {\n responses['200'] = {\n description: 'Successful response',\n content: { 'application/json': { schema: { type: 'object' } } }\n };\n }\n\n if (handlerSource.includes('ctx.html(')) {\n responses['200'] = {\n description: 'Successful HTML response',\n content: { 'text/html': { schema: { type: 'string' } } }\n };\n }\n\n if (handlerSource.includes('ctx.jsx(')) {\n responses['200'] = {\n description: 'Successful HTML response (Rendered JSX)',\n content: { 'text/html': { schema: { type: 'string' } } }\n };\n }\n\n if (handlerSource.includes('ctx.text(')) {\n responses['200'] = {\n description: 'Successful text response',\n content: { 'text/plain': { schema: { type: 'string' } } }\n };\n }\n\n if (handlerSource.includes('ctx.file(')) {\n responses['200'] = {\n description: 'File download',\n content: { 'application/octet-stream': { schema: { type: 'string', format: 'binary' } } }\n };\n }\n\n if (handlerSource.includes('ctx.redirect(')) {\n let hasSpecificRedirect = false;\n const redirectMatches = Array.from(handlerSource.matchAll(/ctx\\.redirect\\([^,]+,\\s*(\\d{3})\\)/g));\n for (const match of redirectMatches) {\n const status = match[1];\n // Ensure the status is a valid redirect code\n if (/^30[12378]$/.test(status)) {\n responses[status] = { description: `Redirect (${status})` };\n hasSpecificRedirect = true;\n }\n }\n\n if (!hasSpecificRedirect) {\n responses['302'] = { description: 'Redirect' };\n }\n }\n\n // Fallback to JSON for plain object returns\n if (!responses['200'] && /return\\s+\\{/.test(handlerSource)) {\n responses['200'] = {\n description: 'Successful response',\n content: { 'application/json': { schema: { type: 'object' } } }\n };\n }\n\n // Detect Error Responses\n const errorStatusMatches = Array.from(handlerSource.matchAll(REGEX_PATTERNS.ERROR_STATUS));\n for (const match of errorStatusMatches) {\n const statusCode = match[1];\n if (statusCode && statusCode !== '200') {\n responses[statusCode] = { description: `Error response (${statusCode})` };\n }\n }\n\n if (Object.keys(responses).length > 0) {\n inferredSpec.responses = responses;\n }\n\n return { inferredSpec };\n}\n\n/**\n * Gets deduped AST routes if available.\n */\n\n/**\n * Statically generate an OpenAPI spec from a ShokupanRouter instance.\n * \n * @param rootRouter - The root router instance to generate the spec tree from.\n * @param options - Optional OpenAPI configuration options.\n * @returns The generated OpenAPI spec.\n */\nexport async function generateOpenApi<T extends Record<string, any>>(rootRouter: ShokupanRouter<T>, options: OpenAPIOptions = {}): Promise<any> {\n const paths: Record<string, any> = {};\n const tagGroups = new Map<string, Set<string>>();\n\n const defaultTagGroup = options.defaultTagGroup || \"General\";\n const defaultTagName = options.defaultTag || \"Application\";\n\n // Attempt to run AST Analysis\n let astRoutes: any[] = [];\n let astMiddlewareRegistry: Record<string, any> = {};\n let applications: any[] = [];\n try {\n const { OpenAPIAnalyzer } = await import('./analyzer');\n // Use the application entrypoint if available to restrict analysis scope\n const entrypoint = rootRouter.metadata?.file;\n const analyzer = new OpenAPIAnalyzer(process.cwd(), entrypoint);\n const analysisResult = await analyzer.analyze();\n applications = analysisResult.applications;\n astRoutes = await getAstRoutes(applications);\n\n // Build middleware registry from AST-analyzed applications\n let middlewareId = 0;\n for (const app of applications) {\n if (app.middleware && app.middleware.length > 0) {\n for (const mw of app.middleware) {\n const id = `middleware-${middlewareId++}`;\n astMiddlewareRegistry[id] = {\n ...mw,\n id,\n usedBy: [] // Will be populated when processing routes\n };\n }\n }\n }\n } catch (e) {\n // Silently fail if analysis cannot run (e.g. runtime environment issues)\n // console.warn(\"OpenAPI AST analysis skipped:\", e);\n if (options.warnings) {\n options.warnings.push({\n type: 'ast-analysis-failed',\n message: 'AST Analysis failed or skipped',\n detail: e.message\n });\n }\n }\n\n const collect = (router: ShokupanRouter<T>, prefix = \"\", currentGroup = defaultTagGroup, defaultTag = defaultTagName, inheritedMiddleware: any[] = [], isRootLevel = true) => {\n let group = currentGroup;\n let tag = defaultTag;\n\n if (router.config?.group) group = router.config.group;\n if (router.config?.name) {\n tag = router.config.name;\n }\n else {\n const mountPath = router[$mountPath];\n // Only create a new tag from mountPath if this is a root-level router (or direct child of root)\n // Otherwise, inherit the tag from the parent\n const isDirectChild = (router as any)[$parent] === rootRouter;\n if ((isRootLevel || isDirectChild) && mountPath && mountPath !== \"/\") {\n const segments = mountPath.split(\"/\").filter(Boolean);\n if (segments.length > 0) {\n const lastSegment = segments[segments.length - 1];\n tag = lastSegment.replace(/[-_]/g, ' ').replace(/\\b\\w/g, c => c.toUpperCase());\n }\n }\n }\n\n let isBuiltinPlugin = false;\n let pluginName = '';\n\n // Detect builtin plugins\n if ((router.metadata as any)?.pluginName) {\n isBuiltinPlugin = true;\n pluginName = (router.metadata as any).pluginName;\n tag = pluginName.replace(/[-_]/g, ' ').replace(/\\b\\w/g, c => c.toUpperCase());\n }\n else if (router.metadata?.file && router.metadata.file.includes('plugins/application/')) {\n isBuiltinPlugin = true;\n // Extract plugin name from path .../plugins/application/<name>/...\n const match = router.metadata.file.match(/plugins\\/application\\/([^/]+)/);\n if (match) {\n pluginName = match[1].replace(/\\.(ts|js|mjs|mts|cjs)$/, '');\n // Override tag for builtin plugins to group them properly\n tag = pluginName.replace(/[-_]/g, ' ').replace(/\\b\\w/g, c => c.toUpperCase());\n }\n }\n\n if (!tagGroups.has(group)) tagGroups.set(group, new Set());\n\n const routerMiddleware = router.middleware || [];\n\n const routes = (router as any)[$routes] || [];\n\n for (const route of routes) {\n // Filter out non-HTTP methods (e.g. AsyncAPI PUB/SUB events)\n if (!['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'].includes(route.method.toUpperCase())) {\n continue;\n }\n\n const routeGroup = route.group || group;\n const cleanPrefix = prefix.endsWith(\"/\") ? prefix.slice(0, -1) : prefix;\n const cleanSubPath = route.path.startsWith(\"/\") ? route.path : \"/\" + route.path;\n let fullPath = (cleanPrefix + cleanSubPath) || \"/\";\n\n if (fullPath.length > 1 && fullPath.endsWith('/')) {\n fullPath = fullPath.slice(0, -1);\n }\n\n // Convert Express-style :param to OpenAPI-style {param}\n fullPath = fullPath.replace(/:([a-zA-Z0-9_]+)/g, '{$1}');\n\n if (!paths[fullPath]) paths[fullPath] = {};\n\n const operation: any = {\n responses: { '200': { description: \"Successful response\" } },\n tags: [tag]\n };\n\n // Collect Middleware - both runtime and AST-analyzed\n const routeMiddleware = route.middleware || [];\n const allMiddleware = [...inheritedMiddleware, ...routerMiddleware, ...routeMiddleware];\n\n // Find matching AST middleware for this route's path and method\n const astMiddlewareForRoute: any[] = [];\n for (const [mwId, mw] of Object.entries(astMiddlewareRegistry)) {\n // For now, associate all middleware from the same app with all routes from that app\n // In a more sophisticated implementation, we'd track router-level vs global vs route-level scope\n const appForRoute = applications.find((app: any) =>\n app.routes?.some((r: any) => r.path === fullPath && r.method === route.method.toUpperCase())\n );\n const appForMiddleware = applications.find((app: any) =>\n app.middleware?.some((m: any) => m.name === mw.name && m.file === mw.file)\n );\n\n if (appForRoute && appForMiddleware && appForRoute.filePath === appForMiddleware.filePath) {\n astMiddlewareForRoute.push({ ...mw, id: mwId });\n // Track which routes use this middleware\n if (!mw.usedBy.includes(fullPath)) {\n mw.usedBy.push(fullPath);\n }\n }\n }\n\n // Merge middleware responses into operation\n for (const astMw of astMiddlewareForRoute) {\n if (astMw.responseTypes) {\n for (const [statusCode, responseSpec] of Object.entries(astMw.responseTypes)) {\n // Don't override existing responses, middleware responses have lower priority\n if (!operation.responses[statusCode]) {\n operation.responses[statusCode] = responseSpec;\n }\n }\n }\n }\n\n if (allMiddleware.length > 0 || astMiddlewareForRoute.length > 0) {\n operation['x-shokupan-middleware'] = [\n ...allMiddleware.map(mw => ({\n name: mw.name || 'middleware',\n metadata: mw.metadata\n })),\n ...astMiddlewareForRoute.map(mw => ({\n id: mw.id,\n name: mw.name,\n responses: mw.responseTypes,\n headers: mw.headers,\n file: mw.file,\n line: mw.startLine\n }))\n ];\n }\n\n if (route.guards) {\n for (const guard of route.guards) {\n if (guard.spec) {\n if (guard.spec.security) {\n const existing = operation.security || [];\n for (const req of guard.spec.security) {\n const reqStr = JSON.stringify(req);\n if (!existing.some((e: any) => JSON.stringify(e) === reqStr)) {\n existing.push(req);\n }\n }\n operation.security = existing;\n }\n if (guard.spec.responses) {\n operation.responses = { ...operation.responses, ...guard.spec.responses };\n }\n }\n }\n }\n\n // Match with AST routes\n let astMatch = astRoutes.find(r =>\n r.method.toUpperCase() === route.method.toUpperCase() &&\n r.path === fullPath\n );\n\n\n\n if (!astMatch) {\n // Heuristic matching based on source code similarity\n const runtimeSource = ((route.handler as any).originalHandler || route.handler).toString();\n const runtimeHandlerSrc = runtimeSource.replace(/\\s+/g, ' ');\n\n const sameMethodRoutes = astRoutes.filter(r => r.method.toUpperCase() === route.method.toUpperCase());\n\n astMatch = sameMethodRoutes.find(r => {\n const astHandlerSrc = (r.handlerSource || r.handlerName || '').replace(/\\s+/g, ' ');\n if (!astHandlerSrc || astHandlerSrc.length < 20) return false;\n return runtimeHandlerSrc.includes(astHandlerSrc) ||\n astHandlerSrc.includes(runtimeHandlerSrc) ||\n (r.handlerSource && runtimeHandlerSrc.includes(r.handlerSource.substring(0, 50)));\n });\n }\n\n if (astMatch) {\n if (astMatch.summary) operation.summary = astMatch.summary;\n if (astMatch.description) operation.description = astMatch.description;\n if (astMatch.tags) operation.tags = astMatch.tags;\n if (astMatch.operationId) operation.operationId = astMatch.operationId;\n\n // Add source info\n if (astMatch.sourceContext) {\n const sc = astMatch.sourceContext;\n operation[\"x-source-info\"] = {\n file: sc.file,\n line: sc.startLine,\n snippet: sc.snippet || astMatch.handlerSource, // Fallback\n offset: sc.snippetStartLine || sc.startLine,\n highlightLines: [sc.startLine, sc.endLine],\n highlights: sc.highlights\n };\n\n // Add x-shokupan-source for standard frontend handling\n operation[\"x-shokupan-source\"] = {\n file: sc.file,\n line: sc.startLine,\n code: sc.snippet || astMatch.handlerSource || ''\n };\n\n // Removed markdown source block per request\n }\n\n\n\n if (astMatch.requestTypes?.body) {\n operation.requestBody = {\n content: { 'application/json': { schema: astMatch.requestTypes.body } }\n };\n }\n\n if (astMatch.responseSchema) {\n operation.responses['200'] = {\n description: 'Successful response',\n content: { 'application/json': { schema: astMatch.responseSchema } }\n };\n\n // Add warning if schema has unknown fields\n if (astMatch.hasUnknownFields) {\n if (options.warnings) {\n options.warnings.push({\n type: 'unknown-fields',\n message: 'Response contains fields with unknown types',\n detail: `Route: ${fullPath} [${route.method}]`,\n location: { file: astMatch.sourceContext?.file, line: astMatch.sourceContext?.startLine }\n });\n }\n operation['x-warning'] = true;\n operation['x-warning-reason'] = 'Response contains fields with unknown types that could not be statically analyzed';\n }\n } else if (astMatch.responseType) {\n let contentType = 'application/json';\n if (astMatch.responseType === 'string') contentType = 'text/plain';\n else if (astMatch.responseType === 'html') contentType = 'text/html';\n\n operation.responses['200'] = {\n description: 'Successful response',\n content: { [contentType]: { schema: { type: 'string' } } }\n };\n }\n\n const params: any[] = [];\n if (astMatch.requestTypes?.query) {\n for (const [name, _type] of Object.entries(astMatch.requestTypes.query)) {\n params.push({ name, in: 'query', schema: { type: 'string' } });\n }\n }\n if (params.length > 0) {\n operation.parameters = params;\n }\n } else {\n // No static analysis match - Add Warning and Runtime Source\n if (options.warnings) {\n options.warnings.push({\n type: 'route-not-found',\n message: 'Route could not be statically analyzed',\n detail: `Route: ${fullPath} [${route.method}]`,\n location: route.metadata ? { file: route.metadata.file, line: route.metadata.line } : undefined\n });\n }\n const runtimeSource = ((route.handler as any).originalHandler || route.handler).toString();\n // Removed markdown source block and warning per request (or simplified)\n // Minimal warning\n // operation.description = (operation.description || '') + \"\\n\\n> [!WARNING]\\n> **Static Analysis Failed**\";\n\n // Extract file/line from Error stack if available\n let file: string | undefined;\n let line: number | undefined;\n\n // Try to get source info from route metadata if present\n if (route.metadata?.file) {\n file = route.metadata.file;\n line = route.metadata.line || 1;\n }\n\n // Provide x-source-info with available metadata\n operation[\"x-source-info\"] = {\n snippet: runtimeSource,\n isRuntime: true,\n ...(file ? { file, line: line || 1 } : {})\n };\n\n // If we have file info, add it to x-shokupan-source for the API Explorer\n if (file) {\n operation[\"x-shokupan-source\"] = {\n file,\n line: line || 1,\n code: runtimeSource,\n pluginName: (route.handler as any).pluginName // Inject pluginName from handler\n };\n }\n }\n\n if (isBuiltinPlugin) {\n operation[\"x-shokupan-builtin\"] = true;\n }\n\n // Explicitly set plugin name if available on handler (even if not builtin, or overriding builtin guess)\n if ((route.handler as any).pluginName) {\n operation[\"x-shokupan-plugin-name\"] = (route.handler as any).pluginName;\n if (!operation[\"x-shokupan-source\"]) operation[\"x-shokupan-source\"] = {};\n operation[\"x-shokupan-source\"].pluginName = (route.handler as any).pluginName;\n } else if (pluginName) {\n // Fallback to inferred plugin name\n operation[\"x-shokupan-plugin-name\"] = pluginName;\n }\n\n // Path pattern params\n if (route.keys.length > 0) {\n const pathParams = route.keys.map((key: string) => ({\n name: key,\n in: \"path\",\n required: true,\n schema: { type: \"string\" }\n }));\n const existingParams = operation.parameters || [];\n const mergedParams = [...existingParams];\n\n pathParams.forEach(p => {\n const idx = mergedParams.findIndex(ep => ep.in === 'path' && ep.name === p.name);\n if (idx >= 0) {\n mergedParams[idx] = deepMerge(mergedParams[idx], p);\n } else {\n mergedParams.push(p);\n }\n });\n operation.parameters = mergedParams;\n }\n\n // Runtime analysis\n const { inferredSpec } = analyzeHandler(route.handler);\n if (inferredSpec) {\n if (inferredSpec.parameters) {\n const existingParams = operation.parameters || [];\n const mergedParams = [...existingParams];\n\n for (const p of inferredSpec.parameters) {\n const idx = mergedParams.findIndex((ep: any) => ep.name === p.name && ep.in === p.in);\n if (idx >= 0) {\n mergedParams[idx] = deepMerge(mergedParams[idx], p);\n } else {\n mergedParams.push(p);\n }\n }\n operation.parameters = mergedParams;\n delete inferredSpec.parameters;\n }\n deepMerge(operation, inferredSpec);\n }\n\n if (route.handlerSpec) {\n deepMerge(operation, route.handlerSpec);\n }\n\n if (!operation.tags || operation.tags.length === 0) operation.tags = [tag];\n\n if (operation.tags) {\n operation.tags = Array.from(new Set(operation.tags));\n for (const t of operation.tags) {\n if (!tagGroups.has(routeGroup)) tagGroups.set(routeGroup, new Set());\n tagGroups.get(routeGroup)?.add(t);\n }\n }\n\n const methodLower = route.method.toLowerCase();\n if (methodLower === \"all\") {\n [\"get\", \"post\", \"put\", \"delete\", \"patch\"].forEach(m => {\n if (!paths[fullPath][m]) paths[fullPath][m] = { ...operation };\n });\n } else {\n paths[fullPath][methodLower] = operation;\n }\n }\n\n const controllers = router[$childControllers];\n for (const controller of controllers) {\n const controllerName = controller.constructor.name || \"UnknownController\";\n tagGroups.get(group)?.add(controllerName);\n }\n\n const childRouters = router[$childRouters];\n for (const child of childRouters) {\n const mountPath = child[$mountPath];\n const cleanPrefix = prefix.endsWith(\"/\") ? prefix.slice(0, -1) : prefix;\n const cleanMount = mountPath.startsWith(\"/\") ? mountPath : \"/\" + mountPath;\n const nextPrefix = (cleanPrefix + cleanMount) || \"/\";\n // Pass false for isRootLevel since these are child routers\n collect(child, nextPrefix, group, tag, [...inheritedMiddleware, ...routerMiddleware], false);\n }\n };\n\n collect(rootRouter);\n\n const xTagGroups: { name: string; tags: string[]; }[] = [];\n for (const [name, tags] of tagGroups.entries()) {\n xTagGroups.push({ name, tags: Array.from(tags).sort() });\n }\n\n\n // Add virtual middleware paths (if middleware tracking is active)\n if (!options.compliant) {\n for (const [id, mw] of Object.entries(astMiddlewareRegistry || {}) as any[]) {\n const virtualPath = `/_middleware/${id}`;\n paths[virtualPath] = {\n get: {\n tags: ['System', 'Middleware'],\n summary: `Middleware: ${mw.name}`,\n description: `Virtual endpoint for middleware analysis.\n**File**: ${mw.file}\n**Line**: ${mw.startLine}`,\n operationId: `getMiddleware_${id}`,\n parameters: [],\n responses: {\n '200': {\n description: \"Middleware Analysis\",\n content: {\n 'application/json': {\n schema: { type: 'object' }\n }\n }\n }\n },\n 'x-middleware-metadata': mw,\n 'x-virtual': true,\n 'x-middleware-detail': true,\n 'x-source-info': {\n file: mw.file,\n line: mw.startLine,\n code: mw.snippet\n },\n \"x-shokupan-source\": {\n file: mw.file,\n line: mw.startLine,\n code: mw.snippet\n }\n }\n };\n }\n }\n\n const spec: any = {\n openapi: \"3.1.0\",\n info: { title: \"Shokupan API\", version: \"1.0.0\", ...options.info },\n paths,\n components: options.components,\n servers: options.servers,\n tags: options.tags,\n externalDocs: options.externalDocs,\n \"x-tagGroups\": xTagGroups,\n \"x-middleware-registry\": astMiddlewareRegistry\n };\n\n if (options.compliant) {\n spec[\"x-tagGroups\"] = undefined;\n spec[\"x-middleware-registry\"] = undefined;\n\n // Recursive strip function\n const stripExtensions = (obj: any) => {\n if (!obj || typeof obj !== 'object') return;\n if (Array.isArray(obj)) {\n obj.forEach(stripExtensions);\n return;\n }\n for (const key of Object.keys(obj)) {\n if (key.startsWith('x-')) {\n delete obj[key];\n } else {\n stripExtensions(obj[key]);\n }\n }\n };\n\n stripExtensions(spec);\n }\n\n return spec;\n}\n\n","import { Eta } from 'eta';\nimport { readdir, readFile, stat } from 'fs/promises';\nimport { basename, join, resolve, sep } from 'path';\nimport type { ShokupanContext } from '../../context';\nimport type { Middleware, StaticServeOptions } from '../../util/types';\n\nconst eta = new Eta();\n\nexport function serveStatic<T extends Record<string, any>>(config: StaticServeOptions<T>, prefix: string) {\n const rootPath = resolve(config.root || \".\");\n const normalizedPrefix = prefix.endsWith('/') && prefix !== '/' ? prefix.slice(0, -1) : prefix;\n\n const serveStaticMiddleware: Middleware = async (ctx: ShokupanContext<any>) => {\n // 1. Calculate relative path\n // ctx.path is full path.\n // If prefix is /static, and path is /static/foo.css, relative is /foo.css\n let relative = ctx.path.slice(normalizedPrefix.length);\n if (!relative.startsWith('/') && relative.length > 0) relative = '/' + relative;\n if (relative.length === 0) relative = '/';\n\n // Security: Check for null bytes BEFORE decoding\n if (relative.includes('\\0')) {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n\n // Decode URI components\n try {\n relative = decodeURIComponent(relative);\n } catch (e) {\n // Invalid URL encoding\n return ctx.json({ error: 'Bad Request' }, 400);\n }\n\n // Security: Check for null bytes AFTER decoding\n if (relative.includes('\\0')) {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n\n // Security: Check for directory traversal patterns\n if (relative.includes('../') || relative.includes('..\\\\')) {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n\n // Security: Prevent directory traversal with proper path normalization\n const requestPath = resolve(join(rootPath, relative));\n const normalizedRoot = resolve(rootPath);\n\n // Ensure the resolved path is within the root directory\n // Use separator to prevent partial matching (e.g., /var/www vs /var/www-evil)\n if (!requestPath.startsWith(normalizedRoot + sep) && requestPath !== normalizedRoot) {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n\n // Hooks: onRequest\n if (config.hooks?.onRequest) {\n const res = await config.hooks.onRequest(ctx);\n if (res) return res;\n }\n\n // Check Excludes\n if (config.exclude) {\n for (let i = 0; i < config.exclude.length; i++) {\n const pattern = config.exclude[i];\n if (pattern instanceof RegExp) {\n if (pattern.test(relative)) return ctx.json({ error: 'Forbidden' }, 403);\n } else if (typeof pattern === 'string') {\n if (relative.includes(pattern)) return ctx.json({ error: 'Forbidden' }, 403);\n }\n }\n }\n\n // Dotfiles\n if (basename(requestPath).startsWith('.')) {\n const behavior = config.dotfiles || 'ignore';\n if (behavior === 'deny') return ctx.json({ error: 'Forbidden' }, 403);\n if (behavior === 'ignore') return ctx.json({ error: 'Not Found' }, 404);\n }\n\n let finalPath = requestPath;\n let stats;\n\n try {\n stats = await stat(requestPath);\n } catch (e) {\n // Path not found. Try extensions.\n if (config.extensions) {\n for (let i = 0; i < config.extensions.length; i++) {\n const ext = config.extensions[i];\n const p = requestPath + (ext.startsWith('.') ? ext : '.' + ext);\n try {\n const s = await stat(p);\n if (s.isFile()) {\n finalPath = p;\n stats = s;\n break;\n }\n } catch { }\n }\n }\n if (!stats) return ctx.json({ error: 'Not Found' }, 404);\n }\n\n // Directory handling\n if (stats.isDirectory()) {\n // Return 302 Redirect to add trailing slash if missing and not root\n // This ensures relative paths in served files work correctly.\n if (!ctx.path.endsWith('/')) {\n const query = ctx.url.search;\n return ctx.redirect(ctx.path + '/' + query, 302);\n }\n\n // Try indexes\n let indexes: string[] = [];\n if (config.index === undefined) {\n indexes = ['index.html', 'index.htm'];\n }\n else if (Array.isArray(config.index)) {\n indexes = config.index;\n }\n else if (config.index) {\n indexes = [config.index];\n }\n\n let foundIndex = false;\n for (let i = 0; i < indexes.length; i++) {\n const idx = indexes[i];\n const idxPath = join(finalPath, idx);\n try {\n const idxStats = await stat(idxPath);\n if (idxStats.isFile()) {\n finalPath = idxPath;\n foundIndex = true;\n break;\n }\n } catch { }\n }\n\n if (!foundIndex) {\n if (config.listDirectory) {\n // List directory\n try {\n const files = await readdir(requestPath);\n // Simple HTML listing\n const listing = eta.renderString(`\n <!DOCTYPE html>\n <html>\n <head>\n <title>Index of <%= it.relative %></title>\n <style>\n body { font-family: system-ui, -apple-system, sans-serif; padding: 2rem; max-width: 800px; margin: 0 auto; }\n ul { list-style: none; padding: 0; }\n li { padding: 0.5rem 0; border-bottom: 1px solid #eee; }\n a { text-decoration: none; color: #0066cc; }\n a:hover { text-decoration: underline; }\n h1 { font-size: 1.5rem; margin-bottom: 1rem; }\n </style>\n </head>\n <body>\n <h1>Index of <%= it.relative %></h1>\n <ul>\n <% if (it.relative !== '/') { %>\n <li><a href=\"../\">../</a></li>\n <% } %>\n <% it.files.forEach(function(f) { %>\n <li><a href=\"<%= f %>\"><%= f %></a></li>\n <% }) %>\n </ul>\n </body>\n </html>\n `, { relative, files, join });\n return new Response(listing, { headers: { 'Content-Type': 'text/html' } });\n } catch (e) {\n return ctx.json({ error: 'Internal Server Error' }, 500);\n }\n } else {\n // If no index and no listing, it's 404 or 403. typically 404/403.\n // Nginx returns 403 Forbidden.\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n }\n }\n\n // Serving File\n // @ts-ignore\n let response: Response;\n\n if (typeof Bun !== \"undefined\") {\n response = new Response(Bun.file(finalPath));\n } else {\n // Node.js fallback using fs\n const fileBuffer = await readFile(finalPath, { encoding: 'binary' });\n\n // Set content-type from fileOptions if provided\n // if (fileOptions?.type) {\n // headers.set('content-type', fileOptions.type);\n // }\n\n response = new Response(fileBuffer);\n }\n\n if (config.hooks?.onResponse) {\n const hooked = await config.hooks.onResponse(ctx, response);\n if (hooked) response = hooked;\n }\n return response;\n };\n\n serveStaticMiddleware.isBuiltin = true;\n serveStaticMiddleware.pluginName = 'ServeStatic';\n\n return serveStaticMiddleware;\n}\n","\n/**\n * Simple Dependency Injection Container\n */\nexport class Container {\n private static services = new Map<any, any>();\n\n public static register<T>(target: new (...args: any[]) => T, instance: T) {\n this.services.set(target, instance);\n }\n\n public static get<T>(target: new (...args: any[]) => T): T | undefined {\n return this.services.get(target);\n }\n\n public static has(target: any): boolean {\n return this.services.has(target);\n }\n\n public static resolve<T>(target: new (...args: any[]) => T): T {\n if (this.services.has(target)) {\n return this.services.get(target);\n }\n\n // Auto-instantiate if possible (transient)\n // Note: For full DI we would read constructor params here using 'design:paramtypes'\n // But Bun/Esbuild need distinct config for that.\n // For now, we assume simple instantiation or manual registration.\n const instance = new target();\n this.services.set(target, instance);\n return instance;\n }\n}\n\n/**\n * Decorator to mark a class as injectable (Service).\n */\nexport function Injectable() {\n return (target: any) => {\n // Just a marker for now, or could auto-register\n };\n}\n\n/**\n * Property Decorator: Injects a service.\n */\nexport function Inject(token: any) {\n return (target: any, key: string) => {\n Object.defineProperty(target, key, {\n get: () => Container.resolve(token),\n enumerable: true,\n configurable: true\n });\n };\n}\n","import { SpanKind, SpanStatusCode, trace } from \"@opentelemetry/api\";\nimport type { Middleware, ShokupanHandler } from \"./types\";\n\nconst tracer = trace.getTracer(\"shokupan.middleware\");\n\n/**\n * Wraps a middleware function with an OpenTelemetry span.\n */\nexport function traceMiddleware(fn: Middleware, name?: string): Middleware {\n const middlewareName = name || fn.name || \"anonymous middleware\";\n\n return async (ctx, next) => {\n return tracer.startActiveSpan(`middleware - ${middlewareName}`, {\n kind: SpanKind.INTERNAL,\n attributes: {\n \"code.function\": middlewareName,\n \"component\": \"shokupan.middleware\"\n }\n }, async (span) => {\n try {\n const result = await fn(ctx, next);\n return result;\n }\n catch (err: any) {\n span.recordException(err);\n span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });\n throw err;\n }\n finally {\n span.end();\n }\n });\n };\n}\n\n/**\n * Wraps a route handler with an OpenTelemetry span.\n */\nexport function traceHandler(fn: ShokupanHandler | ((...args: any[]) => any), name: string): ShokupanHandler {\n return async function (this: any, ...args: any[]) {\n return tracer.startActiveSpan(`route handler - ${name}`, {\n kind: SpanKind.INTERNAL,\n attributes: {\n \"http.route\": name,\n \"component\": \"shokupan.route\"\n }\n }, async (span) => {\n try {\n const result = await (fn as Function).apply(this, args);\n return result;\n }\n catch (err: any) {\n span.recordException(err);\n span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });\n throw err;\n }\n finally {\n span.end();\n }\n });\n };\n}\n","/**\n * Captures the file and line number of the caller.\n * Use skipFrames to skip helper functions in the stack trace.\n */\nexport function getCallerInfo(skipFrames = 1): { file: string; line: number; } {\n let file = 'unknown';\n let line = 0;\n\n try {\n const err = new Error();\n const stack = err.stack?.split('\\n') || [];\n\n // Skip Error line and requested frames\n // Bun stack traces usually look like:\n // Error\n // at getCallerInfo (...)\n // at callingFunction (...)\n //\n // Standard Bun Stack Line: \"at functionName (/path/to/file.ts:123:45)\" or \"at /path/to/file.ts:123:45\"\n\n let found = 0;\n for (let i = 1; i < stack.length; i++) {\n const l = stack[i];\n\n // Ignore internals\n if (!l.includes(':')) continue; // likely not File:Line context\n if (l.includes('node_modules')) continue;\n if (l.includes('bun:main')) continue;\n if (l.includes('bun:wrap')) continue;\n if (l.includes('src/util/stack.ts')) continue; // Ignore self\n if (l.includes('src/router.ts')) continue; // Ignore router internals\n if (l.includes('src/util/decorators.ts')) continue; // Ignore decorators\n if (l.includes('src/shokupan.ts')) continue; // Ignore framework internals\n\n found++;\n if (found >= skipFrames) {\n // Parse this line\n const match = l.match(/\\((.*):(\\d+):(\\d+)\\)/) || l.match(/at (.*):(\\d+):(\\d+)/);\n if (match) {\n file = match[1];\n // Clean up file path if it has \"async \" prefix or similar if regex was loose,\n // but the regex capture group 1 should be the path.\n // Sometimes match[1] might contain \"functionName (/path...)\" if the regex matched weirdly,\n // but the above regexes look for parenthesis wrap or clean \"at path\".\n\n line = parseInt(match[2], 10);\n return { file, line };\n }\n }\n }\n\n } catch (e) { }\n\n return { file, line };\n}\n","import type { OpenAPI } from '@scalar/openapi-types';\nimport type { Server } from 'bun';\nimport type { Server as NodeServer } from 'node:http';\nimport type { ConnectOptions, Engines } from 'surrealdb';\nimport type { ShokupanContext } from '../context';\nimport { $isRouter } from \"./symbol\";\n\nexport type HeadersInit = Headers | Record<string, string> | [string, string][];\n\nexport interface ShokupanPluginOptions {\n path?: string;\n}\n\nexport interface ShokupanPlugin {\n onInit: (app: any, options?: ShokupanPluginOptions) => void | Promise<void>;\n}\n\nexport type DeepPartial<T> = T extends Function ? T : T extends object ? {\n [P in keyof T]?: DeepPartial<T[P]>;\n} : T;\n\n/**\n * Helper type for applications that don't use ctx.state.\n * Prevents accidental property access on state.\n * \n * @example\n * ```typescript\n * const app = new Shokupan<EmptyState>();\n * ```\n */\nexport type EmptyState = Record<string, never>;\n\n/**\n * Default state type that allows any properties.\n * This is the default if no state type is specified.\n * \n * @example\n * ```typescript\n * const app = new Shokupan<DefaultState>();\n * // Equivalent to: new Shokupan();\n * ```\n */\nexport type DefaultState = Record<string, any>;\n\n// Utility type to extract parameter names from a route path\n// Example: \"/users/:id/posts/:postId\" => { id: string, postId: string }\ntype ParsePathParams<Path extends string> =\n Path extends `${infer _Start}:${infer Param}/${infer Rest}`\n ? { [K in Param | keyof ParsePathParams<`/${Rest}`>]: string }\n : Path extends `${infer _Start}:${infer Param}`\n ? { [K in Param]: string }\n : {};\n\n// Helper type for route parameters\n// Falls back to Record<string, string> if no params are detected\nexport type RouteParams<Path extends string> =\n string extends Path\n ? Record<string, string>\n : ParsePathParams<Path> extends Record<string, never>\n ? Record<string, string>\n : ParsePathParams<Path>;\n\nexport interface RouteMetadata {\n file: string;\n line: number;\n name?: string;\n isBuiltin?: boolean;\n pluginName?: string;\n}\n\nexport type MethodAPISpec = OpenAPI.Operation;\nexport type GuardAPISpec = DeepPartial<OpenAPI.Operation>;\nexport type RouterAPISpec = OpenAPI.Operation & Pick<Required<OpenAPI.Operation>, 'tags'> & { group: string; };\n\nexport interface OpenAPIOptions {\n info?: OpenAPI.Document['info'];\n servers?: OpenAPI.Document['servers'];\n components?: OpenAPI.Document['components'];\n tags?: OpenAPI.Document['tags'];\n externalDocs?: OpenAPI.Document['externalDocs'];\n defaultTagGroup?: string;\n defaultTag?: string;\n /**\n * Whether to generate a strictly compliant OpenAPI spec (stripping x- extensions).\n * @default false\n */\n compliant?: boolean;\n /**\n * Array to collect warnings during generation.\n */\n warnings?: any[];\n}\n\nexport interface AsyncAPIOptions {\n info?: {\n title: string;\n version: string;\n description?: string;\n };\n defaultTag?: string;\n /**\n * Array to collect warnings during generation.\n */\n warnings?: any[];\n}\n\nexport interface AsyncAPISpec {\n type?: 'publish' | 'subscribe';\n summary?: string;\n description?: string;\n tags?: string[];\n message?: {\n name?: string;\n title?: string;\n summary?: string;\n payload?: any;\n headers?: any;\n };\n}\n\nexport interface ShokupanHooks<T = any> {\n onError?: (ctx: ShokupanContext<T>, error: unknown) => void | Promise<void>;\n onRequestStart?: (ctx: ShokupanContext<T>) => void | Promise<void>;\n onRequestEnd?: (ctx: ShokupanContext<T>) => void | Promise<void>;\n onResponseStart?: (ctx: ShokupanContext<T>, response: Response) => void | Promise<void>;\n onResponseEnd?: (ctx: ShokupanContext<T>, response: Response) => void | Promise<void>;\n beforeValidate?: (ctx: ShokupanContext<T>, data: any) => void | Promise<void>;\n afterValidate?: (ctx: ShokupanContext<T>, data: any) => void | Promise<void>;\n onReadTimeout?: (ctx: ShokupanContext<T>) => void | Promise<void>;\n onWriteTimeout?: (ctx: ShokupanContext<T>) => void | Promise<void>;\n onRequestTimeout?: (ctx: ShokupanContext<T>) => void | Promise<void>;\n}\n\nexport interface CookieOptions {\n maxAge?: number;\n expires?: Date;\n httpOnly?: boolean;\n secure?: boolean;\n domain?: string;\n path?: string;\n sameSite?: boolean | 'lax' | 'strict' | 'none' | 'Lax' | 'Strict' | 'None';\n priority?: 'low' | 'medium' | 'high' | 'Low' | 'Medium' | 'High';\n}\n\n\nexport type ShokupanHandler<\n State extends Record<string, any> = Record<string, any>,\n Params extends Record<string, string> = Record<string, string>\n> = ((ctx: ShokupanContext<State, Params>, next?: NextFn) => Promise<any> | any) & { originalHandler?: ShokupanHandler<State, Params>; };\nexport const HTTPMethods = [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"HEAD\", \"OPTIONS\", \"ALL\"];\nexport type Method = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"OPTIONS\" | \"HEAD\" | \"ALL\";\n\nexport enum RouteParamType {\n BODY = \"BODY\",\n PARAM = \"PARAM\",\n QUERY = \"QUERY\",\n HEADER = \"HEADER\",\n REQUEST = \"REQUEST\",\n CONTEXT = \"CONTEXT\"\n}\n\nexport interface ServerFactory {\n (options: any): Server<any> | Promise<Server<any>> | NodeServer | Promise<NodeServer>;\n}\n\nexport type NextFn = () => Promise<any>;\nexport type Middleware = ((ctx: ShokupanContext<unknown>, next: NextFn) => Promise<any> | any) & {\n isBuiltin?: boolean;\n pluginName?: string;\n metadata?: RouteMetadata;\n order?: number;\n};\nexport type JSXRenderer = (element: any, args?: unknown) => string | Promise<string>;\n\nexport type ShokupanRouteConfig = DeepPartial<{\n name: string;\n group: string;\n /**\n * Timeout for this specific route (milliseconds).\n */\n requestTimeout: number;\n openapi: DeepPartial<OpenAPI.Operation>;\n /**\n * Custom renderer for this route.\n */\n renderer: JSXRenderer;\n\n /**\n * Hooks for this route/router.\n */\n hooks: ShokupanHooks | ShokupanHooks[];\n /**\n * Whether to enforce that only controller classes (constructors) are accepted by the router.\n * @default false\n */\n controllersOnly: boolean;\n\n /**\n * Whether to enable automatic backpressure based on system CPU load.\n * @default false\n */\n autoBackpressureFeedback: boolean;\n /**\n * The CPU usage percentage threshold (0-100) at which to start rejecting requests.\n */\n autoBackpressureLevel: number;\n}>;\n\nexport type ShokupanRoute = {\n /**\n * HTTP method\n */\n method: Method;\n /**\n * Route path\n */\n path: string;\n /**\n * Compiled regex for the route\n */\n regex: RegExp;\n /**\n * Route parameters\n */\n keys: string[];\n /**\n * Route handler\n */\n handler: ShokupanHandler;\n /**\n * Optimization: Handler with hooks baked in.\n * Used by runtime router, while `handler` is used by OpenAPI generator.\n */\n bakedHandler?: ShokupanHandler;\n /**\n * OpenAPI spec for the route\n */\n handlerSpec?: MethodAPISpec | AsyncAPISpec;\n /**\n * Group for the route\n */\n group?: string;\n /**\n * Guards for the route\n */\n guards?: {\n /**\n * Guard handler\n */\n handler: ShokupanHandler;\n /**\n * Guard OpenAPI spec\n */\n spec?: GuardAPISpec;\n }[];\n /**\n * Timeout for this specific route (milliseconds).\n */\n requestTimeout?: number;\n /**\n * Custom JSX renderer for this route.\n */\n renderer?: JSXRenderer;\n /**\n * Hooks from the router/route definition\n */\n hooks?: ShokupanHooks;\n /**\n * Source metadata\n */\n metadata?: RouteMetadata;\n /**\n * Order of the middleware\n */\n order?: number;\n /**\n * Controller instance this route belongs to\n */\n controller?: any;\n /**\n * Middleware stack metadata for this route (Controller/Method level)\n */\n middleware?: Middleware[];\n};\n\nexport type ShokupanConfig<T extends Record<string, any> = Record<string, any>> = Partial<{\n /**\n * The port to be used for the server.\n * @default 3000\n */\n port: number;\n /**\n * The hostname to be used for the server.\n * @default \"localhost\"\n */\n hostname: string;\n /**\n * Whether to run in development mode.\n * @default process.env.NODE_ENV !== \"production\"\n */\n development: boolean;\n /**\n * Whether to enable AsyncLocalStorage.\n * (Request local storage)\n * @default false\n */\n enableAsyncLocalStorage: boolean;\n /**\n * Whether to enable OpenAPI generation.\n * @default true\n */\n enableOpenApiGen: boolean;\n /**\n * Whether to block server startup until OpenAPI generation completes.\n * Only applies when enableOpenApiGen is true.\n * When false, OpenAPI generation happens asynchronously in the background.\n * @default true\n */\n blockOnOpenApiGen: boolean;\n /**\n * Whether to enable AsyncAPI generation.\n * @default false\n */\n enableAsyncApiGen: boolean;\n /**\n * Whether to block server startup until AsyncAPI generation completes.\n * Only applies when enableAsyncApiGen is true.\n * When false, AsyncAPI generation happens asynchronously in the background.\n * @default true\n */\n blockOnAsyncApiGen: boolean;\n /**\n * Whether to reuse the port.\n * @default false\n */\n reusePort: boolean;\n /**\n * Whether to enforce that only controller classes (constructors) are accepted by the router.\n * @default false\n */\n controllersOnly: boolean;\n /**\n * Whether to enable OpenTelemetry tracing.\n * @default false\n */\n enableTracing?: boolean;\n\n /**\n * JSON parser to use for parsing request bodies.\n * \n * Options:\n * - `'native'`: Use the built-in JSON.parse (fastest, default)\n * - `'parse-json'`: Use the parse-json library for better error messages with minimal performance overhead (~5% slower than native)\n * - `'secure-json-parse'`: Use secure-json-parse for protection against prototype pollution (20-30% slower than native)\n * \n * Performance implications based on benchmarks:\n * - `native`: Fastest option, excellent for production\n * - `parse-json`: Nearly identical performance to native with better error messages, good for development\n * - `secure-json-parse`: Provides security at the cost of performance, use only for untrusted input\n * \n * @default 'native'\n */\n jsonParser?: 'native' | 'parse-json' | 'secure-json-parse';\n\n /**\n * Whether to enable automatic backpressure based on system CPU load.\n * @default false\n */\n autoBackpressureFeedback?: boolean;\n /**\n * The CPU usage percentage threshold (0-100) at which to start rejecting requests (429).\n * @default 60\n */\n autoBackpressureLevel?: number;\n\n /**\n * Whether to enable middleware and handler tracking.\n * When enabled, `ctx.handlerStack` will be populated with the handlers the request has passed through.\n * Also, `ctx.state` will be a Proxy that tracks changes made by each handler.\n * @default false\n */\n enableMiddlewareTracking: boolean;\n /**\n * Maximum number of middleware executions to store in the datastore.\n * Only applies when enableMiddlewareTracking is true.\n * @default 10000\n */\n middlewareTrackingMaxCapacity?: number;\n /**\n * Whether to enable the HTTP bridge for WebSocket.\n * This enables websocket messages to run through the HTTP server.\n * e.g. \n * ```json\n * {\n * \"method\": \"POST\",\n * \"path\": \"/api/v1/myHttpEndpoint\",\n * \"headers\": {},\n * \"body\": {\n * \"type\": \"text\",\n * \"data\": \"Hello, world!\"\n * }\n * }\n * ```\n * @default false\n */\n enableHTTPBridge?: boolean;\n /**\n * Handler for WebSocket events that throw an exception.\n */\n websocketErrorHandler?: (err: any, ctx: ShokupanContext<T>) => void | Promise<void>;\n /**\n * Unique ID generator function for requests.\n * @default nanoid\n */\n idGenerator?: () => string;\n /**\n * Time-to-live for middleware tracking entries in milliseconds.\n * Entries older than this will be cleaned up.\n * Only applies when enableMiddlewareTracking is true.\n * @default 86400000 (1 day)\n */\n middlewareTrackingTTL?: number;\n /**\n * HTTP logger function.\n */\n httpLogger: (ctx: ShokupanContext<T>) => void;\n /**\n * Logger object.\n */\n logger: {\n verbose: boolean;\n info: (msg: string, props: Record<string, any>) => void;\n debug: (msg: string, props: Record<string, any>) => void;\n warning: (msg: string, props: Record<string, any>) => void;\n error: (msg: string, props: Record<string, any>) => void;\n /**\n * Something fatally went wrong and the application cannot continue.\n */\n fatal: (msg: string, props: Record<string, any>) => void;\n };\n /**\n * Timeout for reading the request body (milliseconds).\n * Maps to Bun's `idleTimeout`.\n * @default 30000\n */\n readTimeout: number;\n /**\n * Timeout for processing the request (milliseconds).\n * Maps to `server.timeout(req, seconds)`.\n * @default 0 (disabled)\n */\n requestTimeout: number;\n /**\n * Timeout for writing the response (milliseconds).\n * Not currently supported by Bun.serve natively.\n * @experimental\n */\n writeTimeout: number;\n\n /**\n * JSX Rendering function.\n */\n renderer: JSXRenderer;\n\n /**\n * Factory function to create the server instance.\n * Defaults to Bun.serve.\n * @deprecated Use `adapter` instead.\n */\n serverFactory: ServerFactory;\n\n /**\n * The server adapter to use.\n * overrides `serverFactory`.\n */\n adapter?: 'bun' | 'node' | 'wintercg' | import('./adapter/adapters').ServerAdapter;\n\n /**\n * The file system adapter to use for `ctx.file`.\n */\n fileSystem?: import('./adapter/filesystem').FileSystemAdapter;\n\n /**\n * Lifecycle hooks.\n */\n hooks: ShokupanHooks<T> | ShokupanHooks<T>[];\n\n /**\n * Whether to validate response status codes.\n * @default true\n */\n validateStatusCodes: boolean;\n\n /**\n * Configuration for SurrealDB.\n */\n surreal?: {\n /**\n * SurrealDB engines.\n * @default Embedded\n */\n engines?: Engines;\n /**\n * SurrealDB connection URL.\n * @default 'rocksdb://database'\n */\n url?: string;\n /**\n * SurrealDB connection options.\n */\n connectOptions?: ConnectOptions;\n /**\n * SurrealDB namespace.\n */\n namespace?: string;\n /**\n * SurrealDB database.\n */\n database?: string;\n };\n\n /**\n * Configuration for the AI Plugin manifest (.well-known/ai-plugin.json).\n * If enabled, Shokupan will serve the manifest at the standard location.\n */\n aiPlugin?: {\n enabled?: boolean;\n name_for_human?: string;\n name_for_model?: string;\n description_for_human?: string;\n description_for_model?: string;\n auth?: {\n type: 'none' | 'service_http' | 'user_http' | 'oauth';\n [key: string]: any;\n };\n api?: {\n type: 'openapi';\n url?: string;\n is_user_authenticated?: boolean;\n };\n logo_url?: string;\n contact_email?: string;\n legal_info_url?: string;\n };\n\n /**\n * Configuration for the API Catalog (.well-known/api-catalog).\n * If enabled, Shokupan will serve the catalog at the standard location.\n */\n apiCatalog?: {\n enabled?: boolean;\n versions?: Array<{\n name: string;\n url: string;\n spec_url: string;\n }>;\n };\n\n /**\n * Any other config options are allowed, but will be ignored. \n * @deprecated\n */\n [key: string]: any;\n}>;\n\n\nexport interface RequestOptions {\n path?: string;\n url?: string;\n method?: Method;\n headers?: Record<string, string>;\n body?: any;\n query?: Record<string, string>;\n}\n\nexport interface ProcessResult {\n status: number;\n headers: Record<string, string>;\n data: any;\n}\n\nexport type ShokupanController<T = any> = (new (...args: any[]) => T) & {\n [$isRouter]?: undefined;\n};\n\nexport interface StaticServeHooks<T extends Record<string, any>> {\n onRequest?: (ctx: ShokupanContext<T>) => Promise<Response | void> | Response | void;\n onResponse?: (ctx: ShokupanContext<T>, response: Response) => Promise<Response> | Response;\n}\n\nexport interface StaticServeOptions<T extends Record<string, any>> {\n /**\n * Root directory to serve files from.\n * Can be an absolute path or relative to the CWD.\n */\n root?: string;\n /**\n * Whether to list directory contents if no index file is found.\n * \n * Security Note: Directory listing is disabled by default to prevent information disclosure.\n * Enable this only if you specifically need it and understand the security implications.\n * \n * @default false\n */\n listDirectory?: boolean;\n /**\n * Index file(s) to look for when a directory is requested.\n * @default ['index.html', 'index.htm']\n */\n index?: string | string[];\n /**\n * Hooks to intercept requests/responses.\n */\n hooks?: StaticServeHooks<T>;\n /**\n * How to treat dotfiles (files starting with .)\n * 'allow': Serve them\n * 'deny': Return 403\n * 'ignore': Return 404\n * @default 'ignore'\n */\n dotfiles?: 'allow' | 'deny' | 'ignore';\n /**\n * Regex or glob patterns to exclude\n */\n exclude?: (string | RegExp)[];\n /**\n * Try to append these extensions to the path if the file is not found.\n * e.g. ['html', 'htm']\n */\n extensions?: string[];\n /**\n * OpenAPI specification for the static route.\n */\n openapi?: MethodAPISpec;\n}\n","\nimport { ShokupanContext } from '../context';\nimport { compose } from '../middleware';\nimport type { ShokupanRouter } from '../router';\nimport { Container } from './di';\nimport { traceHandler } from './instrumentation';\nimport { getCallerInfo } from './stack';\nimport {\n $controllerPath,\n $eventMethods,\n $isMounted,\n $middleware,\n $mountPath,\n $routeArgs,\n $routeMethods,\n $routeSpec\n} from './symbol';\nimport { HTTPMethods, type Method, RouteParamType } from './types';\n\nexport class ControllerScanner {\n public static scan<T extends Record<string, any>>(router: ShokupanRouter<T>, prefix: string, controller: any) {\n let instance = controller;\n if (typeof controller === 'function') {\n // DI Resolution\n instance = Container.resolve(controller as any);\n\n // Controller Parameter Decorator (@Controller('prefix'))\n const controllerPath = (controller as any)[$controllerPath];\n if (controllerPath !== undefined) {\n // Combine mount prefix + controller path\n const p1 = prefix.endsWith(\"/\") ? prefix.slice(0, -1) : prefix;\n const p2 = controllerPath.startsWith(\"/\") ? controllerPath : \"/\" + controllerPath;\n prefix = (p1 + p2);\n // Normalize\n if (!prefix) prefix = \"/\";\n }\n }\n else {\n // Controller is an instance, read metadata from constructor\n const ctor = instance.constructor;\n const controllerPath = (ctor as any)[$controllerPath];\n if (controllerPath !== undefined) {\n const p1 = prefix.endsWith(\"/\") ? prefix.slice(0, -1) : prefix;\n const p2 = controllerPath.startsWith(\"/\") ? controllerPath : \"/\" + controllerPath;\n prefix = (p1 + p2);\n if (!prefix) prefix = \"/\";\n }\n }\n\n instance[$mountPath] = prefix;\n\n // Capture metadata for controller instance\n const info = getCallerInfo();\n (instance as any).metadata = {\n file: info.file,\n line: info.line,\n name: instance.constructor.name\n };\n\n router.registerControllerInstance(instance);\n\n // Get Middleware for Controller\n const controllerMiddleware = (typeof controller === 'function' ? (controller as any)[$middleware] : (instance as any)[$middleware]) || [];\n\n // Get all method names from the prototype (for classes)\n const proto = Object.getPrototypeOf(instance);\n const methods = new Set<string>();\n\n // Scan prototype chain\n let current = proto;\n while (current !== undefined && current !== Object.prototype) {\n Object.getOwnPropertyNames(current).forEach(name => methods.add(name));\n current = Object.getPrototypeOf(current);\n }\n // Also scan own properties (for objects or bound methods)\n Object.getOwnPropertyNames(instance).forEach(name => methods.add(name));\n\n const decoratedRoutes = (instance as any)[$routeMethods] || (proto && (proto as any)[$routeMethods]);\n const decoratedArgs = (instance as any)[$routeArgs] || (proto && (proto as any)[$routeArgs]);\n const methodMiddlewareMap = (instance as any)[$middleware] || (proto && (proto as any)[$middleware]);\n const decoratedEvents = (instance as any)[$eventMethods] || (proto && (proto as any)[$eventMethods]);\n\n let routesAttached = 0;\n for (let i = 0; i < Array.from(methods).length; i++) {\n const name = Array.from(methods)[i];\n if (name === \"constructor\") continue;\n if ([\"arguments\", \"caller\", \"callee\"].includes(name)) continue;\n\n const originalHandler = (instance as any)[name];\n if (typeof originalHandler !== \"function\") continue;\n\n let method: Method | undefined;\n let subPath = \"\";\n\n // 1. Check for Decorator Metadata\n let methodSource: { file: string, line: number; } | undefined;\n\n const routeConfig = decoratedRoutes?.get(name);\n if (routeConfig !== undefined) {\n method = routeConfig.method;\n subPath = routeConfig.path;\n methodSource = routeConfig.source;\n }\n // 2. Fallback to Convention\n else {\n // Check if name starts with HTTP verb\n for (let j = 0; j < HTTPMethods.length; j++) {\n const m = HTTPMethods[j];\n if (name.toUpperCase().startsWith(m)) {\n method = m as Method;\n const rest = name.slice(m.length);\n if (rest.length === 0) {\n subPath = \"/\";\n }\n else {\n subPath = \"\";\n let buffer = \"\";\n const flush = () => {\n if (buffer.length > 0) {\n subPath += \"/\" + buffer.toLowerCase();\n buffer = \"\";\n }\n };\n for (let i = 0; i < rest.length; i++) {\n const char = rest[i];\n if (char === \"$\") {\n flush();\n subPath += \"/:\";\n continue;\n }\n buffer += char;\n }\n if (buffer.length > 0) flush();\n\n subPath = rest\n .replace(/\\$/g, \"/:\") // $id -> /:id\n .replace(/([a-z0-9])([A-Z])/g, \"$1/$2\") // camelCase -> camel/Case\n .toLowerCase();\n\n if (!subPath.startsWith(\"/\")) {\n subPath = \"/\" + subPath;\n }\n }\n break;\n }\n }\n }\n\n // Skip empty methods\n if (method !== undefined && (method as any) !== '') {\n routesAttached++;\n const cleanPrefix = prefix.endsWith(\"/\") ? prefix.slice(0, -1) : prefix;\n const cleanSubPath = subPath === \"/\" ? \"\" : subPath;\n\n let joined: string;\n if (cleanSubPath.length === 0) {\n joined = cleanPrefix;\n }\n else if (cleanSubPath.startsWith(\"/\")) {\n joined = cleanPrefix + cleanSubPath;\n }\n else {\n joined = cleanPrefix + \"/\" + cleanSubPath;\n }\n\n const fullPath = joined || \"/\";\n const normalizedPath = fullPath.replace(/\\/+/g, \"/\");\n\n // -- Compose Handler with Middleware and Param Resolution --\n const methodMw = (methodMiddlewareMap instanceof Map) ? (methodMiddlewareMap.get(name) || []) : [];\n const allMiddleware = [...controllerMiddleware, ...methodMw];\n\n // Check for Args\n const routeArgs = decoratedArgs && decoratedArgs.get(name);\n\n // Create Wrapper\n const wrappedHandler = async (ctx: ShokupanContext<T>) => {\n // Resolve Arguments\n let args: any[] = [ctx];\n\n if (routeArgs?.length > 0) {\n args = [];\n // Sort by index\n const sortedArgs = [...routeArgs].sort((a: any, b: any) => a.index - b.index);\n\n // Fill args array\n for (let k = 0; k < sortedArgs.length; k++) {\n const arg = sortedArgs[k];\n switch (arg.type) {\n case RouteParamType.BODY:\n args[arg.index] = await ctx.body();\n break;\n case RouteParamType.PARAM:\n args[arg.index] = arg.name ? ctx.params[arg.name] : ctx.params;\n break;\n case RouteParamType.QUERY: {\n const url = new URL(ctx.req.url);\n if (arg.name) {\n const vals = url.searchParams.getAll(arg.name);\n args[arg.index] = vals.length > 1 ? vals : vals[0];\n } else {\n const query: Record<string, any> = {};\n const keys = Object.keys(url.searchParams);\n for (let k = 0; k < keys.length; k++) {\n const key = keys[k];\n const vals = url.searchParams.getAll(key);\n query[key] = vals.length > 1 ? vals : vals[0];\n }\n args[arg.index] = query;\n }\n break;\n }\n case RouteParamType.HEADER:\n args[arg.index] = arg.name ? ctx.req.headers.get(arg.name) : ctx.req.headers;\n break;\n case RouteParamType.REQUEST:\n args[arg.index] = ctx.req;\n break;\n case RouteParamType.CONTEXT:\n args[arg.index] = ctx;\n break;\n }\n }\n }\n\n const tracedOriginalHandler = ctx.app?.applicationConfig.enableTracing\n ? traceHandler(originalHandler, normalizedPath)\n : originalHandler;\n\n return tracedOriginalHandler.apply(instance, args);\n };\n\n // Apply Middleware wrapping\n let finalHandler = wrappedHandler;\n if (allMiddleware.length > 0) {\n const composed = compose(allMiddleware);\n finalHandler = async (ctx) => {\n return composed(ctx, () => wrappedHandler(ctx));\n };\n }\n\n (finalHandler as any).originalHandler = originalHandler;\n if (finalHandler !== wrappedHandler) {\n (wrappedHandler as any).originalHandler = originalHandler;\n }\n\n // Inject Controller Name as Tag\n const tagName = instance.constructor.name;\n\n // Retrieve @Spec metadata\n const decoratedSpecs = (instance as any)[$routeSpec] || (proto && (proto as any)[$routeSpec]);\n const userSpec = decoratedSpecs && decoratedSpecs.get(name);\n\n // Merge with existing spec from decorator if available\n const spec = { tags: [tagName], ...userSpec };\n\n router.add({\n method,\n path: normalizedPath,\n handler: finalHandler,\n spec,\n controller: instance,\n metadata: methodSource || (instance as any).metadata,\n middleware: allMiddleware\n });\n }\n\n // 3. Check for Event Decorator\n const eventConfig = decoratedEvents?.get(name);\n if (eventConfig !== undefined) {\n routesAttached++;\n const routeArgs = decoratedArgs?.get(name);\n\n const wrappedHandler = async (ctx: ShokupanContext<T>) => {\n let args: any[] = [ctx];\n if (routeArgs?.length > 0) {\n args = [];\n const sortedArgs = [...routeArgs].sort((a: any, b: any) => a.index - b.index);\n for (let k = 0; k < sortedArgs.length; k++) {\n const arg = sortedArgs[k];\n switch (arg.type) {\n case RouteParamType.BODY:\n args[arg.index] = await ctx.body();\n break;\n case RouteParamType.CONTEXT:\n args[arg.index] = ctx;\n break;\n case RouteParamType.REQUEST:\n args[arg.index] = ctx.req;\n break;\n case RouteParamType.HEADER:\n args[arg.index] = arg.name ? ctx.req.headers.get(arg.name) : ctx.req.headers;\n break;\n default:\n args[arg.index] = undefined;\n }\n }\n }\n return originalHandler.apply(instance, args);\n };\n\n // Attach metadata to the handler for AsyncAPI generator\n const decoratedSpecs = (instance as any)[$routeSpec] || (proto && (proto as any)[$routeSpec]);\n const userSpec = decoratedSpecs && decoratedSpecs.get(name);\n\n const spec = { tags: [{ name: instance.constructor.name }], ...userSpec };\n (wrappedHandler as any).spec = spec;\n (wrappedHandler as any).originalHandler = originalHandler;\n\n router.event(eventConfig.eventName, wrappedHandler);\n }\n }\n\n if (routesAttached === 0) {\n console.warn(`No routes attached to controller ${instance.constructor.name}`);\n }\n instance[$isMounted] = true;\n }\n}\n","/**\n * Standard HTTP Error class with status code.\n * This standardizes on the `status` property instead of dual `status`/`statusCode`.\n */\nexport class HttpError extends Error {\n public readonly status: number;\n\n constructor(message: string, status: number) {\n super(message);\n this.name = 'HttpError';\n this.status = status;\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, HttpError);\n }\n }\n}\n\n/**\n * Extracts HTTP status code from an error object.\n * Supports both `status` and `statusCode` properties for backward compatibility.\n * Defaults to 500 (Internal Server Error) if no status is found.\n * \n * @param err - Error object (may have `status` or `statusCode` property)\n * @returns HTTP status code\n */\nexport function getErrorStatus(err: any): number {\n // Handle null/undefined\n if (!err || typeof err !== 'object') {\n return 500;\n }\n\n // Prioritize `status` over `statusCode` to encourage standardization\n if (typeof err.status === 'number') {\n return err.status;\n }\n if (typeof err.statusCode === 'number') {\n return err.statusCode;\n }\n // Default to 500 Internal Server Error\n return 500;\n}\n\n/**\n * Common HTTP Errors\n */\n\nexport class BadRequestError extends HttpError {\n constructor(message: string = 'Bad Request') {\n super(message, 400);\n this.name = 'BadRequestError';\n }\n}\n\nexport class UnauthorizedError extends HttpError {\n constructor(message: string = 'Unauthorized') {\n super(message, 401);\n this.name = 'UnauthorizedError';\n }\n}\n\nexport class ForbiddenError extends HttpError {\n constructor(message: string = 'Forbidden') {\n super(message, 403);\n this.name = 'ForbiddenError';\n }\n}\n\nexport class NotFoundError extends HttpError {\n constructor(message: string = 'Not Found') {\n super(message, 404);\n this.name = 'NotFoundError';\n }\n}\n\nexport class InternalServerError extends HttpError {\n constructor(message: string = 'Internal Server Error') {\n super(message, 500);\n this.name = 'InternalServerError';\n }\n}\n\nexport class EventError extends HttpError {\n constructor(message: string = 'Event Error') {\n super(message, 500);\n this.name = 'EventError';\n }\n}\n","\nimport { RecordId } from 'surrealdb';\nimport { ShokupanContext } from '../context';\nimport type { Middleware, ShokupanHandler } from '../util/types';\n\nexport class MiddlewareTracker {\n public static wrap(\n handler: Middleware | ShokupanHandler<any>,\n context: { file: string, line: number, name?: string, isBuiltin?: boolean, pluginName?: string; }\n ): any {\n const { file, line, name, isBuiltin, pluginName } = context;\n const handlerName = name || handler.name || 'anonymous';\n\n const trackedHandler = async (ctx: ShokupanContext<any>, next?: () => Promise<void>) => {\n if (!ctx.app?.applicationConfig.enableMiddlewareTracking) {\n // If tracking disabled, just run\n // Note: This check happens at runtime, but wrapper is applied at registration\n return handler(ctx, next);\n }\n\n const startTime = performance.now();\n let error: any = undefined;\n\n try {\n ctx.handlerStack.push({\n name: handlerName,\n file,\n line,\n isBuiltin,\n startTime,\n duration: -1\n });\n return await handler(ctx, next);\n } catch (e) {\n error = e;\n throw e;\n } finally {\n const duration = performance.now() - startTime;\n\n // Update duration in stack\n const stackItem = ctx.handlerStack[ctx.handlerStack.length - 1];\n if (stackItem && stackItem.name === handlerName) {\n stackItem.duration = duration;\n }\n\n // Async store to DB\n Promise.resolve().then(async () => {\n try {\n const db = ctx.app?.db;\n if (!db) return;\n\n const timestamp = Date.now();\n await db.upsert(new RecordId('middleware_tracking', {\n timestamp,\n name: handlerName\n }), {\n name: handlerName,\n path: ctx.path,\n timestamp,\n duration,\n file,\n line,\n error: error ? String(error) : undefined,\n metadata: {\n isBuiltin,\n pluginName\n }\n });\n\n // Cleanup logic could be moved to a background job or throttled\n // For now we keep it simple or delegate to a separate Cleanup task\n } catch (err) {\n // Ignore\n }\n });\n }\n };\n\n // Preserve metadata\n (trackedHandler as any).metadata = (handler as any).metadata || context;\n Object.defineProperty(trackedHandler, 'name', { value: handlerName });\n (trackedHandler as any).originalHandler = (handler as any).originalHandler || handler;\n\n return trackedHandler;\n }\n}\n","import type { Method } from './types';\n\nexport type ShokupanRequestProps = {\n method: Method;\n url: string;\n headers: Headers | Record<string, string>;\n body: any;\n};\n\n/**\n * This class is used to create a request object.\n * It is used to make requests to the router.\n */\nclass ShokupanRequestBase {\n method: Method;\n url: string;\n headers: Headers;\n body: any;\n\n async json(): Promise<any> { return JSON.parse(this.body); }\n async text(): Promise<string> { return this.body; }\n async formData(): Promise<FormData> {\n if (this.body instanceof FormData) {\n return this.body;\n }\n return new Response(this.body, { headers: this.headers }).formData() as any;\n }\n\n constructor(props: ShokupanRequestProps) {\n Object.assign(this, props);\n if (!(this.headers instanceof Headers)) {\n this.headers = new Headers(this.headers);\n }\n }\n}\n\n/**\n * This type is used to add properties to the request object.\n */\nexport type ShokupanRequest<T> = ShokupanRequestBase & T;\n\ninterface ShokupanConstructor {\n new <T extends Record<string, any>>(props: ShokupanRequestProps): ShokupanRequest<T>;\n}\n\n/**\n * This class is used to create a request object.\n * It is used to make requests to the router.\n */\nexport const ShokupanRequest = ShokupanRequestBase as ShokupanConstructor;\n","import type { Method, ShokupanHandler } from './types';\n\nexport interface RouteMatch<T = any> {\n handler: ShokupanHandler<T>;\n params: Record<string, string>;\n // Reference to the baked handler if strictly needed, \n // but typically we insert the optimal handler (baked) into the trie.\n}\n\ninterface Node<T> {\n // Static path segments\n children: Record<string, Node<T>>;\n\n // Parameter segment (e.g. :id)\n paramChild?: Node<T>;\n paramName?: string;\n\n // Wildcard segment (*)\n wildcardChild?: Node<T>;\n\n // Recursive segment (**)\n recursiveChild?: Node<T>;\n\n // Handlers stored at this node\n handlers?: Record<string, ShokupanHandler<T>>;\n\n // Optional: Keep track of path pattern for debugging\n pathPattern?: string;\n}\n\nexport class RouterTrie<T = any> {\n private root: Node<T>;\n\n constructor() {\n this.root = this.createNode();\n }\n\n private createNode(): Node<T> {\n return {\n children: {},\n };\n }\n\n public insert(method: Method, path: string, handler: ShokupanHandler<T>) {\n let node = this.root;\n const segments = this.splitPath(path);\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n if (segment === '**') {\n if (!node.recursiveChild) {\n node.recursiveChild = this.createNode();\n }\n node = node.recursiveChild;\n }\n else if (segment === '*') {\n if (!node.wildcardChild) {\n node.wildcardChild = this.createNode();\n }\n node = node.wildcardChild;\n }\n else if (segment.startsWith(':')) {\n const paramName = segment.slice(1);\n if (!node.paramChild) {\n node.paramChild = this.createNode();\n node.paramChild.paramName = paramName;\n }\n node = node.paramChild;\n node.paramName = paramName;\n }\n else {\n if (!node.children[segment]) {\n node.children[segment] = this.createNode();\n }\n node = node.children[segment];\n }\n }\n\n if (!node.handlers) {\n node.handlers = {};\n }\n node.handlers[method] = handler;\n }\n\n public search(method: string, path: string): RouteMatch<T> | null {\n const segments = this.splitPath(path);\n const params: Record<string, string> = {};\n\n const match = this.findNode(this.root, segments, 0, params);\n\n if (match && match.handlers) {\n const handler = match.handlers[method] || match.handlers['ALL'];\n if (handler) {\n return { handler, params };\n }\n if (method === 'HEAD' && match.handlers['GET']) {\n return { handler: match.handlers['GET'], params };\n }\n }\n\n return null;\n }\n\n private findNode(node: Node<T>, segments: string[], index: number, params: Record<string, string>): Node<T> | null {\n // Base case: verified all segments\n if (index === segments.length) {\n if (node.handlers) return node;\n\n // If we are at the end, checks if we have a recursive child that matches empty?\n // e.g. /files/** matches /files\n if (node.recursiveChild && node.recursiveChild.handlers) {\n return node.recursiveChild;\n }\n return null;\n }\n\n const segment = segments[index];\n\n // 1. Static Match\n const child = node.children[segment];\n if (child) {\n const result = this.findNode(child, segments, index + 1, params);\n if (result) return result;\n }\n\n // 2. Param Match\n if (node.paramChild) {\n params[node.paramChild.paramName!] = segment;\n const result = this.findNode(node.paramChild, segments, index + 1, params);\n if (result) return result;\n delete params[node.paramChild.paramName!];\n }\n\n // 3. Single Wildcard Match (*)\n if (node.wildcardChild) {\n // Strictly match one segment\n const result = this.findNode(node.wildcardChild, segments, index + 1, params);\n if (result) return result;\n }\n\n // 4. Recursive Wildcard Match (**)\n if (node.recursiveChild) {\n // Greedy or non-greedy?\n // We need to match 'remaining segments' against recursive child.\n // But recursive child is a Node that might have further structure OR be terminal.\n\n // Try matching 0 to N segments.\n // We iterate from N down to 0 (greedy) or 0 to N?\n // Standard is usually longest match wins? Or first match?\n // \"Correct\" catch-all usually means it consumes as much as needed.\n // Let's try consuming k segments.\n\n const remaining = segments.length - index;\n for (let k = 0; k <= remaining; k++) {\n // Skip k segments\n const result = this.findNode(node.recursiveChild, segments, index + k, params);\n if (result) return result;\n }\n }\n\n return null;\n }\n\n private splitPath(path: string): string[] {\n if (path === '/' || path === '') return [];\n const s = path.startsWith('/') ? path.slice(1) : path;\n if (s === '') return [];\n return s.split('/');\n }\n}\n","import { ShokupanContext } from './context';\nimport { compose } from './middleware';\nimport { generateOpenApi } from './plugins/application/openapi/openapi';\nimport { serveStatic } from './plugins/middleware/serve-static';\nimport type { Shokupan } from './shokupan';\nimport { ControllerScanner } from './util/controller-scanner';\nimport type { SurrealDatastore } from './util/datastore';\nimport { EventError, getErrorStatus } from './util/http-error';\nimport { HTTP_STATUS } from './util/http-status';\nimport { MiddlewareTracker } from './util/middleware-tracker';\nimport { ShokupanRequest } from './util/request';\nimport { getCallerInfo } from './util/stack';\nimport { $appRoot, $childControllers, $childRouters, $debug, $dispatch, $isApplication, $isMounted, $isRouter, $mountPath, $parent, $routes } from './util/symbol';\nimport { RouterTrie } from './util/trie';\nimport { type GuardAPISpec, type HeadersInit, type JSXRenderer, type Method, type MethodAPISpec, type Middleware, type OpenAPIOptions, type ProcessResult, type RequestOptions, type RouteMetadata, type RouteParams, type ShokupanController, type ShokupanHandler, type ShokupanHooks, type ShokupanRoute, type ShokupanRouteConfig, type StaticServeOptions } from './util/types';\n\n\nexport const RouterRegistry = new Map<string, ShokupanRouter<any>>();\n\nexport const ShokupanApplicationTree = {};\n\n/**\n * Shokupan Router\n * \n * A router for organizing and grouping routes with shared middleware and configuration.\n * \n * @template State - The shape of `ctx.state` for all routes in this router.\n * Provides type safety for state management within the router's middleware and handlers.\n * \n * @example Basic Router\n * ```typescript\n * const router = new ShokupanRouter();\n * router.get('/users', (ctx) => ctx.json({ users: [] }));\n * \n * app.mount('/api', router);\n * // Routes: GET /api/users\n * ```\n * \n * @example Typed State Router\n * ```typescript\n * interface AuthState {\n * userId: string;\n * isAuthenticated: boolean;\n * }\n * \n * class AuthRouter extends ShokupanRouter<AuthState> {\n * constructor() {\n * super();\n * \n * // Router middleware has typed state\n * this.use((ctx, next) => {\n * ctx.state.userId = 'user-123';\n * ctx.state.isAuthenticated = true;\n * return next();\n * });\n * \n * this.get('/me', (ctx) => {\n * // State is fully typed\n * return ctx.json({ userId: ctx.state.userId });\n * });\n * }\n * }\n * \n * app.mount('/auth', new AuthRouter());\n * ```\n * \n * @example Router with Middleware\n * ```typescript\n * const apiRouter = new ShokupanRouter();\n * \n * // Router-level middleware\n * apiRouter.use(async (ctx, next) => {\n * console.log(`API request: ${ctx.method} ${ctx.path}`);\n * return next();\n * });\n * \n * apiRouter.get('/status', (ctx) => ctx.json({ status: 'ok' }));\n * app.mount('/api', apiRouter);\n * ```\n */\nexport class ShokupanRouter<T extends Record<string, any> = Record<string, any>> {\n // Internal marker to identify Router vs. Application\n private [$isApplication]: boolean = false;\n private [$isMounted]: boolean = false;\n private [$isRouter]: true = true;\n private [$appRoot]: Shokupan;\n public [$mountPath]: string = \"/\"; // Public via Symbol for OpenAPI generator\n\n private [$parent]: ShokupanRouter<T> | null = null;\n public [$childRouters]: ShokupanRouter<T>[] = [];\n public [$childControllers]: ShokupanController[] = [];\n\n private _hasOnResponseEndHook: boolean;\n private _hasOnRequestStartHook: boolean;\n private _hasOnRequestEndHook: boolean;\n private _hasOnResponseStartHook: boolean;\n private _hasOnErrorHook: boolean;\n private _hasOnRequestTimeoutHook: boolean;\n private _hasOnReadTimeoutHook: boolean;\n private _hasOnWriteTimeoutHook: boolean;\n private _hasBeforeValidateHook: boolean;\n private _hasAfterValidateHook: boolean;\n get hasOnResponseEndHook() { return this._hasOnResponseEndHook; };\n get hasOnRequestStartHook() { return this._hasOnRequestStartHook; };\n get hasOnRequestEndHook() { return this._hasOnRequestEndHook; };\n get hasOnResponseStartHook() { return this._hasOnResponseStartHook; };\n get hasOnErrorHook() { return this._hasOnErrorHook; };\n get hasOnRequestTimeoutHook() { return this._hasOnRequestTimeoutHook; };\n get hasOnReadTimeoutHook() { return this._hasOnReadTimeoutHook; };\n get hasOnWriteTimeoutHook() { return this._hasOnWriteTimeoutHook; };\n get hasBeforeValidateHook() { return this._hasBeforeValidateHook; };\n get hasAfterValidateHook() { return this._hasAfterValidateHook; };\n\n public requestTimeout?: number;\n\n public get db(): SurrealDatastore | undefined {\n return this.root?.db;\n }\n\n private hookCache = new Map<keyof ShokupanHooks, Function[]>();\n private hooksInitialized: boolean = false;\n\n public middleware: Middleware[] = [];\n\n get rootConfig() {\n return this[$appRoot]?.applicationConfig;\n }\n get root() {\n return this[$appRoot];\n }\n\n public [$routes]: ShokupanRoute[] = []; // Public via Symbol for OpenAPI generator\n private trie = new RouterTrie<T>();\n public metadata?: RouteMetadata; // Metadata for the router itself\n\n private currentGuards: { handler: ShokupanHandler<T>; spec?: GuardAPISpec; }[] = [];\n private eventHandlers = new Map<string, ShokupanHandler<T>[]>();\n\n /**\n * Registers middleware for this router.\n * Middleware will run for all routes matched by this router.\n */\n public use(middleware: Middleware) {\n // Basic middleware registration\n this.middleware.push(middleware);\n return this;\n }\n\n\n // Registry Accessor\n public getComponentRegistry(): {\n metadata: RouteMetadata,\n middleware: { name: string, metadata: RouteMetadata, order: number, _fn: Middleware; }[],\n routes: { type: 'route', path: string, method: Method, metadata: RouteMetadata, handlerName: string, tags: string[], order: number, _fn: ShokupanHandler<T>; }[],\n routers: { type: 'router', path: string, metadata: RouteMetadata, children: { routes: any[]; }; }[],\n controllers: { type: 'controller', path: string, name: string, metadata: RouteMetadata; children: { routes: any[]; }; }[];\n events: { type: 'event', name: string, handlerName: string, metadata: RouteMetadata; _fn: ShokupanHandler<T>; }[];\n } {\n // Separation logic: Group routes by controller instance\n const controllerRoutesMap = new Map<any, any[]>();\n const localRoutes: any[] = [];\n\n for (let i = 0; i < this[$routes].length; i++) {\n const r = this[$routes][i];\n const entry = {\n type: 'route' as 'route',\n path: r.path.startsWith('/') ? r.path : '/' + r.path,\n method: r.method,\n metadata: r.metadata,\n handlerName: r.handler.name,\n tags: r.handlerSpec?.tags,\n order: r.order,\n _fn: r.handler\n };\n\n if (r.controller) {\n if (!controllerRoutesMap.has(r.controller)) {\n controllerRoutesMap.set(r.controller, []);\n }\n controllerRoutesMap.get(r.controller)!.push(entry);\n } else {\n localRoutes.push(entry);\n }\n }\n\n // Collect middleware (if exists, e.g. on Shokupan app)\n const mw = this.middleware;\n const middleware = mw ? mw.map(m => ({\n name: m.name || 'middleware',\n metadata: m.metadata,\n order: m.order,\n _fn: m // Expose function for debugging instrumentation\n })) : [];\n\n // Collect child routers\n const routers = this[$childRouters].map((r: ShokupanRouter<T>) => ({\n type: 'router' as 'router',\n path: r[$mountPath].startsWith('/') ? r[$mountPath] : '/' + r[$mountPath],\n metadata: r.metadata,\n children: r.getComponentRegistry()\n }));\n\n // Collect child controllers\n const controllers = this[$childControllers].map((c: ShokupanController<T>) => {\n const routes = controllerRoutesMap.get(c) || [];\n return {\n type: 'controller' as 'controller',\n path: (c as any)[$mountPath] || '/',\n name: c.constructor.name,\n metadata: (c as any).metadata,\n children: { routes }\n };\n });\n\n // Collect event handlers\n const events: any[] = [];\n this.eventHandlers.forEach((handlers, name) => {\n handlers.forEach(h => {\n events.push({\n type: 'event',\n name,\n handlerName: h.name,\n metadata: (h as any).source ? { file: (h as any).source.file, line: (h as any).source.line } : undefined,\n _fn: h\n });\n });\n });\n\n return {\n metadata: this.metadata,\n middleware,\n routes: localRoutes,\n routers,\n controllers,\n events\n };\n }\n\n constructor(\n public readonly config?: ShokupanRouteConfig\n ) {\n if (config?.requestTimeout) {\n this.requestTimeout = config.requestTimeout;\n }\n if (config?.hooks) {\n this.ensureHooksInitialized();\n }\n }\n\n private isRouterInstance(target: any): target is ShokupanRouter<T> {\n // Check if it's an object and has your specific symbol\n return typeof target === 'object' && target !== null && $isRouter in target;\n }\n\n /**\n * Registers an event handler for WebSocket.\n */\n public event(name: string, handler: ShokupanHandler<T>) {\n const info = getCallerInfo();\n (handler as any).source = { file: info.file, line: info.line };\n\n if (this.eventHandlers.has(name)) {\n const err = new EventError(`Event handler \\`${name}\\` already exists.`);\n console.warn(err);\n const handlers = this.eventHandlers.get(name)!;\n handlers.push(handler);\n this.eventHandlers.set(name, handlers);\n }\n else {\n this.eventHandlers.set(name, [handler]);\n }\n return this;\n }\n\n /**\n * Registers a lifecycle hook dynamically.\n */\n public hook(name: keyof ShokupanHooks, handler: Function) {\n if (!this.hooksInitialized) {\n this.ensureHooksInitialized();\n }\n\n let handlers = this.hookCache.get(name);\n if (!handlers) {\n handlers = [];\n this.hookCache.set(name, handlers);\n\n // Set the has hooks flags\n this._hasOnErrorHook ||= name === 'onError';\n this._hasOnRequestStartHook ||= name === 'onRequestStart';\n this._hasOnRequestEndHook ||= name === 'onRequestEnd';\n this._hasOnResponseStartHook ||= name === 'onResponseStart';\n this._hasOnResponseEndHook ||= name === 'onResponseEnd';\n this._hasOnRequestTimeoutHook ||= name === 'onRequestTimeout';\n this._hasOnReadTimeoutHook ||= name === 'onReadTimeout';\n this._hasOnWriteTimeoutHook ||= name === 'onWriteTimeout';\n this._hasBeforeValidateHook ||= name === 'beforeValidate';\n this._hasAfterValidateHook ||= name === 'afterValidate';\n }\n handlers.push(handler);\n return this;\n }\n\n /**\n * Finds an event handler(s) by name.\n */\n public findEvent(name: string): ShokupanHandler<T>[] | null {\n // Check local\n const handlers = this.eventHandlers.get(name);\n if (handlers !== undefined) {\n return handlers;\n }\n\n // Check children\n for (const child of this[$childRouters]) {\n const handler = child.findEvent(name);\n if (handler) return handler;\n }\n\n return null;\n }\n\n /**\n * Registers a controller instance to the router.\n */\n public registerControllerInstance(controller: any) {\n this[$childControllers].push(controller);\n }\n\n /**\n * Returns all registered event handlers.\n */\n public getEventHandlers(): Map<string, ShokupanHandler<T>[]> {\n return this.eventHandlers;\n }\n\n /**\n * Mounts a controller instance to a path prefix.\n * \n * Controller can be a convection router or an arbitrary class.\n * \n * Routes are derived from method names:\n * - get(ctx) -> GET /prefix/\n * - getUsers(ctx) -> GET /prefix/users\n * - postCreate(ctx) -> POST /prefix/create\n */\n public mount(prefix: string, controller: ShokupanController | ShokupanController<T> | ShokupanRouter | ShokupanRouter<T> | Record<string, any>) {\n // strict controller check\n const isRouter = this.isRouterInstance(controller);\n const isFunction = typeof controller === 'function';\n const controllersOnly = this.config?.controllersOnly ?? this.rootConfig?.controllersOnly ?? false;\n\n if (controllersOnly && !isFunction && !isRouter) {\n throw new Error(`[Shokupan] strict controller check failed: ${controller.constructor.name || typeof controller} is not a class constructor.`);\n }\n\n if (this.isRouterInstance(controller)) {\n this.mountRouter(prefix, controller);\n }\n // Controller is an arbitrary class\n else {\n ControllerScanner.scan(this, prefix, controller);\n }\n\n return this;\n }\n\n /**\n * Returns all routes attached to this router and its descendants.\n */\n public getRoutes(): { method: Method, path: string, handler: ShokupanHandler<T>; }[] {\n const routes = this[$routes].map(r => ({\n method: r.method,\n path: r.path,\n handler: r.handler\n }));\n\n for (let i = 0; i < this[$childRouters].length; i++) {\n const child = this[$childRouters][i];\n const childRoutes = child.getRoutes();\n for (let j = 0; j < childRoutes.length; j++) {\n const route = childRoutes[j];\n const cleanPrefix = child[$mountPath].endsWith(\"/\") ? child[$mountPath].slice(0, -1) : child[$mountPath];\n const cleanPath = route.path.startsWith(\"/\") ? route.path : \"/\" + route.path;\n const fullPath = (cleanPrefix + cleanPath) || \"/\";\n\n routes.push({\n method: route.method as Method,\n path: fullPath,\n handler: route.handler\n });\n }\n }\n return routes;\n }\n\n /**\n * Makes an internal request through this router's full routing pipeline.\n * This is useful for calling other routes internally and supports streaming responses.\n * @param options The request options.\n * @returns The raw Response object.\n */\n public async internalRequest(arg: {\n path: string;\n method?: Method;\n headers?: HeadersInit;\n body?: any;\n } | string): Promise<Response> {\n const options = typeof arg === \"string\" ? { path: arg } : arg;\n\n let url = options.path;\n // If path is relative, make it absolute (required by Request constructor)\n if (!url.startsWith(\"http\")) {\n const base = `http://${this.rootConfig?.hostname || \"localhost\"}:${this.rootConfig.port || 3000}`;\n\n // Ensure path starts with /\n const path = url.startsWith(\"/\") ? url : \"/\" + url;\n url = base + path;\n }\n\n const req = new ShokupanRequest({\n method: options.method || \"GET\",\n url,\n headers: options.headers as any,\n body: options.body ? JSON.stringify(options.body) : undefined\n });\n\n return this.root[$dispatch](req);\n }\n\n /**\n * Processes a request for testing purposes.\n * Returns a simplified { status, headers, data } object instead of a Response.\n */\n public async testRequest(options: RequestOptions): Promise<ProcessResult> {\n let url = options.url || options.path || \"/\";\n if (!url.startsWith(\"http\")) {\n const base = `http://${this.rootConfig?.hostname || \"localhost\"}:${this.rootConfig?.port || 3000}`;\n const path = url.startsWith(\"/\") ? url : \"/\" + url;\n url = base + path;\n }\n\n // Handle query params in options\n if (options.query) {\n const u = new URL(url);\n const entries = Object.entries(options.query);\n for (let i = 0; i < entries.length; i++) {\n const [k, v] = entries[i];\n u.searchParams.set(k, v);\n }\n url = u.toString();\n }\n\n const req = new ShokupanRequest({\n method: (options.method || \"GET\") as Method,\n url,\n headers: options.headers as any,\n body: options.body && typeof options.body === \"object\" ? JSON.stringify(options.body) : options.body\n });\n\n // Basic Dispatch Logic (moved/duplicated from Shokupan.handleRequest but simpler for pure Router)\n // Note: Pure Routers don't have global middleware usually, but if we call processRequest on them, \n // we just run their routing logic.\n // HOWEVER, Shokupan.override will invoke middleware.\n\n const ctx = new ShokupanContext<T>(req);\n\n let result: any = null;\n let status: number = HTTP_STATUS.OK;\n const headers: Record<string, string> = {};\n\n const match = this.find(req.method, ctx.path);\n if (match) {\n ctx.params = match.params;\n try {\n result = await match.handler(ctx);\n } catch (err: any) {\n console.error(err);\n status = getErrorStatus(err);\n result = { error: err.message || \"Internal Server Error\" };\n if (err.errors) result.errors = err.errors;\n }\n }\n else {\n status = HTTP_STATUS.NOT_FOUND;\n result = \"Not Found\";\n }\n\n // Normalize Result\n // If result is Response object, we need to read it back to ProcessResult?\n // The user wants { status, headers, data }.\n // If handler returns Response, we extract data.\n\n if (result instanceof Response) {\n status = result.status;\n result.headers.forEach((v, k) => headers[k] = v);\n\n if (headers['content-type']?.includes('application/json')) {\n result = await result.json();\n }\n else {\n result = await result.text();\n }\n }\n\n return {\n status,\n headers,\n data: result\n };\n }\n\n private wrapWithHooks(handler: ShokupanHandler<T>) {\n // Ensure hooks are initialized before checking the cache\n if (!this.hooksInitialized) {\n this.ensureHooksInitialized();\n }\n\n const hasStart = this.hookCache.get('onRequestStart')?.length > 0;\n const hasEnd = this.hookCache.get('onRequestEnd')?.length > 0;\n const hasError = this.hookCache.get('onError')?.length > 0;\n\n if (!hasStart && !hasEnd && !hasError) return handler;\n\n const originalHandler = handler;\n\n const wrapped = async (ctx: ShokupanContext<T>) => {\n await this.runHooks(\"onRequestStart\", ctx);\n\n const debug = ctx[$debug];\n let debugId: string | undefined;\n let previousNode: string | undefined;\n\n if (debug) {\n // @ts-ignore\n debugId = originalHandler._debugId || originalHandler.name || 'handler';\n previousNode = debug.getCurrentNode();\n debug.trackEdge(previousNode, debugId);\n debug.setNode(debugId!);\n }\n\n const start = performance.now();\n try {\n const res = await originalHandler(ctx);\n debug?.trackStep(debugId, 'handler', performance.now() - start, 'success');\n\n await this.runHooks(\"onRequestEnd\", ctx);\n return res;\n } catch (err) {\n debug?.trackStep(debugId, 'handler', performance.now() - start, 'error', err);\n\n await this.runHooks(\"onError\", ctx, err);\n throw err;\n } finally {\n if (debug && previousNode) debug.setNode(previousNode);\n }\n };\n // Preserve original handler reference for analysis if needed\n (wrapped as any).originalHandler = (originalHandler as any).originalHandler ?? originalHandler;\n return wrapped;\n }\n\n private mountRouter(prefix: string, router: ShokupanRouter<T>) {\n if (router[$isMounted]) {\n throw new Error(\"Router is already mounted\");\n }\n\n router[$mountPath] = prefix;\n\n // Capture mount location if not already present\n if (!router.metadata) {\n const info = getCallerInfo();\n router.metadata = {\n file: info.file,\n line: info.line,\n name: 'MountedRouter'\n };\n }\n this[$childRouters].push(router);\n\n /**\n * Descendants are defined first, then mounted backwards up to the application root.\n * Thus, we have to recurse through the children and assign the root reference.\n */\n router[$parent] = this;\n\n const setRouterContext = (router: ShokupanRouter<T>) => {\n router[$appRoot] = this.root;\n router[$childRouters].forEach((child) => setRouterContext(child));\n };\n setRouterContext(router);\n\n router[$appRoot] = this.root;\n router[$isMounted] = true;\n }\n\n\n /**\n * Find a route matching the given method and path.\n * @param method HTTP method\n * @param path Request path\n * @returns Route handler and parameters if found, otherwise null\n */\n public find(method: string, path: string): { handler: ShokupanHandler<T>; params: Record<string, string>; } | null {\n // console.log(`[Router] find ${method} ${path} (routes: ${this.routes.length}, children: ${this[$childRouters].length})`);\n\n\n // 1. Check local routes\n let result = this.trie.search(method, path);\n if (result) return result;\n\n // Fallback: If HEAD not found, try GET\n if (method === \"HEAD\") {\n result = this.trie.search(\"GET\", path);\n if (result) return result;\n }\n\n // 2. Check child routers\n for (let i = 0; i < this[$childRouters].length; i++) {\n const child = this[$childRouters][i];\n const prefix = child[$mountPath];\n\n if (path === prefix || path.startsWith(prefix + \"/\")) {\n const subPath = path.slice(prefix.length) || \"/\";\n const match = child.find(method, subPath);\n // Child router handlers are already wrapped with child hooks\n // Just return them as-is (parent hooks are applied at the app level in handleRequest)\n if (match) return match;\n }\n // Handle case where prefix ends with /\n if (prefix.endsWith(\"/\")) {\n if (path.startsWith(prefix)) {\n const subPath = path.slice(prefix.length) || \"/\";\n const match = child.find(method, subPath);\n if (match) return match;\n }\n }\n }\n\n return null; // Not found\n }\n\n private parsePath(path: string): { regex: RegExp; keys: string[]; } {\n if (typeof path !== 'string') {\n throw new Error(`Route path must be a string or regexp, received ${typeof path == \"function\" ? (path['name'] || path['constructor']?.['name'] || 'function') : typeof path}. Dynamic paths are **highly** discouraged.`);\n }\n\n const keys: string[] = [];\n\n // Security: Validate path length to prevent ReDoS\n if (path.length > 2048) {\n throw new Error('Path too long');\n }\n\n const pattern = path\n .replace(/:([a-zA-Z0-9_]+)/g, (_, key) => {\n keys.push(key);\n // Security: Add length limit to prevent ReDoS\n return \"([^/]{1,255})\";\n })\n // Security: Limit recursive wildcard to prevent ReDoS\n .replace(/\\*\\*/g, \".{0,1000}\")\n // Security: Limit single segment wildcard to prevent ReDoS \n .replace(/\\*/g, \"[^/]{1,255}\");\n\n return {\n regex: new RegExp(`^${pattern}$`),\n keys\n };\n }\n\n /**\n * Adds a route to the router.\n * \n * @param arg - Route configuration object\n * @param arg.method - HTTP method\n * @param arg.path - URL path\n * @param arg.spec - OpenAPI specification for the route\n * @param arg.handler - Route handler function\n * @param arg.regex - Custom regex for path matching\n * @param arg.group - Group for the route\n * @param arg.requestTimeout - Timeout for this route in milliseconds\n * @param arg.renderer - JSX renderer for the route\n * @param arg.controller - Controller for the route\n */\n public add({ method, path, spec, handler, regex: customRegex, group, requestTimeout, renderer, controller, metadata, middleware }: {\n method: Method,\n path: string,\n spec?: MethodAPISpec,\n handler: ShokupanHandler<T>;\n regex?: RegExp;\n group?: string;\n requestTimeout?: number;\n renderer?: JSXRenderer;\n controller?: any;\n metadata?: { file: string, line: number; };\n middleware?: Middleware[];\n }) {\n const { regex, keys } = customRegex\n ? { regex: customRegex, keys: [] }\n : this.parsePath(path);\n\n // Merge specs from guards\n if (this.currentGuards.length > 0) {\n spec = spec || {};\n for (let i = 0; i < this.currentGuards.length; i++) {\n const guard = this.currentGuards[i];\n if (guard.spec) {\n // Merge Responses\n if (guard.spec.responses) {\n spec.responses = spec.responses || {};\n Object.assign(spec.responses, guard.spec.responses);\n }\n\n // Merge Security\n if (guard.spec.security) {\n spec.security = spec.security || [];\n spec.security.push(...guard.spec.security);\n }\n }\n }\n }\n\n // Wrap handler with current guards if any exist\n let wrappedHandler = async (ctx: ShokupanContext<T>) => {\n // Check for WebSocket upgrade before executing handler logic\n // This allows the router to handle the request (running middleware/guards)\n // but upgrading to WebSocket instead of running the HTTP handler.\n // if (ctx.upgrade()) {\n // return undefined;\n // }\n return handler(ctx);\n };\n (wrappedHandler as any).originalHandler = (handler as any).originalHandler || handler;\n const routeGuards = [...this.currentGuards];\n\n // Wrap for Timeout\n const effectiveTimeout = requestTimeout ?? this.requestTimeout ?? this.rootConfig?.requestTimeout;\n\n if (effectiveTimeout !== undefined && effectiveTimeout > 0) {\n const originalHandler = wrappedHandler;\n wrappedHandler = async (ctx: ShokupanContext<T>) => {\n if (ctx.server) {\n ctx.server.timeout(ctx.req as unknown as Request, effectiveTimeout / 1000);\n }\n return originalHandler(ctx);\n };\n (wrappedHandler as any).originalHandler = (originalHandler as any).originalHandler || originalHandler;\n }\n\n if (routeGuards.length > 0) {\n const innerHandler = wrappedHandler;\n wrappedHandler = async (ctx: ShokupanContext<T>) => {\n // Execute guards in order\n for (let i = 0; i < routeGuards.length; i++) {\n const guard = routeGuards[i];\n let guardPassed = false;\n let nextCalled = false;\n const next = () => {\n nextCalled = true;\n return Promise.resolve();\n };\n\n try {\n const result = await guard.handler(ctx, next);\n if (result === true || nextCalled) {\n guardPassed = true;\n } else if (result !== undefined && result !== null && result !== false) {\n return result;\n } else {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n } catch (error) {\n throw error;\n }\n\n if (!guardPassed) {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n }\n return innerHandler(ctx);\n };\n }\n\n // Inject Renderer\n const effectiveRenderer = renderer ?? this.config?.renderer ?? this.rootConfig?.renderer;\n if (effectiveRenderer) {\n const innerHandler = wrappedHandler;\n wrappedHandler = async (ctx: ShokupanContext<T>) => {\n ctx.setRenderer(effectiveRenderer);\n return innerHandler(ctx);\n };\n }\n\n // --- Middleware Tracking Logic ---\n // If metadata is provided (e.g. from controller), use it. Otherwise capture caller info.\n const { file, line } = metadata || getCallerInfo();\n\n wrappedHandler = MiddlewareTracker.wrap(wrappedHandler, {\n file,\n line,\n name: handler.name || 'anonymous',\n isBuiltin: (handler as any).isBuiltin,\n pluginName: (handler as any).pluginName\n });\n\n // Bake in Hooks if present (Optimization)\n let bakedHandler = wrappedHandler;\n if (this.config?.hooks) {\n bakedHandler = this.wrapWithHooks(wrappedHandler);\n }\n\n // Store for OpenAPI (still use list)\n this[$routes].push({\n method,\n path,\n regex: regex ?? new RegExp(''),\n keys: keys ?? [],\n handler,\n bakedHandler,\n handlerSpec: spec,\n group,\n hooks: this.config?.hooks as any,\n requestTimeout,\n renderer,\n metadata: {\n file,\n line\n },\n controller,\n middleware: middleware || []\n });\n\n // Insert into Trie\n this.trie.insert(method, path, bakedHandler);\n\n return this;\n }\n\n /**\n * Adds a GET route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public get<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a GET route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public get<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public get(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"GET\", path, ...args);\n return this;\n }\n\n /**\n * Adds a POST route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public post<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a POST route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public post<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public post(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"POST\", path, ...args);\n return this;\n }\n\n /**\n * Adds a PUT route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public put<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a PUT route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public put<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public put(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"PUT\", path, ...args);\n return this;\n }\n\n /**\n * Adds a DELETE route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public delete<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a DELETE route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public delete<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public delete(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"DELETE\", path, ...args);\n return this;\n }\n\n /**\n * Adds a PATCH route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public patch<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a PATCH route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public patch<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public patch(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"PATCH\", path, ...args);\n return this;\n }\n\n /**\n * Adds a OPTIONS route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public options<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a OPTIONS route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public options<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public options(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"OPTIONS\", path, ...args);\n return this;\n }\n\n /**\n * Adds a HEAD route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public head<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a HEAD route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public head<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public head(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"HEAD\", path, ...args);\n return this;\n }\n\n /**\n * Adds a guard to the router that applies to all routes added **after** this point.\n * Guards must return true or call `ctx.next()` to allow the request to continue.\n * \n * @param handler - Guard handler function \n */\n public guard(handler: ShokupanHandler<T>): void;\n /**\n * Adds a guard to the router that applies to all routes added **after** this point.\n * Guards must return true or call `ctx.next()` to allow the request to continue.\n \n * @param spec - OpenAPI specification for the guard\n * @param handler - Guard handler function \n */\n public guard(spec: GuardAPISpec, handler: ShokupanHandler<T>);\n public guard(specOrHandler: GuardAPISpec | ShokupanHandler<T>, handler?: ShokupanHandler<T>) {\n const spec = typeof specOrHandler === \"function\" ? undefined : specOrHandler as GuardAPISpec;\n const guardHandler = typeof specOrHandler === \"function\" ? specOrHandler as ShokupanHandler<T> : handler as ShokupanHandler<T>;\n\n // --- Middleware Tracking Logic ---\n let file = 'unknown';\n let line = 0;\n try {\n const err = new Error();\n const stack = err.stack?.split('\\n') || [];\n const callerLine = stack.find(l =>\n l.includes(':') &&\n !l.includes('router.ts') &&\n !l.includes('shokupan.ts') &&\n !l.includes('node_modules') &&\n !l.includes('bun:main')\n );\n if (callerLine) {\n // Regex should prevent regex DoS attacks\n const match = callerLine.match(/\\((.{0,1000}):(\\d{1,10}):(?:\\d{1,10})\\)/) ||\n callerLine.match(/at (.{0,1000}):(\\d{1,10}):(?:\\d{1,10})/);\n if (match) {\n file = match[1];\n line = parseInt(match[2], 10);\n }\n }\n } catch (e) { }\n\n const trackedGuard = MiddlewareTracker.wrap(guardHandler, {\n file,\n line,\n name: guardHandler.name || 'guard'\n });\n\n this.currentGuards.push({ handler: trackedGuard, spec });\n\n return this;\n }\n\n /**\n * Statically serves a directory with standard options.\n * @param uriPath URL path prefix\n * @param options Configuration options or root directory string\n */\n public static(uriPath: string, options: string | StaticServeOptions<T>) {\n const config: StaticServeOptions<T> = typeof options === 'string' ? { root: options } : options;\n // Normalize path prefix to ensure it has leading slash and no trailing slash for consistent matching\n const prefix = uriPath.startsWith('/') ? uriPath : '/' + uriPath;\n const normalizedPrefix = prefix.endsWith('/') && prefix !== '/' ? prefix.slice(0, -1) : prefix;\n\n // Correct usage of the new plugin:\n const handlerMiddleware = serveStatic(config, prefix);\n\n const routeHandler = async (ctx: ShokupanContext<T>) => {\n return handlerMiddleware(ctx, async () => { });\n };\n\n // Derive Group/Tag name from the path's last segment\n // e.g. /assets -> Assets\n let groupName = \"Static\";\n const segments = normalizedPrefix.split('/').filter(Boolean);\n if (segments.length > 0) {\n const last = segments[segments.length - 1];\n groupName = last.charAt(0).toUpperCase() + last.slice(1);\n }\n\n const defaultSpec = {\n summary: \"Static Content\",\n description: \"Serves static files from \" + normalizedPrefix,\n tags: [groupName]\n };\n const spec = config.openapi ? config.openapi : defaultSpec;\n if (!spec.tags) spec.tags = [groupName];\n else if (!spec.tags.includes(groupName)) spec.tags.push(groupName);\n\n const pattern = `^${normalizedPrefix}(/.*)?$`;\n const regex = new RegExp(pattern);\n\n // Display path in OpenAPI as /prefix/*\n const displayPath = normalizedPrefix === '/' ? '/*' : normalizedPrefix + '/*';\n\n this.add({ method: 'GET', path: displayPath, handler: routeHandler, spec, regex });\n this.add({ method: 'HEAD', path: displayPath, handler: routeHandler, spec, regex });\n\n return this;\n }\n\n\n /**\n * Attach the verb routes with their overload signatures.\n * Use compose to handle multiple handlers (middleware).\n */\n private attachVerb(method: Method, path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n let spec: MethodAPISpec | undefined;\n let handlers: ShokupanHandler<T>[] = [];\n\n if (args.length > 0) {\n // Check if first arg is an object (Spec) and NOT a ShokupanHandler (function)\n if (typeof args[0] === 'object' && args[0] !== null) {\n spec = args[0] as MethodAPISpec;\n handlers = args.slice(1) as ShokupanHandler<T>[];\n } else {\n handlers = args as ShokupanHandler<T>[];\n }\n }\n\n if (handlers.length === 0) {\n // Should potentially throw or warn?\n return;\n }\n\n let finalHandler = handlers[handlers.length - 1];\n\n if (handlers.length > 1) {\n // Since handlers are [ctx, next?], they fit Strict Middleware signature.\n // compose takes Middleware[].\n // We assume ALL provided handlers are valid middleware/handlers.\n const fn = compose(handlers as any);\n finalHandler = (ctx) => fn(ctx);\n }\n\n this.add({\n method,\n path,\n spec,\n handler: finalHandler,\n middleware: handlers.slice(0, handlers.length - 1) as Middleware[]\n });\n }\n\n /**\n * Generates an OpenAPI 3.1 Document by recursing through the router and its descendants.\n * Now includes runtime analysis of handler functions to infer request/response types.\n */\n public generateApiSpec(options: OpenAPIOptions = {}): Promise<any> {\n return generateOpenApi(this, options);\n }\n\n public hasHooks(name: keyof ShokupanHooks): boolean {\n if (!this.hooksInitialized) {\n this.ensureHooksInitialized();\n }\n const hooks = this.hookCache.get(name);\n return hooks !== undefined && hooks.length > 0;\n }\n\n private ensureHooksInitialized() {\n const hooks = this.config?.hooks;\n if (hooks) {\n const hookList = Array.isArray(hooks) ? hooks : [hooks];\n\n // Pre-compute lookup for each hook type\n const hookTypes: (keyof ShokupanHooks)[] = [\n 'onRequestStart', 'onRequestEnd',\n 'onResponseStart', 'onResponseEnd',\n 'onError',\n 'beforeValidate', 'afterValidate',\n 'onRequestTimeout', 'onReadTimeout', 'onWriteTimeout'\n ];\n\n for (let i = 0; i < hookTypes.length; i++) {\n const type = hookTypes[i];\n const fns: Function[] = [];\n for (let j = 0; j < hookList.length; j++) {\n const h = hookList[j];\n if (h[type]) fns.push(h[type]!);\n }\n if (fns.length > 0) {\n // console.log(`[Router] Found hook ${type} (${fns.length}) for router ${this.constructor.name}`);\n // Set the has hooks flags for much faster check\n this._hasOnErrorHook ||= type === 'onError';\n this._hasOnRequestStartHook ||= type === 'onRequestStart';\n this._hasOnRequestEndHook ||= type === 'onRequestEnd';\n this._hasOnResponseStartHook ||= type === 'onResponseStart';\n this._hasOnResponseEndHook ||= type === 'onResponseEnd';\n this._hasOnRequestTimeoutHook ||= type === 'onRequestTimeout';\n this._hasOnReadTimeoutHook ||= type === 'onReadTimeout';\n this._hasOnWriteTimeoutHook ||= type === 'onWriteTimeout';\n this._hasBeforeValidateHook ||= type === 'beforeValidate';\n this._hasAfterValidateHook ||= type === 'afterValidate';\n\n this.hookCache.set(type, fns);\n }\n }\n }\n this.hooksInitialized = true;\n }\n\n public runHooks(name: keyof ShokupanHooks, ...args: any[]): void | Promise<void[]> {\n // Optimization: Use hasHook check before calling this usually\n // But we ensure initialized here too just in case\n if (!this.hooksInitialized) {\n this.ensureHooksInitialized();\n }\n const fns = this.hookCache.get(name);\n if (!fns) return;\n\n // Check if debug tracking is enabled (ctx is typically the first argument for most hooks)\n const ctx = args?.[0] instanceof ShokupanContext ? args[0] : undefined;\n const debug = ctx?.[$debug];\n\n if (debug) {\n // Track each hook individually with debug timing\n return Promise.all(fns.map(async (fn, index) => {\n const hookId = `hook_${name}_${fn.name || index}`;\n const previousNode = debug.getCurrentNode();\n\n debug.trackEdge(previousNode, hookId);\n debug.setNode(hookId);\n\n const start = performance.now();\n try {\n await fn(...args);\n const duration = performance.now() - start;\n debug.trackStep(hookId, 'hook', duration, 'success');\n } catch (error) {\n const duration = performance.now() - start;\n debug.trackStep(hookId, 'hook', duration, 'error', error);\n throw error;\n } finally {\n if (previousNode) debug.setNode(previousNode);\n }\n }));\n } else {\n // Fast path: no debug tracking\n return Promise.all(fns.map(fn => fn(...args)));\n }\n }\n}\n","import type { Server } from \"bun\";\nimport * as http from \"node:http\";\nimport * as https from \"node:https\";\nimport type { ServerFactory } from \"../../util/types\";\n\n/**\n * Creates a server factory that uses the standard Node.js `http` module.\n * @returns A ServerFactory compatible with Shokupan.\n */\nexport function createHttpServer(): ServerFactory {\n return async (options: any): Promise<Server<any>> => {\n const server = http.createServer(async (req, res) => {\n const url = new URL(req.url!, `http://${req.headers.host}`);\n const request = new Request(url.toString(), {\n method: req.method,\n headers: req.headers as any,\n body: ['GET', 'HEAD'].includes(req.method!) ? undefined : new ReadableStream({\n start(controller) {\n req.on('data', chunk => controller.enqueue(chunk));\n req.on('end', () => controller.close());\n req.on('error', err => controller.error(err));\n }\n }) as any,\n // Required for Node.js undici when sending a body\n duplex: 'half'\n } as any);\n\n const response = await options.fetch(request, fauxServer);\n\n res.statusCode = response.status;\n response.headers.forEach((v, k) => res.setHeader(k, v));\n\n if (response.body) {\n // Optimize: Use arrayBuffer for direct conversion instead of async iteration\n const buffer = await response.arrayBuffer();\n res.end(Buffer.from(buffer));\n } else {\n res.end();\n }\n });\n\n const fauxServer: Server<any> = {\n stop: () => {\n server.close();\n return Promise.resolve(); // Bun.Server stop usually returns void but in type definition it might vary.\n },\n upgrade(req, options) {\n return false;\n },\n reload(options) {\n return fauxServer as any;\n },\n get port() {\n const addr = server.address();\n if (typeof addr === 'object' && addr !== null) {\n return addr.port;\n }\n return options.port;\n },\n hostname: options.hostname,\n development: options.development,\n pendingRequests: 0,\n requestIP: (req) => null,\n publish: () => 0,\n subscriberCount: () => 0,\n url: new URL(`http://${options.hostname}:${options.port}`),\n // Expose the raw Node.js server for generic socket/websocket support (e.g. Socket.IO)\n nodeServer: server\n } as unknown as Server<any>;\n\n return new Promise((resolve) => {\n server.listen(options.port, options.hostname, () => {\n resolve(fauxServer);\n });\n });\n };\n}\n\n/**\n * Creates a server factory that uses the standard Node.js `https` module.\n * @param sslOptions - Node.js HTTPS options (key, cert, etc.)\n * @returns A ServerFactory compatible with Shokupan.\n */\nexport function createHttpsServer(sslOptions: https.ServerOptions): ServerFactory {\n return async (options: any): Promise<Server<any>> => {\n const server = https.createServer(sslOptions, async (req, res) => {\n const url = new URL(req.url!, `https://${req.headers.host}`);\n const request = new Request(url.toString(), {\n method: req.method,\n headers: req.headers as any,\n body: ['GET', 'HEAD'].includes(req.method!) ? undefined : new ReadableStream({\n start(controller) {\n req.on('data', chunk => controller.enqueue(chunk));\n req.on('end', () => controller.close());\n req.on('error', err => controller.error(err));\n }\n }) as any,\n // Required for Node.js undici when sending a body\n duplex: 'half'\n } as any);\n\n const response = await options.fetch(request, fauxServer);\n\n res.statusCode = response.status;\n response.headers.forEach((v, k) => res.setHeader(k, v));\n\n if (response.body) {\n // Optimize: Use arrayBuffer for direct conversion instead of async iteration\n const buffer = await response.arrayBuffer();\n res.end(Buffer.from(buffer));\n } else {\n res.end();\n }\n });\n\n const fauxServer: Server<any> = {\n stop: () => {\n server.close();\n },\n upgrade(req, options) {\n return false;\n },\n reload(options) {\n return fauxServer as any;\n },\n get port() {\n const addr = server.address();\n if (typeof addr === 'object' && addr !== null) {\n return addr.port;\n }\n return options.port;\n },\n hostname: options.hostname,\n development: options.development,\n pendingRequests: 0,\n requestIP: (req) => null,\n publish: () => 0,\n subscriberCount: () => 0,\n url: new URL(`https://${options.hostname}:${options.port}`),\n // Expose the raw Node.js server for generic socket/websocket support\n nodeServer: server\n } as unknown as Server<any>;\n\n return new Promise((resolve) => {\n server.listen(options.port, options.hostname, () => {\n resolve(fauxServer);\n });\n });\n };\n}\n","import type { Server } from \"bun\";\nimport { ShokupanContext } from \"../../context\";\nimport { compose } from \"../../middleware\";\nimport { createHttpServer } from \"../../plugins/application/http-server\";\nimport type { Shokupan } from \"../../shokupan\";\nimport { ShokupanRequest } from \"../request\";\nimport { $ws } from \"../symbol\";\n\nexport interface ServerAdapter {\n listen(port: number, app: Shokupan): Promise<any>;\n stop?(): Promise<void>;\n}\n\nexport class BunAdapter implements ServerAdapter {\n private server?: Server<any>;\n\n async listen(port: number, app: Shokupan): Promise<Server<any>> {\n // @ts-ignore\n if (typeof Bun === \"undefined\") {\n throw new Error(\"BunAdapter requires the Bun runtime.\");\n }\n\n const serveOptions = {\n port: port,\n hostname: app.applicationConfig.hostname,\n development: app.applicationConfig.development,\n fetch: app.fetch.bind(app),\n reusePort: app.applicationConfig.reusePort,\n idleTimeout: app.applicationConfig.readTimeout ? app.applicationConfig.readTimeout / 1000 : undefined,\n websocket: {\n // @ts-ignore\n open(ws) {\n ws.data?.handler?.open?.(ws);\n },\n // @ts-ignore\n async message(ws, message) {\n if (ws.data?.handler?.message) {\n return ws.data.handler.message(ws, message);\n }\n\n // Buffer vs Uint8Array handling for cross-platform compatibility\n let msgString: string = \"\";\n if (typeof message === \"string\") {\n msgString = message;\n } else if (message instanceof Uint8Array || message instanceof ArrayBuffer) {\n msgString = new TextDecoder().decode(message);\n } else if (typeof Buffer !== \"undefined\" && message instanceof Buffer) {\n // @ts-ignore\n msgString = message.toString();\n } else {\n return; // Unknown format\n }\n\n if (typeof msgString !== \"string\") return;\n\n let payload: any;\n let isJSONPayload = false;\n if (msgString.startsWith('{')) {\n try {\n payload = JSON.parse(msgString);\n isJSONPayload = true;\n } catch { /* Ignore JSON parsing errors */ }\n }\n\n if (payload) {\n const self = app;\n // HTTP Bridge\n if (isJSONPayload && self.applicationConfig['enableHttpBridge'] && payload.type === 'HTTP') {\n const { id, method, path, headers, body } = payload;\n const url = new URL(path, `http://${self.applicationConfig.hostname || 'localhost'}:${port}`);\n\n const req = new Request(url.toString(), {\n method,\n headers,\n body: typeof body === 'object' ? JSON.stringify(body) : body\n });\n\n const res = await self.fetch(req);\n\n const resBody: any = await res.json()\n .catch(err => res.text());\n\n const resHeaders: Record<string, string> = {};\n res.headers.forEach((v, k) => resHeaders[k] = v);\n\n ws.send(JSON.stringify({\n type: 'RESPONSE',\n id,\n status: res.status,\n headers: resHeaders,\n body: resBody\n }));\n return;\n }\n\n // Event Handling\n const eventName = payload.event || (payload.type === 'EVENT' ? payload.name : undefined);\n if (eventName) {\n const handlers = self.findEvent(eventName);\n const handler = handlers?.length == 1 ? handlers[0] : compose(handlers || []);\n if (handler) {\n const data = payload.data || payload.body || payload.payload || payload;\n\n // Construct a Context that mocks a Request\n const req = new ShokupanRequest({\n url: `http://${self.applicationConfig.hostname || 'localhost'}/event/${eventName}`,\n method: 'POST',\n headers: new Headers({ 'content-type': 'application/json' }),\n body: JSON.stringify(data)\n });\n\n const ctx = new ShokupanContext(\n // @ts-ignore\n req,\n // @ts-ignore\n self.server,\n {},\n self,\n null,\n self.applicationConfig.enableMiddlewareTracking,\n payload.id\n );\n // Expose socket on context for reply\n (ctx as any)[$ws] = ws;\n\n // Link context to socket for disconnect hooks\n ws.data ??= {} as any;\n ws.data['ctx'] = ctx;\n\n try {\n await handler(ctx as any);\n } catch (err) {\n if (self.applicationConfig['websocketErrorHandler']) {\n await self.applicationConfig['websocketErrorHandler'](err, ctx as any);\n } else {\n console.error(`Error in event ${eventName}:`, err);\n }\n }\n }\n }\n }\n },\n // @ts-ignore\n drain(ws) {\n ws.data?.handler?.drain?.(ws);\n },\n // @ts-ignore\n close(ws, code, reason) {\n ws.data?.handler?.close?.(ws, code, reason);\n // Shokupan Disconnect Hooks\n const ctx: any = ws.data?.['ctx'];\n if (ctx && typeof ctx.getDisconnectCallbacks === 'function') {\n const callbacks = ctx.getDisconnectCallbacks();\n if (Array.isArray(callbacks) && callbacks.length > 0) {\n Promise.all(callbacks.map((cb: Function) => cb())).catch(err => {\n console.error(\"Error executing socket disconnect hook:\", err);\n });\n }\n }\n }\n }\n };\n\n // @ts-ignore\n this.server = Bun.serve(serveOptions);\n return this.server!;\n }\n\n async stop() {\n if (this.server) {\n this.server.stop();\n }\n }\n}\n\nexport class NodeAdapter implements ServerAdapter {\n private server?: any;\n\n async listen(port: number, app: Shokupan): Promise<any> {\n let factory = app.applicationConfig.serverFactory;\n\n if (!factory) {\n factory = createHttpServer();\n }\n\n const serveOptions = {\n port: port,\n hostname: app.applicationConfig.hostname,\n development: app.applicationConfig.development,\n fetch: app.fetch.bind(app),\n reusePort: app.applicationConfig.reusePort,\n // Node adapter might not support all options exactly the same\n };\n\n this.server = await factory(serveOptions);\n return this.server;\n }\n\n async stop() {\n if (this.server?.stop) {\n await this.server.stop();\n }\n }\n}\n\nexport class WinterCGAdapter implements ServerAdapter {\n async listen(port: number, app: Shokupan): Promise<any> {\n console.warn(\"WinterCGAdapter does not support 'listen()'. Use 'export default app' or invoke 'app.fetch' directly.\");\n return {};\n }\n}\n","\nexport interface FileSystemAdapter {\n readFile(path: string): Promise<Uint8Array | string | ReadableStream>;\n stat?(path: string): Promise<{ size: number; mtime: Date; }>;\n}\n\nlet fs: typeof import(\"node:fs/promises\") | undefined;\n\n/**\n * Default file system adapter that uses Bun.file for Bun and Node.js fs.promises for Node.js.\n */\nexport class DefaultFileSystemAdapter implements FileSystemAdapter {\n async readFile(path: string): Promise<Uint8Array | string | ReadableStream> {\n // @ts-ignore\n if (typeof Bun !== \"undefined\") {\n // @ts-ignore\n return Bun.file(path);\n } else {\n // Dynamic import for Node.js compatibility without top-level import\n fs ??= await import('node:fs/promises');\n return fs.readFile(path);\n }\n }\n\n async stat(path: string): Promise<{ size: number; mtime: Date; }> {\n // @ts-ignore\n if (typeof Bun !== \"undefined\") {\n // @ts-ignore\n const file = Bun.file(path);\n return {\n size: file.size,\n mtime: new Date(file.lastModified)\n };\n } else {\n fs ??= await import('node:fs/promises');\n const stats = await fs.stat(path);\n return {\n size: stats.size,\n mtime: stats.mtime\n };\n }\n }\n}\n\nexport class NoOpFileSystemAdapter implements FileSystemAdapter {\n async readFile(path: string): Promise<Uint8Array | string | ReadableStream> {\n throw new Error(\"File system access is not supported in this environment (NoOpFileSystemAdapter).\");\n }\n}\n","\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\n\nimport type { Span } from \"@opentelemetry/api\";\n\nexport class RequestContextStore {\n request?: Request;\n span?: Span;\n [key: string]: any;\n}\n\nexport const asyncContext = new AsyncLocalStorage<RequestContextStore>();\n\nexport function runInContext<T>(callback: () => T, initialStore = new RequestContextStore()): T {\n return asyncContext.run(initialStore, callback);\n}\n","// import * as os from 'node:os';\ntype CpuInfo = { times: { user: number; nice: number; sys: number; idle: number; irq: number; }; };\n\nexport class SystemCpuMonitor {\n private interval: Timer | null = null;\n private lastCpus: CpuInfo[] = [];\n private currentUsage: number = 0;\n private osStub: any = null;\n\n constructor(private readonly intervalMs: number = 1000) {\n this.init();\n }\n\n private async init() {\n try {\n // @ts-ignore\n if (typeof process !== \"undefined\" && process.versions && process.versions.node) {\n this.osStub = await import('node:os');\n }\n } catch (e) {\n // Ignore\n }\n }\n\n public start() {\n if (this.interval) return;\n if (!this.osStub) return; // silent failure in unsupported envs\n\n this.lastCpus = this.osStub.cpus();\n this.interval = setInterval(() => this.update(), this.intervalMs);\n }\n\n public stop() {\n if (this.interval) {\n clearInterval(this.interval);\n this.interval = null;\n }\n }\n\n public getUsage(): number {\n return this.currentUsage;\n }\n\n private update() {\n if (!this.osStub) return;\n\n const cpus = this.osStub.cpus();\n let idle = 0;\n let total = 0;\n\n for (let i = 0; i < cpus.length; i++) {\n const cpu = cpus[i];\n const prev = this.lastCpus[i];\n\n if (!prev) continue;\n\n let type: keyof typeof cpu.times;\n for (type in cpu.times) {\n const ticks = cpu.times[type];\n const prevTicks = prev.times[type];\n const diff = ticks - prevTicks;\n total += diff;\n if (type === 'idle') {\n idle += diff;\n }\n }\n }\n\n this.lastCpus = cpus;\n this.currentUsage = total === 0 ? 0 : (1 - idle / total) * 100;\n }\n}\n","import { RecordId, Surreal, type RecordIdRange, type Table } from 'surrealdb';\n\n\nexport class SurrealDatastore {\n constructor(\n private readonly db: Surreal\n ) {\n process.on(\"exit\", async () => {\n await this.disconnect();\n });\n }\n\n createSchema() {\n this.db.query(`\n DEFINE TABLE OVERWRITE failed_requests SCHEMALESS COMMENT \"Created by Shokupan\";\n DEFINE TABLE OVERWRITE sessions SCHEMALESS COMMENT \"Created by Shokupan\";\n DEFINE TABLE OVERWRITE users SCHEMALESS COMMENT \"Created by Shokupan\";\n DEFINE TABLE OVERWRITE idempotency_keys SCHEMALESS COMMENT \"Created by Shokupan\";\n DEFINE TABLE OVERWRITE middleware_tracking SCHEMALESS COMMENT \"Created by Shokupan\";\n DEFINE TABLE OVERWRITE requests SCHEMALESS COMMENT \"Created by Shokupan\";\n DEFINE TABLE OVERWRITE metrics SCHEMALESS COMMENT \"Created by Shokupan\";\n `).collect();\n }\n\n /**\n * Select a record or contents of a table by its ID.\n */\n async select<T = unknown>(id: RecordId | RecordIdRange | Table) {\n return this.db.select<T>(id as any);\n }\n\n /**\n * Merge update data into a record by its ID.\n */\n async merge<T extends Record<string, any>>(id: RecordId, data: T) {\n return this.db.update<T>(id).merge(data).catch((err: any) => {\n if (err.message.includes('This transaction can be retried')) {\n return this.db.update<T>(id).merge(data);\n }\n throw err;\n });\n }\n\n /**\n * Create a record by its ID.\n */\n async create<T extends Record<string, any>>(id: RecordId, data: Omit<T, 'id'>) {\n return this.db.create(id).content(data).catch((err: any) => {\n if (err.message.includes('This transaction can be retried')) {\n return this.db.create(id).content(data);\n }\n throw err;\n });\n }\n\n /**\n * Upsert a record by its ID.\n */\n async upsert<T extends Record<string, any>>(id: RecordId, data: T) {\n return this.db.upsert<T>(id).content(data).catch((err: any) => {\n if (err.message.includes('This transaction can be retried')) {\n return this.db.upsert<T>(id).content(data);\n }\n throw err;\n });\n }\n\n /**\n * Delete a record by its ID.\n */\n async delete(id: RecordId) {\n return this.db.delete(id).catch((err: any) => {\n if (err.message.includes('This transaction can be retried')) {\n return this.db.delete(id);\n }\n throw err;\n });\n }\n\n /**\n * Run a SurrealDB query.\n */\n async query<T extends Array<unknown>>(query: string, vars?: Record<string, any>) {\n return this.db.query(query, vars).collect<T>().catch((err: any) => {\n if (err.message.includes('This transaction can be retried')) {\n return this.db.query(query, vars).collect<T>();\n }\n throw err;\n });\n }\n\n /**\n * Create a relationship between two records.\n */\n async relate(fromId, edgeId, toId, data?: Record<string, any>) {\n return this.db.relate(fromId, edgeId, toId, data).catch((err: any) => {\n if (err.message.includes('This transaction can be retried')) {\n return this.db.relate(fromId, edgeId, toId, data);\n }\n throw err;\n });\n }\n\n\n disconnect() {\n return this.db.close();\n }\n}\n","import { context, trace } from '@opentelemetry/api';\nimport type { Server } from 'bun';\nimport { dump } from 'js-yaml';\nimport { Surreal } from 'surrealdb';\nimport { ShokupanContext } from \"./context\";\nimport { compose } from \"./middleware\";\nimport { generateOpenApi } from \"./plugins/application/openapi/openapi\";\nimport { ShokupanRouter } from './router';\nimport { BunAdapter, NodeAdapter } from './util/adapter/adapters';\nimport { DefaultFileSystemAdapter } from './util/adapter/filesystem';\nimport { asyncContext, RequestContextStore } from \"./util/async-hooks\";\nimport { SystemCpuMonitor } from \"./util/cpu-monitor\";\nimport { SurrealDatastore } from './util/datastore';\nimport { getErrorStatus } from \"./util/http-error\";\nimport { HTTP_STATUS } from \"./util/http-status\";\nimport \"./util/instrumentation\";\nimport { MiddlewareTracker } from './util/middleware-tracker';\nimport { ShokupanRequest } from './util/request';\nimport { getCallerInfo } from './util/stack';\nimport { $appRoot, $dispatch, $finalResponse, $isApplication, $routeMatched } from './util/symbol';\nimport type { Method, Middleware, ProcessResult, RequestOptions, ShokupanConfig, ShokupanPlugin } from './util/types';\n\n\nconst defaults: ShokupanConfig = {\n port: 3000,\n hostname: \"localhost\",\n development: process.env.NODE_ENV !== \"production\",\n enableAsyncLocalStorage: false,\n enableHttpBridge: false,\n reusePort: false,\n};\n\n\n/**\n * Shokupan Application\n * \n * The main application class for creating a Shokupan web server.\n * \n * @template State - The shape of `ctx.state` for all routes in the application.\n * Use this to provide type safety for state management across middleware and handlers.\n * \n * @example Basic Usage\n * ```typescript\n * const app = new Shokupan();\n * app.get('/hello', (ctx) => ctx.json({ message: 'Hello' }));\n * await app.listen(3000);\n * ```\n * \n * @example Typed State\n * ```typescript\n * interface AppState {\n * userId: string;\n * tenant: string;\n * requestId: string;\n * }\n * \n * const app = new Shokupan<AppState>();\n * \n * // Middleware has typed state access\n * app.use((ctx, next) => {\n * ctx.state.userId = 'user-123'; // ✓ Type-safe\n * ctx.state.requestId = crypto.randomUUID();\n * return next();\n * });\n * \n * // Handlers have typed state access\n * app.get('/profile', (ctx) => {\n * const { userId, tenant } = ctx.state; // ✓ TypeScript knows these exist\n * return ctx.json({ userId, tenant });\n * });\n * ```\n * \n * @example Empty State (No State Management)\n * ```typescript\n * import { EmptyState } from 'shokupan';\n * \n * const app = new Shokupan<EmptyState>();\n * // ctx.state will be an empty object with no properties\n * ```\n * \n * @example Combining Path Params and State\n * ```typescript\n * interface RequestState {\n * userId: string;\n * permissions: string[];\n * }\n * \n * const app = new Shokupan<RequestState>();\n * \n * app.get('/users/:userId/posts/:postId', (ctx) => {\n * // Both params and state are fully typed!\n * const { userId, postId } = ctx.params; // ✓ Path params typed\n * const { permissions } = ctx.state; // ✓ State typed\n * return ctx.json({ userId, postId, permissions });\n * });\n * ```\n */\nexport class Shokupan<T = any> extends ShokupanRouter<T> {\n readonly applicationConfig: ShokupanConfig = {};\n public openApiSpec?: any;\n public asyncApiSpec?: any;\n private openApiSpecPromise?: Promise<any>;\n private asyncApiSpecPromise?: Promise<any>;\n private composedMiddleware?: Middleware;\n private cpuMonitor?: SystemCpuMonitor;\n private server?: Server<any>;\n private datastore?: SurrealDatastore;\n public dbPromise?: Promise<any>;\n\n public override get db(): SurrealDatastore | undefined {\n return this.datastore;\n }\n\n get logger() {\n return this.applicationConfig.logger;\n }\n\n\n constructor(\n applicationConfig: ShokupanConfig = {}\n ) {\n const config = Object.assign({}, defaults, applicationConfig);\n\n // Initialize Default FileSystem Adapter if not provided\n config.fileSystem ??= new DefaultFileSystemAdapter();\n\n // Exclude hooks from the router config passed to super() to avoid double execution\n // The application handles app-level hooks in handleRequest()\n const { hooks, ...routerConfig } = config;\n super({ ...routerConfig, hooks });\n\n this[$isApplication] = true;\n this[$appRoot] = this;\n this.applicationConfig = config;\n\n // Capture metadata for the application instance\n const { file, line } = getCallerInfo();\n this.metadata = {\n file,\n line,\n name: 'ShokupanApplication'\n };\n\n if (this.applicationConfig.adapter !== 'wintercg') {\n this.dbPromise = this.initDatastore().catch(err => {\n // Log but don't crash if optional datastore init fails\n this.logger?.debug(\"Failed to initialize default datastore\", { error: err });\n });\n }\n }\n\n private async initDatastore() {\n let engines = this.applicationConfig.surreal?.engines;\n\n if (!engines && !this.applicationConfig.surreal?.url?.match(/^(?:wss?|https?):\\/\\//)) {\n engines = (await import('@surrealdb/node')).createNodeEngines();\n }\n\n const db = new Surreal({ engines });\n this.datastore = new SurrealDatastore(db);\n\n await db.connect(\n this.applicationConfig.surreal?.url ?? (process.env.NODE_ENV === 'test' ? 'mem://' : 'surrealkv://database'),\n this.applicationConfig.surreal?.connectOptions\n ).catch(err => {\n this.logger?.error(\"Failed to connect to SurrealDB\", { error: err });\n });\n\n await db.use({\n namespace: this.applicationConfig.surreal?.namespace ?? \"vendor\",\n database: this.applicationConfig.surreal?.database ?? \"shokupan\"\n });\n\n await db.query(\"DEFINE TABLE OVERWRITE request;\");\n await db.query(\"DEFINE TABLE OVERWRITE failed_request;\");\n await db.query(\"DEFINE TABLE OVERWRITE metric;\");\n\n }\n\n /**\n * Adds middleware to the application.\n */\n /**\n * Adds middleware to the application.\n */\n public override use(middleware: Middleware) {\n\n // --- Middleware Tracking Logic ---\n const { file, line } = getCallerInfo();\n\n const wrapped = MiddlewareTracker.wrap(middleware, {\n file,\n line,\n name: middleware.name || 'middleware',\n isBuiltin: (middleware as any).isBuiltin,\n pluginName: (middleware as any).pluginName\n });\n\n if (this.applicationConfig.enableMiddlewareTracking) {\n (wrapped as any).order = this.middleware.length;\n this.middleware.push(wrapped);\n } else {\n this.middleware.push(middleware);\n }\n\n return this;\n }\n\n /**\n * Registers a plugin.\n */\n public register(plugin: ShokupanPlugin, options?: { path?: string; }) {\n plugin.onInit(this, options);\n return this;\n }\n\n private startupHooks: (() => Promise<void> | void)[] = [];\n\n /**\n * Registers a callback to be executed before the server starts listening.\n */\n public onStart(callback: () => Promise<void> | void) {\n this.startupHooks.push(callback);\n return this;\n }\n\n private specAvailableHooks: ((spec: any) => void | Promise<void>)[] = [];\n\n /**\n * Registers a callback to be executed when the OpenAPI spec is available.\n * This happens after generateOpenApi() but before the server starts listening (or at least before it finishes startup if async).\n */\n public onSpecAvailable(callback: (spec: any) => void | Promise<void>) {\n this.specAvailableHooks.push(callback);\n return this;\n }\n\n /**\n * Starts the application server.\n * \n * @param port - The port to listen on. If not specified, the port from the configuration is used. If that is not specified, port 3000 is used.\n * @returns The server instance.\n */\n public async listen(port?: number) {\n const finalPort = port ?? this.applicationConfig.port ?? 3000;\n\n if (finalPort < 0 || finalPort > 65535 || finalPort % 1 !== 0) {\n throw new Error(\"Invalid port number\");\n }\n\n // Run startup hooks\n await Promise.all(this.startupHooks.map(hook => hook()));\n\n if (this.applicationConfig.enableOpenApiGen) {\n // --- Well-Known Files Implementation ---\n\n // 1. .well-known/openapi.yaml\n this.get(\"/.well-known/openapi.yaml\", async (ctx) => {\n try {\n // Wait for spec if not ready yet\n await this.openApiSpecPromise;\n const yaml = dump(this.openApiSpec);\n return ctx.send(yaml, { status: 200, headers: { 'content-type': 'application/yaml' } });\n } catch (e) {\n this.logger?.error(\"Failed to generate OpenAPI YAML\", { error: e });\n return ctx.text(\"Internal Server Error\", 500);\n }\n });\n\n // 2. .well-known/ai-plugin.json\n if (this.applicationConfig.aiPlugin?.enabled !== false) {\n this.get(\"/.well-known/ai-plugin.json\", async (ctx) => {\n // Wait for spec if not ready yet\n await this.openApiSpecPromise;\n\n const config = this.applicationConfig.aiPlugin || {};\n let pkg: any = {};\n try {\n pkg = await Bun.file(\"package.json\").json();\n } catch (e) { }\n\n const manifest = {\n schema_version: \"v1\",\n name_for_human: config.name_for_human || this.openApiSpec.info.title || pkg.name || \"Shokupan App\",\n name_for_model: config.name_for_model || this.openApiSpec.info.title || pkg.name || \"Shokupan App\",\n description_for_human: config.description_for_human || this.openApiSpec.info.description || pkg.description || \"Shokupan Application\",\n description_for_model: config.description_for_model || this.openApiSpec.info.description || pkg.description || \"Shokupan Application\",\n auth: config.auth || { type: \"none\" },\n api: config.api || {\n type: \"openapi\",\n url: `${this.applicationConfig.hostname === 'localhost' ? 'http' : 'https'}://${this.applicationConfig.hostname}:${finalPort}/.well-known/openapi.yaml`,\n is_user_authenticated: false\n },\n logo_url: config.logo_url || `${this.applicationConfig.hostname === 'localhost' ? 'http' : 'https'}://${this.applicationConfig.hostname}:${finalPort}/logo.png`, // Placeholder default\n contact_email: config.contact_email || pkg.author?.email || \"support@example.com\",\n legal_info_url: config.legal_info_url || `${this.applicationConfig.hostname === 'localhost' ? 'http' : 'https'}://${this.applicationConfig.hostname}:${finalPort}/legal`\n };\n\n return ctx.json(manifest);\n });\n }\n\n // 3. .well-known/api-catalog\n if (this.applicationConfig.apiCatalog?.enabled !== false) {\n this.get(\"/.well-known/api-catalog\", async (ctx) => {\n // Wait for spec if not ready yet\n await this.openApiSpecPromise;\n\n const config = this.applicationConfig.apiCatalog || {};\n const catalog = {\n versions: config.versions || [\n {\n name: this.openApiSpec.info.version || \"v1\",\n url: `${this.applicationConfig.hostname === 'localhost' ? 'http' : 'https'}://${this.applicationConfig.hostname}:${finalPort}/`,\n spec_url: `${this.applicationConfig.hostname === 'localhost' ? 'http' : 'https'}://${this.applicationConfig.hostname}:${finalPort}/.well-known/openapi.yaml`\n }\n ]\n };\n return ctx.json(catalog);\n });\n }\n\n // Create the generation promise\n this.openApiSpecPromise = generateOpenApi(this).then(spec => {\n this.openApiSpec = spec;\n return spec;\n });\n\n // Decide whether to block or not\n const shouldBlock = this.applicationConfig.blockOnOpenApiGen !== false;\n\n if (shouldBlock) {\n // Wait for generation to complete before proceeding\n await this.openApiSpecPromise;\n }\n\n // Run spec available hooks (either now after blocking, or later after async completion)\n if (shouldBlock) {\n await Promise.all(this.specAvailableHooks.map(hook => hook(this.openApiSpec)));\n } else {\n // Run hooks after async generation completes\n this.openApiSpecPromise.then(spec => {\n return Promise.all(this.specAvailableHooks.map(hook => hook(spec)));\n }).catch(err => {\n this.logger?.error(\"Error running spec available hooks\", { error: err });\n });\n }\n }\n\n if (this.applicationConfig.enableAsyncApiGen) {\n const { generateAsyncApi } = await import(\"./plugins/application/asyncapi/generator\");\n\n // Create the generation promise\n this.asyncApiSpecPromise = generateAsyncApi(this).then(spec => {\n this.asyncApiSpec = spec;\n return spec;\n });\n\n // Decide whether to block or not\n const shouldBlock = this.applicationConfig.blockOnAsyncApiGen !== false;\n\n if (shouldBlock) {\n await this.asyncApiSpecPromise;\n }\n }\n\n if (port === 0 && process.platform === \"linux\") {\n\n }\n\n if (this.applicationConfig.autoBackpressureFeedback === true) {\n this.cpuMonitor = new SystemCpuMonitor();\n this.cpuMonitor.start();\n }\n\n\n // Use Adapter\n let adapter = this.applicationConfig.adapter;\n if (!adapter) {\n // Auto-detect if adapter not specified\n // @ts-ignore\n if (typeof Bun !== \"undefined\") {\n this.applicationConfig.adapter = 'bun';\n adapter = new BunAdapter();\n } else {\n this.applicationConfig.adapter = 'node';\n adapter = new NodeAdapter();\n }\n } else if (adapter === 'bun') {\n adapter = new BunAdapter();\n } else if (adapter === 'node') {\n adapter = new NodeAdapter();\n } else if (adapter === 'wintercg') {\n // WinterCG adapter doesn't listen\n throw new Error(\"WinterCG adapter does not support listen(). Use fetch directly.\");\n }\n\n // @ts-ignore\n this.server = await adapter.listen(finalPort, this);\n return this.server;\n }\n\n\n /**\n * Stops the application server.\n * \n * This method gracefully shuts down the server and stops any running monitors.\n * Works transparently in both Bun and Node.js runtimes.\n * \n * @returns A promise that resolves when the server has been stopped.\n * \n * @example\n * ```typescript\n * const app = new Shokupan();\n * const server = await app.listen(3000);\n * \n * // Later, when you want to stop the server\n * await app.stop();\n * ```\n * @param closeActiveConnections — Immediately terminate in-flight requests, websockets, and stop accepting new connections.\n */\n public async stop(closeActiveConnections?: boolean): Promise<void> {\n // Stop CPU monitor if running\n if (this.cpuMonitor) {\n this.cpuMonitor.stop();\n this.cpuMonitor = undefined;\n }\n\n // Stop the server if it exists\n if (this.server) {\n await this.server.stop(closeActiveConnections);\n this.server = undefined;\n }\n }\n\n public [$dispatch](req: ShokupanRequest<T>) {\n return this.fetch(req as unknown as Request);\n }\n\n /**\n * Processes a request by wrapping the standard fetch method.\n */\n public override async testRequest(options: RequestOptions): Promise<ProcessResult> {\n let url = options.url || options.path || \"/\";\n if (!url.startsWith(\"http\")) {\n const base = `http://${this.applicationConfig.hostname || \"localhost\"}:${this.applicationConfig.port || 3000}`;\n const path = url.startsWith(\"/\") ? url : \"/\" + url;\n url = base + path;\n }\n\n if (options.query) {\n const u = new URL(url);\n const entries = Object.entries(options.query);\n for (let i = 0; i < entries.length; i++) {\n const [k, v] = entries[i];\n u.searchParams.set(k, v);\n }\n url = u.toString();\n }\n\n // Create Request to pass to fetch\n const reqBody = options.body && typeof options.body === \"object\" ? JSON.stringify(options.body) : options.body;\n const reqHeaders = new Headers(options.headers as any);\n if (typeof options.body === \"object\" && !reqHeaders.has(\"content-type\")) {\n reqHeaders.set(\"content-type\", \"application/json\");\n }\n\n const req = new ShokupanRequest({\n method: (options.method || \"GET\") as Method,\n url,\n headers: reqHeaders,\n body: reqBody\n }) as unknown as ShokupanRequest<T>;\n\n const res = await this.fetch(req as unknown as Request);\n\n // Convert Response to ProcessResult\n const status = res.status;\n const headers: Record<string, string> = {};\n res.headers.forEach((v, k) => headers[k] = v);\n\n let data: any;\n if (headers['content-type']?.includes('application/json')) {\n data = await res.json();\n }\n else {\n data = await res.text();\n }\n\n return {\n status,\n headers,\n data\n };\n }\n\n /**\n * Handles an incoming request (Bun.serve interface).\n * This logic contains the middleware chain and router dispatch.\n * \n * @param req - The request to handle.\n * @param server - The server instance.\n * @returns The response to send.\n */\n public async fetch(req: Request, server?: Server<any>): Promise<Response> {\n\n\n if (this.applicationConfig.enableTracing) {\n const tracer = trace.getTracer(\"shokupan.application\");\n const store = asyncContext.getStore();\n\n const attrs = {\n attributes: {\n \"http.url\": req.url,\n \"http.method\": req.method\n }\n };\n\n const parent = store?.span;\n const ctx = parent ? trace.setSpan(context.active(), parent) : undefined;\n return tracer.startActiveSpan(`${req.method} ${new URL(req.url).pathname}`, attrs, ctx, span => {\n const ctxStore = new RequestContextStore();\n ctxStore.span = span;\n ctxStore.request = req;\n\n return asyncContext.run(ctxStore, () => this.handleRequest(req, server).finally(() => span.end()));\n });\n }\n\n // If ALS is enabled but tracing is not\n if (this.applicationConfig.enableAsyncLocalStorage) {\n const ctxStore = new RequestContextStore();\n ctxStore.request = req;\n return asyncContext.run(ctxStore, () => this.handleRequest(req, server));\n }\n\n return this.handleRequest(req, server);\n }\n\n private async handleRequest(req: Request, server?: Server<any>): Promise<Response> {\n // Cast to ShokupanRequest if needed, though at runtime it's just a Request\n // But ShokupanContext expects ShokupanRequest.\n const request = req as unknown as ShokupanRequest<T>;\n\n const controller = new AbortController();\n const ctx = new ShokupanContext<T>(request, server, undefined, this, controller.signal, this.applicationConfig.enableMiddlewareTracking);\n\n const handle = async () => {\n\n // Auto-Backpressure Check\n if (this.cpuMonitor && this.cpuMonitor.getUsage() > (this.applicationConfig.autoBackpressureLevel ?? 60)) {\n // Return 429 immediately\n const msg = \"Too Many Requests (CPU Backpressure)\";\n const res = ctx.text(msg, 429);\n // Trigger hooks so metrics are recorded\n if (this.hasOnResponseEndHook) await this.runHooks('onResponseEnd', ctx, res);\n return res;\n }\n\n try {\n // Request Start Hook\n // Request Start Hook\n if (this.hasOnRequestStartHook) await this.runHooks('onRequestStart', ctx);\n\n // Compose middleware + router dispatch\n const fn = this.composedMiddleware ??= compose(this.middleware);\n\n // Object.defineProperty(fn, 'name', { value: \"middleware chain\", configurable: false });\n\n // The \"next\" at the end of the middleware chain is the router dispatch\n const result = await fn(ctx, async () => {\n // Start body parsing early for applicable HTTP methods to overlap with route lookup\n let bodyParsing: Promise<void> | undefined;\n if (req.method !== 'GET' && req.method !== 'HEAD') {\n // For POST/PUT/PATCH/DELETE, start parsing\n bodyParsing = ctx.parseBody();\n }\n\n const match = this.find(req.method, ctx.path);\n\n\n if (match) {\n ctx[$routeMatched] = true;\n ctx.params = match.params;\n\n // Ensure body is parsed before handler executes\n if (bodyParsing) await bodyParsing;\n\n return match.handler(ctx);\n }\n\n return null;\n });\n\n let response: Response | Promise<Response>;\n if (result instanceof Response) {\n response = result;\n }\n // Check explicit void return but response set in context\n else if ((result === null || result === undefined) && ctx[$finalResponse] instanceof Response) {\n response = ctx[$finalResponse];\n }\n // (Logic moved to main block below)\n else if (result === null || result === undefined) {\n // Handler returned nothing (void/null/undefined)\n\n if (ctx[$finalResponse] instanceof Response) {\n response = ctx[$finalResponse];\n }\n else if (ctx.isUpgraded) {\n // Request was successfully upgraded to WebSocket\n return undefined as unknown as Response;\n }\n // 2. Logic Split: Route Matched vs Not Found\n else if (ctx[$routeMatched]) {\n // A route WAS matched but returned nothing.\n // Default to 200 OK (unless user set status manually via ctx.response.status)\n // We send an empty response with the context's status (defaults to 200)\n response = ctx.send(null, { status: ctx.response.status, headers: ctx.response.headers });\n }\n else {\n // Fallback: If no route matched, check if it's a WebSocket upgrade request that can be handled by default handlers\n // This supports Shokupan's Native WebSocket Events if no specific middleware/route handled it\n if (ctx.upgrade()) {\n return undefined as unknown as Response;\n }\n\n // No route matched - return 404 Not Found\n // Exception: If middleware manually changed the status from default 200,\n // respect that (e.g., auth middleware set 401)\n if (ctx.response.status !== HTTP_STATUS.OK) {\n response = ctx.send(null, { status: ctx.response.status, headers: ctx.response.headers });\n } else {\n response = ctx.text(\"Not Found\", HTTP_STATUS.NOT_FOUND);\n }\n }\n }\n else if (typeof result === \"object\") {\n response = ctx.json(result);\n }\n else {\n response = ctx.text(String(result));\n }\n\n // Request End Hook - Processing finished, response ready\n if (this.hasOnRequestEndHook) await this.runHooks('onRequestEnd', ctx);\n\n if (response instanceof Promise) {\n response = await response;\n }\n\n // Response Start Hook - About to send response\n if (this.hasOnResponseStartHook) await this.runHooks('onResponseStart', ctx, response);\n\n return response;\n\n }\n catch (err: any) {\n const span = asyncContext.getStore()?.span;\n if (span) span.setStatus({ code: 2 }); // Error\n\n // Extract status from error object (supports both .status and .statusCode)\n let status = getErrorStatus(err);\n\n // Handle JSON Parse errors specifically\n if (err instanceof SyntaxError && err.message.includes('JSON')) {\n status = 400;\n }\n\n const body: any = { error: err.message || \"Internal Server Error\" };\n if (err.errors) body.errors = err.errors;\n\n // Error Hook\n if (this.hasOnErrorHook) await this.runHooks('onError', ctx, err);\n\n return ctx.json(body, status);\n }\n };\n\n // Timeout Logic\n let executionPromise = handle();\n const timeoutMs = this.applicationConfig.requestTimeout;\n\n if (timeoutMs && timeoutMs > 0) {\n let timeoutId: any;\n const timeoutPromise = new Promise<Response>((_, reject) => {\n timeoutId = setTimeout(async () => {\n controller.abort(); // Signal cancellation to handlers\n await this.runHooks('onRequestTimeout', ctx);\n reject(new Error(\"Request Timeout\"));\n }, timeoutMs);\n });\n\n executionPromise = Promise.race([executionPromise, timeoutPromise])\n .finally(() => clearTimeout(timeoutId));\n }\n\n return executionPromise\n .catch((err) => {\n if (err.message === \"Request Timeout\") {\n return ctx.text(\"Request Timeout\", HTTP_STATUS.REQUEST_TIMEOUT);\n }\n console.error(\"Unexpected error in request execution:\", err);\n return ctx.text(\"Internal Server Error\", HTTP_STATUS.INTERNAL_SERVER_ERROR);\n })\n .then(async (res) => {\n // Response End Hook - Response returned\n // Note: We can't guarantee it's fully sent to client here, but it's handed off to Bun\n await this.runHooks('onResponseEnd', ctx, res);\n return res;\n });\n }\n}\n","import type { ShokupanContext } from \"../../context\";\nimport type { Middleware, NextFn } from \"../../util/types\";\n\nexport interface RateLimitOptions {\n /**\n * Window in milliseconds\n */\n windowMs?: number;\n /**\n * Maximum number of requests allowed in the window\n */\n max?: number;\n /**\n * Alias for max\n */\n limit?: number;\n /**\n * Message to send when rate limited\n */\n message?: string | object | ((ctx: ShokupanContext, key: string) => string | object);\n /**\n * Status code to send when rate limited\n */\n statusCode?: number;\n /**\n * Whether to include X-RateLimit headers in the response\n */\n headers?: boolean;\n /**\n * Function to generate a unique key for each request\n * This is used to identify the user or source of the request\n * Defaults to the request's ip address.\n */\n keyGenerator?: (ctx: ShokupanContext) => string;\n /**\n * Function to execute when a request is rate limited\n */\n onRateLimited?: (ctx: ShokupanContext, key: string) => void | Response | Promise<void | Response>;\n /**\n * Function to determine whether to skip rate limiting\n */\n skip?: (ctx: ShokupanContext) => boolean;\n /**\n * Mode to use for rate limiting\n * - user: Rate limit per user (generated key, defaults to ip address)\n * - absolute: Rate limit for all users\n */\n mode?: 'user' | 'absolute';\n /**\n * List of trusted proxy IPs\n */\n trustedProxies?: string[];\n}\n\ninterface HitRecord {\n hits: number;\n resetTime: number;\n}\n\n/**\n * Rate limit middleware.\n * @param options Rate limit options\n * @returns Middleware function\n */\nexport function RateLimitMiddleware(options: RateLimitOptions = {}): Middleware {\n const windowMs = options.windowMs || 60 * 1000; // 1 minute\n const max = options.limit || options.max || 5; // 5 requests per window\n const message = options.message || \"Too many requests, please try again later.\";\n const statusCode = options.statusCode || 429;\n const headers = options.headers !== false;\n const mode = options.mode || 'user';\n const trustedProxies = options.trustedProxies || [];\n\n const keyGenerator = options.keyGenerator || ((ctx) => {\n if (mode === 'absolute') {\n return 'global';\n }\n\n // Security: Use proper IP detection with trusted proxy support\n const xForwardedFor = ctx.headers.get(\"x-forwarded-for\");\n\n if (xForwardedFor && trustedProxies.length > 0) {\n // Parse X-Forwarded-For from right to left (most recent proxy first)\n const ips = xForwardedFor.split(',').map(ip => ip.trim());\n\n // Get the rightmost IP that is not in trusted proxies\n for (let i = ips.length - 1; i >= 0; i--) {\n const ip = ips[i];\n if (!trustedProxies.includes(ip)) {\n // Validate IP format (basic check)\n if (/^[\\d.:a-fA-F]+$/.test(ip)) {\n return ip;\n }\n }\n }\n }\n\n // Fallback to server IP detection\n return (ctx.server as any)?.requestIP?.(ctx.request)?.address || \"unknown\";\n });\n const skip = options.skip || (() => false);\n\n // In-memory store\n const hits = new Map<string, HitRecord>();\n\n // Cleanup interval\n const interval = setInterval(() => {\n const now = Date.now();\n const entries = Array.from(hits.entries());\n for (let i = 0; i < entries.length; i++) {\n const [key, record] = entries[i];\n if (record.resetTime <= now) {\n hits.delete(key);\n }\n }\n }, windowMs);\n\n // Ensure interval doesn't block process exit\n if (interval.unref) interval.unref();\n\n const rateLimitMiddleware: Middleware = async function RateLimitMiddleware(ctx: ShokupanContext, next: NextFn) {\n if (skip(ctx)) return next();\n\n const key = keyGenerator(ctx);\n const now = Date.now();\n let record = hits.get(key);\n\n // Initialize record if not exists or expired\n if (!record || record.resetTime <= now) {\n record = {\n hits: 0,\n resetTime: now + windowMs\n };\n hits.set(key, record);\n }\n\n record.hits++;\n\n const remaining = Math.max(0, max - record.hits);\n const resetTime = Math.ceil(record.resetTime / 1000); // Epoch seconds\n const retryAfter = Math.ceil((record.resetTime - now) / 1000); // Seconds until reset\n\n // Helper to set headers\n const setHeaders = (res: Response | any) => {\n if (!headers || !res || !res.headers) return;\n try {\n res.headers.set(\"X-RateLimit-Limit\", String(max));\n res.headers.set(\"X-RateLimit-Remaining\", String(remaining));\n res.headers.set(\"X-RateLimit-Reset\", String(resetTime));\n } catch (e) { /* ignore */ }\n };\n\n if (record.hits > max) {\n\n if (options.onRateLimited) {\n const result = await options.onRateLimited(ctx, key);\n if (result instanceof Response) {\n return result;\n }\n }\n\n // Dispatch 429\n const msg = typeof message === 'function' ? message(ctx, key) : message;\n const res = await (typeof msg === 'object' ? ctx.json(msg, statusCode) : ctx.text(String(msg), statusCode));\n\n if (headers) {\n setHeaders(res);\n res.headers.set(\"Retry-After\", String(retryAfter));\n }\n\n return res;\n }\n\n const response = await next();\n\n // If response is a Response object, attach headers\n if (response instanceof Response && headers) {\n setHeaders(response);\n }\n\n return response;\n };\n\n rateLimitMiddleware.isBuiltin = true;\n rateLimitMiddleware.pluginName = 'RateLimit';\n\n return rateLimitMiddleware;\n}\n","import { RateLimitMiddleware, type RateLimitOptions } from \"../plugins/middleware/rate-limit\";\nimport { getCallerInfo } from \"./stack\";\nimport { $controllerPath, $eventMethods, $middleware, $routeArgs, $routeMethods, $routeSpec } from \"./symbol\";\nimport type { AsyncAPISpec, GuardAPISpec, MethodAPISpec } from \"./types\";\nimport { type Method, type Middleware, RouteParamType } from \"./types\";\n\n/**\n * Class Decorator: Defines the base path for a controller.\n */\nexport function Controller(path: string = \"/\") {\n return (target: any) => {\n target[$controllerPath] = path;\n };\n}\n\n/**\n * Decorator: Applies middleware to a class or method.\n */\nexport function Use(...middleware: Middleware[]) {\n return (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) => {\n // If propertyKey is undefined, it's a class decorator\n if (!propertyKey) {\n const existing = target[$middleware] || [];\n target[$middleware] = [...existing, ...middleware];\n }\n // Method decorator\n else {\n if (!target[$middleware]) {\n target[$middleware] = new Map();\n }\n const existing = target[$middleware].get(propertyKey) || [];\n target[$middleware].set(propertyKey, [...existing, ...middleware]);\n }\n };\n}\n\n// --- Parameter Decorators ---\n\nfunction createParamDecorator(type: RouteParamType) {\n return (name?: string) => {\n return (target: any, propertyKey: string, parameterIndex: number) => {\n if (!target[$routeArgs]) {\n target[$routeArgs] = new Map();\n }\n if (!target[$routeArgs].has(propertyKey)) {\n target[$routeArgs].set(propertyKey, []);\n }\n target[$routeArgs].get(propertyKey).push({\n index: parameterIndex,\n type,\n name\n });\n };\n };\n}\n\n/**\n * Decorator: Binds a parameter to the request body.\n */\nexport const Body = createParamDecorator(RouteParamType.BODY);\n\n/**\n * Decorator: Binds a parameter to the request parameters.\n */\nexport const Param = createParamDecorator(RouteParamType.PARAM);\n\n/**\n * Decorator: Binds a parameter to the request query string.\n */\nexport const Query = createParamDecorator(RouteParamType.QUERY);\n\n/**\n * Decorator: Binds a parameter to the request headers.\n */\nexport const Headers = createParamDecorator(RouteParamType.HEADER);\n\n/**\n * Decorator: Binds a parameter to the request object.\n */\nexport const Req = createParamDecorator(RouteParamType.REQUEST);\n\n/**\n * Decorator: Binds a parameter to the request context.\n */\nexport const Ctx = createParamDecorator(RouteParamType.CONTEXT);\n\n\n/**\n * Decorator: Overrides the OpenAPI specification for a route.\n */\nexport function Spec(spec: MethodAPISpec | GuardAPISpec | AsyncAPISpec) {\n return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {\n if (!target[$routeSpec]) {\n target[$routeSpec] = new Map();\n }\n target[$routeSpec].set(propertyKey, spec);\n };\n}\n\n/**\n * Creates a method decorator for a specific HTTP verb.\n */\nfunction createMethodDecorator(method: Method) {\n return (path: string = \"/\") => {\n return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {\n if (!target[$routeMethods]) {\n target[$routeMethods] = new Map();\n }\n\n target[$routeMethods].set(propertyKey, {\n method,\n path,\n source: getCallerInfo(2)\n });\n if (path.includes('/user')) {\n console.log(`[Decorator] Captured source for ${propertyKey}:`, getCallerInfo());\n }\n };\n };\n}\n\n/**\n * Decorator: Binds a method to the GET HTTP verb.\n */\nexport const Get = createMethodDecorator(\"GET\");\n\n/**\n * Decorator: Binds a method to the POST HTTP verb.\n */\nexport const Post = createMethodDecorator(\"POST\");\n\n/**\n * Decorator: Binds a method to the PUT HTTP verb.\n */\nexport const Put = createMethodDecorator(\"PUT\");\n\n/**\n * Decorator: Binds a method to the DELETE HTTP verb.\n */\nexport const Delete = createMethodDecorator(\"DELETE\");\n\n/**\n * Decorator: Binds a method to the PATCH HTTP verb.\n */\nexport const Patch = createMethodDecorator(\"PATCH\");\n\n/**\n * Decorator: Binds a method to the OPTIONS HTTP verb.\n */\nexport const Options = createMethodDecorator(\"OPTIONS\");\n\n/**\n * Decorator: Binds a method to the HEAD HTTP verb.\n */\nexport const Head = createMethodDecorator(\"HEAD\");\n\n/**\n * Decorator: Binds a method to ANY HTTP verb.\n */\nexport const All = createMethodDecorator(\"ALL\");\n\n/**\n * Decorator: Binds a method to the WebSocket event.\n * @param eventName The name of the event to listen for.\n */\nexport function Event(eventName: string) {\n return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {\n target[$eventMethods] ??= new Map();\n target[$eventMethods].set(propertyKey, {\n eventName\n });\n };\n}\n\n/**\n * Decorator: Applies a rate limit to a class or method.\n */\nexport function RateLimit(options: RateLimitOptions) {\n return Use(RateLimitMiddleware(options));\n}\n","\n\n// Type definitions for better clarity\ninterface Route {\n method: string;\n path: string;\n op: any;\n}\n\ninterface GroupNode {\n name: string;\n type: 'group' | 'subgroup' | 'route';\n routes?: Route[];\n children?: GroupNode[];\n path?: string;\n isBuiltin?: boolean;\n}\n\nexport function ApiExplorerApp({ spec, asyncSpec, config }: any) {\n // Build hierarchy: router -> controller -> routes\n const hierarchy = new Map<string, Route[]>();\n\n // Helper to add route to hierarchy\n const addRoute = (groupKey: string, route: Route) => {\n if (!hierarchy.has(groupKey)) {\n hierarchy.set(groupKey, []);\n }\n hierarchy.get(groupKey)!.push(route);\n };\n\n // Helper to determine group key (controller/router)\n const getGroupKey = (op: any, source: any): string => {\n // 1. Prefer explicit tags if they look like \"titles\" (not paths)\n if (op.tags && op.tags.length > 0) {\n const tag = typeof op.tags[0] === 'string' ? op.tags[0] : op.tags[0].name;\n if (!tag.startsWith('/')) return tag;\n }\n\n // 2. Class Name (Controller)\n if (source?.className) return source.className;\n\n // 3. File Name (Router - Pretty)\n if (source?.file) {\n const parts = source.file.split('/');\n const filename = parts[parts.length - 1].replace(/\\.(ts|js)$/, '');\n // Convert snake_case or kebab-case to Title Case\n return filename.split(/[-_]/).map((w: string) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');\n }\n\n // 4. Fallback to path tag if we ignored it in step 1\n if (op.tags && op.tags.length > 0) {\n const tag = typeof op.tags[0] === 'string' ? op.tags[0] : op.tags[0].name;\n return tag;\n }\n\n return 'Ungrouped';\n };\n\n // Helper to find the longest common prefix of all paths in a group\n const findCommonPrefix = (routes: Route[]): string[] => {\n if (routes.length === 0) return [];\n\n const allSegments = routes.map(r => {\n const cleaned = r.path.replace(/^\\/|\\/$/g, '');\n return cleaned.split('/');\n });\n\n // Find the shortest path length\n const minLength = Math.min(...allSegments.map(s => s.length));\n\n const commonPrefix: string[] = [];\n for (let i = 0; i < minLength; i++) {\n const segment = allSegments[0][i];\n if (allSegments.every(segments => segments[i] === segment)) {\n commonPrefix.push(segment);\n } else {\n break;\n }\n }\n\n return commonPrefix;\n };\n\n // Recursive function to create subgroups based on path prefixes\n // Only creates subgroups when 3+ routes share a common prefix AND have diverging subpaths\n const createSubgroups = (routes: Route[], depth: number = 0, commonPrefixLength: number = 0): GroupNode[] => {\n if (routes.length < 3 || depth > 5) {\n // Don't create subgroups if less than 3 routes or too deep\n return routes.map(route => ({\n name: route.path,\n type: 'route' as const,\n path: route.path,\n routes: [route]\n }));\n }\n\n // Analyze path structure to find common prefixes\n const pathSegments = routes.map(r => {\n // Remove leading/trailing slashes and split\n const cleaned = r.path.replace(/^\\/|\\/$/g, '');\n const segments = cleaned.split('/');\n // Strip the common prefix for this group\n return segments.slice(commonPrefixLength);\n });\n\n // Find common prefix groups\n const prefixGroups = new Map<string, Route[]>();\n const ungrouped: Route[] = [];\n\n routes.forEach((route, idx) => {\n const segments = pathSegments[idx];\n if (segments.length <= depth) {\n ungrouped.push(route);\n return;\n }\n\n // Use the segment at current depth as prefix\n const prefix = segments.slice(0, depth + 1).join('/');\n if (!prefixGroups.has(prefix)) {\n prefixGroups.set(prefix, []);\n }\n prefixGroups.get(prefix)!.push(route);\n });\n\n // Create subgroups for prefixes with 3+ routes that actually diverge\n const result: GroupNode[] = [];\n\n prefixGroups.forEach((groupRoutes, prefix) => {\n if (groupRoutes.length >= 3) {\n // Check if routes diverge after this prefix\n // If all routes in this group have the same next segment, don't create a subgroup yet\n const nextSegments = new Set<string>();\n groupRoutes.forEach((route, idx) => {\n const routeIdx = routes.indexOf(route);\n const segments = pathSegments[routeIdx];\n if (segments.length > depth + 1) {\n nextSegments.add(segments[depth + 1]);\n }\n });\n\n // Only create a subgroup if there are diverging paths (2+ different next segments)\n // OR if we're at terminal paths (no more segments)\n const hasDivergingPaths = nextSegments.size >= 2;\n const allTerminal = groupRoutes.every((route, idx) => {\n const routeIdx = routes.indexOf(route);\n return pathSegments[routeIdx].length === depth + 1;\n });\n\n if (hasDivergingPaths || allTerminal) {\n // Create a subgroup and recurse\n const prefixName = prefix.split('/').pop() || prefix;\n result.push({\n name: prefixName,\n type: 'subgroup' as const,\n path: '/' + prefix,\n children: createSubgroups(groupRoutes, depth + 1, commonPrefixLength)\n });\n } else {\n // Don't create a subgroup, just recurse with increased depth\n // This flattens the common mount path\n result.push(...createSubgroups(groupRoutes, depth + 1, commonPrefixLength));\n }\n } else {\n // Add to ungrouped\n ungrouped.push(...groupRoutes);\n }\n });\n\n // Add ungrouped routes as individual items\n ungrouped.forEach(route => {\n result.push({\n name: route.path,\n type: 'route' as const,\n path: route.path,\n routes: [route]\n });\n });\n\n // Sort: subgroups first, then routes\n result.sort((a, b) => {\n if (a.type === 'subgroup' && b.type !== 'subgroup') return -1;\n if (a.type !== 'subgroup' && b.type === 'subgroup') return 1;\n return a.name.localeCompare(b.name);\n });\n\n return result;\n };\n\n // Process OpenAPI paths\n Object.entries(spec.paths || {}).forEach(([path, methods]: [string, any]) => {\n Object.entries(methods).forEach(([method, op]: [string, any]) => {\n if (!op.operationId) {\n op.operationId = `${method}-${path.replace(/\\//g, '-').replace(/[{}:]/g, '')}`;\n }\n\n const route: Route = { method, path, op };\n const source = (op as any)['x-shokupan-source'];\n const groupKey = getGroupKey(op, source);\n\n addRoute(groupKey, route);\n });\n });\n\n // Skip AsyncAPI channels - they should only appear in the AsyncAPI plugin\n // Object.entries(asyncSpec?.channels || {}).forEach(([name, ch]: [string, any]) => {\n // const operations = [];\n // if (ch.publish) operations.push({ method: 'recv', op: ch.publish });\n // if (ch.subscribe) operations.push({ method: 'send', op: ch.subscribe });\n\n // operations.forEach(({ method, op }) => {\n // if (!op.operationId) op.operationId = `${method}-${name.replace(/[^a-zA-Z0-9]/g, '-')}`;\n\n // const route: Route = { method, path: name, op };\n // const source = (op as any)['x-shokupan-source'] || (op as any)['x-source-info'];\n // const groupKey = getGroupKey(op, source);\n\n // addRoute(groupKey, route);\n // });\n // });\n\n // Build hierarchical groups with subgroups\n const hierarchicalGroups = Array.from(hierarchy.entries())\n .map(([name, routes]) => {\n // Sort routes by path\n routes.sort((a, b) => a.path.localeCompare(b.path));\n\n // Find the common prefix for all routes in this group\n const commonPrefix = findCommonPrefix(routes);\n const commonPrefixPath = '/' + commonPrefix.join('/');\n\n // Create subgroups recursively, stripping the common prefix\n const children = createSubgroups(routes, 0, commonPrefix.length);\n\n // Find middleware for this group by matching router/controller names\n const groupMiddleware: any[] = [];\n if (spec['x-middleware-registry']) {\n Object.entries(spec['x-middleware-registry']).forEach(([id, mw]: [string, any]) => {\n // Match middleware to this group based on file path\n const firstRoute = routes[0];\n const routeSource = firstRoute?.op?.['x-shokupan-source'];\n\n const mwFile = mw.file?.split('/').pop();\n const routeFile = routeSource?.file?.split('/').pop();\n\n // Include middleware if it comes from the same file as the routes in this group\n if (mwFile && routeFile && mwFile === routeFile && mw.scope !== 'global') {\n groupMiddleware.push({ ...mw, id, type: 'middleware' });\n }\n });\n }\n\n const isBuiltin = routes.some(r => r.op['x-shokupan-builtin'] === true);\n\n return {\n name,\n type: 'group' as const,\n children,\n middleware: groupMiddleware,\n commonPrefixPath, // Store for display stripping\n isBuiltin\n };\n });\n\n // Add Global Middleware group\n if (spec['x-middleware-registry']) {\n const allGroupMiddleware = hierarchicalGroups.flatMap((g: any) => g.middleware || []).map((m: any) => m.id);\n const globalMiddleware = Object.entries(spec['x-middleware-registry'])\n .filter(([id]) => !allGroupMiddleware.includes(id))\n .map(([id, mw]: [string, any]) => ({ ...mw, id, type: 'middleware' }));\n\n if (globalMiddleware.length > 0) {\n hierarchicalGroups.push({\n name: 'Global Middleware',\n type: 'group' as const,\n children: [],\n middleware: globalMiddleware,\n commonPrefixPath: '',\n isBuiltin: false\n });\n }\n }\n\n // Sort groups\n hierarchicalGroups.sort((a, b) => {\n if (a.name === 'Ungrouped') return 1;\n if (b.name === 'Ungrouped') return -1;\n if (a.name === 'Global Middleware') return 1;\n if (b.name === 'Global Middleware') return -1;\n return a.name.localeCompare(b.name);\n });\n\n // Flatten for client-side data (keep all routes in flat structure for main content)\n const allRoutes = Array.from(hierarchy.values()).flat();\n\n return (\n <html lang=\"en\">\n <head>\n <meta charSet=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>{spec.info?.title || 'API Explorer'}</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin=\"anonymous\" />\n <link href=\"https://fonts.googleapis.com/css2?family=Google+Sans+Code:ital,wght@0,300..800;1,300..800&family=Vend+Sans:ital,wght@0,300..700;1,300..700&display=swap\" rel=\"stylesheet\" />\n <link rel=\"stylesheet\" href=\"style.css\" />\n <link rel=\"stylesheet\" href=\"theme.css\" />\n <script src=\"https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js\"></script>\n <script src=\"https://cdn.jsdelivr.net/npm/monaco-editor@0.45.0/min/vs/loader.js\"></script>\n <script dangerouslySetInnerHTML={{\n __html: `\n (function() {\n if (!window.location.pathname.endsWith('/') && !window.location.pathname.split('/').pop().includes('.')) {\n var newUrl = window.location.pathname + '/' + window.location.search + window.location.hash;\n window.history.replaceState(null, null, newUrl);\n window.location.reload(); \n }\n })();\n `}}></script>\n </head>\n <body class=\"dark-theme\">\n <div id=\"app\">\n <Sidebar spec={spec} hierarchicalGroups={hierarchicalGroups} />\n <MainContent allRoutes={allRoutes} config={config} spec={spec} />\n </div>\n <script src=\"explorer-client.mjs\" type=\"module\"></script>\n </body>\n </html>\n );\n}\n\n\nfunction Sidebar({ spec, hierarchicalGroups }: any) {\n // Helper to strip common prefix from path for display\n const stripPrefix = (path: string, prefix: string): string => {\n if (!prefix || prefix === '/') return path;\n if (path.startsWith(prefix)) {\n const stripped = path.substring(prefix.length);\n return stripped || '/';\n }\n return path;\n };\n\n // Helper to convert OpenAPI params to original format and highlight them\n const formatAndHighlightPath = (path: string): string => {\n // Convert {param} to :param\n const converted = path.replace(/\\{([^}]+)\\}/g, ':$1');\n\n // Highlight :param with color\n return converted.replace(/:([a-zA-Z0-9_]+)/g, '<span class=\"param-highlight\">:$1</span>');\n };\n\n // Recursive function to render navigation nodes\n const renderNavNode = (node: GroupNode, depth: number = 0, commonPrefix: string = ''): any => {\n if (node.type === 'route') {\n const route = node.routes![0];\n const source = route.op['x-shokupan-source'] || route.op['x-source-info'];\n const isRuntime = route.op['x-source-info']?.isRuntime;\n const displayPath = stripPrefix(route.path, commonPrefix);\n const highlightedPath = formatAndHighlightPath(displayPath);\n\n return (\n <div class=\"nav-item-wrapper\" style={`padding-left: ${depth * 12}px;`}>\n <a\n key={route.op.operationId}\n href={`#${route.op.operationId}`}\n class=\"nav-item\"\n data-id={route.op.operationId}\n title={route.path}\n >\n <span class={`badge badge-${route.method.toUpperCase()}`}>{route.method.toUpperCase()}</span>\n <span class=\"nav-label\" dangerouslySetInnerHTML={{ __html: highlightedPath }}></span>\n {isRuntime && (\n <span class=\"nav-warning\" title=\"Static Analysis Failed\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"></path>\n <line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"></line>\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"></line>\n </svg>\n </span>\n )}\n </a>\n {source?.file && (\n <a\n href={`vscode://file/${source.file}:${source.line || 1}`}\n class=\"nav-source-link\"\n title={`${source.file}:${source.line || 1}`}\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polyline points=\"16 18 22 12 16 6\"></polyline>\n <polyline points=\"8 6 2 12 8 18\"></polyline>\n </svg>\n </a>\n )}\n </div>\n );\n } else if (node.type === 'subgroup') {\n return (\n <div class=\"nav-subgroup collapsed\" style={`padding-left: ${depth * 12}px;`}>\n <div class=\"nav-subgroup-title\">\n <span class=\"chevron\">\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </span>\n <span>{node.name}</span>\n </div>\n <div class=\"nav-subgroup-items\">\n {node.children?.map((child: GroupNode) => renderNavNode(child, depth + 1, commonPrefix))}\n </div>\n </div>\n );\n }\n };\n\n return (\n <aside class=\"sidebar\">\n <div class=\"resize-handle\"></div>\n <header class=\"sidebar-header\">\n <button class=\"toggle-sidebar\">☰</button>\n <h1>{spec.info?.title}</h1>\n <div class=\"version\">{spec.info?.version}</div>\n </header>\n <div class=\"sidebar-collapse-trigger\">➔</div>\n <nav class=\"nav-groups\">\n {hierarchicalGroups.map((group: any) => (\n <div class={`nav-group collapsed ${group.isBuiltin ? 'builtin-group' : ''}`} key={group.name}>\n <div class=\"nav-group-title\">\n <span class=\"chevron\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </span>\n {group.isBuiltin && (\n <span class=\"builtin-icon\" title=\"Built-in Plugin\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"5\" ry=\"5\"></rect>\n <path d=\"M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z\"></path>\n <line x1=\"17.5\" y1=\"6.5\" x2=\"17.51\" y2=\"6.5\"></line>\n </svg>\n </span>\n )}\n {group.name}\n </div>\n <div class=\"nav-items\">\n {/* Render middleware first if any */}\n {group.middleware && group.middleware.length > 0 && (\n <div class=\"group-middleware\">\n {group.middleware.map((mw: any) => (\n <a\n key={mw.id}\n href={`#middleware-${mw.id}`}\n class=\"nav-item middleware-nav-item\"\n data-middleware-id={mw.id}\n title={mw.name}\n >\n <span class=\"middleware-icon\">⚙</span>\n <span class=\"nav-label\">{mw.name}</span>\n {mw.usedBy && mw.usedBy.length > 0 && (\n <span class=\"middleware-badge\" title={`Used by ${mw.usedBy.length} routes`}>{mw.usedBy.length}</span>\n )}\n {mw.file && (\n <a\n href={`vscode://file/${mw.file}:${mw.startLine || 1}`}\n class=\"nav-source-link\"\n title={`${mw.file}:${mw.startLine || 1}`}\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polyline points=\"16 18 22 12 16 6\"></polyline>\n <polyline points=\"8 6 2 12 8 18\"></polyline>\n </svg>\n </a>\n )}\n </a>\n ))}\n </div>\n )}\n {/* Then render routes */}\n {group.children?.map((child: GroupNode) => renderNavNode(child, 0, group.commonPrefixPath || ''))}\n </div>\n </div>\n ))}\n </nav>\n\n\n </aside>\n );\n}\n\nfunction MainContent({ allRoutes, config, spec }: any) {\n // Serialize data for client-side consumption\n const explorerData = JSON.stringify({\n routes: allRoutes,\n config,\n info: spec.info,\n middlewareRegistry: spec['x-middleware-registry'] || {}\n });\n\n const safeJson = explorerData.replace(/<\\/script>/g, '<\\\\/script>');\n\n return (\n <main class=\"content\" id=\"main-content\">\n <div id=\"ide-container\">\n <div class=\"empty-state\">Select a request to view details</div>\n </div>\n <script id=\"explorer-data\" type=\"application/json\" dangerouslySetInnerHTML={{ __html: safeJson }}></script>\n </main>\n );\n}\n","import { readFile } from 'fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport renderToString from 'preact-render-to-string';\nimport { ShokupanRouter } from '../../../router';\nimport type { Shokupan } from '../../../shokupan.ts';\nimport type { ShokupanPlugin, ShokupanPluginOptions } from '../../../util/types.ts';\nimport { ApiExplorerApp } from './components.tsx';\nexport interface ApiExplorerOptions {\n baseDocument?: any;\n path?: string;\n}\n\nexport class ApiExplorerPlugin extends ShokupanRouter implements ShokupanPlugin {\n\n constructor(private readonly pluginOptions: ApiExplorerOptions = {}) {\n console.log('ApiExplorerPlugin: CONSTRUCTOR CALLED');\n super({ renderer: renderToString });\n pluginOptions.path ??= '/explorer';\n\n // Metadata\n this.metadata = {\n file: import.meta.file,\n line: 1,\n name: 'ApiExplorerPlugin',\n pluginName: 'ApiExplorer'\n };\n\n this.init();\n }\n\n onInit(app: Shokupan, options?: ShokupanPluginOptions) {\n const path = this.pluginOptions.path || options?.path || '/apiexplorer';\n app.mount(path, this);\n\n // Ensure async api gen is enabled if this plugin is used\n if (app.applicationConfig.enableOpenApiGen !== true) {\n console.warn('ApiExplorerPlugin: enableOpenApiGen is disabled. ApiExplorerPlugin will not generate spec.');\n }\n }\n\n private static getBasePath() {\n const dir = dirname(fileURLToPath(import.meta.url));\n // In production (dist/), files are in dist/plugins/application/api-explorer/\n if (dir.endsWith('dist')) {\n return dir + '/plugins/application/api-explorer';\n }\n // In dev mode (src/plugins/application/api-explorer/), files are in same directory\n return dir;\n }\n\n init() {\n\n const serveFile = async (ctx: any, file: string, type: string) => {\n const content = await readFile(join(ApiExplorerPlugin.getBasePath(), 'static', file), 'utf-8');\n ctx.set('Content-Type', type);\n return ctx.send(content);\n };\n\n const stripSourceCode = (spec: any) => {\n if (!spec || !spec.paths) return spec;\n Object.values(spec.paths).forEach((methods: any) => {\n Object.values(methods).forEach((op: any) => {\n if (op['x-source-info']?.snippet) {\n delete op['x-source-info'].snippet;\n }\n if (op['x-shokupan-source']?.code) {\n console.log('Deleting x-shokupan-source.code');\n delete op['x-shokupan-source'].code;\n }\n });\n });\n return spec;\n };\n\n this.get('/style.css', ctx => serveFile(ctx, 'style.css', 'text/css'));\n this.get('/theme.css', ctx => serveFile(ctx, 'theme.css', 'text/css'));\n this.get('/explorer-client.mjs', ctx => serveFile(ctx, 'explorer-client.mjs', 'application/javascript'));\n\n this.get('/_source', async (ctx) => {\n const file = ctx.query['file'];\n if (!file) return ctx.text('Missing file parameter', 400);\n try {\n // Security check? For now assuming internal tool usage / local strictness not needed as much\n // But ideally we verify it's within source root. \n // Given the context of \"ApiExplorerSource\", we probably trust the file paths coming from our own metadata.\n const content = await readFile(file, 'utf-8');\n return ctx.text(content);\n } catch (err) {\n return ctx.text('File not found', 404);\n }\n });\n\n this.get('/openapi.json', async (ctx) => {\n const spec = (this.root as any).openApiSpec\n ? structuredClone((this.root as any).openApiSpec)\n : await (this.root || this).generateApiSpec();\n return ctx.json(stripSourceCode(spec));\n });\n\n this.get('/', async (ctx) => {\n const spec = (this.root as any).openApiSpec\n ? structuredClone((this.root as any).openApiSpec)\n : await (this.root || this).generateApiSpec();\n const asyncSpec = (ctx.app as any).asyncApiSpec;\n\n const element = ApiExplorerApp({ spec: stripSourceCode(spec), asyncSpec });\n const html = renderToString(element);\n if (html.length === 0) throw new Error('ApiExplorerPlugin: rendered page is blank.');\n return ctx.html(html);\n });\n }\n}\n","\n\n\n\nexport function AsyncApiApp({ spec, serverUrl, base, disableSourceView, navTree }: any) {\n return (\n <html lang=\"en\">\n <head>\n <meta charSet=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Shokupan AsyncAPI</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin=\"anonymous\" />\n <link href=\"https://fonts.googleapis.com/css2?family=Google+Sans+Code:ital,wght@0,300..800;1,300..800&family=Vend+Sans:ital,wght@0,300..700;1,300..700&display=swap\" rel=\"stylesheet\" />\n <link rel=\"stylesheet\" href={`${base}/theme.css`} />\n <link rel=\"stylesheet\" href={`${base}/style.css`} />\n <script dangerouslySetInnerHTML={{\n __html: `\n window.INITIAL_SPEC = ${JSON.stringify(spec)};\n window.INITIAL_SERVER_URL = \"${serverUrl}\";\n window.DISABLE_SOURCE_VIEW = ${JSON.stringify(disableSourceView)};\n window.BASE_PATH = \"${base}\";\n `}} />\n </head>\n <body>\n <div class=\"app-container\">\n <Sidebar navTree={navTree} disableSourceView={disableSourceView} />\n\n <div class=\"resizer\" id=\"resizer-left\"></div>\n\n <MainContent />\n\n <div class=\"resizer\" id=\"resizer-right\"></div>\n\n <ConsolePanel serverUrl={serverUrl} />\n </div>\n\n <script src=\"https://cdn.socket.io/4.7.4/socket.io.min.js\"></script>\n <script src=\"https://cdn.jsdelivr.net/npm/monaco-editor@0.45.0/min/vs/loader.js\"></script>\n <script src={`${base}/asyncapi-client.mjs`} type=\"module\"></script>\n </body>\n </html>\n );\n}\n\nfunction Sidebar({ navTree, disableSourceView }: any) {\n return (\n <div class=\"sidebar scroller\" id=\"sidebar\">\n <div class=\"sidebar-header\" style=\"display:flex; justify-content:space-between; align-items:center;\">\n <h2>AsyncAPI</h2>\n <button id=\"btn-collapse-nav\" class=\"btn-icon\" title=\"Collapse Sidebar\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polyline points=\"15 18 9 12 15 6\"></polyline>\n </svg>\n </button>\n </div>\n <div class=\"nav-list\" id=\"nav-list\">\n <NavNode node={navTree} level={0} disableSourceView={disableSourceView} />\n </div>\n </div>\n );\n}\n\nfunction NavNode({ node, level, disableSourceView }: any) {\n // Sort children\n const sortedEntries = Object.entries(node.children || {}).sort((a, b) => {\n const [aKey, aItem] = a as [string, any];\n const [bKey, bItem] = b as [string, any];\n\n // Prioritize Warnings\n const isWarningA = aItem.data?.op?.['x-warning'];\n const isWarningB = bItem.data?.op?.['x-warning'];\n if (isWarningA && !isWarningB) return -1;\n if (!isWarningA && isWarningB) return 1;\n\n if (aKey === bKey) return 0;\n if (aKey === 'Warning' || aKey === 'Warnings') return -1;\n if (bKey === 'Warning' || bKey === 'Warnings') return 1;\n if (aKey === 'Application') return -1;\n if (bKey === 'Application') return 1;\n\n // Directories/Groups first? Original code seemed to just sort by string, \n // with specific exceptions.\n if (aKey[0] === '/') return 1;\n if (bKey[0] === '/') return -1;\n\n return aKey.localeCompare(bKey);\n });\n\n return (\n <>\n {sortedEntries.map(([key, item]: [string, any]) => {\n const hasChildren = Object.keys(item.children || {}).length > 0;\n\n if (level === 0) {\n // Top Level Group\n return (\n <div key={key}>\n <div class=\"group-label\">{key}</div>\n {hasChildren && (\n <div class=\"tree-node\" style=\"margin-left: 0\">\n <NavNode node={item} level={level + 1} disableSourceView={disableSourceView} />\n </div>\n )}\n </div>\n );\n }\n\n // Nested Nodes\n const isLeaf = item.isLeaf;\n\n return (\n <div key={key}>\n {isLeaf ? (\n <LeafNode item={item} label={key} disableSourceView={disableSourceView} />\n ) : (\n <div class=\"tree-item\" style=\"color: var(--text-muted)\">\n <span class=\"tree-label\">{key}</span>\n </div>\n )}\n\n {hasChildren && (\n <div class=\"tree-node\">\n <NavNode node={item} level={level + 1} disableSourceView={disableSourceView} />\n </div>\n )}\n </div>\n );\n })}\n </>\n );\n}\n\nfunction LeafNode({ item, label, disableSourceView }: any) {\n const isWarning = item.data?.op?.['x-warning'];\n const opId = item.data?.name; // Using name as ID for referencing\n const sourceInfo = item.data?.op?.['x-source-info'];\n\n let content;\n if (isWarning) {\n content = (\n <>\n <span style=\"margin-right: 6px;\">⚠️</span>\n <span class=\"tree-label\">{label}</span>\n </>\n );\n } else {\n const badgeText = item.data.type === 'publish' ? 'SEND' : 'RECV';\n const isPlugin = item.data.op?.['x-shokupan-plugin-name'] || sourceInfo?.pluginName;\n\n content = (\n <>\n <span class={`badge badge-${badgeText}`}>{badgeText}</span>\n {isPlugin && (\n <span class=\"builtin-icon\" title=\"Built-in Plugin\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"5\" ry=\"5\"></rect>\n <path d=\"M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z\"></path>\n <line x1=\"17.5\" y1=\"6.5\" x2=\"17.51\" y2=\"6.5\"></line>\n </svg>\n </span>\n )}\n <span class=\"tree-label\">{label}</span>\n </>\n );\n }\n\n return (\n <div class=\"tree-item\" data-event={opId} style={isWarning ? \"color: #fbbf24\" : \"\"}>\n {content}\n {sourceInfo && !disableSourceView && (\n <a href={`vscode://file/${sourceInfo.file}:${sourceInfo.line}`}\n class=\"source-link\"\n onClick={(e) => { e.stopPropagation(); }} // This won't work in SSR string, handled in client script\n title={`${sourceInfo.file}:${sourceInfo.line}`}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" style=\"display:block\">\n <polyline points=\"16 18 22 12 16 6\"></polyline><polyline points=\"8 6 2 12 8 18\"></polyline>\n </svg>\n </a>\n )}\n </div>\n );\n}\n\n\nfunction MainContent() {\n return (\n <div id=\"main-wrapper\" style=\"flex: 1; min-width: 0; position: relative; overflow: hidden;\">\n <button id=\"btn-expand-nav\" class=\"btn-icon floating-toggle left\" title=\"Expand Sidebar\" style=\"display:none;\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </button>\n <button id=\"btn-expand-console\" class=\"btn-icon floating-toggle right\" title=\"Expand Console\" style=\"display:none;\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polyline points=\"15 18 9 12 15 6\"></polyline>\n </svg>\n </button>\n\n <main class=\"main-content scroller\" id=\"doc-panel\" style=\"height: 100%;\">\n <div class=\"empty-state\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\">\n <path d=\"M4 19.5A2.5 2.5 0 0 1 6.5 17H20\"></path>\n <path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z\"></path>\n </svg>\n <h3>Select an event to view details</h3>\n </div>\n </main>\n </div>\n );\n}\n\nfunction ConsolePanel({ serverUrl }: any) {\n return (\n <div class=\"console-panel\" id=\"console-panel\">\n <div class=\"console-header\">\n <div style=\"display:flex; justify-content:space-between; align-items:center; margin-bottom: 8px;\">\n <h3 style=\"margin:0; font-size:1rem;\">Console</h3>\n <div style=\"display:flex; gap: 4px;\">\n <button id=\"btn-maximize-console\" class=\"btn-icon\" title=\"Maximize Console\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect>\n </svg>\n </button>\n <button id=\"btn-collapse-console\" class=\"btn-icon\" title=\"Collapse Console\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </button>\n </div>\n </div>\n <div class=\"connection-bar\">\n <select id=\"protocol\">\n <option value=\"ws\">WS</option>\n <option value=\"wss\">WSS</option>\n <option value=\"socket.io\">Socket.IO</option>\n </select>\n <div style=\"width: 1px; background: rgba(255,255,255,0.1); margin: 2px 0;\"></div>\n <input type=\"text\" id=\"url\" value={serverUrl} />\n </div>\n <div style=\"display: grid; grid-template-columns: 1fr auto; gap: 8px;\">\n <button id=\"connect-btn\" class=\"btn\">Connect</button>\n <button id=\"clear-logs-btn\" class=\"btn secondary\" title=\"Clear Logs\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"></path>\n </svg>\n </button>\n </div>\n <div class=\"status-indicator\">\n <div id=\"status-dot\" class=\"dot\"></div>\n <span id=\"connection-status\">Disconnected</span>\n </div>\n </div>\n\n <div class=\"logs-container scroller\" id=\"logs\">\n <div class=\"log-shim\" id=\"log-shim\"></div>\n </div>\n\n <div class=\"compose-area\">\n <div class=\"compose-header\">\n <span>Payload</span>\n <span id=\"target-event\" style=\"color: var(--primary);\">--</span>\n </div>\n <div id=\"editor-container\"></div>\n <div class=\"send-bar\">\n <button id=\"send-btn\" class=\"btn\">Send Message</button>\n </div>\n </div>\n </div>\n );\n}\n\n// Logic to build the tree from spec\nexport function buildNavTree(spec: any) {\n if (!spec || !spec.channels) return { children: {} };\n\n const root: any = { children: {} };\n\n Object.keys(spec.channels).forEach(name => {\n const ch = spec.channels[name];\n const op = ch.publish || ch.subscribe;\n const type = ch.publish ? 'publish' : 'subscribe';\n\n // Get Tag (Controller Name)\n const tag = (op.tags && op.tags.length > 0) ? op.tags[0].name : 'General';\n\n // Ensure Tag Group Exists\n if (!root.children[tag]) root.children[tag] = { children: {} };\n\n const parts = name.split(/[\\.\\/]/);\n let current = root.children[tag];\n\n parts.forEach((part, i) => {\n if (!current.children[part]) current.children[part] = { children: {} };\n current = current.children[part];\n\n if (i === parts.length - 1) {\n current.isLeaf = true;\n current.data = { name, op, type };\n }\n });\n });\n\n return root;\n}\n","\nimport type { ShokupanRouter } from '../../../router';\nimport { $childRouters, $isApplication, $mountPath, $routes } from '../../../util/symbol';\nimport type { AsyncAPIOptions } from '../../../util/types';\nimport { getAstRoutes } from '../shared/ast-utils';\n\n/**\n * Regex patterns for detecting emit calls.\n */\n\n/**\n * Check if a schema contains fields with unknown types\n */\nfunction hasUnknownFields(schema: any): boolean {\n if (!schema) return false;\n if (schema['x-unknown']) return true;\n\n if (schema.type === 'object' && schema.properties) {\n return Object.values(schema.properties).some((prop: any) =>\n hasUnknownFields(prop)\n );\n }\n\n if (schema.type === 'array' && schema.items) {\n return hasUnknownFields(schema.items);\n }\n\n return false;\n}\n\n/**\n * Gets deduped AST routes if available.\n * Duplicated from openapi.ts to avoid cross-module dependency issues.\n */\n\nexport async function generateAsyncApi<T extends Record<string, any>>(rootRouter: ShokupanRouter<T>, options: AsyncAPIOptions = {}): Promise<any> {\n const channels: Record<string, any> = {};\n\n // Attempt to run AST Analysis\n let astRoutes: any[] = [];\n let astMiddlewareRegistry: Record<string, any> = {};\n let applications: any[] = [];\n try {\n const { OpenAPIAnalyzer } = await import('../openapi/analyzer');\n const entrypoint = (globalThis as any).Bun?.main || require.main?.filename || process.argv[1];\n const analyzer = new OpenAPIAnalyzer(process.cwd(), entrypoint);\n const analysisResult = await analyzer.analyze();\n applications = analysisResult.applications;\n astRoutes = await getAstRoutes(applications, {\n includePrefix: false,\n pathTransform: (p) => p.startsWith('/') ? p.slice(1) : p\n });\n\n // Build middleware registry from AST-analyzed applications\n let middlewareId = 0;\n for (const app of applications) {\n if (app.middleware && app.middleware.length > 0) {\n for (const mw of app.middleware) {\n const id = `middleware-${middlewareId++}`;\n astMiddlewareRegistry[id] = {\n ...mw,\n id,\n usedBy: [] // Will be populated when processing events\n };\n }\n }\n }\n } catch (e) {\n // Silently fail if analysis cannot run\n if (options.warnings) {\n options.warnings.push({\n type: 'ast-analysis-failed',\n message: 'AST Analysis failed or skipped',\n detail: e.message\n });\n }\n }\n\n const matchedAstRoutes = new Set<any>();\n\n const collect = async (router: ShokupanRouter<T>, prefix = \"\") => {\n // Collect Event Handlers (Client -> Server)\n const eventHandlers = router.getEventHandlers();\n\n // Determine Router Tag\n let routerTag = \"Other\";\n if ((router as any)[$isApplication]) {\n routerTag = \"Application\";\n } else if (router.constructor.name && router.constructor.name !== \"ShokupanRouter\") {\n routerTag = router.constructor.name;\n } else {\n routerTag = (router as any)[$mountPath] || \"Router\";\n }\n\n if (eventHandlers) {\n for (const [eventName, handlers] of eventHandlers.entries()) {\n // Iterate through all handlers to accumulate source info\n for (const handler of handlers) {\n const specName = `event/${eventName}`;\n\n // Check for @Spec metadata\n const userSpec = (handler as any).spec;\n\n // Determine tags: Use userSpec tags (from decorators) or fallback to Router context\n let tags = userSpec?.tags;\n if (!tags && routerTag) {\n tags = [{ name: routerTag }];\n }\n\n // Match with AST route to find emits and source info\n let astMatch = astRoutes.find(r =>\n (r.method === 'EVENT' || r.method === 'ON') &&\n r.path === eventName\n );\n\n if (!astMatch) {\n // Heuristic matching\n const runtimeSource = ((handler as any).originalHandler || handler).toString();\n const stripComments = (s: string) => s.replace(/\\/\\*[\\s\\S]*?\\*\\/|([^\\\\:]|^)\\/\\/.*$/gm, '$1');\n const normalize = (s: string) => stripComments(s).replace(/\\s+/g, '');\n\n const runtimeHandlerSrc = normalize(runtimeSource);\n\n const eventRoutes = astRoutes.filter(r => r.method === 'EVENT' || r.method === 'ON');\n\n astMatch = eventRoutes.find(r => {\n const astHandlerSrc = normalize(r.handlerSource || r.handlerName || '');\n\n if (!astHandlerSrc || astHandlerSrc.length < 5) return false;\n return runtimeHandlerSrc.includes(astHandlerSrc) ||\n astHandlerSrc.includes(runtimeHandlerSrc) ||\n (r.handlerSource && runtimeHandlerSrc.includes(normalize(r.handlerSource).substring(0, 50)));\n });\n }\n\n if (astMatch) matchedAstRoutes.add(astMatch);\n\n const sourceInfo = ((handler as any).source || astMatch?.sourceContext) ? {\n file: (handler as any).source?.file || astMatch?.sourceContext?.file,\n line: (handler as any).source?.line || astMatch?.sourceContext?.startLine,\n startLine: (handler as any).source?.line || astMatch?.sourceContext?.startLine,\n endLine: astMatch?.sourceContext?.endLine,\n highlightLines: astMatch?.sourceContext ? [astMatch.sourceContext.startLine, astMatch.sourceContext.endLine] : undefined\n } : undefined;\n\n const message = {\n ...(userSpec?.message || {})\n };\n let inferenceFailed = false;\n\n if (!message.payload) {\n if (astMatch) {\n if (astMatch.requestTypes?.body) {\n message.payload = astMatch.requestTypes.body;\n // Check if generic object\n if (message.payload.type === 'object' &&\n !message.payload.properties &&\n !message.payload.additionalProperties &&\n Object.keys(message.payload).length === 1) {\n inferenceFailed = true;\n }\n } else {\n // Valid AST match but no body usage -> Payload is unused\n }\n } else {\n // Default to object if no AST and no user spec\n message.payload = { type: 'object' };\n inferenceFailed = true;\n }\n }\n\n if (!channels[eventName]) {\n const publishOp = {\n operationId: `on${eventName.charAt(0).toUpperCase() + eventName.slice(1)}`,\n tags,\n message,\n ...(userSpec?.type === 'publish' ? userSpec : {}),\n \"x-source-info\": sourceInfo ? [sourceInfo] : [],\n \"x-shokupan-source\": {\n ...sourceInfo,\n pluginName: (handler as any).pluginName\n }\n };\n\n if (inferenceFailed) {\n (publishOp as any)['x-warning'] = true;\n if (!publishOp.summary) publishOp.summary = \"Payload Inference Failed\";\n if (!publishOp.description) publishOp.description = \"The payload format could not be statically inferred from the source code. Please add a type assertion or @Spec decorator.\";\n }\n\n // Apply user-defined summary/description if not already set by inferenceFailed warning\n if (userSpec?.summary && !publishOp.summary) publishOp.summary = userSpec.summary;\n if (userSpec?.description && !publishOp.description) publishOp.description = userSpec.description;\n\n channels[eventName] = {\n publish: publishOp\n };\n } else {\n // Accumulate source info from additional handlers\n if (sourceInfo) {\n if (!channels[eventName].publish[\"x-source-info\"]) {\n channels[eventName].publish[\"x-source-info\"] = [];\n }\n const exists = channels[eventName].publish[\"x-source-info\"].some((s: any) =>\n s.file === sourceInfo.file && s.line === sourceInfo.line\n );\n if (!exists) {\n channels[eventName].publish[\"x-source-info\"].push(sourceInfo);\n }\n }\n }\n\n // Analyze for outgoing events\n let emits = astMatch?.emits || [];\n\n for (const emit of emits) {\n if (emit.event === '__DYNAMIC_EMIT__') {\n const warningKey = `${eventName}/Dynamic Emit`;\n if (options.warnings) {\n options.warnings.push({\n type: 'dynamic-emit',\n message: 'Dynamic emit detected',\n detail: `Event: ${eventName}`,\n location: { file: astMatch?.sourceContext?.file, line: emit.location?.startLine }\n });\n }\n channels[warningKey] = {\n subscribe: {\n operationId: `dynamicEmitWarning${eventName}`,\n summary: \"Dynamic Emit Detected\",\n description: \"This handler emits an event with a dynamic name that could not be determined statically.\",\n tags: tags,\n \"x-warning\": true,\n \"x-source-info\": {\n file: astMatch?.sourceContext?.file,\n line: emit.location?.startLine,\n startLine: emit.location?.startLine,\n endLine: emit.location?.endLine,\n highlightLines: emit.location ? [emit.location.startLine, emit.location.endLine] : undefined\n },\n \"x-shokupan-source\": {\n file: astMatch?.sourceContext?.file,\n line: emit.location?.startLine,\n },\n message: { payload: { type: 'object' } }\n }\n };\n continue;\n }\n\n const emitStart = emit.location?.startLine;\n const emitEnd = emit.location?.endLine;\n\n const newSourceInfo = (sourceInfo && emitStart) ? {\n file: sourceInfo.file,\n line: emitStart,\n startLine: emitStart,\n endLine: emitEnd,\n highlightLines: sourceInfo.highlightLines,\n emitHighlightLines: [emitStart, emitEnd]\n } : undefined;\n\n if (!channels[emit.event]) {\n const payload = emit.payload || { type: 'object' };\n const warning = hasUnknownFields(payload);\n\n channels[emit.event] = {\n subscribe: {\n operationId: `emit${emit.event.charAt(0).toUpperCase() + emit.event.slice(1)}`,\n tags,\n message: {\n payload\n },\n ...(warning ? {\n 'x-warning': true,\n 'x-warning-reason': 'Payload contains fields with unknown types that could not be statically analyzed'\n } : {}),\n \"x-source-info\": newSourceInfo ? [newSourceInfo] : [],\n \"x-shokupan-source\": (sourceInfo && emitStart) ? {\n file: sourceInfo.file,\n line: emitStart,\n pluginName: (handler as any).pluginName\n } : undefined\n }\n };\n } else {\n if (newSourceInfo) {\n if (!channels[emit.event].subscribe[\"x-source-info\"]) {\n channels[emit.event].subscribe[\"x-source-info\"] = [];\n }\n const existing = channels[emit.event].subscribe[\"x-source-info\"];\n const exists = existing.some((s: any) =>\n s.file === newSourceInfo.file && s.line === newSourceInfo.line\n );\n if (!exists) {\n existing.push(newSourceInfo);\n }\n }\n }\n }\n }\n } // end for handler\n }; // end for eventHandlers\n\n // Collect HTTP Routes (Server -> Client Emits Only)\n const httpRoutes = router[$routes];\n if (httpRoutes) {\n for (const route of httpRoutes) {\n const handler = route.handler;\n\n // Determine tags\n let tags = route.handlerSpec?.tags;\n if (!tags && routerTag) {\n tags = [{ name: routerTag }];\n }\n\n // Find AST match\n const methodUpper = route.method.toUpperCase();\n let astMatch = astRoutes.find(r =>\n r.method === methodUpper &&\n (r.path === route.path || r.path === '/' + route.path)\n );\n\n if (!astMatch) {\n const runtimeSource = ((handler as any).originalHandler || handler).toString();\n const runtimeHandlerSrc = runtimeSource.replace(/\\s+/g, ' ');\n const sameMethodRoutes = astRoutes.filter(r => r.method === methodUpper);\n\n astMatch = sameMethodRoutes.find(r => {\n const astHandlerSrc = (r.handlerSource || r.handlerName || '').replace(/\\s+/g, ' ');\n if (!astHandlerSrc || astHandlerSrc.length < 20) return false;\n return runtimeHandlerSrc.includes(astHandlerSrc) ||\n astHandlerSrc.includes(runtimeHandlerSrc) ||\n (r.handlerSource && runtimeHandlerSrc.includes(r.handlerSource.substring(0, 50)));\n });\n }\n\n // Reconstruct SourceInfo for reuse\n const sourceInfo = ((handler as any).source || astMatch?.sourceContext) ? {\n file: (handler as any).source?.file || astMatch?.sourceContext?.file,\n line: (handler as any).source?.line || astMatch?.sourceContext?.startLine,\n startLine: (handler as any).source?.line || astMatch?.sourceContext?.startLine,\n endLine: astMatch?.sourceContext?.endLine,\n highlightLines: astMatch?.sourceContext ? [astMatch.sourceContext.startLine, astMatch.sourceContext.endLine] : undefined\n } : undefined;\n\n let emits = astMatch?.emits || [];\n\n for (const emit of emits) {\n const emitStart = emit.location?.startLine;\n const emitEnd = emit.location?.endLine;\n\n const newSourceInfo = (sourceInfo && emitStart) ? {\n file: sourceInfo.file,\n line: emitStart,\n startLine: emitStart,\n endLine: emitEnd,\n highlightLines: sourceInfo.highlightLines,\n emitHighlightLines: [emitStart, emitEnd]\n } : undefined;\n\n // Only add if not already defined\n if (!channels[emit.event]) {\n const payload = emit.payload || { type: 'object' };\n const warning = hasUnknownFields(payload);\n\n channels[emit.event] = {\n subscribe: {\n operationId: `emit${emit.event.charAt(0).toUpperCase() + emit.event.slice(1)}`,\n tags,\n message: {\n payload\n },\n ...(warning ? {\n 'x-warning': true,\n 'x-warning-reason': 'Payload contains fields with unknown types that could not be statically analyzed'\n } : {}),\n \"x-source-info\": newSourceInfo ? [newSourceInfo] : [],\n \"x-shokupan-source\": (sourceInfo && emitStart) ? {\n file: sourceInfo.file,\n line: emitStart,\n } : undefined\n }\n };\n } else {\n if (newSourceInfo) {\n if (!channels[emit.event].subscribe[\"x-source-info\"]) {\n channels[emit.event].subscribe[\"x-source-info\"] = [];\n }\n const existing = channels[emit.event].subscribe[\"x-source-info\"];\n const exists = existing.some((s: any) =>\n s.file === newSourceInfo.file && s.line === newSourceInfo.line\n );\n if (!exists) {\n existing.push(newSourceInfo);\n }\n }\n }\n }\n }\n }\n\n // Recursively check children\n const childRouters = router[$childRouters];\n for (const child of childRouters) {\n await collect(child);\n }\n };\n\n await collect(rootRouter);\n\n\n // Process detected dynamic/unknown events from AST that weren't matched\n const dynamicEvents = astRoutes.filter(r => r.path === '__DYNAMIC_EVENT__' && !matchedAstRoutes.has(r));\n dynamicEvents.forEach((r, i) => {\n // Try to identify context\n let prefix = \"Anonymous\";\n if (r.handlerName && !r.handlerName.includes('=>') && !r.handlerName.includes('{')) {\n const parts = r.handlerName.split('.');\n if (parts.length > 0) prefix = parts[0];\n }\n\n const key = `${prefix}.Dynamic Event ${i + 1}`;\n if (options.warnings) {\n options.warnings.push({\n type: 'dynamic-event',\n message: 'Dynamic event listener detected',\n detail: `Event listener with dynamic name`,\n location: { file: r.sourceContext?.file, line: r.sourceContext?.startLine }\n });\n }\n\n channels[key] = {\n publish: {\n operationId: `dynamicEventWarning${i}`,\n summary: \"Dynamic Event Detected\",\n description: `A dynamic event listener was detected in your source code but the event name could not be determined statically.`,\n tags: [{ name: \"Warnings\" }],\n \"x-warning\": true,\n \"x-source-info\": {\n file: r.sourceContext?.file,\n line: r.sourceContext?.startLine,\n startLine: r.sourceContext?.startLine,\n endLine: r.sourceContext?.endLine,\n highlightLines: r.sourceContext ? [r.sourceContext.startLine, r.sourceContext.endLine] : undefined\n },\n \"x-shokupan-source\": {\n file: r.sourceContext?.file,\n line: r.sourceContext?.startLine,\n },\n message: { payload: { type: 'object' } }\n }\n };\n });\n\n return {\n asyncapi: \"3.0.0\",\n info: { title: \"Shokupan AsyncAPI\", version: \"1.0.0\", ...options.info },\n channels,\n \"x-middleware-registry\": astMiddlewareRegistry\n };\n};\n","import { readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport renderToString from 'preact-render-to-string';\nimport { ShokupanRouter } from '../../../router';\nimport type { Shokupan } from '../../../shokupan';\nimport { deepMerge } from '../../../util/deep-merge';\nimport type { DeepPartial, ShokupanPlugin, ShokupanPluginOptions } from '../../../util/types';\nimport { AsyncApiApp, buildNavTree } from './components.tsx';\nimport { generateAsyncApi } from './generator';\n\nexport interface AsyncApiPluginOptions {\n path?: string;\n spec?: DeepPartial<any>;\n disableSourceView?: boolean;\n}\n\nexport class AsyncApiPlugin extends ShokupanRouter<any> implements ShokupanPlugin {\n\n private static getBasePath() {\n const dir = dirname(fileURLToPath(import.meta.url));\n // In production (dist/), files are in dist/plugins/application/asyncapi/\n if (dir.endsWith('dist')) {\n return dir + '/plugins/application/asyncapi';\n }\n // In dev mode (src/plugins/application/asyncapi/), files are in same directory\n return dir;\n }\n\n constructor(private pluginOptions: AsyncApiPluginOptions = {}) {\n super({ renderer: renderToString });\n this.pluginOptions.path ??= '/asyncapi';\n\n // Metadata\n this.metadata = {\n file: import.meta.file,\n line: 1,\n name: 'AsyncApiPlugin',\n pluginName: 'AsyncAPI'\n };\n\n this.init();\n }\n\n onInit(app: Shokupan, options?: ShokupanPluginOptions) {\n const path = this.pluginOptions.path || options?.path || '/asyncapi';\n app.mount(path, this);\n\n // Ensure async api gen is enabled if this plugin is used\n if (app.applicationConfig.enableAsyncApiGen !== true) {\n console.warn('AsyncApiPlugin: enableAsyncApiGen is disabled. AsyncApiPlugin will not generate spec.');\n }\n }\n\n private init() {\n const serveFile = async (ctx: any, file: string, type: string) => {\n const content = await readFile(join(AsyncApiPlugin.getBasePath(), 'static', file), 'utf-8');\n ctx.set('Content-Type', type);\n return ctx.send(content);\n };\n\n this.get('/style.css', ctx => serveFile(ctx, 'style.css', 'text/css'));\n this.get('/theme.css', ctx => serveFile(ctx, 'theme.css', 'text/css'));\n this.get('/asyncapi-client.mjs', ctx => serveFile(ctx, 'asyncapi-client.mjs', 'application/javascript'));\n\n this.get('/', async ctx => {\n let spec = ctx.app?.asyncApiSpec;\n if (!spec) {\n spec = await generateAsyncApi(ctx.app!);\n }\n if (this.pluginOptions.spec) {\n deepMerge(spec, this.pluginOptions.spec);\n }\n\n const serverUrl = `${ctx.hostname}:${ctx.app?.applicationConfig.port}`;\n const base = this.pluginOptions.path!;\n\n const disableSourceView = this.pluginOptions.disableSourceView;\n\n // Build navigation tree from spec\n const navTree = buildNavTree(spec);\n\n return ctx.jsx(AsyncApiApp({ spec, serverUrl, base, disableSourceView, navTree }));\n });\n\n this.get('/json', async ctx => {\n let spec = ctx.app?.asyncApiSpec;\n if (!spec) {\n // Fallback generation\n spec = await generateAsyncApi(ctx.app!);\n }\n\n if (this.pluginOptions.spec) {\n deepMerge(spec, this.pluginOptions.spec);\n }\n return ctx.json(spec);\n });\n\n this.get('/_code', async ctx => {\n const file = ctx.query['file'];\n if (!file || typeof file !== 'string') {\n return ctx.text('Missing file parameter', 400);\n }\n\n // Security: Prevent directory traversal\n // Ensure path is absolute and within the project (cwd)\n // Or just allow reading any file if it's a dev tool?\n // Given the context of \"Dev Mode\", strict sandboxing might be overkill but good practice.\n // For now, we will trust the path if it's absolute, as this is a dev-only tool.\n\n try {\n const content = await readFile(file, 'utf8');\n return ctx.text(content);\n } catch (e: any) {\n return ctx.text('File not found: ' + e.message, 404);\n }\n });\n }\n}\n","\nimport { ShokupanContext } from \"../../context\";\nimport { ShokupanRouter } from \"../../router\";\nimport type { Shokupan } from \"../../shokupan\";\nimport type { ShokupanPlugin, ShokupanPluginOptions } from \"../../util/types\";\n\nexport interface AuthUser {\n id: string;\n email?: string;\n name?: string;\n picture?: string;\n provider: string;\n raw?: any;\n}\n\nexport interface ProviderConfig {\n /**\n * Client ID\n */\n clientId: string;\n /**\n * Client secret\n */\n clientSecret: string;\n /**\n * Redirect URI\n */\n redirectUri: string; // Must be absolute\n /**\n * Scopes\n */\n scopes?: string[];\n /**\n * Tenant ID (MSFT AD)\n */\n tenantId?: string;\n /**\n * Domain (Auth0, Okta)\n */\n domain?: string;\n /**\n * Team ID (Apple)\n */\n teamId?: string;\n /**\n * Key ID (Apple)\n */\n keyId?: string;\n /**\n * Auth URL (Generic OAuth2)\n */\n authUrl?: string;\n /**\n * Token URL (Generic OAuth2)\n */\n tokenUrl?: string;\n /**\n * User info URL (Generic OAuth2)\n */\n userInfoUrl?: string;\n}\n\nexport interface AuthConfig {\n /**\n * JWT secret\n */\n jwtSecret: string | Uint8Array;\n /**\n * JWT expiration\n */\n jwtExpiration?: string; // e.g. \"2h\"\n /**\n * Cookie options\n */\n cookieOptions?: {\n /**\n * HTTP only\n */\n httpOnly?: boolean;\n /**\n * Secure\n */\n secure?: boolean;\n /**\n * Same site\n */\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n /**\n * Path\n */\n path?: string;\n /**\n * Max age\n */\n maxAge?: number;\n };\n /**\n * Success callback\n */\n onSuccess?: (user: AuthUser, ctx: ShokupanContext) => Promise<any> | any;\n /**\n * Providers\n */\n providers: {\n github?: ProviderConfig;\n google?: ProviderConfig;\n microsoft?: ProviderConfig;\n apple?: ProviderConfig;\n auth0?: ProviderConfig;\n okta?: ProviderConfig;\n oauth2?: ProviderConfig;\n [key: string]: ProviderConfig | undefined;\n };\n}\n\n/**\n * Authentication plugin\n */\nexport class AuthPlugin extends ShokupanRouter<any> implements ShokupanPlugin {\n private secret: Uint8Array;\n private arctic!: typeof import(\"arctic\");\n private jose!: typeof import(\"jose\");\n\n constructor(private authConfig: AuthConfig) {\n super();\n this.secret = typeof authConfig.jwtSecret === 'string'\n ? new TextEncoder().encode(authConfig.jwtSecret)\n : authConfig.jwtSecret;\n }\n\n async onInit(app: Shokupan, options?: ShokupanPluginOptions) {\n // Load dependencies asynchronously\n this.arctic = await import(\"arctic\");\n this.jose = await import(\"jose\");\n\n // Initialize routes\n this.init();\n\n // If registered via app.register(), mount it to root or specified path\n if (options?.path) {\n app.mount(options.path, this);\n } else {\n app.mount(options.path ?? '/', this);\n }\n }\n\n private getProviderInstance(name: string, p: ProviderConfig) {\n const { GitHub, Google, MicrosoftEntraId, Apple, Auth0, Okta, OAuth2Client } = this.arctic;\n\n switch (name) {\n case 'github':\n return new GitHub(p.clientId, p.clientSecret, p.redirectUri);\n case 'google':\n return new Google(p.clientId, p.clientSecret, p.redirectUri);\n case 'microsoft':\n return new MicrosoftEntraId(p.tenantId!, p.clientId, p.clientSecret, p.redirectUri);\n case 'apple':\n // TODO: There is a type issue, requires testing.\n return new Apple(\n p.clientId,\n p.teamId!,\n p.keyId!,\n p.clientSecret as any,\n p.redirectUri\n );\n case 'auth0':\n return new Auth0(p.domain!, p.clientId, p.clientSecret, p.redirectUri);\n case 'okta':\n return new Okta(p.domain!, p.authUrl, p.clientId, p.clientSecret, p.redirectUri);\n case 'oauth2':\n return new OAuth2Client(p.clientId, p.clientSecret, p.redirectUri);\n default:\n return null;\n }\n }\n\n private async createSession(user: AuthUser, ctx: ShokupanContext) {\n const alg = 'HS256';\n const jwt = await new this.jose.SignJWT({ ...user })\n .setProtectedHeader({ alg })\n .setIssuedAt()\n .setExpirationTime(this.authConfig.jwtExpiration || '24h')\n .sign(this.secret);\n\n // Set cookie\n const opts = this.authConfig.cookieOptions || {};\n let cookie = `auth_token=${jwt}; Path=${opts.path || '/'}; HttpOnly`;\n if (opts.secure) cookie += '; Secure';\n if (opts.sameSite) cookie += `; SameSite=${opts.sameSite}`;\n if (opts.maxAge) cookie += `; Max-Age=${opts.maxAge}`;\n\n ctx.set('Set-Cookie', cookie);\n\n return jwt;\n }\n\n private init() {\n const { generateState, generateCodeVerifier, GitHub, Google, MicrosoftEntraId, Apple, Auth0, Okta, OAuth2Client } = this.arctic;\n const providerEntries = Object.entries(this.authConfig.providers);\n\n for (let i = 0; i < providerEntries.length; i++) {\n const [providerName, providerConfig] = providerEntries[i];\n if (!providerConfig) continue;\n\n const provider = this.getProviderInstance(providerName, providerConfig);\n if (!provider) {\n continue;\n }\n\n // Login Route\n this.get(`/auth/${providerName}/login`, async (ctx) => {\n const state = generateState();\n const codeVerifier = (providerName === 'google' || providerName === 'microsoft' || providerName === 'auth0' || providerName === 'okta')\n ? generateCodeVerifier() : undefined; // PKCE for some\n\n // Store state/verifier in cookie for verification\n const scopes = providerConfig.scopes || [];\n let url: URL;\n\n if (provider instanceof GitHub) {\n url = await provider.createAuthorizationURL(state, scopes);\n } else if (provider instanceof Google || provider instanceof MicrosoftEntraId || provider instanceof Auth0 || provider instanceof Okta) {\n // These all support PKCE in recent versions\n // Types might vary slightly but usually createAuthorizationURL(state, codeVerifier, scopes)\n url = await (provider as any).createAuthorizationURL(state, codeVerifier!, scopes);\n } else if (provider instanceof Apple) {\n url = await provider.createAuthorizationURL(state, scopes);\n } else if (provider instanceof OAuth2Client) {\n if (!providerConfig.authUrl) return ctx.text(\"Config error: authUrl required for oauth2\", 500);\n url = await provider.createAuthorizationURL(providerConfig.authUrl, state, scopes);\n } else {\n return ctx.text(\"Provider config error\", 500);\n }\n\n // Security: Set secure cookies with SameSite=Lax to prevent CSRF attacks\n const isSecure = ctx.secure;\n ctx.res.headers.set(\"Set-Cookie\", `oauth_state=${state}; Path=/; HttpOnly; SameSite=Lax${isSecure ? '; Secure' : ''}; Max-Age=600`);\n if (codeVerifier) {\n ctx.res.headers.append(\"Set-Cookie\", `oauth_verifier=${codeVerifier}; Path=/; HttpOnly; SameSite=Lax${isSecure ? '; Secure' : ''}; Max-Age=600`);\n }\n\n return ctx.redirect(url.toString());\n });\n\n // Callback Route\n this.get(`/auth/${providerName}/callback`, async (ctx) => {\n const url = new URL(ctx.req.url);\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n\n const cookieHeader = ctx.req.headers.get(\"Cookie\");\n const storedState = cookieHeader?.match(/oauth_state=([^;]+)/)?.[1];\n const storedVerifier = cookieHeader?.match(/oauth_verifier=([^;]+)/)?.[1];\n\n if (!code || !state || !storedState || state !== storedState) {\n return ctx.text(\"Invalid state or code\", 400);\n }\n\n try {\n let tokens: any;\n let idToken: string | undefined;\n\n if (provider instanceof GitHub) {\n tokens = await provider.validateAuthorizationCode(code);\n } else if (provider instanceof Google || provider instanceof MicrosoftEntraId) {\n if (!storedVerifier) return ctx.text(\"Missing verifier\", 400);\n tokens = await provider.validateAuthorizationCode(code, storedVerifier);\n } else if (provider instanceof Auth0 || provider instanceof Okta) {\n tokens = await (provider as any).validateAuthorizationCode(code, storedVerifier || \"\");\n } else if (provider instanceof Apple) {\n tokens = await provider.validateAuthorizationCode(code);\n idToken = tokens.idToken;\n } else if (provider instanceof OAuth2Client) {\n if (!providerConfig.tokenUrl) return ctx.text(\"Config error: tokenUrl required for oauth2\", 500);\n tokens = await provider.validateAuthorizationCode(providerConfig.tokenUrl, code, null);\n }\n\n const accessToken = tokens.accessToken || tokens.access_token;\n const user = await this.fetchUser(providerName, accessToken, providerConfig, idToken);\n\n if (this.authConfig.onSuccess) {\n const res = await this.authConfig.onSuccess(user, ctx);\n if (res) return res; // Allow override response\n }\n\n // Default behavior: create encoded session and returning it or redirect\n const jwt = await this.createSession(user, ctx);\n return ctx.json({ token: jwt, user });\n\n } catch (e: any) {\n // Security: Log detailed errors server-side, return generic message to client\n console.error(\"Auth Error\", e);\n return ctx.text(\"Authentication failed. Please try again.\", 500);\n }\n });\n }\n }\n\n private async fetchUser(provider: string, token: string, config: ProviderConfig, idToken?: string): Promise<AuthUser> {\n let user: AuthUser = { id: 'unknown', provider };\n\n if (provider === 'github') {\n const res = await fetch(\"https://api.github.com/user\", {\n headers: { Authorization: `Bearer ${token}` }\n });\n const data = await res.json() as any;\n user = {\n id: String(data.id),\n name: data.name || data.login,\n email: data.email,\n picture: data.avatar_url,\n provider,\n raw: data\n };\n }\n else if (provider === 'google') {\n const res = await fetch(\"https://openidconnect.googleapis.com/v1/userinfo\", {\n headers: { Authorization: `Bearer ${token}` }\n });\n const data = await res.json() as any;\n user = {\n id: data.sub,\n name: data.name,\n email: data.email,\n picture: data.picture,\n provider,\n raw: data\n };\n }\n else if (provider === 'microsoft') {\n const res = await fetch(\"https://graph.microsoft.com/v1.0/me\", {\n headers: { Authorization: `Bearer ${token}` }\n });\n const data = await res.json() as any;\n user = {\n id: data.id,\n name: data.displayName,\n email: data.mail || data.userPrincipalName,\n provider,\n raw: data\n };\n }\n else if (provider === 'auth0' || provider === 'okta') {\n const domain = config.domain!.startsWith('http') ? config.domain! : `https://${config.domain}`;\n const endpoint = provider === 'auth0' ? `${domain}/userinfo` : `${domain}/oauth2/v1/userinfo`;\n\n const res = await fetch(endpoint, {\n headers: { Authorization: `Bearer ${token}` }\n });\n const data = await res.json() as any;\n user = {\n id: data.sub,\n name: data.name,\n email: data.email,\n picture: data.picture,\n provider,\n raw: data\n };\n }\n else if (provider === 'apple') {\n // Apple user info is in the ID Token\n if (idToken) {\n const payload = this.jose.decodeJwt(idToken);\n user = {\n id: payload.sub!,\n email: payload['email'] as string,\n provider,\n raw: payload\n };\n }\n }\n else if (provider === 'oauth2') {\n if (config.userInfoUrl) {\n const res = await fetch(config.userInfoUrl, {\n headers: { Authorization: `Bearer ${token}` }\n });\n const data = await res.json() as any;\n user = {\n id: data.id || data.sub || 'unknown',\n name: data.name,\n email: data.email,\n picture: data.picture,\n provider,\n raw: data\n };\n }\n }\n\n return user;\n }\n\n /**\n * Middleware to verify JWT\n */\n public getMiddleware() {\n return async (ctx: ShokupanContext, next: () => Promise<any>) => {\n if (!this.jose) {\n // Try to load jose if not already loaded (e.g. middleware used without full plugin init?)\n // Ideally onInit should have run.\n this.jose = await import(\"jose\");\n }\n\n const authHeader = ctx.req.headers.get(\"Authorization\");\n let token = authHeader?.startsWith(\"Bearer \") ? authHeader.substring(7) : null;\n\n if (!token) {\n // Try cookie\n const cookieHeader = ctx.req.headers.get(\"Cookie\");\n token = cookieHeader?.match(/auth_token=([^;]+)/)?.[1] || null;\n }\n\n if (token) {\n try {\n const { payload } = await this.jose.jwtVerify(token, this.secret);\n (ctx as any).user = payload;\n } catch {\n // Invalid token, just proceed without user or throw?\n // Usually proceed, let guard handle it if required\n }\n }\n return next();\n };\n }\n}\n","import cluster from 'node:cluster';\nimport net from 'node:net';\nimport os from 'node:os';\nimport type { Shokupan } from '../../shokupan';\nimport type { ShokupanPlugin } from '../../util/types';\n\nexport interface ClusterOptions {\n /**\n * Number of workers to spawn.\n * Set to -1 or 'auto' to spawn one worker per available CPU.\n * @default 'auto'\n */\n workers?: number | 'auto';\n\n /**\n * Whether to pipe stdout/stderr to the parent process.\n * @default false\n */\n silent?: boolean;\n\n /**\n * Enable sticky sessions (useful for Socket.io).\n * Currently only supported in Node.js runtime.\n * @default false\n */\n sticky?: boolean;\n}\n\n/**\n * Cluster Plugin\n * \n * Automatically manages clustering for Node.js and Bun.\n */\nexport class ClusterPlugin implements ShokupanPlugin {\n constructor(private options: ClusterOptions = {}) { }\n\n onInit(app: Shokupan) {\n const originalListen = app.listen.bind(app);\n const { workers = 'auto', silent = false, sticky = false } = this.options;\n const isBun = typeof Bun !== 'undefined';\n const numCPUs = os.cpus().length;\n const numWorkers = (workers === 'auto' || workers === -1) ? numCPUs : workers;\n\n if (numWorkers <= 1) {\n // No clustering needed\n return;\n }\n\n app.listen = async (port?: number) => {\n const finalPort = port ?? app.applicationConfig.port ?? 3000;\n\n if (isBun) {\n return this.handleBun(app, finalPort, numWorkers, originalListen);\n } else {\n return this.handleNode(app, finalPort, numWorkers, originalListen, silent, sticky);\n }\n };\n }\n\n private async handleBun(app: Shokupan, port: number, workers: number, originalListen: Function) {\n // We use Bun's native behavior where multiple processes share the port via SO_REUSEPORT (reusePort: true).\n\n // Check if we are a worker\n const workerId = process.env['SHOKUPAN_WORKER_ID'];\n\n if (workerId) {\n // WORKER MODE\n // Force reusePort to true\n app.applicationConfig.reusePort = true;\n return originalListen(port);\n }\n\n // PRIMARY MODE\n console.log(`[Cluster] Starting ${workers} Bun workers on port ${port}...`);\n\n const spawnWorker = (id: string) => {\n // In Bun, we re-run the same script.\n // We must ensure arguments are passed correctly.\n Bun.spawn([process.argv0, ...process.argv.slice(1)], {\n env: { ...process.env, SHOKUPAN_WORKER_ID: id },\n stdio: ['inherit', 'inherit', 'inherit'],\n onExit(proc, exitCode, signalCode, error) {\n console.log(`[Cluster] Worker ${id} died (code: ${exitCode}). Restarting...`);\n spawnWorker(id);\n }\n });\n };\n\n for (let i = 0; i < workers; i++) {\n spawnWorker(process.pid + '_' + i + 1);\n }\n\n // Keep primary alive\n // in Bun, if simply returning, the script might exit if no event loop.\n // We just set an interval to ensure Bun doesn't exit.\n setInterval(() => { }, 1000 * 60 * 60);\n\n // Return a dummy object to satisfy Promise<Server> signature if needed, \n // though app.listen returns Server.\n return {\n stop: () => { },\n port\n } as any;\n }\n\n private async handleNode(app: Shokupan, port: number, workers: number, originalListen: Function, silent: boolean, sticky: boolean) {\n if (cluster.isPrimary) {\n console.log(`[Cluster] Master ${process.pid} is running`);\n\n // Fork workers\n const fork = () => cluster.fork(process.env);\n\n for (let i = 0; i < workers; i++) {\n fork();\n }\n\n cluster.on('exit', (worker, code, signal) => {\n console.log(`[Cluster] Worker ${worker.process.pid} died. Restarting...`);\n fork();\n });\n\n if (sticky) {\n // Sticky Session Master Logic\n // Create a net server to pause connections and distribute them\n const server = net.createServer({ pauseOnConnect: true }, (connection) => {\n const remote = connection.remoteAddress || '';\n // Simple hash\n let hash = 0;\n for (let i = 0; i < remote.length; i++) {\n hash = (hash << 5) - hash + remote.charCodeAt(i);\n hash |= 0;\n }\n const index = Math.abs(hash) % workers;\n\n // Get worker\n const worker = Object.values(cluster.workers!)[index];\n if (worker) {\n worker.send('sticky-session:connection', connection);\n } else {\n connection.end();\n }\n });\n\n server.listen(port, () => {\n console.log(`[Cluster] Sticky Load Balancer listening on port ${port}`);\n });\n\n // Return dummy server\n return {\n close: () => server.close(),\n port\n } as any;\n } else {\n // Standard Cluster (Round Robin by Node)\n // Master doesn't need to listen, workers will listen on the same port.\n // Node cluster handles the port sharing.\n return {\n close: () => { }, // Master controls\n port\n } as any;\n }\n\n } else {\n // WORKER MODE\n if (sticky) {\n // Sticky Worker Logic\n // We shouldn't listen on the PORT, because the master does.\n // We listen on 0 (random/ephemeral) just to initialize the internal http server.\n // Then we intercept messages.\n\n // Call listen with 0 to start server without binding public port\n const server = await originalListen(0);\n\n process.on('message', (message, handle) => {\n if (message !== 'sticky-session:connection') return;\n if (!handle) return;\n\n // Emulate connection \n (server as any).emit('connection', handle);\n // Connection was paused by master, resume it\n (handle as any).resume();\n });\n return server;\n } else {\n // Standard Worker\n return originalListen(port);\n }\n }\n }\n}\n","// @ts-nocheck\n\n\n\nexport function DashboardApp({ metrics, uptime, integrations, base, getRequestHeadersSource, rootPath, linkPattern }: any) {\n return (\n <html lang=\"en\">\n <head>\n <meta charSet=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Shokupan Debug Dashboard</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin=\"anonymous\" />\n <link href=\"https://fonts.googleapis.com/css2?family=Google+Sans+Code:ital,wght@0,300..800;1,300..800&family=Vend+Sans:ital,wght@0,300..700;1,300..700&display=swap\" rel=\"stylesheet\" />\n <link href=\"https://unpkg.com/tabulator-tables@5.5.0/dist/css/tabulator_bootstrap5.min.css\" rel=\"stylesheet\" />\n <link rel=\"stylesheet\" href=\"https://esm.sh/@xyflow/react@12.3.6/dist/style.css\" />\n\n <link rel=\"stylesheet\" href={`${base}/theme.css`} />\n <link rel=\"stylesheet\" href={`${base}/styles.css`} />\n <link rel=\"stylesheet\" href={`${base}/reactflow.css`} />\n <link rel=\"stylesheet\" href={`${base}/registry.css`} />\n <link rel=\"stylesheet\" href={`${base}/tabulator.css`} />\n\n <script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script>\n <script type=\"text/javascript\" src=\"https://unpkg.com/tabulator-tables@5.5.0/dist/js/tabulator.min.js\"></script>\n {/* Monaco Editor Loader */}\n <script src=\"https://cdn.jsdelivr.net/npm/monaco-editor@0.44.0/min/vs/loader.js\"></script>\n </head>\n <body>\n <div class=\"container\">\n <header>\n <div>\n <h1>Shokupan</h1>\n </div>\n <div style=\"margin-left: 8px\">\n <span style=\"color: var(--text-secondary)\">Uptime: <span id=\"uptime\">{uptime}</span></span>\n <span id=\"ws-status\" title=\"WebSocket: Disconnected\" style=\"width: 10px; height: 10px; border-radius: 50%; background: #6b7280; display: inline-block; margin-left: 10px;\"></span>\n </div>\n <div style=\"flex: 1;\"></div>\n <div class=\"tabs\">\n <button class=\"tab-btn active\" onclick=\"switchTab('overview')\">Overview</button>\n <button class=\"tab-btn\" onclick=\"switchTab('application')\">Application</button>\n <button class=\"tab-btn\" onclick=\"switchTab('network')\">Network</button>\n {integrations.scalar && (\n <button class=\"tab-btn\" onclick=\"switchTab('scalar')\">Scalar</button>\n )}\n {integrations.apiExplorer && (\n <button class=\"tab-btn\" onclick=\"switchTab('api-explorer')\">REST API</button>\n )}\n {integrations.asyncapi && (\n <button class=\"tab-btn\" onclick=\"switchTab('asyncapi')\">WS API</button>\n )}\n </div>\n </header>\n <div class=\"contents\">\n {/* Overview Tab */}\n <div id=\"tab-overview\" class=\"tab-content active\">\n <MetricsGrid metrics={metrics} />\n\n <div id=\"chart-container\" style=\"display: flex; flex-direction: column; gap: 1rem;\">\n <div style=\"display: flex; justify-content: flex-end;\">\n <select id=\"time-range-selector\" onchange=\"updateCharts(); updateDashboard(); fetchTopStats();\" style=\"background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--card-border); padding: 5px; border-radius: 4px;\">\n <option value=\"1m\">1 Minute</option>\n <option value=\"5m\">5 Minutes</option>\n <option value=\"30m\">30 Minutes</option>\n <option value=\"1h\">1 Hour</option>\n <option value=\"2h\">2 Hours</option>\n <option value=\"6h\">6 Hours</option>\n <option value=\"12h\">12 Hours</option>\n <option value=\"1d\">1 Day</option>\n <option value=\"3d\">3 Days</option>\n <option value=\"7d\">7 Days</option>\n <option value=\"30d\">30 Days</option>\n </select>\n </div>\n\n <div class=\"card-container\">\n <ChartCard title=\"Response Time\" id=\"latencyChart\" />\n <ChartCard title=\"Requests / Second\" id=\"rpsChart\" />\n <ChartCard title=\"CPU & Load\" id=\"cpuChart\" />\n <ChartCard title=\"Memory\" id=\"memoryChart\" />\n <ChartCard title=\"Heap Usage\" id=\"heapChart\" />\n <ChartCard title=\"Event Loop Latency\" id=\"eventLoopChart\" />\n <ChartCard title=\"Error Rate\" id=\"errorRateChart\" />\n </div>\n\n <div class=\"card-title\" style=\"margin-top: 1rem;\">Top Statistics</div>\n <div class=\"card-container\">\n <Card title=\"Top Requests\" contentId=\"top-requests-table\" />\n <Card title=\"Top Errors\" contentId=\"top-errors-table\" />\n <Card title=\"Most Frequent Failures\" contentId=\"failing-requests-table\" />\n <Card title=\"Slowest Requests\" contentId=\"slowest-requests-table\" />\n </div>\n\n <div id=\"table-container\" style=\"padding: 0; margin-top: 1rem;\">\n <div id=\"requests-table\" class=\"table-dark\"></div>\n </div>\n </div>\n <div style=\"height: 2rem\"></div>\n </div>\n\n {/* Application Tab */}\n <div id=\"tab-application\" class=\"tab-content\">\n <div style=\"margin: 2rem 2rem 0 2rem; display: flex; gap: 1rem; align-items: center;\">\n <div class=\"button-group\">\n <button class=\"view-btn active\" onclick=\"switchApplicationView('registry')\">Registry</button>\n <button class=\"view-btn\" onclick=\"switchApplicationView('graph')\">Graph</button>\n </div>\n </div>\n {/* Registry Sub-View */}\n <div id=\"app-view-registry\" class=\"app-view active\" style=\"max-width: 1200px; align-self: center; margin: 0 auto\">\n <div id=\"registry-container\" class=\"card\" style=\"margin: 2rem; margin-top: 1rem;\">\n <div class=\"card-title\">Component Registry</div>\n <div id=\"registry-tree\" style=\"padding: 0 1rem 1rem 1rem; font-family: monospace; font-size: 0.9rem;\"></div>\n </div>\n <div style=\"height: .1px\"></div>\n </div>\n\n {/* Graph Sub-View */}\n <div id=\"app-view-graph\" class=\"app-view\" style=\"height: 100%;\">\n <div class=\"card\" style=\"margin: 1rem 2rem;\">\n <div style=\"display: flex; gap: 1rem;\">\n <input type=\"text\" id=\"graph-search\" placeholder=\"Search routes or middleware...\" aria-label=\"Search routes or middleware\" style=\"flex:1; padding: 0.5rem; border-radius: 0.5rem; background: var(--bg-primary); border: 1px solid var(--card-border); color: var(--text-primary);\" />\n </div>\n </div>\n <div id=\"cy\" style=\"margin: 0 2rem; height: calc(100% - 10rem);\"></div>\n </div>\n </div>\n\n {/* Network Tab */}\n <div id=\"tab-network\" class=\"tab-content\">\n <div style=\"margin: 1rem 2rem 0 2rem;\">\n {/* Filter Bar will be injected by requests.js */}\n <div id=\"network-filter-bar\" class=\"card\" style=\"margin-bottom: 1rem; padding: 0.5rem; display: flex; gap: 0.5rem; flex-wrap: wrap; flex-direction: row\">\n {/* Placeholder for filters */}\n <div style=\"display: flex; background: var(--bg-secondary); border: 1px solid var(--card-border); border-radius: 4px; overflow: hidden;\">\n <button class=\"filter-direction active\" data-value=\"all\" style=\"padding: 4px 12px; border: none; background: var(--bg-primary); color: var(--text-primary); cursor: pointer; border-right: 1px solid var(--card-border);\">All</button>\n <button class=\"filter-direction\" data-value=\"inbound\" style=\"padding: 4px 12px; border: none; background: transparent; color: var(--text-secondary); cursor: pointer; border-right: 1px solid var(--card-border);\">Inbound</button>\n <button class=\"filter-direction\" data-value=\"outbound\" style=\"padding: 4px 12px; border: none; background: transparent; color: var(--text-secondary); cursor: pointer;\">Outbound</button>\n </div>\n <input type=\"text\" id=\"network-filter-text\" placeholder=\"Filter...\" style=\"background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--card-border); padding: 4px 8px; border-radius: 4px; flex: 1;\" />\n <select id=\"network-filter-type\" style=\"background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--card-border); borderRadius: 4px;\">\n <option value=\"all\">All Types</option>\n <option value=\"xhr\">XHR/Fetch</option>\n <option value=\"fetch\">Outbound</option>\n <option value=\"ws\">WS</option>\n <option value=\"other\">Other</option>\n </select>\n <button onclick=\"fetchRequests()\" style=\"background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--card-border); padding: 4px 8px; border-radius: 4px; cursor: pointer;\">Refresh</button>\n <button onclick=\"purgeRequests()\" style=\"background: var(--bg-primary); color: var(--color-error, #ef4444); border: 1px solid var(--card-border); padding: 4px 8px; border-radius: 4px; cursor: pointer;\">Purge</button>\n </div>\n </div>\n\n <div id=\"network-view\" class=\"active\" style=\"display: block; height: calc(100vh - 170px);\">\n <div style=\"margin: 0 2rem; display: flex; gap: 1rem; height: 100%;\">\n <div id=\"requests-list-container\" style=\"flex: 1; height: 100%; border-radius: 6px; overflow: hidden; border: 1px solid var(--card-border);\"></div>\n\n <div id=\"request-details-container\" class=\"card\" style=\"display: none; width: 500px; height: 100%; overflow-y: auto; flex-shrink: 0; background: var(--bg-secondary); border: 1px solid var(--card-border); position: relative;\">\n <div id=\"details-drag-handle\" style=\"position: absolute; left: 0; top: 0; bottom: 0; width: 5px; cursor: col-resize; z-index: 11; background: transparent;\"></div>\n <div style=\"display: flex; justify-content: space-between; align-items: center; position: sticky; top: 0; background: var(--bg-secondary); padding: 0.5rem 1rem; border-bottom: 1px solid var(--border-color); z-index: 10;\">\n <div class=\"card-title\" style=\"margin: 0;\">Request Details</div>\n <button onclick=\"closeRequestDetails()\" style=\"background: transparent; border: none; color: var(--text-secondary); cursor: pointer; font-size: 1.2rem;\">×</button>\n </div>\n <div style=\"padding: 1rem;\">\n <div id=\"request-details-content\"></div>\n <div class=\"card-title\" style=\"margin-top: 1rem;\">Middleware Trace</div>\n <div id=\"middleware-trace-container\"></div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n {integrations.scalar && (\n <div id=\"tab-scalar\" class=\"tab-content\" style=\"overflow: hidden; height: 100%; width: 100%\">\n <iframe src={integrations.scalar} style=\"width: 100%; height: 100%; border: none;\"></iframe>\n </div>\n )}\n\n {integrations.apiExplorer && (\n <div id=\"tab-api-explorer\" class=\"tab-content\" style=\"overflow: hidden; height: 100%; width: 100%\">\n <iframe src={integrations.apiExplorer} style=\"width: 100%; height: 100%; border: none;\"></iframe>\n </div>\n )}\n\n {integrations.asyncapi && (\n <div id=\"tab-asyncapi\" class=\"tab-content\" style=\"overflow: hidden; height: 100%; width: 100%\">\n <iframe src={integrations.asyncapi} style=\"width: 100%; height: 100%; border: none;\"></iframe>\n </div>\n )}\n </div>\n </div>\n\n <script dangerouslySetInnerHTML={{\n __html: `\n // Injected function from server config\n const getRequestHeaders = ${getRequestHeadersSource};\n window.SHOKUPAN_CONFIG = {\n rootPath: \"${rootPath || \"\"}\",\n linkPattern: \"${linkPattern || \"\"}\"\n };\n `}} />\n\n <script src={`${base}/client.js`}></script>\n <script src={`${base}/graph.mjs`} type=\"module\"></script>\n <script src={`${base}/charts.js`}></script>\n <script src={`${base}/tables.js`}></script>\n <script src={`${base}/registry.js`}></script>\n <script src={`${base}/failures.js`}></script>\n <script src={`${base}/requests.js`}></script>\n <script src={`${base}/tabs.js`}></script>\n </body>\n </html>\n );\n}\n\nfunction MetricsGrid({ metrics }: any) {\n const total = metrics.totalRequests;\n const active = metrics.activeRequests;\n const finished = total - active;\n\n // Safety check div by zero\n const successRate = finished ? Math.round((metrics.successfulRequests / finished) * 100) : 100;\n const failRate = finished ? Math.round((metrics.failedRequests / finished) * 100) : 0;\n\n return (\n <div class=\"metrics-grid\">\n <div class=\"card\">\n <div class=\"card-title\">Total Requests</div>\n <div class=\"card-value\" id=\"total-requests\">\n {metrics.totalRequests}\n </div>\n </div>\n\n <div class=\"card\">\n <div class=\"card-title\">Active Requests</div>\n <div class=\"card-value\" style=\"color: var(--accent)\" id=\"active-requests\">\n {metrics.activeRequests}\n </div>\n </div>\n\n <div class=\"card\">\n <div class=\"card-title\">Success Rate</div>\n <div class=\"card-value text-success\">\n <span id=\"success-rate\">{successRate}%</span>\n </div>\n <div style=\"color: var(--text-secondary); margin-top: 0.5rem\">\n <span id=\"successful-requests\">{metrics.successfulRequests}</span> successful\n </div>\n </div>\n\n <div class=\"card\">\n <div class=\"card-title\">Fail Rate</div>\n <div class=\"card-value text-error\">\n <span id=\"fail-rate\">{failRate}%</span>\n </div>\n <div style=\"color: var(--text-secondary); margin-top: 0.5rem\">\n <span id=\"failed-requests\">{metrics.failedRequests}</span> failed\n </div>\n </div>\n\n <div class=\"card\">\n <div class=\"card-title\">Avg Latency</div>\n <div class=\"card-value\">\n <span id=\"avg-latency\">\n {metrics.averageTotalTime_ms.toFixed(2)}\n </span> <span style=\"font-size: 1rem; color: var(--text-secondary)\">ms</span>\n </div>\n </div>\n </div>\n );\n}\n\nfunction ChartCard({ title, id }: any) {\n return (\n <div class=\"card\" style=\"height: 300px;\">\n <div class=\"card-title\">{title}</div>\n <div class=\"card-chart\">\n <canvas id={id}></canvas>\n </div>\n </div>\n );\n}\n\nfunction Card({ title, contentId }: any) {\n return (\n <div class=\"card\">\n <div class=\"card-title\">{title}</div>\n <div id={contentId}></div>\n </div>\n );\n}\n","import type { IncomingMessage } from 'node:http';\nimport { createRequire } from 'node:module';\nimport { URL } from 'node:url';\n\nconst require = createRequire(import.meta.url);\nconst http = require('node:http');\nconst https = require('node:https');\n\n\n/**\n * Interface representing the details of an intercepted outbound request.\n */\nexport interface OutboundRequestLog {\n /**\n * The HTTP method of the request (e.g., GET, POST).\n */\n method: string;\n /**\n * The full URL of the request.\n */\n url: string;\n /**\n * The request headers.\n */\n requestHeaders: Record<string, string>;\n /**\n * The HTTP status code of the response.\n */\n status: number;\n /**\n * The response headers.\n */\n responseHeaders: Record<string, string>;\n /**\n * The duration of the request in milliseconds.\n */\n duration: number;\n /**\n * The timestamp when the request started.\n */\n startTime: number;\n /**\n * The request body (if any).\n */\n requestBody?: any;\n /**\n * The response body (if any).\n */\n responseBody?: any;\n /**\n * The hostname of the request.\n */\n domain?: string;\n /**\n * The pathname of the request.\n */\n path?: string;\n /**\n * The protocol scheme (http/https) or version (1.1, 2.0).\n */\n protocol?: string;\n /**\n * The protocol scheme (http/https).\n */\n scheme?: string;\n /**\n * The remote IP address (if available).\n */\n remoteIP?: string;\n /**\n * The number of cookies sent.\n */\n cookies?: number;\n /**\n * The estimated transfer size in bytes.\n */\n transferred?: number;\n}\n\n/**\n * A callback function type for handling captured outbound requests.\n */\nexport type OutboundRequestCallback = (log: OutboundRequestLog) => void;\n\n/**\n * A utility class that intercepts calls to `global.fetch` to track outbound HTTP requests.\n * \n * @warning This class monkey-patches the global `fetch` function. While it attempts to transparently\n * pass through all calls, it may have side effects on global state or other libraries that rely on\n * the original `fetch`. Proceed with caution.\n */\nexport class FetchInterceptor {\n private originalFetch: typeof global.fetch;\n private originalHttpRequest: typeof http.request;\n private originalHttpsRequest: typeof https.request;\n private callbacks: OutboundRequestCallback[] = [];\n private isPatched: boolean = false;\n\n constructor() {\n this.originalFetch = global.fetch;\n this.originalHttpRequest = http.request;\n this.originalHttpsRequest = https.request;\n }\n\n /**\n * Patches the global `fetch` function to intercept requests.\n * If already patched, this method does nothing.\n */\n public patch() {\n if (this.isPatched) return;\n\n this.patchGlobalFetch();\n this.patchNodeRequests();\n\n this.isPatched = true;\n console.log('[FetchInterceptor] Network layer patched.');\n }\n\n private patchGlobalFetch() {\n const self = this;\n const newFetch = async function (input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n\n const startTime = performance.now();\n const timestamp = Date.now();\n let method = 'GET';\n let url = '';\n let requestHeaders: Record<string, string> = {};\n let requestBody: any = undefined;\n\n // Extract request details\n try {\n if (input instanceof URL) {\n url = input.toString();\n } else if (typeof input === 'string') {\n url = input;\n } else if (typeof input === 'object' && 'url' in input) {\n url = input.url;\n method = input.method;\n }\n\n if (init) {\n if (init.method) method = init.method;\n if (init.headers) {\n if (init.headers instanceof Headers) {\n init.headers.forEach((v, k) => requestHeaders[k] = v);\n } else if (Array.isArray(init.headers)) {\n init.headers.forEach(([k, v]) => requestHeaders[k] = v);\n } else {\n Object.assign(requestHeaders, init.headers);\n }\n }\n if (init.body) requestBody = init.body;\n }\n } catch (e) {\n console.warn('[FetchInterceptor] Failed to parse request arguments', e);\n }\n\n try {\n const response = await self.originalFetch.apply(global, [input, init]);\n const clone = response.clone();\n const duration = performance.now() - startTime;\n\n self.processResponse(clone, {\n method,\n url,\n requestHeaders,\n requestBody,\n status: response.status,\n startTime: timestamp,\n duration,\n ...self.extractRequestMeta(url, requestHeaders),\n protocol: '1.1' // native fetch doesn't expose this easily, assume 1.1/2\n });\n\n return response;\n } catch (error) {\n const duration = performance.now() - startTime;\n self.notify({\n method,\n url,\n requestHeaders,\n requestBody,\n status: 0,\n responseHeaders: {},\n responseBody: `Network Error: ${String(error)}`,\n startTime: timestamp,\n duration\n });\n throw error;\n }\n };\n\n // Copy static methods like preconnect\n Object.assign(newFetch, this.originalFetch);\n\n global.fetch = newFetch as typeof global.fetch;\n }\n\n private patchNodeRequests() {\n const self = this;\n const intercept = (module: typeof http | typeof https, original: Function, defaultScheme: string) => {\n // @ts-ignore\n module.request = function (...args: any[]) {\n const startTime = performance.now();\n const timestamp = Date.now();\n let options: any = {};\n let urlObj: URL | undefined;\n\n // Argument normalization\n if (typeof args[0] === 'string' || args[0] instanceof URL) {\n try {\n urlObj = new URL(args[0]);\n options = typeof args[1] === 'object' ? args[1] : {};\n } catch (e) { }\n } else {\n options = args[0] || {};\n try {\n const protocol = options.protocol || defaultScheme + ':';\n const host = options.hostname || options.host || 'localhost';\n const port = options.port ? ':' + options.port : '';\n const path = options.path || '/';\n urlObj = new URL(`${protocol}//${host}${port}${path}`);\n } catch (e) { }\n }\n\n const method = (options.method || 'GET').toUpperCase();\n const url = urlObj ? urlObj.toString() : 'unknown';\n\n // Call original\n const req = original.apply(this, args);\n\n // Helper to get headers\n const getReqHeaders = () => {\n try {\n const h = req.getHeaders();\n // Normalize\n const normalized: Record<string, string> = {};\n for (const k in h) {\n const v = h[k];\n normalized[k] = Array.isArray(v) ? v.join(', ') : String(v);\n }\n return normalized;\n } catch (e) { return {}; }\n };\n\n // Intercept response\n req.on('response', (res: IncomingMessage) => {\n const duration = performance.now() - startTime;\n\n // Normalize response headers\n const resHeaders: Record<string, string> = {};\n if (res.headers) {\n for (const k in res.headers) {\n const v = res.headers[k];\n resHeaders[k] = Array.isArray(v) ? v.join(', ') : String(v || '');\n }\n }\n\n self.notify({\n method,\n url,\n requestHeaders: getReqHeaders(),\n status: res.statusCode || 0,\n responseHeaders: resHeaders,\n startTime: timestamp,\n duration,\n ...self.extractRequestMeta(url, getReqHeaders()),\n protocol: req.httpVersion\n });\n });\n\n req.on('error', (err: Error) => {\n const duration = performance.now() - startTime;\n self.notify({\n method,\n url,\n requestHeaders: getReqHeaders(),\n status: 0,\n responseHeaders: {},\n responseBody: `Error: ${err.message}`, // Capture error\n startTime: timestamp,\n duration\n });\n });\n\n return req;\n };\n };\n\n intercept(http, this.originalHttpRequest, 'http');\n intercept(https, this.originalHttpsRequest, 'https');\n }\n\n /**\n * Restores the original functions.\n */\n public unpatch() {\n if (!this.isPatched) return;\n global.fetch = this.originalFetch;\n http.request = this.originalHttpRequest;\n https.request = this.originalHttpsRequest;\n\n this.isPatched = false;\n console.log('[FetchInterceptor] Network layer restored.');\n }\n\n /**\n * Adds a callback to be notified of outbound requests.\n * @param callback The callback function.\n */\n public on(callback: OutboundRequestCallback) {\n this.callbacks.push(callback);\n }\n\n private extractRequestMeta(urlStr: string, headers: Record<string, string>) {\n try {\n const url = new URL(urlStr);\n const cookiesHeader = headers['cookie'] || headers['Cookie'];\n const cookies = cookiesHeader ? cookiesHeader.split(';').length : 0;\n return {\n domain: url.hostname,\n path: url.pathname,\n scheme: url.protocol.replace(':', ''),\n cookies,\n remoteIP: undefined // Not easily accessible via fetch\n };\n } catch (e) {\n return {};\n }\n }\n\n private async processResponse(response: Response, meta: any) {\n const responseHeaders: Record<string, string> = {};\n response.headers.forEach((v, k) => responseHeaders[k] = v);\n\n let responseBody: any;\n let transferred = 0;\n\n try {\n // Check content type to decide how to read\n const contentType = response.headers.get('content-type') || '';\n let bodyText = '';\n\n if (contentType.includes('application/json') || contentType.includes('text/')) {\n bodyText = await response.text();\n // truncate if too large\n if (bodyText.length > 524288) { // 512KB limit from previous task\n responseBody = bodyText.substring(0, 524288) + '... (truncated)';\n } else {\n responseBody = bodyText;\n }\n } else {\n responseBody = '[Binary Content]';\n // Try to get size from content-length if binary\n const cl = response.headers.get('content-length');\n if (cl) transferred = parseInt(cl, 10);\n }\n\n // Calculate transferred size (headers + body)\n // Approximate headers size\n const headersSize = Object.entries(responseHeaders).reduce((acc, [k, v]) => acc + k.length + v.length + 2, 0);\n if (!transferred && bodyText) {\n transferred = headersSize + bodyText.length;\n } else if (!transferred) {\n transferred = headersSize; // minimal fallback\n }\n\n } catch (e) {\n responseBody = '[Failed to read response body]';\n }\n\n this.notify({\n ...meta,\n responseHeaders,\n responseBody,\n transferred\n });\n }\n\n private notify(log: OutboundRequestLog) {\n this.callbacks.forEach(cb => {\n try {\n cb(log);\n } catch (e) {\n console.error('[FetchInterceptor] Callback failed', e);\n }\n });\n }\n}\n","\nimport * as os from 'node:os';\nimport { monitorEventLoopDelay } from 'node:perf_hooks';\nimport { RecordId } from 'surrealdb';\nimport type { SurrealDatastore } from '../../../util/datastore';\n\ninterface AggregatedMetric {\n timestamp: number;\n interval: string;\n cpu: number;\n memory: {\n used: number;\n total: number;\n heapUsed: number;\n heapTotal: number;\n };\n load: number[];\n eventLoopLatency: {\n min: number;\n max: number;\n mean: number;\n p50: number;\n p95: number;\n p99: number;\n };\n requests: {\n total: number;\n rps: number;\n success: number;\n error: number;\n };\n responseTime: {\n min: number;\n max: number;\n avg: number;\n p50: number;\n p95: number;\n p99: number;\n };\n}\n\nconst INTERVALS = [\n { label: '10s', ms: 10 * 1000 },\n { label: '1m', ms: 60 * 1000 },\n { label: '5m', ms: 5 * 60 * 1000 },\n { label: '1h', ms: 60 * 60 * 1000 },\n { label: '2h', ms: 2 * 60 * 60 * 1000 },\n { label: '6h', ms: 6 * 60 * 60 * 1000 },\n { label: '12h', ms: 12 * 60 * 60 * 1000 },\n { label: '1d', ms: 24 * 60 * 60 * 1000 },\n { label: '3d', ms: 3 * 24 * 60 * 60 * 1000 },\n { label: '7d', ms: 7 * 24 * 60 * 60 * 1000 },\n { label: '30d', ms: 30 * 24 * 60 * 60 * 1000 },\n];\n\nexport class MetricsCollector {\n private currentIntervalStart: Record<string, number> = {};\n private pendingDetails: Record<string, { duration: number, isError: boolean; }[]> = {};\n private eventLoopHistogram = monitorEventLoopDelay({ resolution: 10 });\n private timer: NodeJS.Timeout | null = null;\n\n public db?: SurrealDatastore;\n\n constructor(\n db?: SurrealDatastore,\n private onCollect?: (metric: AggregatedMetric) => void\n ) {\n this.db = db;\n this.eventLoopHistogram.enable();\n // Initialize start times\n const now = Date.now();\n INTERVALS.forEach(int => {\n this.currentIntervalStart[int.label] = this.alignTimestamp(now, int.ms);\n this.pendingDetails[int.label] = [];\n });\n\n // Start collection loop - tick every 10 seconds to process high-res intervals?\n // Actually, for 1m interval, we should tick at least every minute.\n // Let's tick every 10s to be safe and accurate enough.\n this.timer = setInterval(() => this.collect(), 10000);\n }\n\n public recordRequest(duration: number, isError: boolean) {\n INTERVALS.forEach(int => {\n this.pendingDetails[int.label].push({ duration, isError });\n });\n }\n\n private alignTimestamp(ts: number, intervalMs: number): number {\n return Math.floor(ts / intervalMs) * intervalMs;\n }\n\n private async collect() {\n try {\n const now = Date.now();\n // console.log('[MetricsCollector] collect() called at', new Date(now).toISOString());\n\n for (const int of INTERVALS) {\n const start = this.currentIntervalStart[int.label];\n // If we passed the interval boundary\n if (now >= start + int.ms) {\n // console.log(`[MetricsCollector] Flushing ${int.label} interval (boundary crossed)`);\n await this.flushInterval(int.label, start, int.ms);\n // Advance to next interval (could simply be aligning now, but be careful of gaps if app was down)\n // For simplicity, just align now.\n this.currentIntervalStart[int.label] = this.alignTimestamp(now, int.ms);\n }\n }\n } catch (error) {\n console.error('[MetricsCollector] Error in collect():', error);\n }\n }\n\n private async flushInterval(label: string, timestamp: number, durationMs: number) {\n const reqs = this.pendingDetails[label];\n // console.log(`[MetricsCollector] flushInterval(${label}) - ${reqs.length} requests pending`);\n // Reset pending only if we are moving forward. \n // NOTE: In a real concurrent scenario, we'd need locking or atomic swap.\n // Javascript is single threaded so this is safe for CPU-bound stuff, \n // but verify no awaits before clearing.\n this.pendingDetails[label] = [];\n\n if (reqs.length === 0) {\n // console.log(`[MetricsCollector] No requests for ${label}, skipping persist`);\n // Optional: Don't record empty intervals to save space? \n // Or record zeros to show gaps in graphs.\n // Let's record zeros for continuity.\n return; // Don't persist empty intervals\n }\n\n const totalReqs = reqs.length;\n const errorReqs = reqs.filter(r => r.isError).length;\n const successReqs = totalReqs - errorReqs;\n const duratons = reqs.map(r => r.duration).sort((a, b) => a - b);\n\n const rps = totalReqs / (durationMs / 1000);\n\n const sum = duratons.reduce((a, b) => a + b, 0);\n const avg = totalReqs > 0 ? sum / totalReqs : 0;\n\n const getP = (p: number) => {\n if (duratons.length === 0) return 0;\n const idx = Math.floor(duratons.length * p);\n return duratons[idx];\n };\n\n const metric: AggregatedMetric = {\n timestamp,\n interval: label,\n cpu: os.loadavg()[0], // Using load avg for simplicity as per requirements (Load)\n load: os.loadavg(),\n memory: {\n used: process.memoryUsage().rss,\n total: os.totalmem(),\n heapUsed: process.memoryUsage().heapUsed,\n heapTotal: process.memoryUsage().heapTotal,\n },\n eventLoopLatency: {\n min: this.eventLoopHistogram.min / 1e6,\n max: this.eventLoopHistogram.max / 1e6,\n mean: this.eventLoopHistogram.mean / 1e6,\n p50: this.eventLoopHistogram.percentile(50) / 1e6,\n p95: this.eventLoopHistogram.percentile(95) / 1e6,\n p99: this.eventLoopHistogram.percentile(99) / 1e6,\n },\n requests: {\n total: totalReqs,\n rps,\n success: successReqs,\n error: errorReqs,\n },\n responseTime: {\n min: duratons[0] || 0,\n max: duratons[duratons.length - 1] || 0,\n avg,\n p50: getP(0.50),\n p95: getP(0.95),\n p99: getP(0.99),\n }\n };\n\n // console.log(`[MetricsCollector] Persisting ${label} metric at timestamp ${timestamp}`);\n if (!this.db) {\n // console.warn('[MetricsCollector] Skipping collection - No datastore connection');\n return;\n }\n\n try {\n await this.db.upsert(new RecordId(\"metric\", timestamp), metric);\n } catch (e) {\n console.error(`[MetricsCollector] ✗ Failed to save metrics for ${label}:`, e);\n }\n\n // Notify Listeners\n if (this.onCollect) {\n this.onCollect(metric);\n }\n }\n\n // Cleanup if needed\n public stop() {\n if (this.timer) clearInterval(this.timer);\n this.eventLoopHistogram.disable();\n }\n}\n","import type { ServerWebSocket } from 'bun';\nimport { nanoid } from 'nanoid';\nimport { readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport renderToString from 'preact-render-to-string';\nimport { RecordId } from 'surrealdb';\nimport type { DebugCollector } from \"../../../context\";\nimport { ShokupanRouter } from \"../../../router\";\nimport type { Shokupan } from '../../../shokupan';\nimport { $appRoot, $childRouters, $debug, $mountPath } from \"../../../util/symbol\";\nimport type { ShokupanHooks, ShokupanPlugin } from \"../../../util/types\";\nimport { DashboardApp } from './components';\nimport { FetchInterceptor, type OutboundRequestLog } from './fetch-interceptor';\nimport { MetricsCollector } from './metrics-collector';\n\ninterface RequestMetrics {\n totalRequests: number;\n successfulRequests: number;\n failedRequests: number;\n activeRequests: number;\n averageTotalTime_ms: number;\n recentTimings: number[];\n logs: RequestLog[];\n rateLimitedCounts: Record<string, number>;\n\n // Graph Metrics\n nodeMetrics: Record<string, NodeMetric>;\n edgeMetrics: Record<string, number>;\n}\n\ninterface NodeMetric {\n id: string;\n type: string;\n requests: number;\n totalTime: number;\n failures: number;\n name: string;\n}\n\nexport interface RequestLog {\n method: string;\n url: string;\n status: number;\n duration: number;\n timestamp: number;\n handlerStack?: any[];\n body?: any;\n contentType?: string;\n // New fields\n type: 'xhr' | 'fetch' | 'ws';\n direction: 'inbound' | 'outbound';\n size?: number;\n protocol?: string;\n domain?: string;\n path?: string;\n scheme?: string;\n remoteIP?: string;\n cookies?: number;\n transferred?: number;\n requestHeaders?: Record<string, string>;\n responseHeaders?: Record<string, string>;\n requestBody?: any;\n}\n\nexport interface DashboardConfig {\n getRequestHeaders?: () => HeadersInit;\n path?: string;\n /**\n * Retention time in milliseconds\n */\n retentionMs?: number;\n integrations?: {\n scalar?: boolean | { path?: string; };\n asyncapi?: boolean | { path?: string; };\n apiExplorer?: boolean | { path?: string; };\n };\n /**\n * Strategy for pushing request updates to the dashboard.\n * 'immediate' - pushes every request as soon as it completes.\n * 'batched' - buffers requests and pushes them at the interval specified by updateInterval.\n * @default 'immediate'\n */\n updateStrategy?: 'immediate' | 'batched';\n /**\n * Interval in milliseconds for pushing batched updates.\n * @default 10_000\n */\n updateInterval?: number;\n}\n\nclass Collector implements DebugCollector {\n private currentNode: string | undefined;\n\n constructor(private dashboard: Dashboard) { }\n\n trackStep(id: string | undefined, type: string, duration: number, status: 'success' | 'error', error?: any) {\n if (!id) return;\n this.dashboard.recordNodeMetric(id, type, duration, status === 'error');\n }\n\n trackEdge(fromId: string | undefined, toId: string | undefined) {\n if (!fromId || !toId) return;\n this.dashboard.recordEdgeMetric(fromId, toId);\n }\n\n setNode(id: string) {\n this.currentNode = id;\n }\n\n getCurrentNode(): string | undefined {\n return this.currentNode;\n }\n}\n\nexport class Dashboard implements ShokupanPlugin {\n\n private [$appRoot]: Shokupan;\n\n private router = new ShokupanRouter({ renderer: renderToString });\n private metrics: RequestMetrics = {\n totalRequests: 0,\n successfulRequests: 0,\n failedRequests: 0,\n activeRequests: 0,\n averageTotalTime_ms: 0,\n recentTimings: [],\n logs: [],\n rateLimitedCounts: {},\n nodeMetrics: {},\n edgeMetrics: {}\n };\n\n private clients = new Set<ServerWebSocket<any>>();\n private broadcastTimer: any;\n private requestPushTimer: any;\n private requestsBuffer: any[] = [];\n\n private startTime = Date.now();\n private instrumented = false;\n private mountPath = '/dashboard';\n private metricsCollector: MetricsCollector;\n get db() {\n return this[$appRoot].db;\n }\n\n constructor(private readonly dashboardConfig: DashboardConfig = {}) { }\n\n // ShokupanPlugin interface implementation\n public onInit(app: any, options?: { path?: string; }) {\n this[$appRoot] = app;\n\n // Subscribe to MetricsCollector updates\n const onCollect = (metric: any) => {\n this.broadcastMetricUpdate(metric);\n };\n\n this.metricsCollector = new MetricsCollector(this.db, onCollect);\n\n // Initialize Fetch Interceptor\n const fetchInterceptor = new FetchInterceptor();\n fetchInterceptor.patch();\n fetchInterceptor.on((log: OutboundRequestLog) => {\n // Prevent infinite loop by ignoring DB requests\n // SurrealDB driver uses /rpc endpoint\n if (log.url.includes('/rpc')) return;\n try {\n const u = new URL(log.url);\n if (u.pathname.startsWith(this.mountPath)) return;\n } catch (e) { }\n\n // Store outbound request\n const requestData: RequestLog = {\n method: log.method,\n url: log.url,\n status: log.status,\n duration: log.duration,\n timestamp: log.startTime, // Use startTime as timestamp\n type: 'fetch',\n direction: 'outbound',\n size: log.responseBody ? String(log.responseBody).length : 0,\n contentType: log.responseHeaders['content-type'] || log.responseHeaders['Content-Type'],\n body: log.responseBody,\n requestBody: log.requestBody,\n domain: log.domain,\n path: log.path,\n scheme: log.scheme,\n protocol: log.protocol,\n remoteIP: log.remoteIP,\n cookies: log.cookies,\n transferred: log.transferred,\n requestHeaders: log.requestHeaders,\n responseHeaders: log.responseHeaders,\n // No handler stack for outbound\n };\n\n this.metrics.logs.push(requestData);\n\n // Persist\n // We use 'request' table for both inbound and outbound.\n // ID generation: 'req_out_<timestamp>_<random>'\n\n // Persist\n // We use 'request' table for both inbound and outbound.\n // ID generation: 'req_out_<timestamp>_<random>'\n\n const recordId = new RecordId(\"request\", nanoid());\n const idString = recordId.toString();\n\n // Fire and forget save\n this.db.query('UPSERT $id CONTENT $data', {\n id: recordId,\n data: requestData\n }).catch(e => console.error(\"Failed to save outbound request\", e));\n\n // Broadcast\n const strategy = this.dashboardConfig.updateStrategy || 'immediate';\n if (strategy === 'immediate') {\n this.broadcastRequestUpdates([{ ...requestData, id: idString }]);\n } else {\n this.requestsBuffer.push({ ...requestData, id: idString });\n }\n });\n\n if (app.onStart) {\n app.onStart(async () => {\n if (app.dbPromise) {\n await app.dbPromise;\n if (app.db) {\n this.metricsCollector.db = app.db;\n console.log('[Dashboard] Attached datastore to MetricsCollector');\n }\n }\n });\n }\n this.mountPath = options?.path || this.dashboardConfig.path || '/dashboard';\n\n // Register hooks on the app to track all requests\n const hooks = this.getHooks();\n if (!app.middleware) {\n app.middleware = [];\n }\n\n // Create middleware that wraps the hooks\n const hooksMiddleware = async (ctx: any, next: any) => {\n if (hooks.onRequestStart) {\n await hooks.onRequestStart(ctx);\n }\n\n // Track start time for duration calculation\n (ctx as any)._startTime = performance.now();\n\n await next();\n };\n\n app.use(hooksMiddleware);\n\n if (hooks.onResponseEnd) {\n app.hook('onResponseEnd', hooks.onResponseEnd);\n }\n\n // Mount the dashboard router\n app.mount(this.mountPath, this.router);\n\n // Metadata for registry\n this.router.metadata = {\n file: import.meta.file,\n line: 1,\n name: 'DashboardPlugin',\n pluginName: 'Dashboard'\n };\n\n // Set up all routes on the internal router\n this.setupRoutes();\n\n // Start request push timer if batched\n const strategy = this.dashboardConfig.updateStrategy || 'immediate';\n if (strategy === 'batched') {\n this.startRequestPushTimer();\n }\n }\n\n private detectIntegrations() {\n const integrations: Record<string, string | undefined> = {};\n const routers = this[$appRoot]?.[$childRouters] || [];\n // Helper to check config\n const checkConfig = (key: 'scalar' | 'asyncapi' | 'apiExplorer') => {\n const conf = this.dashboardConfig.integrations?.[key];\n if (conf === false) return { enabled: false };\n if (typeof conf === 'object' && conf.path) return { enabled: true, path: conf.path };\n return { enabled: true };\n };\n\n // Scalar\n const scalarConf = checkConfig('scalar');\n if (scalarConf.enabled) {\n if (scalarConf.path) {\n integrations['scalar'] = scalarConf.path;\n } else {\n const plugin = routers.find(r => r.constructor.name === 'ScalarPlugin');\n if (plugin) {\n integrations['scalar'] = (plugin as any)[$mountPath];\n }\n }\n }\n\n // AsyncAPI\n const asyncApiConf = checkConfig('asyncapi');\n if (asyncApiConf.enabled) {\n if (asyncApiConf.path) {\n integrations['asyncapi'] = asyncApiConf.path;\n } else {\n const plugin = routers.find(r => r.constructor.name === 'AsyncApiPlugin');\n if (plugin) {\n integrations['asyncapi'] = (plugin as any)[$mountPath];\n }\n }\n }\n\n const apiExplorerConf = checkConfig('apiExplorer');\n if (apiExplorerConf.enabled) {\n if (apiExplorerConf.path) {\n integrations['apiExplorer'] = apiExplorerConf.path;\n } else {\n const plugin = routers.find(r => r.constructor.name === 'ApiExplorerPlugin');\n if (plugin) {\n integrations['apiExplorer'] = (plugin as any)[$mountPath];\n }\n }\n }\n\n return integrations;\n }\n\n // Get base path for dashboard files - works in both dev (src/) and production (dist/)\n private static getBasePath() {\n const dir = dirname(fileURLToPath(import.meta.url));\n // In production (dist/), files are in dist/plugins/application/dashboard/\n if (dir.endsWith('dist')) {\n return dir + '/plugins/application/dashboard';\n }\n // In dev mode (src/plugins/application/dashboard/), files are in same directory\n return dir;\n }\n\n private setupRoutes() {\n this.router.get(\"/ws\", (ctx) => {\n const success = ctx.upgrade({\n data: {\n handler: {\n open: (ws: ServerWebSocket<any>) => {\n this.clients.add(ws);\n console.log(`[Dashboard] Client connected. Total clients: ${this.clients.size}`);\n // Send default 1m history\n this.sendHistory(ws, '1m');\n },\n close: (ws: ServerWebSocket<any>) => {\n this.clients.delete(ws);\n console.log(`[Dashboard] Client disconnected. Total clients: ${this.clients.size}`);\n },\n message: (ws: ServerWebSocket<any>, message: string) => {\n try {\n const msg = JSON.parse(message);\n if (msg.type === 'get-history') {\n this.sendHistory(ws, msg.interval || '1m');\n }\n } catch (e) { }\n }\n }\n }\n });\n\n if (success) return undefined;\n return ctx.text(\"WebSocket upgrade failed\", 400);\n });\n\n this.router.get(\"/metrics\", async (ctx) => {\n const uptime = this.getUptime();\n const interval = ctx.query['interval'];\n if (interval) {\n const intervalMap: Record<string, number> = {\n '10s': 10 * 1000,\n '1m': 60 * 1000,\n '5m': 5 * 60 * 1000,\n '30m': 30 * 60 * 1000,\n '1h': 60 * 60 * 1000,\n '2h': 2 * 60 * 60 * 1000,\n '6h': 6 * 60 * 60 * 1000,\n '12h': 12 * 60 * 60 * 1000,\n '1d': 24 * 60 * 60 * 1000,\n '3d': 3 * 24 * 60 * 60 * 1000,\n '7d': 7 * 24 * 60 * 60 * 1000,\n '30d': 30 * 24 * 60 * 60 * 1000,\n };\n const ms = intervalMap[interval] || 60 * 1000;\n const startTime = Date.now() - ms;\n\n // For accuracy, query the requests table for the specific window\n let stats;\n try {\n stats = await this.db.query(`\n SELECT \n count() as total,\n count(IF status < 400 THEN 1 END) as success,\n count(IF status >= 400 THEN 1 END) as failed,\n math::mean(duration) as avg_latency\n FROM request \n WHERE timestamp >= $start\n GROUP ALL\n `, { start: startTime });\n } catch (error) {\n console.error('[Dashboard] Query failed at plugin.ts:180-191', {\n error,\n errorMessage: error.message,\n errorStack: error.stack,\n interval,\n startTime,\n query: 'metrics interval stats',\n stack: new Error().stack\n });\n throw error;\n }\n\n const s = stats[0] || { total: 0, success: 0, failed: 0, avg_latency: 0 };\n\n return ctx.json({\n metrics: {\n totalRequests: this.metrics.totalRequests,\n successfulRequests: this.metrics.successfulRequests,\n failedRequests: this.metrics.failedRequests,\n activeRequests: this.metrics.activeRequests,\n averageTotalTime_ms: s.avg_latency || 0,\n recentTimings: this.metrics.recentTimings,\n logs: [],\n rateLimitedCounts: this.metrics.rateLimitedCounts,\n nodeMetrics: this.metrics.nodeMetrics,\n edgeMetrics: this.metrics.edgeMetrics\n },\n uptime\n });\n }\n\n return ctx.json({\n metrics: this.metrics,\n uptime\n });\n });\n this.router.get(\"/metrics/history\", async (ctx) => {\n const interval = ctx.query['interval'] || '1m';\n\n // Map interval to milliseconds\n const intervalMap: Record<string, number> = {\n '10s': 10 * 1000,\n '1m': 60 * 1000,\n '5m': 5 * 60 * 1000,\n '30m': 30 * 60 * 1000,\n '1h': 60 * 60 * 1000,\n '2h': 2 * 60 * 60 * 1000,\n '6h': 6 * 60 * 60 * 1000,\n '12h': 12 * 60 * 60 * 1000,\n '1d': 24 * 60 * 60 * 1000,\n '3d': 3 * 24 * 60 * 60 * 1000,\n '7d': 7 * 24 * 60 * 60 * 1000,\n '30d': 30 * 24 * 60 * 60 * 1000,\n };\n\n const periodMs = intervalMap[interval] || 60 * 1000;\n // Expand window to 3x the requested period to ensure we catch the aligned start points.\n const startTime = Date.now() - (periodMs * 3);\n const endTime = Date.now();\n\n const result = await this.db.query(\n \"SELECT * FROM metrics WHERE timestamp >= $start AND timestamp <= $end AND interval = $interval ORDER BY timestamp ASC\",\n { start: startTime, end: endTime, interval }\n );\n\n return ctx.json({\n metrics: result[0] || [],\n });\n });\n\n const getIntervalStartTime = (interval?: string) => {\n if (!interval) return 0;\n const intervalMap: Record<string, number> = {\n '10s': 10 * 1000,\n '1m': 60 * 1000,\n '5m': 5 * 60 * 1000,\n '30m': 30 * 60 * 1000,\n '1h': 60 * 60 * 1000,\n '2h': 2 * 60 * 60 * 1000,\n '6h': 6 * 60 * 60 * 1000,\n '12h': 12 * 60 * 60 * 1000,\n '1d': 24 * 60 * 60 * 1000,\n '3d': 3 * 24 * 60 * 60 * 1000,\n '7d': 7 * 24 * 60 * 60 * 1000,\n '30d': 30 * 24 * 60 * 60 * 1000,\n };\n const ms = intervalMap[interval] || 0;\n return ms ? Date.now() - ms : 0;\n };\n\n // Top Requests Endpoint\n this.router.get(\"/requests/top\", async (ctx) => {\n const startTime = getIntervalStartTime(ctx.query['interval']);\n const result = await this.db.query(\n \"SELECT method, url, count() as count FROM request WHERE timestamp >= $start GROUP BY method, url ORDER BY count DESC LIMIT 10\",\n { start: startTime }\n );\n return ctx.json({ top: result[0] || [] });\n });\n\n // Top Errors Endpoint\n this.router.get(\"/errors/top\", async (ctx) => {\n const startTime = getIntervalStartTime(ctx.query['interval']);\n const result = await this.db.query(\n \"SELECT status, count() as count FROM failed_request WHERE timestamp >= $start GROUP BY status ORDER BY count DESC LIMIT 10\",\n { start: startTime }\n );\n return ctx.json({ top: result[0] || [] });\n });\n\n // Failing Requests Endpoint\n this.router.get(\"/requests/failing\", async (ctx) => {\n const startTime = getIntervalStartTime(ctx.query['interval']);\n const result = await this.db.query(\n \"SELECT method, url, count() as count FROM failed_request WHERE timestamp >= $start GROUP BY method, url ORDER BY count DESC LIMIT 10\",\n { start: startTime }\n );\n return ctx.json({ top: result[0] || [] });\n });\n\n // Slowest Requests Endpoint\n this.router.get(\"/requests/slowest\", async (ctx) => {\n const startTime = getIntervalStartTime(ctx.query['interval']);\n const result = await this.db.query(\n \"SELECT method, url, duration, status, timestamp FROM request WHERE timestamp >= $start ORDER BY duration DESC LIMIT 10\",\n { start: startTime }\n );\n return ctx.json({ slowest: result[0] || [] });\n });\n\n this.router.get(\"/registry\", (ctx) => {\n const app = this[$appRoot];\n if (!this.instrumented && app) {\n this.instrumentApp(app);\n }\n const registry = app?.getComponentRegistry?.();\n if (registry) {\n this.assignIdsToRegistry(registry, 'root');\n }\n return ctx.json({ registry: registry || {} });\n });\n\n // Requests Listing Endpoint\n this.router.get(\"/requests\", async (ctx) => {\n console.log(`[Dashboard] Handling /requests from ${ctx.ip} ${ctx.get('User-Agent')}`);\n const result = await this.db.query(\"SELECT * FROM request ORDER BY timestamp DESC LIMIT 100\");\n const items: any[] = result[0] as any[] || [];\n console.log(`[Dashboard] /requests returning ${items.length} items`);\n return ctx.json({ requests: items });\n });\n\n this.router.delete(\"/requests\", async (ctx) => {\n console.log(`[Dashboard] Purging all requests`);\n await this.db.query(\"DELETE request; DELETE failed_request;\");\n this.metrics.logs = [];\n this.metrics.totalRequests = 0;\n this.metrics.activeRequests = 0;\n this.metrics.successfulRequests = 0;\n this.metrics.failedRequests = 0;\n this.metrics.recentTimings = [];\n this.metrics.rateLimitedCounts = {};\n this.metrics.nodeMetrics = {};\n this.metrics.edgeMetrics = {};\n // Broadcast clear event? Or just let next update handle it?\n // Sending an empty list via requests-update might work if client handles it.\n // But we should probably send a specific \"purge\" event or just rely on client refresh.\n // Let's send a requests-update with empty list if validation shows it helps.\n // For now just return success.\n return ctx.json({ success: true });\n });\n\n // Request Details Endpoint\n this.router.get(\"/requests/:id\", async (ctx) => {\n const result = await this.db.query(\"SELECT * FROM request WHERE id = $id\", { id: ctx.params['id'] });\n return ctx.json({ request: result[0]?.[0] });\n });\n\n // Replay/Failed Requests Endpoints\n this.router.get(\"/failures\", async (ctx) => {\n const result = await this.db.query(\"SELECT * FROM failed_request ORDER BY timestamp DESC LIMIT 50\");\n return ctx.json({ failures: result[0] });\n });\n\n this.router.post(\"/replay\", async (ctx) => {\n const body = await ctx.body();\n // Logic to replay request:\n // We can't easily replay against the running server instance from inside without a loopback fetch.\n // We can use Shokupan.processRequest if we have access to app.\n const app = (this as any)[$appRoot];\n if (!app) return unknownError(ctx);\n\n // Construct request\n try {\n // body should contain method, url, headers, body\n const result = await app.processRequest({\n method: body.method,\n path: body.url, // or path\n headers: body.headers,\n body: body.body\n });\n return ctx.json({\n status: result.status,\n headers: result.headers,\n data: result.data\n });\n } catch (e) {\n return ctx.json({ error: String(e) }, 500);\n }\n });\n\n this.router.get(\"/**\", async (ctx) => {\n // Determine relative path by stripping the mount path\n const mountPath = this.router[$mountPath] || this.dashboardConfig.path || '/dashboard';\n\n let relativePath = ctx.path;\n if (relativePath.startsWith(mountPath)) {\n relativePath = relativePath.slice(mountPath.length);\n }\n // Strip leading slash\n if (relativePath.startsWith('/')) {\n relativePath = relativePath.slice(1);\n }\n\n const path = relativePath;\n\n // Serve static files if they match known extensions/files\n const staticFiles = [\n 'charts.js', 'failures.js', 'graph.mjs', 'client.js',\n 'reactflow.css', 'registry.css', 'registry.js', 'requests.js',\n 'styles.css', 'tables.js', 'tabs.js', 'tabulator.css', 'theme.css'\n ];\n\n if (staticFiles.includes(path)) {\n const content = await readFile(join(Dashboard.getBasePath(), 'static', path), 'utf-8');\n if (path.endsWith('.css')) ctx.set('Content-Type', 'text/css');\n else if (path.endsWith('.js') || path.endsWith('.mjs')) ctx.set('Content-Type', 'application/javascript');\n return ctx.send(content);\n }\n\n // Otherwise serve Dashboard\n const uptime = this.getUptime();\n\n const linkPattern = this.getLinkPattern();\n const integrations = this.detectIntegrations();\n\n const getRequestHeadersSource = this.dashboardConfig.getRequestHeaders ? this.dashboardConfig.getRequestHeaders.toString() : \"undefined\";\n\n const html = renderToString(DashboardApp({\n metrics: this.metrics,\n uptime,\n rootPath: process.cwd(),\n linkPattern,\n integrations,\n base: mountPath,\n getRequestHeadersSource\n }));\n return ctx.html(`<!DOCTYPE html>${html}`);\n });\n }\n\n private getUptime() {\n const uptimeSeconds = Math.floor((Date.now() - this.startTime) / 1000);\n return `${Math.floor(uptimeSeconds / 3600)}h ${Math.floor((uptimeSeconds % 3600) / 60)}m ${uptimeSeconds % 60}s`;\n }\n\n private getPublicMetrics() {\n return {\n totalRequests: this.metrics.totalRequests,\n successfulRequests: this.metrics.successfulRequests,\n failedRequests: this.metrics.failedRequests,\n activeRequests: this.metrics.activeRequests,\n averageTotalTime_ms: this.metrics.averageTotalTime_ms,\n recentTimings: this.metrics.recentTimings,\n logs: [], // Don't broadcast logs for now to save bandwidth\n rateLimitedCounts: this.metrics.rateLimitedCounts,\n nodeMetrics: this.metrics.nodeMetrics,\n edgeMetrics: this.metrics.edgeMetrics\n };\n }\n\n private broadcastMetricUpdate(metric: any) {\n if (this.clients.size === 0) return;\n // console.log(`[Dashboard] Broadcasting metric update to ${this.clients.size} clients`);\n\n const data = JSON.stringify({\n type: 'metric-update',\n metric\n });\n\n for (const client of this.clients) {\n client.send(data);\n }\n }\n\n private async sendHistory(ws: ServerWebSocket<any>, interval: string) {\n // Map interval to milliseconds\n const intervalMap: Record<string, number> = {\n '10s': 10 * 1000,\n '1m': 60 * 1000,\n '5m': 5 * 60 * 1000,\n '30m': 30 * 60 * 1000,\n '1h': 60 * 60 * 1000,\n '2h': 2 * 60 * 60 * 1000,\n '6h': 6 * 60 * 60 * 1000,\n '12h': 12 * 60 * 60 * 1000,\n '1d': 24 * 60 * 60 * 1000,\n '3d': 3 * 24 * 60 * 60 * 1000,\n '7d': 7 * 24 * 60 * 60 * 1000,\n '30d': 30 * 24 * 60 * 60 * 1000,\n };\n\n const periodMs = intervalMap[interval] || 60 * 1000;\n const startTime = Date.now() - (periodMs * 30); // Get 30 points of history\n const endTime = Date.now();\n\n let history: any[] = [];\n try {\n const result = await this.db.query<[any[]]>(\n \"SELECT * FROM metric WHERE timestamp >= $start AND timestamp <= $end AND interval = $interval ORDER BY timestamp ASC\",\n { start: startTime, end: endTime, interval }\n );\n history = result[0] || [];\n } catch (e) {\n console.error('[Dashboard] Failed to fetch history for WS', e);\n }\n\n ws.send(JSON.stringify({\n type: 'init',\n metrics: { ...this.metrics, logs: [] },\n uptime: this.getUptime(),\n history\n }));\n }\n\n private broadcastMetrics() {\n if (this.clients.size === 0) return;\n console.log(`[Dashboard] Broadcasting metrics to ${this.clients.size} clients`);\n\n const data = JSON.stringify({\n type: 'metrics',\n metrics: this.getPublicMetrics(),\n uptime: this.getUptime()\n });\n\n for (const client of this.clients) {\n client.send(data);\n }\n }\n\n private instrumentApp(app: any) {\n if (!app.getComponentRegistry) return;\n\n const registry = app.getComponentRegistry();\n this.assignIdsToRegistry(registry, 'root');\n this.instrumented = true;\n }\n\n // Traverses registry, generates IDs, and attaches them to the actual function objects\n private assignIdsToRegistry(node: any, parentId: string) {\n if (!node) return;\n\n const makeId = (type: string, parent: string, idx: number, name: string) =>\n `${type}_${parent}_${idx}_${name.replace(/[^a-zA-Z0-9]/g, '')}`;\n\n // Middleware\n node.middleware?.forEach((mw: any, idx: number) => {\n const id = makeId('mw', parentId, idx, mw.name);\n mw.id = id; // Assign to registry object for frontend\n if (mw._fn) (mw._fn as any)._debugId = id; // Assign to function for runtime tracking\n });\n\n // Controllers\n node.controllers?.forEach((ctrl: any, idx: number) => {\n const id = makeId('ctrl', parentId, idx, ctrl.name);\n ctrl.id = id;\n // Controllers don't have a single function. Attributes are on routes.\n // But we can store metadata if needed.\n });\n\n // Routes (in this node/router/controller)\n node.routes?.forEach((r: any, idx: number) => {\n // Route ID: logic?\n // Frontend doesn't explicitly ID route nodes unless they are loose.\n // But we need to track them.\n const id = makeId('route', parentId, idx, r.handlerName || 'handler');\n r.id = id;\n if (r._fn) (r._fn as any)._debugId = id;\n });\n\n // Child Routers\n node.routers?.forEach((r: any, idx: number) => {\n const id = makeId('router', parentId, idx, r.path);\n r.id = id;\n // Does router have a function? wrappedHandler?\n // Routers are containers mainly.\n this.assignIdsToRegistry(r.children, id);\n });\n\n // Events\n node.events?.forEach((e: any, idx: number) => {\n const id = makeId('event', parentId, idx, e.name);\n e.id = id;\n if (e._fn) (e._fn as any)._debugId = id;\n });\n }\n\n public recordNodeMetric(id: string, type: string, duration: number, isError: boolean) {\n if (!this.metrics.nodeMetrics[id]) {\n this.metrics.nodeMetrics[id] = {\n id,\n type,\n requests: 0,\n totalTime: 0,\n failures: 0,\n name: id // simplify\n };\n }\n const m = this.metrics.nodeMetrics[id];\n m.requests++;\n m.totalTime += duration;\n if (isError) m.failures++;\n }\n\n public recordEdgeMetric(from: string, to: string) {\n const key = `${from}|${to}`;\n this.metrics.edgeMetrics[key] = (this.metrics.edgeMetrics[key] || 0) + 1;\n }\n\n private getLinkPattern(): string {\n const term = process.env['TERM_PROGRAM'] || '';\n if (['vscode', 'cursor', 'antigravity'].some(t => term.includes(t))) {\n return 'vscode://file/{{absolute}}:{{line}}';\n }\n\n return 'vscode://file/{{absolute}}:{{line}}';\n }\n\n public getHooks(): ShokupanHooks {\n return {\n onRequestStart: (ctx) => {\n const app = (this as any)[$appRoot];\n if (!this.instrumented && app) {\n this.instrumentApp(app);\n }\n\n this.metrics.totalRequests++;\n this.metrics.activeRequests++;\n // (ctx as any)._debugStartTime = performance.now(); // Removed, now handled by middleware\n\n // Attach Collector\n ctx[$debug] = new Collector(this);\n\n // Broadcast immediate update for active requests? \n // Maybe throttle this if high load, but for now direct update is fine for lower loads.\n // Throttling:\n if (!this.broadcastTimer) {\n this.broadcastTimer = setTimeout(() => {\n this.broadcastMetrics();\n this.broadcastTimer = undefined;\n }, 100);\n }\n },\n\n onResponseEnd: async (ctx: any, response: any) => {\n // Ignore dashboard requests to prevent noise and loops\n if (ctx.path.startsWith(this.mountPath)) return;\n\n this.metrics.activeRequests = Math.max(0, this.metrics.activeRequests - 1);\n const duration = (performance.now() - (ctx as any)._startTime) || 0;\n\n // Handle WebSocket upgrade or missing response\n if (!response) {\n if (ctx.isUpgraded) {\n // WebSocket upgrade success, we can log it as 101 or skip\n // Let's create a dummy response object for logging purposes\n response = {\n status: 101,\n headers: {}\n };\n } else {\n // Unknown case, skip\n return;\n }\n }\n\n // Record in MetricsCollector\n const isError = response.status >= 400;\n this.metricsCollector.recordRequest(duration, isError);\n\n // Broadcast updates immediately\n if (!this.broadcastTimer) {\n this.broadcastTimer = setTimeout(() => {\n this.broadcastMetrics();\n this.broadcastTimer = undefined;\n }, 100);\n }\n\n if (response.status >= 400) {\n this.metrics.failedRequests++;\n if (response.status === 429) {\n const path = ctx.path;\n this.metrics.rateLimitedCounts[path] = (this.metrics.rateLimitedCounts[path] || 0) + 1;\n }\n\n // Record failure in Datastore\n try {\n const headers: Record<string, string> = {};\n if (ctx.request.headers && typeof ctx.request.headers.forEach === 'function') {\n ctx.request.headers.forEach((v: string, k: string) => {\n headers[k] = v;\n });\n }\n const resHeaders: Record<string, string> = {};\n if (response.headers && typeof response.headers.forEach === 'function') {\n response.headers.forEach((v: string, k: string) => {\n resHeaders[k] = v;\n });\n }\n\n await this.db.upsert(new RecordId(`failed_request`, ctx.requestId), {\n method: ctx.method,\n url: ctx.url.toString(),\n headers: headers,\n status: response.status,\n timestamp: Date.now(),\n state: ctx.state,\n body: this.serializeBody((ctx as any).bodyData || (ctx as any).requestBody),\n responseHeaders: resHeaders,\n responseBody: this.serializeBody((ctx as any).responseBody)\n });\n } catch (e) {\n console.error(\"Failed to record failed request\", e);\n }\n\n } else {\n this.metrics.successfulRequests++;\n }\n\n // Calculate metadata\n const urlObj = new URL(ctx.url.toString());\n const cookieHeader = ctx.request.headers.get('cookie') || '';\n const cookiesCount = cookieHeader ? cookieHeader.split(';').length : 0;\n\n const headers: Record<string, string> = {};\n if (ctx.request.headers && typeof ctx.request.headers.forEach === 'function') {\n ctx.request.headers.forEach((v: string, k: string) => {\n headers[k] = v;\n });\n }\n const resHeaders: Record<string, string> = {};\n if (response.headers && typeof response.headers.forEach === 'function') {\n response.headers.forEach((v: string, k: string) => {\n resHeaders[k] = v;\n });\n }\n\n const responseHeadersSize = Object.entries(response.headers || {}).reduce((acc, [k, v]) => acc + k.length + String(v).length + 2, 0);\n const responseSize = (ctx as any).responseBody ? String((ctx as any).responseBody).length : 0;\n\n // Try to get remote IP from various headers or socket\n const remoteIP = ctx.request.headers.get('x-forwarded-for') || (ctx.req as any)?.socket?.remoteAddress;\n\n const logEntry: RequestLog = {\n method: ctx.method,\n url: ctx.url.toString(),\n status: response.status,\n duration,\n timestamp: Date.now(),\n handlerStack: this.serializeHandlerStack((ctx as any).handlerStack),\n body: this.serializeBody((ctx as any).responseBody),\n requestBody: (ctx as any).bodyData || (ctx as any).requestBody, // ShokupanContext usually stores parsed body here if parsed\n contentType: response.headers['content-type'] || response.headers['Content-Type'],\n type: 'xhr',\n direction: 'inbound',\n size: responseSize,\n protocol: (ctx.req as any)?.httpVersion, // Try to get protocol from raw request if available, Bun might expose it\n domain: urlObj.hostname,\n path: urlObj.pathname,\n scheme: urlObj.protocol.replace(':', ''),\n cookies: cookiesCount,\n transferred: responseSize + responseHeadersSize,\n remoteIP,\n requestHeaders: headers,\n responseHeaders: resHeaders\n };\n // console.log(`[Dashboard Debug] Captured ${ctx.method} ${ctx.path} -> Status: ${response.status}`); // Removed debug log\n\n this.metrics.logs.push(logEntry);\n\n // Persist to datastore for detailed view\n try {\n // Use query explicitly to avoid driver/RecordId issues\n await this.db.query('UPSERT $id CONTENT $data', {\n id: new RecordId(\"request\", ctx.requestId),\n data: {\n ...logEntry,\n direction: \"inbound\"\n }\n });\n } catch (e) {\n console.error(\"Failed to record request log\", e);\n }\n const retention = this.dashboardConfig.retentionMs ?? 7200000;\n const cutoff = Date.now() - retention;\n if (this.metrics.logs.length > 0 && this.metrics.logs[0].timestamp < cutoff) {\n this.metrics.logs = this.metrics.logs.filter(log => log.timestamp >= cutoff);\n }\n\n const requestData = {\n id: ctx.requestId,\n ...logEntry\n };\n\n const strategy = this.dashboardConfig.updateStrategy || 'immediate';\n\n if (strategy === 'immediate') {\n this.broadcastRequestUpdates([requestData]);\n } else {\n // Buffer request for WS push\n this.requestsBuffer.push(requestData);\n }\n }\n };\n }\n\n private startRequestPushTimer() {\n const interval = this.dashboardConfig.updateInterval || 10000;\n this.requestPushTimer = setInterval(() => {\n if (this.requestsBuffer.length > 0) {\n this.broadcastRequestUpdates();\n }\n }, interval);\n }\n\n private broadcastRequestUpdates(requestsOverride?: any[]) {\n if (this.clients.size === 0) {\n if (!requestsOverride) this.requestsBuffer = [];\n return;\n }\n\n let requests;\n if (requestsOverride) {\n requests = requestsOverride;\n } else {\n requests = [...this.requestsBuffer];\n this.requestsBuffer = []; // Clear buffer\n }\n\n if (requests.length === 0) return;\n\n // Debug log\n console.log(`[Dashboard] Broadcasting ${requests.length} requests. Sample ID: ${requests[0].id}`);\n\n const data = JSON.stringify({\n type: 'requests-update',\n requests\n });\n\n for (const client of this.clients) {\n client.send(data);\n }\n }\n\n private updateTiming(duration: number) {\n const alpha = 0.1;\n if (this.metrics.averageTotalTime_ms === 0) {\n this.metrics.averageTotalTime_ms = duration;\n } else {\n this.metrics.averageTotalTime_ms = (alpha * duration) + ((1 - alpha) * this.metrics.averageTotalTime_ms);\n }\n this.metrics.recentTimings.push(duration);\n if (this.metrics.recentTimings.length > 50) {\n this.metrics.recentTimings.shift();\n }\n }\n private serializeHandlerStack(stack: any[]): any[] {\n if (!stack || !Array.isArray(stack)) return [];\n return stack.map(item => ({\n name: item.name,\n file: item.file,\n line: item.line,\n duration: item.duration,\n startTime: item.startTime,\n isBuiltin: item.isBuiltin,\n // stateChanges: item.stateChanges // Exclude complex objects for now\n }));\n }\n\n private serializeBody(body: any): any {\n if (!body) return undefined;\n\n // Handle strings\n if (typeof body === 'string') {\n if (body.length > 524288) {\n return body.substring(0, 524288) + '... (truncated)';\n }\n return body;\n }\n\n // Handle objects (JSON)\n // If it's already an object, we can return it directly if it's JSON-safe\n // But for safety and to avoid circular deps in logs, let's try to stringify if needed\n // Or better yet, we can store it as object and let the JSON serializer handle it when sending over WS\n // But for DB, we might want it as object too (surrealdb handles json)\n // Let's truncate if too big\n if (typeof body === 'object') {\n try {\n // Check size roughly\n const str = JSON.stringify(body);\n if (str.length > 524288) {\n return str.substring(0, 524288) + '... (truncated)';\n }\n return body;\n } catch (e) {\n return '[Circular or Non-Serializable Body]';\n }\n }\n\n return '[Binary or Unreadable Body]';\n }\n}\nfunction unknownError(ctx: any): any {\n return ctx.json({ error: \"Unknown Error\" }, 500);\n}\n\nexport default function DebugDashboard(config?: DashboardConfig) {\n return new Dashboard(config);\n}\n","import type { ApolloServer } from '@apollo/server';\nimport { ShokupanRouter } from '../../router';\nimport type { Shokupan } from '../../shokupan';\nimport type { ShokupanPlugin, ShokupanPluginOptions } from '../../util/types';\n\nexport interface GraphQLPluginOptions {\n /**\n * Path to mount the GraphQL endpoint to.\n * @default '/graphql'\n */\n path?: string;\n\n /**\n * GraphQL Type Definitions\n */\n typeDefs: any;\n\n /**\n * GraphQL Resolvers\n */\n resolvers: any;\n\n /**\n * Optional Apollo Server configuration\n */\n apolloConfig?: Omit<ConstructorParameters<typeof ApolloServer>[0], 'typeDefs' | 'resolvers'>;\n}\n\n/**\n * GraphQL Apollo Server Plugin for Shokupan.\n * Enables serving GraphQL APIs using Apollo Server 4.\n */\nexport class GraphQLApolloPlugin extends ShokupanRouter<any> implements ShokupanPlugin {\n private apolloServer: ApolloServer<any>; // Use generic any or verify type\n\n constructor(private pluginOptions: GraphQLPluginOptions) {\n super();\n this.pluginOptions.path ??= '/graphql';\n }\n\n async onInit(app: Shokupan, options?: ShokupanPluginOptions) {\n // Load peer dependencies\n const { ApolloServer, HeaderMap } = await import('@apollo/server');\n\n this.apolloServer = new ApolloServer({\n typeDefs: this.pluginOptions.typeDefs,\n resolvers: this.pluginOptions.resolvers,\n ...(this.pluginOptions.apolloConfig || {} as any),\n });\n\n const path = options?.path || this.pluginOptions.path || '/graphql';\n app.mount(path, this);\n\n\n // Ensure Apollo Server is started before handling requests\n // app.onStart() ensures this runs before the server listens\n app.onStart(async () => {\n await this.apolloServer.start();\n });\n\n // Handle POST requests for GraphQL operations\n this.post('/', async (ctx) => {\n // Ensure body is parsed\n const body = await ctx.body();\n\n const httpGraphQLResponse = await this.apolloServer.executeHTTPGraphQLRequest({\n httpGraphQLRequest: {\n body,\n method: ctx.req.method,\n search: ctx.url.search,\n headers: new HeaderMap(ctx.req.headers),\n },\n // Pass the Shokupan Context as the GraphQL Context\n context: async () => ({ ...ctx, shokupan: ctx }),\n });\n\n // Set Headers\n for (const [key, value] of httpGraphQLResponse.headers) {\n ctx.set(key, value);\n }\n\n // Send Response\n if (httpGraphQLResponse.body.kind === 'complete') {\n return ctx.send(httpGraphQLResponse.body.string, {\n status: httpGraphQLResponse.status ?? 200,\n });\n } else {\n // Basic support for chunked responses (e.g. invalid query iterator or future defer/stream)\n // For full stream support, we might need a more advanced stream handler\n let string = '';\n for await (const chunk of httpGraphQLResponse.body.asyncIterator) {\n string += chunk;\n }\n return ctx.send(string, {\n status: httpGraphQLResponse.status ?? 200,\n });\n }\n });\n\n // Handle GET requests (Landing Page / Playground)\n this.get('/', async (ctx) => {\n const httpGraphQLResponse = await this.apolloServer.executeHTTPGraphQLRequest({\n httpGraphQLRequest: {\n body: (Object.keys(ctx.query).length > 0) ? ctx.query : undefined,\n method: ctx.req.method,\n search: ctx.url.search,\n headers: new HeaderMap(ctx.req.headers),\n },\n context: async () => ({ ...ctx, shokupan: ctx }),\n });\n\n // Set Headers\n for (const [key, value] of httpGraphQLResponse.headers) {\n ctx.set(key, value);\n }\n\n if (httpGraphQLResponse.body.kind === 'complete') {\n return ctx.html(httpGraphQLResponse.body.string, httpGraphQLResponse.status ?? 200);\n } else {\n let string = '';\n for await (const chunk of httpGraphQLResponse.body.asyncIterator) {\n string += chunk;\n }\n return ctx.html(string, httpGraphQLResponse.status ?? 200);\n }\n });\n }\n}\n","import type { ApiReferenceConfiguration } from '@scalar/api-reference';\nimport type { OpenAPI } from '@scalar/openapi-types';\nimport type { Eta } from 'eta';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { ShokupanRouter } from '../../router';\nimport type { Shokupan } from '../../shokupan';\nimport { deepMerge } from '../../util/deep-merge';\nimport type { DeepPartial, ShokupanPlugin, ShokupanPluginOptions } from '../../util/types';\nimport { OpenAPIAnalyzer } from './openapi/analyzer';\n\n\nexport type ScalarPluginOptions = {\n /**\n * Base document to use for API reference.\n */\n baseDocument?: DeepPartial<OpenAPI.Document>;\n /**\n * Configuration for API reference.\n */\n config?: Partial<ApiReferenceConfiguration>;\n /**\n * Whether to enable static analysis.\n * When this is enabled, the plugin will run static analysis on the entrypoint\n * and generate an OpenAPI document. This is useful for when you want to generate\n * an OpenAPI document without having to manually define it.\n * \n * Only works with TypeScript entrypoints.\n */\n enableStaticAnalysis?: boolean;\n\n /**\n * Path to mount the plugin to.\n * @default '/reference'\n */\n path?: string;\n};\n\n/**\n * Scalar plugin. This plugin provides an API reference interface for your API.\n * @param options Scalar plugin options\n * @returns Scalar plugin instance\n */\nexport class ScalarPlugin extends ShokupanRouter<any> implements ShokupanPlugin {\n private eta: Eta | undefined;\n\n constructor(\n private readonly pluginOptions: ScalarPluginOptions = {}\n ) {\n pluginOptions.config ??= {};\n super();\n\n // Metadata\n this.metadata = {\n file: import.meta.file,\n line: 1,\n name: 'ScalarPlugin',\n pluginName: 'Scalar'\n };\n\n // Initialize routes immediately so the plugin works when mounted directly\n this.initRoutes();\n }\n\n async onInit(app: Shokupan, options?: ShokupanPluginOptions) {\n // Eagerly load Eta during app initialization\n const { Eta } = await import('eta');\n this.eta = new Eta();\n\n const path = options?.path || this.pluginOptions.path || '/reference';\n app.mount(path, this);\n\n // Also run onMount logic if needed\n this.onMount(app);\n }\n\n private async ensureEta() {\n if (!this.eta) {\n const { Eta } = await import('eta');\n this.eta = new Eta();\n }\n }\n\n private initRoutes() {\n const bootId = Date.now().toString();\n\n this.get(\"/_lifecycle\", (ctx) => {\n const success = ctx.upgrade({\n data: {\n bootId,\n handler: {\n open: (ws: any) => {\n ws.send(JSON.stringify({ type: 'hello', bootId }));\n }\n }\n }\n });\n if (success) return undefined;\n return ctx.json({ boot: bootId });\n });\n\n this.get(\"/\", async (ctx) => {\n await this.ensureEta();\n\n let path = ctx.path;\n if (!path.endsWith(\"/\")) path += \"/\";\n\n // Auto-reload script for development mode\n const devScript = ctx.app?.applicationConfig.development ? `\n <script>\n (function() {\n const bootId = \"${bootId}\";\n let ws;\n let reconnectTimer;\n \n function connect() {\n const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n const wsUrl = protocol + '//' + window.location.host + '${path}_lifecycle';\n \n ws = new WebSocket(wsUrl);\n \n ws.onopen = () => {\n console.log('[Scalar] Connected to lifecycle monitor');\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n reconnectTimer = undefined;\n }\n };\n \n ws.onmessage = (event) => {\n try {\n const data = JSON.parse(event.data);\n if (data.type === 'hello') {\n if (data.bootId !== bootId) {\n console.log('[Scalar] Server restarted (timestamp change), reloading...');\n window.location.reload();\n }\n }\n } catch (e) {}\n };\n \n ws.onclose = () => {\n console.log('[Scalar] Lifecycle connection lost');\n ws = undefined;\n scheduleReconnect();\n };\n }\n \n function scheduleReconnect() {\n if (reconnectTimer) return;\n reconnectTimer = setTimeout(() => {\n reconnectTimer = undefined;\n connect();\n }, 2000);\n }\n \n connect();\n })();\n </script>\n ` : '';\n\n // Attempt to read theme.css from src or dist\n let themeCss = '';\n try {\n // Try src location\n try {\n themeCss = readFileSync(join(process.cwd(), 'src/theme.css'), 'utf-8');\n } catch {\n // Try adjacent to main/dist? For now, we rely on src\n }\n } catch (e) { }\n\n if (!this.eta) throw new Error(\"Eta not initialized\");\n\n return ctx.html(this.eta.renderString(`<!doctype html>\n <html lang=\"en\">\n <head>\n <title>API Reference</title>\n <meta charset = \"utf-8\" />\n <meta name=\"viewport\" content = \"width=device-width, initial-scale=1\" />\n <style>\n ${themeCss}\n \n :root {\n --scalar-color-1: var(--primary);\n --scalar-color-2: var(--secondary);\n --scalar-color-3: var(--accent);\n --scalar-color-accent: var(--accent);\n \n --scalar-background-1: var(--bg-primary);\n --scalar-background-2: var(--bg-secondary);\n --scalar-background-3: var(--bg-card);\n \n --scalar-text-1: var(--text-primary);\n --scalar-text-2: var(--text-secondary);\n --scalar-text-3: var(--text-muted);\n \n --scalar-border-color: var(--border-color);\n }\n </style>\n </head>\n\n <body>\n <div id=\"app\"></div>\n <script src=\"https://cdn.jsdelivr.net/npm/@scalar/api-reference\"></script>\n <script>\n Scalar.createApiReference('#app', [{ ...<%~ JSON.stringify(it.config.baseDocument) %>,\n url: \"<%= it.path %>openapi.json\",\n }\n ])\n </script>\n <%~ it.devScript %>\n </body>\n\n </html>`, { path, config: this.pluginOptions, devScript }));\n });\n\n this.get(\"/openapi.json\", async (ctx) => {\n let spec: any;\n // Use pre-generated spec if available (from startup)\n if ((this.root as any).openApiSpec) {\n try {\n spec = structuredClone((this.root as any).openApiSpec);\n } catch (e) {\n // Fallback if structuredClone fails (e.g. non-cloneable types)\n spec = Object.assign({}, (this.root as any).openApiSpec);\n }\n }\n else {\n // Fallback to on-demand generation\n spec = await (this.root || this).generateApiSpec();\n }\n\n // If static analysis ran in onStart, baseDocument is already populated.\n // If NOT (e.g. strict mode or unit test without listen), we might need to lazy load?\n // For now, assume baseDocument has it.\n // But we still need to merge baseDocument (static) + spec (runtime).\n\n if (this.pluginOptions.baseDocument) {\n deepMerge(spec, this.pluginOptions.baseDocument);\n }\n\n return ctx.json(spec);\n });\n }\n\n // New lifecycle method to be called by router.mount\n public onMount(parent: ShokupanRouter<any>) {\n if ((parent as any).onStart) {\n (parent as any).onStart(async () => {\n if (this.pluginOptions.enableStaticAnalysis) {\n try {\n const entrypoint = process.argv[1];\n console.log(`[ScalarPlugin] Running eager static analysis on entrypoint: ${entrypoint}`);\n const analyzer = new OpenAPIAnalyzer(process.cwd(), entrypoint);\n let staticSpec = await analyzer.analyze();\n\n if (!this.pluginOptions.baseDocument) this.pluginOptions.baseDocument = {};\n deepMerge(this.pluginOptions.baseDocument as any, staticSpec);\n console.log('[ScalarPlugin] Static analysis completed successfully.');\n } catch (err) {\n console.error('[ScalarPlugin] Failed to run static analysis:', err);\n }\n }\n });\n }\n }\n}","import * as zlib from \"node:zlib\";\nimport type { ShokupanContext } from \"../../context\";\nimport { $finalResponse, $rawBody } from '../../util/symbol';\nimport type { Middleware, NextFn } from \"../../util/types\";\n\nexport interface CompressionOptions {\n /**\n * Minimum byte size to compress\n */\n threshold?: number;\n /**\n * Allowed algorithms\n */\n allowedAlgorithms?: string[];\n}\n\n/**\n * Compression middleware.\n * @param options Compression options\n * @returns Middleware function\n */\nexport function Compression(options: CompressionOptions = {}): Middleware {\n const threshold = options.threshold ?? 512; // 512 bytes default\n const allowedAlgorithms = new Set(options.allowedAlgorithms ?? ['br', 'gzip', 'zstd', 'deflate']);\n\n const compressionMiddleware: Middleware = async function CompressionMiddleware(ctx: ShokupanContext, next: NextFn) {\n const acceptEncoding = ctx.headers.get(\"accept-encoding\") || \"\";\n\n // Check if compression is supported\n let method: 'br' | 'gzip' | 'zstd' | 'deflate' | null = null;\n if (acceptEncoding.includes(\"br\")) method = \"br\";\n else if (acceptEncoding.includes(\"zstd\")) {\n // Validate zstd is only used in Bun runtime\n if (typeof Bun === 'undefined') {\n throw new Error(\"zstd compression is only available in Bun runtime. Client requested zstd but server is running on Node.js.\");\n }\n method = \"zstd\";\n }\n else if (acceptEncoding.includes(\"gzip\")) method = \"gzip\";\n else if (acceptEncoding.includes(\"deflate\")) method = \"deflate\";\n\n if (!method) return next();\n\n if (!allowedAlgorithms.has(method)) {\n return next();\n }\n\n let response = await next();\n\n // Check for implicit return stored in context\n if (!(response instanceof Response) && ctx[$finalResponse] instanceof Response) {\n response = ctx[$finalResponse];\n }\n\n if (response instanceof Response) {\n // Don't compress if already compressed\n if (response.headers.has(\"Content-Encoding\")) return response;\n\n // Optimized path: use raw body from context if available\n // Optimized path: use raw body from context if available\n let body: ArrayBuffer | Uint8Array;\n let bodySize: number;\n\n if (ctx[$rawBody] !== undefined) {\n // Fast path: we have the raw body from ctx.json() or ctx.text()\n if (typeof ctx[$rawBody] === \"string\") {\n const encoded = new TextEncoder().encode(ctx[$rawBody]);\n body = encoded;\n bodySize = encoded.byteLength;\n } else if (ctx[$rawBody] instanceof Uint8Array) {\n body = ctx[$rawBody];\n bodySize = ctx[$rawBody].byteLength;\n } else {\n body = ctx[$rawBody] as ArrayBuffer;\n bodySize = body.byteLength;\n }\n } else {\n // Fallback: read from response (slower)\n body = await response.arrayBuffer();\n bodySize = body.byteLength;\n }\n\n if (bodySize < threshold) {\n // Don't compress, but we consumed the body so recreate the response\n return new Response(body as any, {\n status: response.status,\n statusText: response.statusText,\n headers: new Headers(response.headers)\n });\n }\n\n let compressed: Uint8Array;\n\n switch (method) {\n case \"br\":\n compressed = await new Promise((res, rej) => zlib.brotliCompress(body, {\n params: {\n [zlib.constants.BROTLI_PARAM_QUALITY]: 4,\n }\n }, (err, data) => {\n if (err) return rej(err);\n res(data);\n }));\n break;\n case \"gzip\":\n compressed = await new Promise((res, rej) => zlib.gzip(body, (err, data) => {\n if (err) return rej(err);\n res(data);\n }));\n break;\n case \"zstd\":\n // Note: Runtime check happens earlier in method selection\n compressed = await Bun.zstdCompress(body);\n break;\n default: // deflate\n compressed = await new Promise((res, rej) => zlib.deflate(body, (err, data) => {\n if (err) return rej(err);\n res(data);\n }));\n break;\n }\n\n const headers = new Headers(response.headers);\n headers.set(\"Content-Encoding\", method);\n headers.set(\"Content-Length\", String(compressed.length));\n\n return new Response(compressed as any, {\n status: response.status,\n statusText: response.statusText,\n headers\n });\n }\n\n return response;\n };\n\n compressionMiddleware.isBuiltin = true;\n compressionMiddleware.pluginName = 'Compression';\n return compressionMiddleware;\n};\n","import type { ShokupanContext } from \"../../context\";\nimport type { Middleware, NextFn } from \"../../util/types\";\n\nexport interface CorsOptions {\n /**\n * Origin to allow. Can be a string, array of strings, or function that returns a string.\n */\n origin?: string | string[] | ((ctx: ShokupanContext) => string | undefined | null | boolean);\n /**\n * HTTP methods to allow.\n */\n methods?: string | string[];\n /**\n * HTTP headers to allow.\n */\n allowedHeaders?: string | string[];\n /**\n * HTTP headers to expose.\n */\n exposedHeaders?: string | string[];\n /**\n * Whether to allow credentials.\n */\n credentials?: boolean;\n /**\n * Maximum age of preflight request.\n */\n maxAge?: number;\n}\n\n/**\n * CORS middleware.\n * @param options CORS options\n * @returns Middleware function\n */\nexport function Cors(options: CorsOptions = {}): Middleware {\n const defaults: CorsOptions = {\n origin: \"*\",\n methods: \"GET,HEAD,PUT,PATCH,POST,DELETE\",\n preflightContinue: false,\n optionsSuccessStatus: 204\n } as any;\n\n const opts = { ...defaults, ...options };\n\n const corsMiddleware: Middleware = async function CorsMiddleware(ctx: ShokupanContext, next: NextFn) {\n const headers: Record<string, string> = {};\n const origin = ctx.headers.get(\"origin\");\n\n const set = (k: string, v: string) => headers[k] = v;\n const append = (k: string, v: string) => {\n const current = headers[k];\n headers[k] = current ? current + ',' + v : v;\n };\n\n // Security: Reject null origin by default (can be used in attacks)\n if (origin === 'null' && opts.origin !== 'null') {\n // Null origin is not allowed unless explicitly set\n return next();\n }\n\n // Set Access-Control-Allow-Origin\n if (opts.origin === \"*\") {\n set(\"Access-Control-Allow-Origin\", \"*\");\n } else if (typeof opts.origin === \"string\") {\n set(\"Access-Control-Allow-Origin\", opts.origin);\n } else if (Array.isArray(opts.origin)) {\n if (origin) {\n // Security: Normalize origins for case-insensitive comparison\n const normalizedOrigin = origin.toLowerCase();\n const normalizedAllowed = opts.origin.map(o => o.toLowerCase());\n\n if (normalizedAllowed.includes(normalizedOrigin)) {\n // Use the original (non-normalized) origin in the response\n set(\"Access-Control-Allow-Origin\", origin);\n append(\"Vary\", \"Origin\");\n }\n }\n } else if (typeof opts.origin === \"function\") {\n const allowed = opts.origin(ctx);\n if (allowed === true && origin) {\n set(\"Access-Control-Allow-Origin\", origin);\n append(\"Vary\", \"Origin\");\n } else if (typeof allowed === 'string') {\n set(\"Access-Control-Allow-Origin\", allowed);\n append(\"Vary\", \"Origin\");\n }\n }\n\n // Access-Control-Allow-Credentials\n if (opts.credentials) {\n set(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n // Access-Control-Expose-Headers\n if (opts.exposedHeaders) {\n const exposed = Array.isArray(opts.exposedHeaders) ? opts.exposedHeaders.join(\",\") : opts.exposedHeaders;\n if (exposed) set(\"Access-Control-Expose-Headers\", exposed);\n }\n\n // Handle Preflight\n if (ctx.method === \"OPTIONS\") {\n // Access-Control-Allow-Methods\n if (opts.methods) {\n const methods = Array.isArray(opts.methods) ? opts.methods.join(\",\") : opts.methods;\n set(\"Access-Control-Allow-Methods\", methods);\n }\n\n // Access-Control-Allow-Headers\n if (opts.allowedHeaders) {\n const h = Array.isArray(opts.allowedHeaders) ? opts.allowedHeaders.join(\",\") : opts.allowedHeaders;\n set(\"Access-Control-Allow-Headers\", h);\n } else {\n // Reflect request headers if not specified\n const reqHeaders = ctx.headers.get(\"access-control-request-headers\");\n if (reqHeaders) {\n set(\"Access-Control-Allow-Headers\", reqHeaders);\n append(\"Vary\", \"Access-Control-Request-Headers\");\n }\n }\n\n // Access-Control-Max-Age\n if (opts.maxAge) {\n set(\"Access-Control-Max-Age\", String(opts.maxAge));\n }\n\n return new Response(null, {\n status: (opts as any).optionsSuccessStatus || 204,\n headers\n });\n }\n\n const response = await next();\n\n if (response instanceof Response) {\n const keys = Object.keys(headers);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n response.headers.set(key, headers[key]);\n }\n }\n\n return response;\n };\n corsMiddleware.isBuiltin = true;\n corsMiddleware.pluginName = 'Cors';\n\n return corsMiddleware;\n}\n","import type { Middleware } from '../../util/types';\n\n/**\n * Adapter to use legacy Express middleware.\n * NOTE: This provides a PARTIAL mock of req/res.\n */\nexport function useExpress(expressMiddleware: any): Middleware {\n return async (ctx, next) => {\n return new Promise((resolve, reject) => {\n // Mock Request\n // Express middleware often mutates req, but Request is readonly.\n // We use a Proxy to intercept writes and store them locally.\n const reqStore: any = {\n method: ctx.method,\n url: ctx.url.pathname + ctx.url.search,\n path: ctx.url.pathname,\n query: ctx.query,\n headers: ctx.headers,\n get: (name: string) => ctx.headers.get(name)\n };\n\n const req = new Proxy(ctx.request, {\n get(target, prop) {\n if (prop in reqStore) return reqStore[prop];\n const val = (target as any)[prop];\n if (typeof val === 'function') return val.bind(target);\n return val;\n },\n set(target, prop, value) {\n reqStore[prop] = value;\n ctx.state[prop as string] = value;\n return true;\n }\n });\n\n // Mock Response (res)\n const res: any = {\n locals: {},\n statusCode: 200,\n setHeader: (name: string, value: string) => {\n ctx.response.headers.set(name, value);\n },\n set: (name: string, value: string) => {\n ctx.response.headers.set(name, value);\n },\n end: (chunk: any) => {\n resolve(new Response(chunk, { status: res.statusCode }));\n },\n status: (code: number) => {\n res.statusCode = code;\n return res;\n },\n send: (body: any) => {\n let content = body;\n if (typeof body === 'object') content = JSON.stringify(body);\n resolve(new Response(content, { status: res.statusCode }));\n },\n json: (body: any) => {\n resolve(Response.json(body, { status: res.statusCode }));\n }\n };\n\n // Execute\n try {\n expressMiddleware(req, res, (err: any) => {\n if (err) return reject(err);\n resolve(next());\n });\n } catch (err) {\n reject(err);\n }\n });\n };\n}","// Lazy-loaded dependencies\nlet plainToInstance: any;\nlet validateOrReject: any;\nimport { ShokupanContext } from \"../../context\";\nimport type { Middleware } from \"../../util/types\";\n\nexport interface ValidationConfig {\n body?: any;\n query?: any;\n params?: any;\n headers?: any;\n}\n\nexport class ValidationError extends Error {\n public status = 400;\n constructor(public errors: any[]) {\n super(\"Validation Error\");\n }\n}\n\n// --- Adapters ---\n\nfunction isZod(schema: any): boolean {\n return typeof schema?.safeParse === 'function';\n}\n\nasync function validateZod(schema: any, data: any) {\n const result = await schema.safeParseAsync(data);\n if (!result.success) {\n throw new ValidationError(result.error.errors);\n }\n return result.data;\n}\n\nfunction isTypeBox(schema: any): boolean {\n return typeof schema?.Check === 'function' && typeof schema?.Errors === 'function';\n}\n\nfunction validateTypeBox(schema: any, data: any) {\n if (!schema.Check(data)) {\n throw new ValidationError([...schema.Errors(data)]);\n }\n return data;\n}\n\nfunction isAjv(schema: any): boolean {\n return typeof schema === 'function' && 'errors' in schema;\n}\n\nfunction validateAjv(schema: any, data: any) {\n const valid = schema(data);\n if (!valid) {\n throw new ValidationError(schema.errors);\n }\n return data;\n}\n\nexport const valibot = (schema: any, parser: Function) => {\n return {\n _valibot: true,\n schema,\n parser\n };\n};\n\nfunction isValibotWrapper(schema: any): boolean {\n return schema?._valibot === true;\n}\n\nasync function validateValibotWrapper(wrapper: any, data: any) {\n const result = await wrapper.parser(wrapper.schema, data);\n if (!result.success) {\n throw new ValidationError(result.issues);\n }\n return result.output;\n}\n\nfunction isClass(schema: any): boolean {\n // Check if it's a constructor for a class\n // Usually classes have names and are functions, but plain functions are also functions.\n // A robust check for a class constructor (especially with decorators) is tricky but checking for prototype \n // and if it looks like a constructor is a start.\n // However, for class-validator/transformer usages, compiling consumers typically pass the class Constructor.\n try {\n if (typeof schema === 'function' && /^\\s*class\\s+/.test(schema.toString())) {\n return true;\n }\n // Fallback for some complied outputs or if it just has a name and prototype\n // But we want to avoid treating `z.string()` (which might yield a function?) \n // actually Zod schemas are objects. Custom validation functions are functions.\n // We can assume if the user passes a class constructor it intends for class-validator.\n return typeof schema === 'function' && schema.prototype && schema.name;\n } catch {\n return false;\n }\n}\n\nasync function validateClassValidator(schema: any, data: any) {\n // Lazy load dependencies\n if (!plainToInstance || !validateOrReject) {\n try {\n const ct = await import('class-transformer');\n const cv = await import('class-validator');\n plainToInstance = ct.plainToInstance;\n validateOrReject = cv.validateOrReject;\n } catch (e) {\n throw new Error(\n 'class-transformer and class-validator are required for class-based validation. ' +\n 'Install them with: bun add class-transformer class-validator reflect-metadata'\n );\n }\n }\n\n // Transform plain object to class instance\n const object = plainToInstance(schema, data);\n try {\n await validateOrReject(object as any);\n return object;\n } catch (errors: any) {\n // Flatten errors or just return them\n // class-validator returns Array<ValidationError>\n // We'll wrap in our ValidationError\n const formattedErrors = Array.isArray(errors)\n ? errors.map((err: any) => ({\n property: err.property,\n constraints: err.constraints,\n children: err.children\n }))\n : errors;\n\n throw new ValidationError(formattedErrors);\n }\n}\n\n\n// --- Body Helper ---\n\nconst safelyGetBody = async (ctx: ShokupanContext) => {\n // Use context's built-in body caching mechanism\n try {\n return await ctx.body();\n } catch (e) {\n return {}; // Return empty object if parsing fails (flexible)\n }\n};\n\n\n// --- Main Middleware ---\n\n// --- Main Middleware ---\n\nfunction getValidator(schema: any): (data: any) => Promise<any> | any {\n if (isZod(schema)) {\n return (data) => validateZod(schema, data);\n }\n if (isTypeBox(schema)) {\n return (data) => validateTypeBox(schema, data);\n }\n if (isAjv(schema)) {\n return (data) => validateAjv(schema, data);\n }\n if (isValibotWrapper(schema)) {\n return (data) => validateValibotWrapper(schema, data);\n }\n if (isClass(schema)) {\n return (data) => validateClassValidator(schema, data);\n }\n if (typeof schema === 'function') {\n return schema;\n }\n throw new Error(\"Unknown validator type provided. Please use a supported library (Zod, Ajv, TypeBox) or a custom function.\");\n}\n\n/**\n * Validation middleware.\n * @param config Validation configuration\n * @returns Middleware function\n */\nexport function validate(config: ValidationConfig): Middleware {\n // Pre-compilation: Resolve validators for each part\n const validators: {\n params?: (data: any) => any;\n query?: (data: any) => any;\n headers?: (data: any) => any;\n body?: (data: any) => any;\n } = {};\n\n if (config.params) validators.params = getValidator(config.params);\n if (config.query) validators.query = getValidator(config.query);\n if (config.headers) validators.headers = getValidator(config.headers);\n if (config.body) validators.body = getValidator(config.body);\n\n return async (ctx: ShokupanContext, next) => {\n // Prepare data for beforeValidate hook\n const dataToValidate: any = {};\n if (config.params) dataToValidate.params = ctx.params;\n let queryObj: Record<string, string> | undefined;\n if (config.query) {\n const url = new URL(ctx.req.url);\n queryObj = Object.fromEntries(url.searchParams.entries());\n dataToValidate.query = queryObj;\n }\n if (config.headers) dataToValidate.headers = Object.fromEntries(ctx.req.headers.entries());\n\n let body: any;\n if (config.body) {\n body = await safelyGetBody(ctx);\n dataToValidate.body = body;\n }\n\n // Call beforeValidate Hook\n await ctx.app.runHooks('beforeValidate', ctx, dataToValidate);\n\n // Validate Params\n if (validators.params) {\n ctx.params = await validators.params(ctx.params);\n }\n\n // Validate Query\n let validQuery: any;\n if (validators.query && queryObj) {\n validQuery = await validators.query(queryObj);\n }\n\n // Validate Headers\n if (validators.headers) {\n const headersObj = Object.fromEntries(ctx.req.headers.entries());\n await validators.headers(headersObj);\n }\n\n // Validate Body\n let validBody: any;\n if (validators.body) {\n // Re-use body accessed above or get again (it's cached)\n const b = body ?? await safelyGetBody(ctx);\n validBody = await validators.body(b);\n\n // Update context's cached body with validated/transformed version\n (ctx as any)._cachedBody = validBody;\n\n // Monkey-patch req.json() to return the validated body\n // This ensures handlers can call ctx.req.json() and get the validated data\n const req = ctx.req as any;\n Object.defineProperty(req, 'json', {\n value: async () => validBody,\n writable: true,\n configurable: true\n });\n\n (ctx as any).body = validBody; // Legacy/Convenience\n }\n\n // Call afterValidate Hook\n const validatedData: any = { ...dataToValidate };\n if (config.params) validatedData.params = ctx.params;\n if (config.query) validatedData.query = validQuery;\n if (config.body) validatedData.body = validBody;\n\n await ctx.app.runHooks('afterValidate', ctx, validatedData);\n\n return next();\n };\n}\n","import Ajv from \"ajv\";\nimport addFormats from \"ajv-formats\";\nimport type { Middleware } from \"../../util/types\";\nimport { ValidationError } from \"./validation\";\n\nconst ajv = new Ajv({ coerceTypes: true, allErrors: true });\naddFormats(ajv);\n\ntype ValidatorCache = Map<string, {\n [method: string]: {\n body?: import(\"ajv\").ValidateFunction;\n query?: import(\"ajv\").ValidateFunction;\n params?: import(\"ajv\").ValidateFunction;\n headers?: import(\"ajv\").ValidateFunction;\n };\n}>;\n\nconst compiledValidators = new WeakMap<any, {\n paths: Map<string, {\n regex: RegExp;\n paramNames: string[];\n }>;\n validators: ValidatorCache;\n}>();\n\nexport function openApiValidator(): Middleware {\n return async (ctx, next) => {\n const app = ctx.app;\n if (!app || !app.openApiSpec) {\n return next();\n }\n\n let cache = compiledValidators.get(app);\n if (!cache) {\n cache = compileValidators(app.openApiSpec);\n compiledValidators.set(app, cache);\n }\n\n let matchPath: string | undefined;\n let matchParams: Record<string, string> = {};\n\n // Try exact match first\n if (cache.validators.has(ctx.path)) {\n matchPath = ctx.path;\n } else {\n // Regex match\n const pathEntries = Array.from(cache.paths.entries());\n for (let i = 0; i < pathEntries.length; i++) {\n const [path, { regex, paramNames }] = pathEntries[i];\n const match = regex.exec(ctx.path);\n if (match) {\n matchPath = path;\n // Extract params\n paramNames.forEach((name, i) => {\n matchParams[name] = match[i + 1];\n });\n break;\n }\n }\n }\n\n if (!matchPath) {\n return next();\n }\n\n const method = ctx.req.method.toLowerCase();\n const validators = cache.validators.get(matchPath)?.[method];\n if (!validators) {\n return next();\n }\n\n const errors: any[] = [];\n\n if (validators.body) {\n let body: any;\n try {\n body = await ctx.req.json().catch(() => ({}));\n } catch {\n body = {};\n }\n const valid = validators.body(body);\n if (!valid && validators.body.errors) {\n errors.push(...validators.body.errors.map(e => ({ ...e, location: 'body' })));\n }\n }\n\n // Validate Query\n if (validators.query) {\n const query = Object.fromEntries(new URL(ctx.req.url).searchParams.entries());\n const valid = validators.query(query);\n if (!valid && validators.query.errors) {\n errors.push(...validators.query.errors.map(e => ({ ...e, location: 'query' })));\n }\n }\n\n // Validate Params\n if (validators.params) {\n // Merge extracted params with context params (if any)\n // Prioritize context params if router already parsed them, otherwise use matchParams\n const params = { ...matchParams, ...ctx.params };\n\n const valid = validators.params(params);\n if (!valid && validators.params.errors) {\n errors.push(...validators.params.errors.map(e => ({ ...e, location: 'path' })));\n }\n }\n\n // Validate Headers\n if (validators.headers) {\n const headers = Object.fromEntries(ctx.req.headers.entries());\n // Headers in OpenAPI are case-insensitive usually, but schema keys are sensitive?\n // Typically headers schema property names are lowercased.\n const valid = validators.headers(headers);\n if (!valid && validators.headers.errors) {\n errors.push(...validators.headers.errors.map(e => ({ ...e, location: 'header' })));\n }\n }\n\n if (errors.length > 0) {\n throw new ValidationError(errors);\n }\n\n return next();\n };\n}\n\nexport function compileValidators(spec: any): { paths: Map<string, { regex: RegExp, paramNames: string[]; }>, validators: ValidatorCache; } {\n const validators: ValidatorCache = new Map();\n const paths = new Map<string, { regex: RegExp, paramNames: string[]; }>();\n\n const pathEntries = Object.entries(spec.paths || {});\n for (let i = 0; i < pathEntries.length; i++) {\n const [path, pathItem] = pathEntries[i];\n // Compile Path Regex\n if (path.includes('{')) {\n const paramNames: string[] = [];\n const regexStr = \"^\" + path.replace(/{([^}]+)}/g, (_, name) => {\n paramNames.push(name);\n return \"([^/]+)\";\n }) + \"$\";\n paths.set(path, {\n regex: new RegExp(regexStr),\n paramNames\n });\n }\n\n const pathValidators: any = {};\n\n const methodEntries = Object.entries(pathItem as any);\n for (let k = 0; k < methodEntries.length; k++) {\n const [method, operation] = methodEntries[k];\n if (method === 'parameters' || method === 'summary' || method === 'description') continue;\n\n const oper = operation as any;\n const opValidators: any = {};\n\n // 1. Compile Request Body\n if (oper.requestBody?.content?.['application/json']?.schema) {\n opValidators.body = ajv.compile(oper.requestBody.content['application/json'].schema);\n }\n\n // 2. Compile Parameters (Query, Path, Header)\n const parameters = [...(oper.parameters || []), ...(pathItem as any).parameters || []];\n\n const queryProps: any = {};\n const pathProps: any = {};\n const headerProps: any = {};\n const queryRequired: string[] = [];\n const pathRequired: string[] = [];\n const headerRequired: string[] = [];\n\n for (let j = 0; j < parameters.length; j++) {\n const param = parameters[j];\n if (param.in === 'query') {\n queryProps[param.name] = param.schema || {};\n if (param.required) queryRequired.push(param.name);\n } else if (param.in === 'path') {\n pathProps[param.name] = param.schema || {};\n pathRequired.push(param.name);\n } else if (param.in === 'header') {\n headerProps[param.name] = param.schema || {};\n if (param.required) headerRequired.push(param.name);\n }\n }\n\n if (Object.keys(queryProps).length > 0) {\n opValidators.query = ajv.compile({\n type: 'object',\n properties: queryProps,\n required: queryRequired.length > 0 ? queryRequired : undefined\n });\n }\n\n if (Object.keys(pathProps).length > 0) {\n opValidators.params = ajv.compile({\n type: 'object',\n properties: pathProps,\n required: pathRequired.length > 0 ? pathRequired : undefined\n });\n }\n\n if (Object.keys(headerProps).length > 0) {\n opValidators.headers = ajv.compile({\n type: 'object',\n properties: headerProps,\n required: headerRequired.length > 0 ? headerRequired : undefined\n });\n }\n\n pathValidators[method] = opValidators;\n }\n\n validators.set(path, pathValidators);\n }\n\n return { paths, validators };\n}\n\n/**\n * Pre-compiles validators for the application using the provided spec.\n * Should be called when the spec is available.\n */\nexport function precompileValidators(app: any, spec: any) {\n const cache = compileValidators(spec);\n compiledValidators.set(app, cache);\n}\n\n/**\n * Enables OpenAPI validation for the application.\n * This registers the middleware and the hook to pre-compile validators when the spec is generated.\n * \n * @param app The Shokupan application instance\n */\nexport function enableOpenApiValidation(app: import(\"../../shokupan\").Shokupan) {\n app.use(openApiValidator());\n app.onSpecAvailable((spec) => {\n precompileValidators(app, spec);\n });\n}\n","import type { ShokupanContext } from \"../../context\";\nimport type { Middleware, NextFn } from \"../../util/types\";\n\nexport interface SecurityHeadersOptions {\n /**\n * Content Security Policy\n */\n contentSecurityPolicy?: boolean | Record<string, any>;\n /**\n * Cross-Origin Embedder Policy\n */\n crossOriginEmbedderPolicy?: boolean;\n /**\n * Cross-Origin Opener Policy\n */\n crossOriginOpenerPolicy?: boolean;\n /**\n * Cross-Origin Resource Policy\n */\n crossOriginResourcePolicy?: boolean;\n /**\n * DNS Prefetch Control\n */\n dnsPrefetchControl?: boolean | { allow: boolean; };\n /**\n * Expect CT\n */\n expectCt?: boolean | { maxAge?: number, enforce?: boolean, reportUri?: string; };\n /**\n * Frameguard\n */\n frameguard?: boolean | { action: 'deny' | 'sameorigin' | 'allow-from', domain?: string; };\n /**\n * Hide Powered By\n */\n hidePoweredBy?: boolean;\n /**\n * HTTP Strict Transport Security\n */\n hsts?: boolean | { maxAge?: number, includeSubDomains?: boolean, preload?: boolean; };\n /**\n * IE No Open\n */\n ieNoOpen?: boolean;\n /**\n * No Sniff\n */\n noSniff?: boolean;\n /**\n * Origin Agent Cluster\n */\n originAgentCluster?: boolean;\n /**\n * Permitted Cross Domain Policies\n */\n permittedCrossDomainPolicies?: boolean | { permittedPolicies: 'none' | 'master-only' | 'by-content-type' | 'all'; };\n /**\n * Referrer Policy\n */\n referrerPolicy?: boolean | { policy: string | string[]; };\n /**\n * X-XSS-Protection\n */\n xssFilter?: boolean;\n}\n\n/**\n * Security headers middleware.\n * @param options Security headers options\n * @returns Middleware function\n */\nexport function SecurityHeaders(options: SecurityHeadersOptions = {}): Middleware {\n const securityHeadersMiddleware: Middleware = async function SecurityHeadersMiddleware(ctx: ShokupanContext, next: NextFn) {\n const headers: Record<string, string> = {};\n\n // Helper to set header if not already set or force it\n const set = (k: string, v: string) => headers[k] = v;\n\n // X-DNS-Prefetch-Control\n if (options.dnsPrefetchControl !== false) {\n const allow = (options.dnsPrefetchControl as any)?.allow;\n set(\"X-DNS-Prefetch-Control\", allow ? \"on\" : \"off\");\n }\n\n // X-Frame-Options\n if (options.frameguard !== false) {\n const opt = options.frameguard as any || {};\n const action = opt.action || 'sameorigin';\n if (action === 'sameorigin') set('X-Frame-Options', 'SAMEORIGIN');\n else if (action === 'deny') set('X-Frame-Options', 'DENY');\n // 'allow-from' is deprecated/obsolete in modern browsers, but we can support it if needed.\n }\n\n // Strict-Transport-Security\n if (options.hsts !== false) {\n const opt = options.hsts as any || {};\n const maxAge = opt.maxAge || 15552000; // 180 days\n let header = `max-age=${maxAge}`;\n if (opt.includeSubDomains !== false) header += '; includeSubDomains';\n if (opt.preload) header += '; preload';\n set('Strict-Transport-Security', header);\n }\n\n // X-Download-Options\n if (options.ieNoOpen !== false) {\n set('X-Download-Options', 'noopen');\n }\n\n // X-Content-Type-Options\n if (options.noSniff !== false) {\n set('X-Content-Type-Options', 'nosniff');\n }\n\n // X-XSS-Protection (Legacy, but still sometimes used)\n if (options.xssFilter !== false) {\n set('X-XSS-Protection', '0'); // Modern recommendation is to disable it as it can introduce vulns\n }\n\n // Referrer-Policy\n if (options.referrerPolicy !== false) {\n const opt = options.referrerPolicy as any || {};\n const policy = opt.policy || 'no-referrer';\n set('Referrer-Policy', Array.isArray(policy) ? policy.join(',') : policy);\n }\n\n // Content-Security-Policy\n if (options.contentSecurityPolicy !== false) {\n // Basic default CSP if true, or use object\n const opt = options.contentSecurityPolicy;\n if (opt === undefined || opt === true) {\n set('Content-Security-Policy', \"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests\");\n } else if (typeof opt === 'object') {\n // Construct CSP string from object (simplified)\n // Assuming user passes raw string or we'd need a directive builder.\n // For now, let's assume they pass directives map.\n const parts = [];\n const optEntries = Object.entries(opt);\n for (let i = 0; i < optEntries.length; i++) {\n const [key, val] = optEntries[i];\n // directives, etc.\n // This is complex to implement fully without a library like 'helmet' itself.\n // We will support a simple string or custom logic later if requested.\n // For now, skip complex object parsing to keep it simple as per \"standard middleware\" MVP.\n }\n }\n }\n\n if (options.hidePoweredBy !== false) {\n // Note: Shokupan doesn't set X-Powered-By by default, so we usually don't need to remove it.\n // But we can ensure it's not there.\n // We can't delete from response easily before it's created, but we can try to suppress it if we had a hook.\n // Here we might just do nothing as we don't add it.\n }\n\n // Apply headers to context response\n // We need to apply these to the response *after* it's generated, or *before* if we use `ctx.headers` mutation?\n // `ctx.headers` is currently read-only wrapper around `req.headers` in `ShokupanContext`?\n // Wait, `ctx.headers` in `ShokupanContext` getter is `this.request.headers`.\n // We cannot set response headers on the request object.\n // We need to intercept the response.\n\n const response = await next();\n\n if (response instanceof Response) {\n const headerEntries = Object.entries(headers);\n for (let i = 0; i < headerEntries.length; i++) {\n const [k, v] = headerEntries[i];\n response.headers.set(k, v);\n }\n return response;\n }\n\n // If next() returned something else (e.g. string/json that router will wrap),\n // we can't easily attach headers here unless we wrap the result in a Response.\n // BUT `compose` and `router` logic allows next() to return result which `router` converts to Response.\n // If middleware runs *before* router, next() returns the router's result.\n\n // If we want to ensure headers are set, we might need to rely on `ctx` having a way to set \"outgoing\" headers \n // that the router respects, OR we must wrap the response.\n\n return response;\n return response;\n };\n securityHeadersMiddleware.isBuiltin = true;\n securityHeadersMiddleware.pluginName = 'SecurityHeaders';\n return securityHeadersMiddleware;\n}\n","import { createHmac, randomUUID } from \"crypto\";\nimport { EventEmitter } from \"events\";\nimport { ShokupanContext } from \"../../context\";\nimport type { Middleware } from \"../../util/types\";\n\n// --- Types ---\n\nexport interface SessionData {\n cookie: Cookie;\n [key: string]: any;\n}\n\nexport interface SessionCookieOptions {\n /**\n * Maximum age of the session cookie in milliseconds.\n */\n maxAge?: number;\n /**\n * Whether the session cookie should be signed.\n */\n signed?: boolean;\n /**\n * Expiration date of the session cookie.\n */\n expires?: Date;\n /**\n * Whether the session cookie should be HTTP-only.\n */\n httpOnly?: boolean;\n /**\n * Path of the session cookie.\n */\n path?: string;\n /**\n * Domain of the session cookie.\n */\n domain?: string;\n /**\n * Whether the session cookie should be secure.\n */\n secure?: boolean | 'auto';\n /**\n * SameSite attribute of the session cookie.\n */\n sameSite?: boolean | 'lax' | 'strict' | 'none';\n /**\n * Priority of the session cookie.\n */\n priority?: 'low' | 'medium' | 'high';\n}\n\nexport interface SessionOptions {\n /**\n * Secret used to sign the session cookie.\n */\n secret: string | string[];\n /**\n * Name of the session cookie.\n */\n name?: string;\n /**\n * Store to use for session data.\n */\n store?: Store;\n /**\n * Options for the session cookie.\n */\n cookie?: SessionCookieOptions;\n /**\n * Function to generate a session ID.\n */\n genid?: (ctx: ShokupanContext) => string;\n /**\n * Whether to force a session identifier cookie to be set on every response.\n */\n resave?: boolean;\n /**\n * Whether to save the session on every request.\n */\n saveUninitialized?: boolean;\n /**\n * Whether to update the session cookie on every request.\n */\n rolling?: boolean;\n /**\n * Whether to destroy or keep the session on logout.\n */\n unset?: 'destroy' | 'keep';\n}\n\nexport interface Store extends EventEmitter {\n /**\n * Retrieves a session by ID.\n */\n get(sid: string, callback: (err: any, session?: SessionData | null) => void): void;\n /**\n * Stores a session.\n */\n set(sid: string, session: SessionData, callback?: (err?: any) => void): void;\n /**\n * Destroys a session.\n */\n destroy(sid: string, callback?: (err?: any) => void): void;\n /**\n * Touches a session.\n */\n touch?(sid: string, session: SessionData, callback?: (err?: any) => void): void;\n /**\n * Retrieves all sessions.\n */\n all?(callback: (err: any, obj?: { [sid: string]: SessionData; } | null) => void): void;\n /**\n * Retrieves the number of sessions.\n */\n length?(callback: (err: any, length?: number) => void): void;\n /**\n * Clears all sessions.\n */\n clear?(callback?: (err?: any) => void): void;\n /**\n * Loads a session.\n */\n load?(sid: string, fn: (err: any, session?: SessionData | null) => void): void;\n /**\n * Creates a session.\n */\n createSession?(req: any, session: SessionData): SessionData;\n}\n\n// --- Cookie Helper ---\n\nclass Cookie implements SessionCookieOptions {\n maxAge?: number;\n signed?: boolean;\n expires?: Date;\n httpOnly?: boolean;\n path?: string;\n domain?: string;\n secure?: boolean | 'auto';\n sameSite?: boolean | 'lax' | 'strict' | 'none';\n originalMaxAge: number | undefined;\n\n constructor(options: SessionCookieOptions = {}) {\n this.path = options.path || '/';\n this.httpOnly = options.httpOnly !== undefined ? options.httpOnly : true;\n this.secure = options.secure;\n this.maxAge = options.maxAge;\n this.sameSite = options.sameSite;\n this.domain = options.domain;\n this.expires = options.expires;\n\n if (this.maxAge !== undefined) {\n this.originalMaxAge = this.maxAge;\n this.expires = new Date(Date.now() + this.maxAge);\n }\n }\n\n serialize(name: string, val: string) {\n let str = `${name}=${encodeURIComponent(val)}`;\n\n if (this.maxAge) {\n const expires = new Date(Date.now() + this.maxAge);\n str += `; Expires=${expires.toUTCString()}`;\n // Also add Max-Age?\n str += `; Max-Age=${Math.floor(this.maxAge / 1000)}`;\n } else if (this.expires) {\n str += `; Expires=${this.expires.toUTCString()}`;\n }\n\n if (this.domain) str += `; Domain=${this.domain}`;\n if (this.path) str += `; Path=${this.path}`;\n if (this.httpOnly) str += `; HttpOnly`;\n if (this.secure) str += `; Secure`;\n if (this.sameSite) {\n const sameSite = typeof this.sameSite === 'string' ?\n this.sameSite.charAt(0).toUpperCase() + this.sameSite.slice(1) : 'Strict';\n str += `; SameSite=${sameSite}`;\n }\n\n return str;\n }\n}\n\n// --- Memory Store ---\n\n\nexport class MemoryStore extends EventEmitter implements Store {\n private sessions: Record<string, string> = {};\n\n get(sid: string, cb: (err: any, session?: SessionData | null) => void) {\n const sess = this.sessions[sid];\n if (!sess) return cb(null, null);\n try {\n const data = JSON.parse(sess);\n // Re-hydrate dates?\n if (data.cookie && data.cookie.expires) {\n data.cookie.expires = new Date(data.cookie.expires);\n }\n cb(null, data);\n } catch (e) {\n cb(e);\n }\n }\n\n set(sid: string, sess: SessionData, cb?: (err?: any) => void) {\n this.sessions[sid] = JSON.stringify(sess);\n cb?.();\n }\n\n destroy(sid: string, cb?: (err?: any) => void) {\n delete this.sessions[sid];\n cb?.();\n }\n\n touch(sid: string, sess: SessionData, cb?: (err?: any) => void) {\n const current = this.sessions[sid];\n if (current) {\n // Update the cookie expiry if needed without changing the whole object if we want to be efficient\n // But for MemoryStore, just set is fine\n this.sessions[sid] = JSON.stringify(sess);\n }\n cb?.();\n }\n\n all(cb: (err: any, obj?: { [sid: string]: SessionData; } | null) => void) {\n const result: Record<string, SessionData> = {};\n const sessionKeys = Object.keys(this.sessions);\n for (let i = 0; i < sessionKeys.length; i++) {\n const sid = sessionKeys[i];\n try {\n result[sid] = JSON.parse(this.sessions[sid]);\n } catch { }\n }\n cb(null, result);\n }\n\n clear(cb?: (err?: any) => void) {\n this.sessions = {};\n cb?.();\n }\n}\n\n// --- Crypto Helpers ---\n\nfunction sign(val: string, secret: string) {\n if (typeof val !== 'string') throw new TypeError(\"Cookie value must be provided as a string.\");\n if (typeof secret !== 'string') throw new TypeError(\"Secret string must be provided.\");\n return val + '.' + createHmac('sha256', secret).update(val).digest('base64').replace(/\\=+$/, '');\n}\n\nfunction unsign(input: string, secret: string) {\n if (typeof input !== 'string') throw new TypeError(\"Signed cookie string must be provided.\");\n if (typeof secret !== 'string') throw new TypeError(\"Secret string must be provided.\");\n const tentValue = input.slice(0, input.lastIndexOf('.'));\n const expectedInput = sign(tentValue, secret);\n\n // Security: Use constant-time comparison with padding to prevent timing attacks\n // Pad both buffers to the same length to avoid length-based timing leaks\n const maxLength = Math.max(expectedInput.length, input.length);\n const paddedExpected = Buffer.alloc(maxLength);\n const paddedInput = Buffer.alloc(maxLength);\n\n Buffer.from(expectedInput).copy(paddedExpected);\n Buffer.from(input).copy(paddedInput);\n\n // Use crypto.timingSafeEqual for constant-time comparison\n try {\n const valid = require('crypto').timingSafeEqual(paddedExpected, paddedInput);\n return valid ? tentValue : false;\n } catch {\n // Buffers are different lengths (shouldn't happen with padding, but handle gracefully)\n return false;\n }\n}\n\n// --- Middleware ---\n\nexport interface SessionContext {\n session: SessionData & {\n id: string;\n regenerate(callback: (err: any) => void): void;\n destroy(callback: (err: any) => void): void;\n reload(callback: (err: any) => void): void;\n save(callback: (err: any) => void): void;\n touch(): void;\n };\n sessionID: string;\n sessionStore: Store;\n}\n\n// Merge into ShokupanContext? TODO: Review.\ndeclare module \"../../context\" {\n interface ShokupanContext {\n session: SessionContext['session'];\n sessionID: string;\n sessionStore: Store;\n }\n}\n\n/**\n * Session middleware.\n * @param options Session options\n * @returns Middleware function\n */\nexport function Session(options: SessionOptions): Middleware {\n const store = options.store || new MemoryStore();\n const name = options.name || 'connect.sid';\n const secrets = Array.isArray(options.secret) ? options.secret : [options.secret];\n\n // Validate store\n // (Could add check for .get .set .destroy)\n\n const generateId = options.genid || (() => randomUUID());\n\n const resave = options.resave === undefined ? true : options.resave;\n const saveUninitialized = options.saveUninitialized === undefined ? true : options.saveUninitialized;\n const rolling = options.rolling || false;\n\n const sessionMiddleware: Middleware = async function SessionMiddleware(ctx: ShokupanContext, next) {\n // 1. Get Session ID from Cookie\n let reqSessionId: string | null = null;\n let isSigned = false;\n\n // Simple cookie parser\n const cookieHeader = ctx.req.headers.get(\"cookie\");\n const cookies: Record<string, string> = {};\n if (cookieHeader) {\n cookieHeader.split(';').forEach(c => {\n const [k, v] = c.split('=').map(s => s.trim());\n if (k && v) cookies[k] = decodeURIComponent(v);\n });\n }\n\n const rawCookie = cookies[name];\n\n if (rawCookie) {\n if (rawCookie.substr(0, 2) === 's:') {\n // Signed cookie\n const val = unsign(rawCookie.slice(2), secrets[0]);\n if (val) {\n reqSessionId = val as string;\n isSigned = true;\n }\n } else {\n reqSessionId = rawCookie;\n }\n }\n\n // 2. Generate new ID if none\n let sessionID = reqSessionId;\n let isNew = false;\n if (!sessionID) {\n sessionID = generateId(ctx);\n isNew = true;\n }\n\n // 3. Helper to wrap session object\n const createSessionObject = (data: SessionData | null): SessionContext['session'] => {\n const existing = data || { cookie: new Cookie(options.cookie) };\n if (!existing.cookie) existing.cookie = new Cookie(options.cookie);\n else {\n // re-hydrate cookie options methods\n const c = new Cookie(options.cookie); // defaults\n Object.assign(c, existing.cookie);\n // ensure expiry is date\n if (c.expires && typeof c.expires === 'string') c.expires = new Date(c.expires);\n existing.cookie = c;\n }\n\n const sessObj = existing as any;\n\n // Methods\n Object.defineProperty(sessObj, 'id', { value: sessionID, configurable: true });\n\n sessObj.save = (cb: any) => {\n store.set(sessObj.id, sessObj, cb);\n };\n\n sessObj.destroy = (cb: any) => {\n store.destroy(sessObj.id, (err) => {\n // TODO: clear cookie?\n if (cb) cb(err);\n });\n };\n\n sessObj.regenerate = (cb: any) => {\n store.destroy(sessObj.id, (err) => {\n sessionID = generateId(ctx);\n // Create new session object\n // We actually need to replace the whole ctx.session object, which is tricky inside a method of that object.\n // Typically middleware attaches a proxy or the consumer does this.\n // But here we can reset properties.\n const keys = Object.keys(sessObj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (key !== 'cookie' && key !== 'id' && typeof sessObj[key] !== 'function') {\n delete sessObj[key];\n }\n }\n Object.defineProperty(sessObj, 'id', { value: sessionID, configurable: true });\n if (cb) cb(err);\n });\n };\n\n sessObj.undefined = () => { }; // Helper? no\n sessObj.reload = (cb: any) => {\n store.get(sessObj.id, (err, sess) => {\n if (err) return cb(err);\n if (!sess) return cb(new Error(\"Session not found\"));\n // Populate\n const keys = Object.keys(sessObj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (key !== 'cookie' && key !== 'id' && typeof sessObj[key] !== 'function') {\n delete sessObj[key];\n }\n }\n Object.assign(sessObj, sess);\n cb(null);\n });\n };\n\n sessObj.touch = () => {\n // Reset maxAge\n sessObj.cookie.expires = new Date(Date.now() + (sessObj.cookie.maxAge || 0));\n if (store.touch) store.touch(sessObj.id, sessObj);\n };\n\n return sessObj;\n };\n\n // 4. Load Session from Store\n let sessionData: SessionData | null = null;\n\n if (!isNew && sessionID) {\n await new Promise<void>((resolve) => {\n store.get(sessionID!, (err, sess) => {\n if (err) {\n // if error, treat as new? or error?\n // express-session logs and creates new\n sessionID = generateId(ctx);\n isNew = true;\n } else if (!sess) {\n // Session expired or invalid\n sessionID = generateId(ctx);\n isNew = true;\n } else {\n sessionData = sess;\n }\n resolve();\n });\n });\n }\n\n const sess = createSessionObject(sessionData);\n\n ctx.session = sess;\n ctx.sessionID = sessionID!;\n ctx.sessionStore = store;\n\n // Hash original sessionStr to detect changes\n const originalHash = JSON.stringify(sess);\n\n // 5. Run next\n const result = await next();\n\n // 6. Save Logic\n const currentHash = JSON.stringify(sess);\n const isModified = originalHash !== currentHash;\n\n if (!sessionID) return result; // Destroyed?\n\n let shouldSave = false;\n\n if (isModified) {\n shouldSave = true;\n } else if (isNew && saveUninitialized) {\n shouldSave = true;\n } else if (!isNew && resave) {\n shouldSave = true;\n }\n\n if (shouldSave) {\n await new Promise<void>((resolve, reject) => {\n store.set(sessionID!, sess, (err) => {\n if (err) console.error(\"Failed to save session\", err);\n resolve();\n });\n });\n }\n\n // 7. Set Cookie\n // Only set if new, or modified (rolling)\n // Express-session rules:\n // - if cookie.expires is set, it might need updating if rolling is true\n // - if isNew is true, definitely set cookie\n\n if (rolling && sess.cookie.maxAge) {\n sess.cookie.expires = new Date(Date.now() + sess.cookie.maxAge);\n }\n\n const shouldSetCookie = shouldSave || (!isNew && rolling);\n\n if (shouldSetCookie) {\n // value is just ID, or signed ID\n let val = sessionID;\n // We do simple signing s:id\n // Not enforcing secrets[0] yet\n if (secrets.length > 0) {\n val = 's:' + sign(val, secrets[0]);\n }\n\n const options = sess.cookie;\n // Serialize\n const str = options.serialize(name, val);\n ctx.set(\"Set-Cookie\", str);\n }\n\n return result;\n };\n sessionMiddleware.isBuiltin = true;\n sessionMiddleware.pluginName = 'Session';\n return sessionMiddleware;\n}\n"],"names":["context","OpenAPIAnalyzer","readFile","RouteParamType","i","k","router","http","options","resolve","generateAsyncApi","tracer","RateLimitMiddleware","Headers","Sidebar","MainContent","join","os","require","URL","strategy","headers","resHeaders","Eta","defaults","sess"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/util/body-parser.ts","../src/util/http-status.ts","../src/util/response.ts","../src/util/symbol.ts","../src/context.ts","../src/middleware.ts","../src/util/deep-merge.ts","../src/plugins/application/shared/ast-utils.ts","../src/plugins/application/openapi/openapi.ts","../src/plugins/middleware/serve-static.ts","../src/plugins/application/opentelemetry/index.ts","../src/plugins/resilience/factory.ts","../src/util/metadata.ts","../src/util/di.ts","../src/util/stack.ts","../src/util/types.ts","../src/util/controller-scanner.ts","../src/util/http-error.ts","../src/util/mcp-protocol.ts","../src/util/middleware-tracker.ts","../src/util/request.ts","../src/util/trie.ts","../src/router.ts","../src/util/adapter/bun.ts","../src/util/adapter/node.ts","../src/server.ts","../src/util/adapter/filesystem.ts","../src/util/async-hooks.ts","../src/util/cpu-monitor.ts","../src/util/datastore.ts","../src/util/promise.ts","../src/shokupan.ts","../src/plugins/middleware/rate-limit.ts","../src/util/decorators.ts","../src/plugins/application/api-explorer/components.tsx","../src/plugins/application/api-explorer/plugin.ts","../src/plugins/application/asyncapi/components.tsx","../src/plugins/application/asyncapi/generator.ts","../src/plugins/application/asyncapi/plugin.ts","../src/plugins/application/auth.ts","../src/plugins/application/cluster.ts","../src/plugins/application/dashboard/components.tsx","../src/plugins/application/dashboard/fetch-interceptor.ts","../src/plugins/application/dashboard/metrics-collector.ts","../src/plugins/application/dashboard/plugin.ts","../src/plugins/application/error-view/monkeypatch.ts","../src/plugins/application/error-view/util/source-reader.ts","../src/plugins/application/error-view/views/error.ts","../src/plugins/application/error-view/views/status.ts","../src/plugins/application/error-view/index.ts","../src/plugins/application/graphql-apollo.ts","../src/plugins/application/graphql-yoga.ts","../src/plugins/application/htmx/index.ts","../src/plugins/application/idempotency/plugin.ts","../src/plugins/application/mcp-server/plugin.ts","../src/plugins/application/scalar.ts","../src/plugins/application/socket-io.ts","../src/plugins/middleware/compression.ts","../src/plugins/middleware/cors.ts","../src/plugins/middleware/express.ts","../src/plugins/middleware/validation.ts","../src/plugins/middleware/openapi-validator.ts","../src/plugins/middleware/proxy.ts","../src/plugins/middleware/security-headers.ts","../src/plugins/middleware/session.ts"],"sourcesContent":["import type { ShokupanRequest } from \"./request\";\nimport type { ShokupanConfig } from \"./types\";\n\n/**\n * Utility class for parsing request bodies.\n * Handles size limits, parsing, and caching logic detached from the Context.\n */\nexport class BodyParser {\n\n /**\n * Parses the body of a request based on Content-Type header.\n * @param req The ShokupanRequest object\n * @param config Application configuration for limits and parser options\n * @returns The parsed body or throws an error\n */\n static async parse(req: ShokupanRequest<any>, config: ShokupanConfig = {}): Promise<{ type: string, body: any; }> {\n const contentType = req.headers.get(\"content-type\") || \"\";\n const maxBodySize = config.maxBodySize ?? 10 * 1024 * 1024; // Default 10MB\n\n if (contentType.includes(\"application/json\") || contentType.includes(\"+json\")) {\n return {\n type: 'json',\n body: await BodyParser.parseJson(req, config.jsonParser || 'native', maxBodySize)\n };\n } else if (contentType.includes(\"multipart/form-data\") || contentType.includes(\"application/x-www-form-urlencoded\")) {\n return {\n type: 'formData',\n body: await BodyParser.parseFormData(req, maxBodySize)\n };\n } else {\n return {\n type: 'text',\n body: await BodyParser.readRawBody(req, maxBodySize)\n };\n }\n }\n\n /**\n * Parsing helper for JSON\n */\n static async parseJson(req: ShokupanRequest<any>, parserType: 'native' | 'parse-json' | 'secure-json-parse', maxBodySize: number): Promise<any> {\n // To enforce maxBodySize, we must read the raw body ourselves\n const rawText = await BodyParser.readRawBody(req, maxBodySize);\n\n if (parserType === 'native') {\n // Handle empty body definition\n if (!rawText) return {};\n return JSON.parse(rawText);\n } else {\n const { getJSONParser } = await import('./json-parser');\n const parser = getJSONParser(parserType);\n return parser(rawText);\n }\n }\n\n /**\n * Parsing helper for FormData\n */\n static async parseFormData(req: ShokupanRequest<any>, maxBodySize: number): Promise<FormData> {\n const clHeader = req.headers.get(\"content-length\");\n if (!clHeader) {\n const err = new Error(\"Length Required\");\n (err as any).status = 411;\n throw err;\n }\n\n const cl = parseInt(clHeader, 10);\n if (isNaN(cl)) {\n const err = new Error(\"Bad Request\");\n (err as any).status = 400;\n throw err;\n }\n\n if (cl > maxBodySize) {\n const err = new Error(\"Payload Too Large\");\n (err as any).status = 413;\n throw err;\n }\n // NOTE: Does not enforce limit during streaming for FormData in this implementation\n return req.formData();\n }\n\n /**\n * Reads raw body as string with size enforcement\n */\n static async readRawBody(req: ShokupanRequest<any>, maxBodySize: number): Promise<string> {\n // Handle test case where body is already a string\n if (typeof (req as any).body === 'string') {\n const body = (req as any).body;\n if (body.length > maxBodySize) {\n const err = new Error(\"Payload Too Large\");\n (err as any).status = 413;\n throw err;\n }\n return body;\n }\n\n const reader = req.body?.getReader();\n if (!reader) {\n return '';\n }\n\n const chunks: Uint8Array[] = [];\n let totalSize = 0;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n totalSize += value.length;\n if (totalSize > maxBodySize) {\n const err = new Error(\"Payload Too Large\");\n (err as any).status = 413;\n throw err;\n }\n\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n\n // Efficiently combine chunks into single buffer\n const result = new Uint8Array(totalSize);\n let offset = 0;\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i];\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return new TextDecoder().decode(result);\n }\n}\n","/**\n * Common HTTP Status Codes\n * Use these constants instead of magic numbers for better readability\n */\nexport const HTTP_STATUS = {\n // 2xx Success\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NO_CONTENT: 204,\n\n // 3xx Redirection\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n SEE_OTHER: 303,\n NOT_MODIFIED: 304,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n\n // 4xx Client Errors\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n REQUEST_TIMEOUT: 408,\n CONFLICT: 409,\n UNPROCESSABLE_ENTITY: 422,\n TOO_MANY_REQUESTS: 429,\n\n // 5xx Server Errors\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n} as const;\n\nexport const VALID_HTTP_STATUSES = new Set<number>([\n 100, 101, 102, 103,\n 200, 201, 202, 203, 204, 205, 206, 207, 208, 226,\n 300, 301, 302, 303, 304, 305, 306, 307, 308,\n 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 421, 422, 423, 424, 425, 426, 428, 429, 431, 451,\n 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511\n]);\n\nexport const VALID_REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);\n","\n/**\n * Custom response class to handle response state (headers, status) \n * before the actual Response object is created.\n */\nexport class ShokupanResponse {\n private _headers: Headers | null = null;\n private _status = 200;\n\n /**\n * Get the current headers\n */\n get headers() {\n if (!this._headers) this._headers = new Headers();\n return this._headers;\n }\n\n /**\n * Get the current status code\n */\n get status() {\n return this._status;\n }\n\n /**\n * Set the status code\n */\n set status(code: number) {\n this._status = code;\n }\n\n /**\n * Set a response header\n * @param key Header name\n * @param value Header value\n */\n public set(key: string, value: string) {\n if (!this._headers) this._headers = new Headers();\n this._headers.set(key, value);\n return this;\n }\n\n /**\n * Append to a response header\n * @param key Header name\n * @param value Header value\n */\n public append(key: string, value: string) {\n if (!this._headers) this._headers = new Headers();\n this._headers.append(key, value);\n return this;\n }\n\n /**\n * Get a response header value\n * @param key Header name\n */\n public get(key: string) {\n return this._headers?.get(key) || null;\n }\n\n /**\n * Check if a header exists\n * @param key Header name\n */\n public has(key: string) {\n return this._headers?.has(key) || false;\n }\n\n /**\n * Internal: check if headers have been initialized/modified\n */\n public get hasPopulatedHeaders() {\n return this._headers !== null;\n }\n}\n","export const $isApplication = Symbol.for(\"Shokupan.app\");\nexport const $appRoot = Symbol.for(\"Shokupan.app-root\");\nexport const $isMounted = Symbol.for(\"Shokupan.isMounted\");\nexport const $routeMethods = Symbol.for(\"Shokupan.routeMethods\");\nexport const $eventMethods = Symbol.for(\"Shokupan.eventMethods\");\nexport const $routeArgs = Symbol.for(\"Shokupan.routeArgs\");\nexport const $controllerPath = Symbol.for(\"Shokupan.controllerPath\");\nexport const $middleware = Symbol.for(\"Shokupan.middleware\");\nexport const $isRouter = Symbol.for(\"Shokupan.router\");\nexport const $parent = Symbol.for(\"Shokupan.parent\");\nexport const $childRouters = Symbol.for(\"Shokupan.child-routers\");\nexport const $childControllers = Symbol.for(\"Shokupan.child-controllers\");\nexport const $mountPath = Symbol.for(\"Shokupan.mount-path\");\nexport const $dispatch = Symbol.for(\"Shokupan.dispatch\");\nexport const $routes = Symbol.for(\"Shokupan.routes\");\nexport const $routeSpec = Symbol.for(\"Shokupan.routeSpec\");\n\n\n\n///\n/// Context object \"hidden\" props that aren't intended for external use.\n/// We use Symbols to hide them internally.\n///\nexport const $url = Symbol.for(\"Shokupan.ctx.url\");\nexport const $requestId = Symbol.for(\"Shokupan.ctx.requestId\");\nexport const $debug = Symbol.for(\"Shokupan.ctx.debug\");\nexport const $finalResponse = Symbol.for(\"Shokupan.ctx.finalResponse\");\nexport const $rawBody = Symbol.for(\"Shokupan.ctx.rawBody\");\nexport const $cachedBody = Symbol.for(\"Shokupan.ctx.cachedBody\");\nexport const $bodyType = Symbol.for(\"Shokupan.ctx.bodyType\");\nexport const $bodyParsed = Symbol.for(\"Shokupan.ctx.bodyParsed\");\nexport const $bodyParseError = Symbol.for(\"Shokupan.ctx.bodyParseError\");\nexport const $routeMatched = Symbol.for(\"Shokupan.ctx.routeMatched\");\nexport const $cachedHostname = Symbol.for(\"Shokupan.ctx.cachedHostname\");\nexport const $cachedProtocol = Symbol.for(\"Shokupan.ctx.cachedProtocol\");\nexport const $cachedHost = Symbol.for(\"Shokupan.ctx.cachedHost\");\nexport const $cachedOrigin = Symbol.for(\"Shokupan.ctx.cachedOrigin\");\nexport const $cachedQuery = Symbol.for(\"Shokupan.ctx.cachedQuery\");\nexport const $cachedCookies = Symbol.for(\"Shokupan.ctx.cachedCookies\");\nexport const $ws = Symbol.for(\"Shokupan.ctx.ws\");\nexport const $socket = Symbol.for(\"Shokupan.ctx.socket\");\nexport const $io = Symbol.for(\"Shokupan.ctx.io\");\n\nexport const $mcpTools = Symbol.for(\"Shokupan.mcp.tools\");\nexport const $mcpPrompts = Symbol.for(\"Shokupan.mcp.prompts\");\nexport const $mcpResources = Symbol.for(\"Shokupan.mcp.resources\");\n\nexport const $resilienceConfig = Symbol.for(\"Shokupan.resilience.config\");\n\n\n","import type { BodyInit, Server, ServerWebSocket } from 'bun';\nimport { nanoid } from 'nanoid';\nimport { readFile } from 'node:fs/promises';\nimport { inspect } from 'node:util';\nimport type { Socket, Server as SocketServer } from 'socket.io';\nimport type { Shokupan } from './shokupan';\nimport { BodyParser } from './util/body-parser';\nimport { VALID_HTTP_STATUSES, VALID_REDIRECT_STATUSES } from './util/http-status';\nimport type { ShokupanRequest } from './util/request';\nimport { ShokupanResponse } from './util/response';\nimport { $bodyParsed, $bodyParseError, $bodyType, $cachedBody, $cachedCookies, $cachedHost, $cachedHostname, $cachedOrigin, $cachedProtocol, $cachedQuery, $debug, $finalResponse, $io, $rawBody, $requestId, $routeMatched, $socket, $url, $ws } from './util/symbol';\nimport type { CookieOptions, HeadersInit, JSXRenderer, SSEMessage, SSEStreamErrorHandler, SSEStreamHelper, StreamErrorHandler, StreamHelper, TextStreamErrorHandler, TextStreamHelper } from './util/types';\n\n/**\n * Security: Validate if a cookie domain is safe to use\n*/\nfunction isValidCookieDomain(domain: string, currentHost: string): boolean {\n // Remove port from current host if present\n const hostWithoutPort = currentHost.split(':')[0];\n\n // Domain must be current host or a parent domain\n if (domain === hostWithoutPort) return true;\n\n // Check if domain is a parent domain (starts with .)\n if (domain.startsWith('.')) {\n const domainWithoutDot = domain.slice(1);\n // Current host must end with the domain\n return hostWithoutPort.endsWith(domainWithoutDot);\n }\n\n return false;\n}\n\n\n\nexport interface HandlerStackItem {\n name: string;\n file: string;\n line: number;\n isBuiltin?: boolean;\n stateChanges?: Record<string, any>;\n startTime?: number;\n duration?: number;\n}\n\nexport interface DebugCollector {\n trackStep(id: string | undefined, type: string, duration: number, status: 'success' | 'error', error?: any): void;\n trackEdge(fromId: string | undefined, toId: string | undefined): void;\n setNode(id: string): void;\n getCurrentNode(): string | undefined;\n}\n\n/**\n * Shokupan Request Context\n * \n * The context object passed to all middleware and route handlers.\n * Provides access to request data, response helpers, and typed state management.\n * \n * @template State - The shape of `ctx.state` for type-safe state access across middleware.\n * @template Params - The shape of `ctx.params` based on the route path pattern.\n * \n * @example Basic Usage\n * ```typescript\n * app.get('/hello', (ctx) => {\n * return ctx.json({ message: 'Hello' });\n * });\n * ```\n * \n * @example Typed State\n * ```typescript\n * interface AppState {\n * userId: string;\n * requestId: string;\n * }\n * \n * const app = new Shokupan<AppState>();\n * \n * app.use((ctx, next) => {\n * ctx.state.requestId = crypto.randomUUID(); // ✓ Type-safe\n * return next();\n * });\n * ```\n * \n * @example Typed Path Parameters\n * ```typescript\n * app.get('/users/:userId/posts/:postId', (ctx) => {\n * // ctx.params is automatically typed as { userId: string; postId: string }\n * const { userId, postId } = ctx.params;\n * return ctx.json({ userId, postId });\n * });\n * ```\n * \n * @example Full Type Safety (State + Params)\n * ```typescript\n * interface RequestState {\n * userId: string;\n * permissions: string[];\n * }\n * \n * const app = new Shokupan<RequestState>();\n * \n * app.get('/admin/users/:userId', (ctx) => {\n * // Both typed!\n * const { userId } = ctx.params; // ✓ From path\n * const { permissions } = ctx.state; // ✓ From state\n * \n * if (!permissions.includes('admin')) {\n * return ctx.json({ error: 'Forbidden' }, 403);\n * }\n * return ctx.json({ userId });\n * });\n * ```\n */\nexport class ShokupanContext<\n State extends Record<string, any> = Record<string, any>,\n Params extends Record<string, string> = Record<string, string>\n> {\n public params: Params = {} as Params; // Router assigns this, but default to empty object\n public state: State;\n public handlerStack: HandlerStackItem[] = [];\n\n public readonly response: ShokupanResponse;\n public [$debug]?: DebugCollector;\n public [$finalResponse]?: Response;\n public [$rawBody]?: string | ArrayBuffer | Uint8Array; // Raw body for compression optimization\n\n // Body caching to avoid double parsing\n private [$url]?: URL;\n private [$cachedBody]?: any;\n private [$bodyType]?: 'json' | 'text' | 'formData' | 'arrayBuffer' | 'blob';\n private [$bodyParsed]: boolean = false;\n private [$bodyParseError]?: Error;\n\n public [$routeMatched]: boolean = false;\n\n\n // Cached URL properties to avoid repeated parsing\n private [$cachedHostname]?: string;\n private [$cachedProtocol]?: string;\n private [$cachedHost]?: string;\n private [$cachedOrigin]?: string;\n private [$cachedQuery]?: Record<string, any>;\n private [$cachedCookies]?: Record<string, string>;\n\n private disconnectCallbacks: (() => void | Promise<void>)[] = [];\n\n /**\n * Registers a callback to be executed when the associated WebSocket disconnects.\n * This is only applicable for requests that are part of a WebSocket interaction or upgrade.\n */\n public onSocketDisconnect(callback: () => void | Promise<void>) {\n this.disconnectCallbacks.push(callback);\n }\n\n /**\n * @internal\n * Retrieves registered disconnect callbacks for execution.\n */\n public getDisconnectCallbacks() {\n return this.disconnectCallbacks;\n }\n private [$ws]?: ServerWebSocket;\n private [$socket]?: Socket;\n private [$io]?: SocketServer;\n\n /**\n * JSX Rendering Function\n */\n private renderer?: JSXRenderer;\n setRenderer(renderer: JSXRenderer) {\n this.renderer = renderer;\n }\n\n private [$requestId]: string;\n get requestId() {\n return this[$requestId] ??= (this.app?.applicationConfig?.idGenerator?.() ?? nanoid());\n }\n\n [\n // Only apply a custom inspect symbol in Node.js, Deno, or Bun.\n globalThis.navigator?.userAgent?.match(/Node\\.js|Deno|Bun/)\n ? Symbol.for(\"nodejs.util.inspect.custom\")\n : Symbol.for(\"no-op\")\n ]() {\n const innerString = inspect({\n method: this.request.method,\n url: this.request.url,\n requestHeaders: new Map(this.request.headers),\n sessionId: this.sessionID,\n state: this.state,\n params: this.params,\n response: this[$finalResponse]?.body,\n responseHeaders: new Map(this[$finalResponse]?.headers as any),\n handlerStack: this.handlerStack.map(h => h.name === \"anonymous\" ? (h.file + \":\" + h.line) : h.name)\n }, { depth: null, colors: true, numericSeparator: true, customInspect: true });\n\n return \"Context(\" + this.requestId + \") {\" + innerString.slice(1, -2) + \",\\n ...others\\n}\";\n }\n\n constructor(\n public readonly request: ShokupanRequest<any>,\n public readonly server?: Server<any>,\n state?: State,\n public readonly app?: Shokupan,\n public readonly signal?: AbortSignal, // Optional as it might not be provided in tests or simple creates\n enableMiddlewareTracking: boolean = false,\n requestId?: string\n ) {\n this.state = state || {} as State;\n this[$requestId] = requestId;\n\n if (enableMiddlewareTracking) {\n const self = this;\n this.state = new Proxy(this.state, {\n set(target, p, newValue, receiver) {\n const result = Reflect.set(target, p, newValue, receiver);\n const currentHandler = self.handlerStack[self.handlerStack.length - 1];\n if (currentHandler) {\n if (!currentHandler.stateChanges) currentHandler.stateChanges = {};\n currentHandler.stateChanges[p as string] = newValue;\n }\n return result;\n }\n });\n }\n this.response = new ShokupanResponse();\n }\n\n get url(): URL {\n if (!this[$url]) {\n // WebSocket contexts may have empty request URLs\n const urlString = this.request.url || 'http://localhost/';\n this[$url] = new URL(urlString);\n }\n return this[$url];\n }\n\n /**\n * Base request\n */\n get req() { return this.request; }\n /**\n * HTTP method\n */\n get method() { return this.request.method; }\n /**\n * Request path\n */\n get path() {\n // Optimization: return cached path if url already parsed\n if (this[$url]) return this[$url].pathname;\n\n // Fast path extraction without URL parsing\n const url = this.request.url;\n\n // Handle full URL: http://localhost:3000/foo?bar\n let queryIndex = url.indexOf('?');\n const end = queryIndex === -1 ? url.length : queryIndex;\n\n // Ensure we skip protocol/host\n let start = 0;\n const protocolIndex = url.indexOf('://');\n if (protocolIndex !== -1) {\n const hostStart = protocolIndex + 3;\n // Find first slash after host\n const pathStart = url.indexOf('/', hostStart);\n if (pathStart !== -1 && pathStart < end) {\n start = pathStart;\n } else {\n return '/';\n }\n } else {\n // Relative or simple path\n if (url.charCodeAt(0) === 47) { // '/'\n start = 0;\n }\n }\n\n return url.substring(start, end);\n }\n /**\n * Request query params\n */\n get query() {\n if (this[$cachedQuery]) return this[$cachedQuery];\n\n // Security: Use Object.create(null) to prevent prototype pollution\n const q: Record<string, any> = Object.create(null);\n\n // Security: Blocklist dangerous property names\n const blocklist = ['__proto__', 'constructor', 'prototype'];\n const mode = this.app?.applicationConfig?.queryParserMode || 'extended';\n\n this.url.searchParams.forEach((value, key) => {\n // Security: Skip dangerous keys\n if (blocklist.includes(key)) return;\n\n // Use hasOwnProperty to avoid prototype chain issues\n if (Object.prototype.hasOwnProperty.call(q, key)) {\n if (mode === 'strict') {\n throw new Error(`Duplicate query parameter '${key}' is not allowed in strict mode.`);\n } else if (mode === 'simple') {\n // Start of list? End of list? Usually first occurrence wins or last. \n // Let's stick to \"first wins\" or \"last wins\". \n // URLSearchParams iteration order is insertion order.\n // If we want \"last wins\" (standard JS object behavior), we just overwrite.\n // If we want \"first wins\", we skip.\n // Let's do \"last wins\" (overwrite) to match standard `Object.fromEntries` behavior usually expected if not handling arrays.\n q[key] = value;\n } else {\n // Extended (Array)\n if (Array.isArray(q[key])) {\n q[key].push(value);\n } else {\n q[key] = [q[key], value];\n }\n }\n } else {\n q[key] = value;\n }\n });\n this[$cachedQuery] = q;\n return q;\n }\n\n /**\n * Request cookies\n */\n get cookies() {\n if (this[$cachedCookies]) return this[$cachedCookies];\n\n const c: Record<string, string> = Object.create(null);\n const cookieHeader = this.request.headers.get(\"cookie\");\n\n if (cookieHeader) {\n const pairs = cookieHeader.split(\";\");\n for (let i = 0; i < pairs.length; i++) {\n const pair = pairs[i];\n const index = pair.indexOf(\"=\");\n if (index > 0) {\n const key = pair.slice(0, index).trim();\n const value = pair.slice(index + 1).trim();\n c[key] = decodeURIComponent(value);\n }\n }\n }\n\n this[$cachedCookies] = c;\n return c;\n }\n\n /**\n * Client IP address\n */\n get ip() { return this.server?.requestIP(this.request as unknown as Request); }\n\n /**\n * Request hostname (e.g. \"localhost\")\n */\n get hostname() {\n return this[$cachedHostname] ??= this.url.hostname;\n }\n\n /**\n * Request host (e.g. \"localhost:3000\")\n */\n get host() {\n return this[$cachedHost] ??= this.url.host;\n }\n\n /**\n * Request protocol (e.g. \"http:\", \"https:\")\n */\n get protocol() {\n return this[$cachedProtocol] ??= this.url.protocol;\n }\n\n /**\n * Whether request is secure (https)\n */\n get secure() { return this.protocol === 'https:'; }\n\n /**\n * Request origin (e.g. \"http://localhost:3000\")\n */\n get origin() {\n return this[$cachedOrigin] ??= this.url.origin;\n }\n\n /**\n * Request headers\n */\n get headers() { return this.request.headers; }\n\n /**\n * Get a request header\n * @param name Header name\n */\n public get(name: string) { return this.request.headers.get(name); }\n\n /**\n * Base response object\n */\n get res() { return this.response; }\n\n /**\n * Get the raw response body content (if available)\n */\n get responseBody() { return this[$rawBody]; }\n\n /**\n * Raw WebSocket connection\n */\n get ws() { return this[$ws]; }\n\n /**\n * Socket.io socket\n */\n get socket() { return this[$socket]; }\n\n /**\n * Socket.io server\n */\n get io() { return this[$io]; }\n\n /**\n * Helper to set a header on the response\n * @param key Header key\n * @param value Header value\n */\n public set(key: string, value: string) {\n this.response.set(key, value);\n return this;\n }\n\n public isUpgraded: boolean = false;\n\n /**\n * Upgrades the request to a WebSocket connection.\n * @param options Upgrade options\n * @returns true if upgraded, false otherwise\n */\n public upgrade(options?: { data?: any; headers?: HeadersInit; }) {\n if (!this.server) return false;\n const success = this.server.upgrade(this.req as any, options);\n if (success) {\n this.isUpgraded = true;\n }\n return success;\n }\n\n /**\n * Set a cookie\n * @param name Cookie name\n * @param value Cookie value\n * @param options Cookie options\n */\n public setCookie(name: string, value: string, options: CookieOptions = {}) {\n // Security: Validate domain attribute to prevent cookie injection\n if (options.domain) {\n const currentHost = this.hostname;\n if (!isValidCookieDomain(options.domain, currentHost)) {\n throw new Error(`Invalid cookie domain: ${options.domain} for host ${currentHost}`);\n }\n }\n\n // Robust Cookie Serialization\n let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;\n if (options.maxAge) cookie += `; Max-Age=${Math.floor(options.maxAge)}`;\n if (options.domain) cookie += `; Domain=${options.domain}`;\n if (options.path) cookie += `; Path=${options.path || '/'}`;\n if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;\n if (options.httpOnly) cookie += `; HttpOnly`;\n if (options.secure) cookie += `; Secure`;\n\n let sameSite = options.sameSite;\n if (sameSite === true) sameSite = 'Strict';\n if (sameSite === undefined || sameSite === false) {\n // Do not set SameSite if undefined/false? Or Default to Lax?\n // Modern browsers default to Lax.\n // We'll leave it omit unless specified.\n } else {\n const stringSameSite = typeof sameSite === 'string' ? sameSite.toLowerCase() : sameSite;\n switch (stringSameSite) {\n case 'lax': cookie += '; SameSite=Lax'; break;\n case 'strict': cookie += '; SameSite=Strict'; break;\n case 'none': cookie += '; SameSite=None'; break;\n default: cookie += '; SameSite=Lax'; break;\n }\n }\n\n if (options.priority) {\n const p = options.priority.toLowerCase();\n if (p === 'low') cookie += '; Priority=Low';\n else if (p === 'medium') cookie += '; Priority=Medium';\n else if (p === 'high') cookie += '; Priority=High';\n }\n\n this.response.append('Set-Cookie', cookie);\n return this;\n }\n\n private mergeHeaders(headers?: HeadersInit): Headers {\n let h: Headers;\n // Optimization: avoid double allocation if response headers are empty/null\n if (this.response.hasPopulatedHeaders) {\n h = new Headers(this.response.headers);\n } else {\n h = new Headers();\n }\n\n if (headers) {\n // Efficient merge dependent on type\n if (headers instanceof Headers) {\n headers.forEach((v, k) => h.set(k, v));\n } else if (Array.isArray(headers)) {\n headers.forEach(([k, v]) => h.set(k, v));\n } else {\n // Object iteration\n const keys = Object.keys(headers);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const val = (headers as any)[key];\n h.set(key, val);\n }\n }\n }\n return h;\n }\n\n\n /**\n * Read request body with caching to avoid double parsing.\n * The body is only parsed once and cached for subsequent reads.\n */\n /**\n * Read request body with caching to avoid double parsing.\n * The body is only parsed once and cached for subsequent reads.\n */\n async body<T = any>(): Promise<T> {\n // If there was an error during pre-parsing, throw it now\n if (this[$bodyParseError] !== undefined) {\n throw this[$bodyParseError];\n }\n\n // Return cached body if already parsed\n if (this[$bodyParsed] === true) {\n return this[$cachedBody] as T;\n }\n\n const config = this.app?.applicationConfig || {};\n const { type, body } = await BodyParser.parse(this.request, config);\n\n this[$bodyType] = type as any;\n this[$cachedBody] = body;\n this[$bodyParsed] = true;\n\n return this[$cachedBody] as T;\n }\n\n /**\n * Pre-parse the request body before handler execution.\n * This improves performance and enables Node.js compatibility for large payloads.\n * Errors are deferred until the body is actually accessed in the handler.\n */\n async parseBody(): Promise<void> {\n // Skip if already parsed\n if (this[$bodyParsed]) {\n return;\n }\n\n // Skip for methods that typically don't have bodies\n if (this.request.method === 'GET' || this.request.method === 'HEAD') {\n return;\n }\n\n const maxBodySize = this.app?.applicationConfig?.maxBodySize ?? 10 * 1024 * 1024; // Default 10MB\n\n // 1. Fast check: Content-Length header\n const contentLength = parseInt(this.request.headers.get(\"content-length\") || \"0\", 10);\n if (contentLength > maxBodySize) {\n this[$bodyParseError] = new Error(\"Payload Too Large\");\n (this[$bodyParseError] as any).status = 413;\n // We can't easily return 413 here since this is async void, error stored for access\n return;\n }\n\n try {\n await this.body(); // Trigger body parsing and caching\n } catch (error: any) {\n if (error.status === 413 || error.message === \"Payload Too Large\") {\n this[$bodyParseError] = error;\n } else {\n // Store error for later throwing when body is accessed\n this[$bodyParseError] = error as Error;\n }\n }\n }\n\n\n\n /**\n * Send a response\n * @param body Response body\n * @param options Response options\n * @returns Response\n */\n send(body?: BodyInit, options?: ResponseInit) {\n const headers = this.mergeHeaders(options?.headers as any);\n const status = options?.status ?? this.response.status ?? 200;\n\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_HTTP_STATUSES.has(status)) {\n throw new Error(`Invalid HTTP status code: ${status}`);\n }\n\n // Store raw body for compression middleware\n if (typeof body === \"string\" || body instanceof ArrayBuffer || body instanceof Uint8Array) {\n this[$rawBody] = body;\n }\n\n // :as any because there are multiple bodyinit providers. What the hell.\n return this[$finalResponse] ??= new Response(body as any, { status, headers });\n }\n\n /**\n * Emit an event to the client (WebSocket only)\n * @param event Event name\n * @param data Event data (Must be JSON serializable)\n */\n emit(event: string, data?: any) {\n if (this[$ws]) {\n this[$ws].send(JSON.stringify({ event, data }));\n } else if (this[$socket]) {\n this[$socket].emit(event, data);\n }\n }\n\n /**\n * Respond with a JSON object\n */\n async json(data: object | Promise<object>, status?: number, headers?: HeadersInit) {\n const finalStatus = status ?? this.response.status ?? 200;\n // Validate redirect status code\n if (!VALID_HTTP_STATUSES.has(finalStatus)) {\n throw new Error(`Invalid HTTP status code: ${finalStatus}`);\n }\n this.response.status = finalStatus;\n\n const jsonString = JSON.stringify(data instanceof Promise ? await data : data);\n\n // Store raw body for compression middleware\n this[$rawBody] = jsonString;\n\n // Fast path: no custom headers and no response headers set\n if (!headers && !this.response.hasPopulatedHeaders) {\n this[$finalResponse] = new Response(jsonString, {\n status: finalStatus,\n headers: { \"content-type\": \"application/json\" }\n });\n return this[$finalResponse];\n }\n\n // Slow path: merge headers\n const finalHeaders = this.mergeHeaders(headers);\n finalHeaders.set(\"content-type\", \"application/json\");\n this[$finalResponse] = new Response(jsonString, { status: finalStatus, headers: finalHeaders });\n return this[$finalResponse];\n }\n\n /**\n * Respond with a text string\n */\n async text(data: string | Promise<string>, status?: number, headers?: HeadersInit) {\n const finalStatus = status ?? this.response.status ?? 200;\n\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_HTTP_STATUSES.has(finalStatus)) {\n throw new Error(`Invalid HTTP status code: ${finalStatus}`);\n }\n this.response.status = finalStatus;\n\n // Store raw body for compression middleware\n this[$rawBody] = data instanceof Promise ? await data : data;\n\n // Fast path: no custom headers and no response headers set\n if (!headers && !this.response.hasPopulatedHeaders) {\n this[$finalResponse] = new Response(this[$rawBody], {\n status: finalStatus,\n headers: { \"content-type\": \"text/plain; charset=utf-8\" }\n });\n return this[$finalResponse];\n }\n\n // Slow path: merge headers\n const finalHeaders = this.mergeHeaders(headers);\n finalHeaders.set(\"content-type\", \"text/plain; charset=utf-8\");\n this[$finalResponse] = new Response(this[$rawBody], { status: finalStatus, headers: finalHeaders });\n return this[$finalResponse];\n }\n\n /**\n * Respond with HTML content\n */\n async html(html: string | Promise<string>, status?: number, headers?: HeadersInit) {\n const finalStatus = status ?? this.response.status ?? 200;\n\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_HTTP_STATUSES.has(finalStatus)) {\n throw new Error(`Invalid HTTP status code: ${finalStatus}`);\n }\n this.response.status = finalStatus;\n\n const finalHeaders = this.mergeHeaders(headers);\n finalHeaders.set(\"content-type\", \"text/html; charset=utf-8\");\n\n // Store raw body for compression middleware\n this[$rawBody] = html instanceof Promise ? await html : html;\n\n this[$finalResponse] = new Response(this[$rawBody], { status: finalStatus, headers: finalHeaders });\n return this[$finalResponse];\n }\n\n /**\n * Respond with a redirect\n */\n async redirect(url: string | Promise<string>, status = 302) {\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_REDIRECT_STATUSES.has(status)) {\n throw new Error(`Invalid redirect status code: ${status}`);\n }\n this.response.status = status;\n\n const finalHeaders = this.mergeHeaders();\n const targetUrl = url instanceof Promise ? await url : url;\n\n // Security: Prevent Open Redirects & XSS via redirect\n // Block protocol-relative URLs (//evil.com) which browsers treat as same-scheme\n if (targetUrl.startsWith('//')) {\n // We could rewrite to / or throw. Throwing is safer/clearer.\n throw new Error(\"Invalid redirect: Protocol-relative URLs are not allowed.\");\n }\n\n // Block dangerous pseudo-protocols\n const lowerUrl = targetUrl.toLowerCase();\n if (lowerUrl.startsWith('javascript:') || lowerUrl.startsWith('data:') || lowerUrl.startsWith('vbscript:')) {\n throw new Error(`Invalid redirect: Unsafe protocol '${targetUrl.split(':')[0]}'`);\n }\n\n finalHeaders.set('Location', targetUrl);\n\n this[$finalResponse] = new Response(null, { status, headers: finalHeaders });\n return this[$finalResponse];\n }\n\n /**\n * Respond with a status code\n * DOES NOT CHAIN!\n */\n async status(statusCode: number | Promise<number>) {\n const status = statusCode instanceof Promise ? await statusCode : statusCode;\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_HTTP_STATUSES.has(status)) {\n throw new Error(`Invalid HTTP status code: ${status}`);\n }\n this.response.status = status;\n\n const finalHeaders = this.mergeHeaders();\n this[$finalResponse] = new Response(null, { status, headers: finalHeaders });\n return this[$finalResponse];\n }\n\n /**\n * Respond with a file\n */\n public async file(path: string, fileOptions?: BlobPropertyBag, responseOptions?: ResponseInit) {\n const finalHeaders = this.mergeHeaders(responseOptions?.headers as any);\n const status = responseOptions?.status ?? this.response.status;\n\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_HTTP_STATUSES.has(status)) {\n throw new Error(`Invalid HTTP status code: ${status}`);\n }\n // status is optional in file responseOptions, so only update if defined, otherwise keep existing\n if (status) this.response.status = status;\n\n if (typeof Bun !== \"undefined\") {\n this[$finalResponse] = new Response(Bun.file(path, fileOptions), { status, headers: finalHeaders });\n return this[$finalResponse];\n } else {\n // Node.js fallback using fs\n const fileBuffer = await readFile(path);\n\n // Set content-type from fileOptions if provided\n if (fileOptions?.type) {\n finalHeaders.set('content-type', fileOptions.type);\n }\n\n this[$finalResponse] = new Response(fileBuffer, { status, headers: finalHeaders });\n return this[$finalResponse];\n }\n }\n\n /**\n * Render a JSX element\n * @param element JSX Element\n * @param args JSX Element Args/Props\n * @param status HTTP Status\n * @param headers HTTP Headers\n */\n public async jsx(element: any, args?: Parameters<JSXRenderer>[1], status?: number, headers?: HeadersInit) {\n status ??= 200;\n\n // Validate redirect status code\n if (this.app.applicationConfig.validateStatusCodes && !VALID_HTTP_STATUSES.has(status)) {\n throw new Error(`Invalid HTTP status code: ${status}`);\n }\n if (!this.renderer) {\n throw new Error(\"No JSX renderer configured\");\n }\n\n const html = await this.renderer(element, args);\n return this.html(html, status, headers); // html() already stores _rawBody\n }\n\n /**\n * Pipe a ReadableStream to the response\n * @param stream ReadableStream to pipe\n * @param options Response options (status, headers)\n */\n public pipe(stream: ReadableStream, options?: ResponseInit): Response {\n const headers = this.mergeHeaders(options?.headers as any);\n const status = options?.status ?? this.response.status ?? 200;\n\n if (this.app?.applicationConfig?.validateStatusCodes && !VALID_HTTP_STATUSES.has(status)) {\n throw new Error(`Invalid HTTP status code: ${status}`);\n }\n\n this[$finalResponse] = new Response(stream, { status, headers });\n return this[$finalResponse];\n }\n\n /**\n * Internal helper to create a streaming response with common infrastructure\n * @private\n */\n private createStreamHelper<THelper>(\n helperFactory: (\n controller: ReadableStreamDefaultController,\n aborted: { value: boolean; },\n abortCallbacks: (() => void)[],\n encoder: TextEncoder\n ) => THelper,\n callback: (helper: THelper) => Promise<void> | void,\n onError?: (err: Error, helper: THelper) => void | Promise<void>,\n headers?: HeadersInit\n ): Response {\n let controller: ReadableStreamDefaultController;\n const aborted = { value: false }; // Use object for reference sharing\n const abortCallbacks: (() => void)[] = [];\n const encoder = new TextEncoder();\n let helper: THelper;\n\n const stream = new ReadableStream({\n start(ctrl) {\n controller = ctrl;\n // Create helper after controller is initialized\n helper = helperFactory(controller, aborted, abortCallbacks, encoder);\n\n // Execute callback asynchronously\n (async () => {\n try {\n await callback(helper);\n controller.close();\n } catch (err) {\n if (onError) {\n try {\n await onError(err as Error, helper);\n } catch (handlerErr) {\n console.error('Error in stream error handler:', handlerErr);\n }\n } else {\n console.error('Stream error:', err);\n }\n if (!aborted.value) {\n controller.close();\n }\n }\n })();\n },\n async pull() {\n // Stream is ready for more data\n },\n cancel() {\n aborted.value = true;\n abortCallbacks.forEach(cb => {\n try {\n cb();\n } catch (err) {\n console.error('Error in abort callback:', err);\n }\n });\n }\n });\n\n return this.pipe(stream, { headers });\n }\n\n /**\n * Generic streaming helper for binary/text data\n * @param callback Callback function that receives a StreamHelper\n * @param onError Optional error handler\n */\n public stream(\n callback: (stream: StreamHelper) => Promise<void> | void,\n onError?: StreamErrorHandler\n ): Response {\n return this.createStreamHelper<StreamHelper>(\n (controller, aborted, abortCallbacks, encoder) => ({\n async write(data: Uint8Array | string): Promise<void> {\n if (aborted.value) return;\n const chunk = typeof data === 'string' ? encoder.encode(data) : data;\n controller.enqueue(chunk);\n },\n async pipe(stream: ReadableStream): Promise<void> {\n if (aborted.value) return;\n const reader = stream.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done || aborted.value) break;\n controller.enqueue(value);\n }\n } finally {\n reader.releaseLock();\n }\n },\n sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n },\n onAbort(callback: () => void): void {\n abortCallbacks.push(callback);\n }\n }),\n callback,\n onError\n );\n }\n\n /**\n * Text streaming helper with proper headers\n * @param callback Callback function that receives a TextStreamHelper\n * @param onError Optional error handler\n */\n public streamText(\n callback: (stream: TextStreamHelper) => Promise<void> | void,\n onError?: TextStreamErrorHandler\n ): Response {\n const headers = new Headers(this.response.headers);\n headers.set('Content-Type', 'text/plain; charset=utf-8');\n headers.set('Transfer-Encoding', 'chunked');\n headers.set('X-Content-Type-Options', 'nosniff');\n\n return this.createStreamHelper<TextStreamHelper>(\n (controller, aborted, abortCallbacks, encoder) => ({\n async write(text: string): Promise<void> {\n if (aborted.value) return;\n controller.enqueue(encoder.encode(text));\n },\n async writeln(text: string): Promise<void> {\n if (aborted.value) return;\n controller.enqueue(encoder.encode(text + '\\n'));\n },\n sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n },\n onAbort(callback: () => void): void {\n abortCallbacks.push(callback);\n }\n }),\n callback,\n onError,\n headers\n );\n }\n\n /**\n * Server-Sent Events (SSE) streaming helper\n * @param callback Callback function that receives an SSEStreamHelper\n * @param onError Optional error handler\n */\n public streamSSE(\n callback: (stream: SSEStreamHelper) => Promise<void> | void,\n onError?: SSEStreamErrorHandler\n ): Response {\n const headers = new Headers(this.response.headers);\n headers.set('Content-Type', 'text/event-stream');\n headers.set('Cache-Control', 'no-cache');\n headers.set('Connection', 'keep-alive');\n\n return this.createStreamHelper<SSEStreamHelper>(\n (controller, aborted, abortCallbacks, encoder) => ({\n async writeSSE(message: SSEMessage): Promise<void> {\n if (aborted.value) return;\n\n let sseMessage = '';\n\n // Format according to SSE spec\n if (message.event) {\n sseMessage += `event: ${message.event}\\n`;\n }\n if (message.id !== undefined) {\n sseMessage += `id: ${message.id}\\n`;\n }\n if (message.retry !== undefined) {\n sseMessage += `retry: ${message.retry}\\n`;\n }\n\n // Data can be multi-line, each line prefixed with \"data: \"\n const dataLines = message.data.split('\\n');\n for (const line of dataLines) {\n sseMessage += `data: ${line}\\n`;\n }\n\n // SSE messages end with double newline\n sseMessage += '\\n';\n\n controller.enqueue(encoder.encode(sseMessage));\n },\n sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n },\n onAbort(callback: () => void): void {\n abortCallbacks.push(callback);\n }\n }),\n callback,\n onError,\n headers\n );\n }\n}\n","import { RecordId } from 'surrealdb';\nimport type { ShokupanContext } from \"./context\";\nimport { $debug } from './util/symbol';\nimport type { Middleware, NextFn } from './util/types';\n\n/**\n * Composes a list of middleware into a single function.\n * This is the onion model (Koa-style).\n * \n * CRITICAL: This must build the chain ONCE, not rebuild it on every request.\n */\nexport const compose = (middleware: Middleware[]) => {\n if (!middleware.length) {\n return (context: ShokupanContext<unknown>, next?: NextFn) => {\n return next ? next() : Promise.resolve();\n };\n }\n\n return function dispatch(context: ShokupanContext<unknown>, next?: NextFn): Promise<any> {\n let index = -1;\n\n async function runner(i: number): Promise<any> {\n if (i <= index) return Promise.reject(new Error('next() called multiple times'));\n index = i;\n\n if (i >= middleware.length) {\n return next ? next() : Promise.resolve();\n }\n\n const fn = middleware[i];\n\n if (typeof fn !== 'function') {\n const name = (fn as any)?.constructor?.name;\n console.error(`[Middleware Error] Item at index ${i} is not a function! It is: ${typeof fn} (${name})`, fn);\n throw new TypeError(`Middleware at index ${i} must be a function, got ${name}`);\n }\n\n // --- Tracking Setup ---\n const trackingEnabled = context.app?.applicationConfig?.enableMiddlewareTracking;\n const meta = fn.metadata;\n let trackingStartTime = 0;\n\n if (trackingEnabled && meta) {\n trackingStartTime = performance.now();\n context.handlerStack.push({\n name: meta.name || fn.name || 'anonymous',\n file: meta.file,\n line: meta.line,\n isBuiltin: meta.isBuiltin,\n startTime: trackingStartTime,\n duration: -1\n });\n }\n\n // --- Debug Setup ---\n const debug = context[$debug];\n let debugId: string | undefined;\n let previousNode: string | undefined;\n let debugStart = 0;\n\n if (debug) {\n debugId = (fn as any)._debugId || fn.name || 'anonymous';\n previousNode = debug.getCurrentNode();\n debug.trackEdge(previousNode, debugId);\n debug.setNode(debugId!);\n debugStart = performance.now();\n }\n\n try {\n // Execute Middleware\n const res = await fn(context, () => runner(i + 1));\n\n // --- Tracking Success ---\n if (trackingEnabled && meta) {\n const duration = performance.now() - trackingStartTime;\n const stackItem = context.handlerStack[context.handlerStack.length - 1];\n if (stackItem) stackItem.duration = duration;\n\n Promise.resolve().then(async () => {\n try {\n const db = context.app?.db;\n if (!db) return;\n\n const timestamp = Date.now();\n await db.upsert(new RecordId('middleware_tracking', {\n timestamp,\n name: meta.name\n }), {\n name: meta.name,\n path: context.path,\n timestamp,\n duration,\n file: meta.file,\n line: meta.line,\n error: undefined,\n metadata: {\n isBuiltin: meta.isBuiltin,\n pluginName: meta.pluginName\n }\n });\n } catch (e) { }\n });\n }\n\n // --- Debug Success ---\n if (debug) {\n debug.trackStep(debugId, 'middleware', performance.now() - debugStart, 'success');\n }\n\n return res;\n\n } catch (err) {\n // --- Tracking Error ---\n if (trackingEnabled && meta) {\n const duration = performance.now() - trackingStartTime;\n const stackItem = context.handlerStack[context.handlerStack.length - 1];\n if (stackItem) stackItem.duration = duration;\n\n Promise.resolve().then(async () => {\n try {\n const db = context.app?.db;\n if (!db) return;\n\n const timestamp = Date.now();\n await db.upsert(new RecordId('middleware_tracking', {\n timestamp,\n name: meta.name\n }), {\n name: meta.name,\n path: context.path,\n timestamp,\n duration,\n file: meta.file,\n line: meta.line,\n error: String(err),\n metadata: {\n isBuiltin: meta.isBuiltin,\n pluginName: meta.pluginName\n }\n });\n } catch (e) { }\n });\n }\n\n // --- Debug Error ---\n if (debug) {\n debug.trackStep(debugId, 'middleware', performance.now() - debugStart, 'error', err);\n }\n\n throw err;\n } finally {\n if (debug && previousNode) debug.setNode(previousNode);\n }\n }\n\n return runner(0);\n };\n};\n","/**\n * Simple object check.\n */\nexport function isObject(item: any): item is Record<string, any> {\n return !!(item && typeof item === 'object' && !Array.isArray(item));\n}\n\n/**\n * Deep merge two objects.\n * \n * - Arrays are concatenated.\n * - Objects are merged recursively.\n * - Primitives are overwritten.\n */\nexport function deepMerge<T extends Record<string, any>>(target: T, ...sources: Partial<T>[]): T {\n if (!sources.length) return target;\n const source = sources.shift();\n\n if (isObject(target) && isObject(source)) {\n const sourceKeys = Object.keys(source);\n for (let i = 0; i < sourceKeys.length; i++) {\n const key = sourceKeys[i];\n if (isObject(source[key])) {\n if (!target[key]) Object.assign(target, { [key]: {} });\n deepMerge(target[key], source[key]);\n } else if (Array.isArray(source[key])) {\n if (!target[key]) Object.assign(target, { [key]: [] });\n\n if (key === 'tags') {\n // Start fresh if tags are provided in source (overwrite)\n (target as any)[key] = source[key];\n continue;\n }\n\n // Concat then deduplicate primitives\n const mergedArray = (target as any)[key].concat(source[key]);\n\n // If all items are primitives, unique them\n const isPrimitive = (item: any) =>\n typeof item === 'string' ||\n typeof item === 'number' ||\n typeof item === 'boolean';\n\n if (mergedArray.every(isPrimitive)) {\n (target as any)[key] = Array.from(new Set(mergedArray));\n }\n else {\n (target as any)[key] = mergedArray;\n }\n } else {\n Object.assign(target, { [key]: source[key] });\n }\n }\n }\n\n return deepMerge(target, ...sources);\n}\n","\n/**\n * Gets deduped AST routes if available.\n */\nexport async function getAstRoutes(applications: any[], options: { includePrefix?: boolean, pathTransform?: (p: string) => string; } = {}) {\n const { includePrefix = true, pathTransform } = options;\n\n const astRoutes: any[] = [];\n\n const getExpandedRoutes = (app: any, prefix: string = '', seen = new Set<string>(), sourceOverride?: any): any[] => {\n if (seen.has(app.name)) return [];\n const newSeen = new Set(seen);\n newSeen.add(app.name);\n\n const expanded: any[] = [];\n\n let currentPrefix = prefix;\n // Only consider controller prefix if includePrefix is true\n if (includePrefix && app.controllerPrefix) {\n const cleanPrefix = currentPrefix.endsWith('/') ? currentPrefix.slice(0, -1) : currentPrefix;\n const cleanCont = app.controllerPrefix.startsWith('/') ? app.controllerPrefix : '/' + app.controllerPrefix;\n currentPrefix = cleanPrefix + cleanCont;\n }\n\n for (const route of app.routes) {\n let path = route.path;\n\n if (includePrefix) {\n const cleanPrefix = currentPrefix.endsWith('/') ? currentPrefix.slice(0, -1) : currentPrefix;\n const cleanPath = path.startsWith('/') ? path : '/' + path;\n path = cleanPrefix + cleanPath;\n if (path.length > 1 && path.endsWith('/')) {\n path = path.slice(0, -1);\n }\n }\n\n // Apply path transformation if provided (e.g. removing leading slash for events)\n if (pathTransform) {\n path = pathTransform(path);\n }\n // For OpenAPI default (if includePrefix true and no transform), ensure leading slash\n else if (includePrefix && !path.startsWith('/')) {\n path = '/' + path;\n }\n\n const expandedRoute = {\n ...route,\n path: path || '/'\n };\n\n if (sourceOverride) {\n expandedRoute.sourceContext = sourceOverride;\n }\n\n expanded.push(expandedRoute);\n }\n\n if (app.mounted) {\n for (const mount of app.mounted) {\n const targetApp = applications.find(a => a.name === mount.target || a.className === mount.target);\n if (targetApp) {\n let nextPrefix = '';\n\n if (includePrefix) {\n const cleanPrefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;\n const mountPrefix = mount.prefix.startsWith('/') ? mount.prefix : '/' + mount.prefix;\n nextPrefix = cleanPrefix + mountPrefix;\n }\n\n // Check for builtin/external dependency to override source\n let nextSourceOverride = sourceOverride;\n if (mount.dependency || (mount.targetFilePath && mount.targetFilePath.includes('node_modules'))) {\n if (mount.sourceContext) {\n nextSourceOverride = {\n ...mount.sourceContext,\n // Add highlight for the mount line to make it clear\n highlightLines: [mount.sourceContext.startLine, mount.sourceContext.endLine],\n highlights: [{\n startLine: mount.sourceContext.startLine,\n endLine: mount.sourceContext.endLine,\n type: 'return-success' // Use the success color (cyan) for the mount point\n }]\n };\n }\n }\n\n expanded.push(...getExpandedRoutes(targetApp, nextPrefix, newSeen, nextSourceOverride));\n }\n }\n }\n return expanded;\n };\n\n applications.forEach(app => {\n astRoutes.push(...getExpandedRoutes(app));\n });\n\n // Deduplicate routes based on score (only relevant for OpenAPI usually, but safe for all)\n const dedupedRoutes = new Map<string, { route: any, score: number; }>();\n\n for (const route of astRoutes) {\n // Key includes method and path\n const key = `${route.method.toUpperCase()}:${route.path}`;\n let score = 0;\n if (route.responseSchema) score += 10;\n if (route.handlerSource) score += 5;\n\n // If duplicate found, keep the one with higher score (better inference)\n if (!dedupedRoutes.has(key) || score > dedupedRoutes.get(key)!.score) {\n dedupedRoutes.set(key, { route, score });\n }\n }\n\n return Array.from(dedupedRoutes.values()).map(v => v.route);\n}\n","import type { ShokupanRouter } from '../../../router';\nimport { deepMerge } from '../../../util/deep-merge';\nimport { $childControllers, $childRouters, $mountPath, $parent, $routes } from '../../../util/symbol';\nimport type { OpenAPIOptions, ShokupanHandler } from '../../../util/types';\nimport { getAstRoutes } from '../shared/ast-utils';\n\n/**\n * Regex patterns for analyzing handler source code to infer types.\n */\nconst REGEX_PATTERNS = {\n QUERY_INT: /parseInt\\(ctx\\.query\\.(\\w+)\\)/g,\n QUERY_FLOAT: /parseFloat\\(ctx\\.query\\.(\\w+)\\)/g,\n QUERY_NUMBER: /Number\\(ctx\\.query\\.(\\w+)\\)/g,\n QUERY_BOOL: /(?:Boolean\\(ctx\\.query\\.(\\w+)\\)|!+ctx\\.query\\.(\\w+))/g,\n QUERY_GENERIC: /ctx\\.query\\.(\\w+)/g,\n PARAM_INT: /parseInt\\(ctx\\.params\\.(\\w+)\\)/g,\n PARAM_FLOAT: /parseFloat\\(ctx\\.params\\.(\\w+)\\)/g,\n PARAM_GENERIC: /ctx\\.params\\.(\\w+)/,\n HEADER_GET: /ctx\\.get\\(['\"](\\w+)['\"]\\)/g,\n ERROR_STATUS: /ctx\\.(?:json|text|html)\\([^)]+,\\s*(\\d{3,})\\)/g\n};\n\n/**\n * Analyze a handler function to infer request/response types based on source code usage.\n */\nfunction analyzeHandler(handler: ShokupanHandler): { inferredSpec?: any; } {\n const handlerSource = handler.toString();\n const inferredSpec: any = {};\n\n // Detect request body\n if (handlerSource.includes('ctx.body') || handlerSource.includes('await ctx.req.json()')) {\n inferredSpec.requestBody = {\n content: { 'application/json': { schema: { type: 'object' } } }\n };\n }\n\n const queryParams = new Map<string, { type: string; format?: string; }>();\n\n // Helper to process regex matches\n const processMatches = (regex: RegExp, type: string, format?: string) => {\n const matches = Array.from(handlerSource.matchAll(regex));\n for (const match of matches) {\n const name = match[1] || match[2];\n if (name && !queryParams.has(name)) {\n queryParams.set(name, { type, format });\n }\n }\n };\n\n processMatches(REGEX_PATTERNS.QUERY_INT, 'integer', 'int32');\n processMatches(REGEX_PATTERNS.QUERY_FLOAT, 'number', 'float');\n processMatches(REGEX_PATTERNS.QUERY_NUMBER, 'number');\n processMatches(REGEX_PATTERNS.QUERY_BOOL, 'boolean');\n processMatches(REGEX_PATTERNS.QUERY_GENERIC, 'string');\n\n if (queryParams.size > 0) {\n if (!inferredSpec.parameters) inferredSpec.parameters = [];\n queryParams.forEach((schema, paramName) => {\n inferredSpec.parameters.push({\n name: paramName,\n in: 'query',\n schema: { type: schema.type, ...(schema.format ? { format: schema.format } : {}) }\n });\n });\n }\n\n const pathParams = new Map<string, { type: string; format?: string; }>();\n const processPathMatches = (regex: RegExp, type: string, format?: string) => {\n const matches = Array.from(handlerSource.matchAll(regex));\n for (const match of matches) {\n const name = match[1];\n if (name) pathParams.set(name, { type, format });\n }\n };\n\n processPathMatches(REGEX_PATTERNS.PARAM_INT, 'integer', 'int32');\n processPathMatches(REGEX_PATTERNS.PARAM_FLOAT, 'number', 'float');\n\n if (pathParams.size > 0) {\n if (!inferredSpec.parameters) inferredSpec.parameters = [];\n pathParams.forEach((schema, paramName) => {\n inferredSpec.parameters.push({\n name: paramName,\n in: 'path',\n required: true,\n schema: { type: schema.type, ...(schema.format ? { format: schema.format } : {}) }\n });\n });\n }\n\n // Detect Headers\n const headerMatches = Array.from(handlerSource.matchAll(REGEX_PATTERNS.HEADER_GET));\n for (const match of headerMatches) {\n if (match[1]) {\n if (!inferredSpec.parameters) inferredSpec.parameters = [];\n inferredSpec.parameters.push({\n name: match[1],\n in: 'header',\n schema: { type: 'string' }\n });\n }\n }\n\n // Detect response formats\n const responses: any = {};\n\n if (handlerSource.includes('ctx.json(')) {\n responses['200'] = {\n description: 'Successful response',\n content: { 'application/json': { schema: { type: 'object' } } }\n };\n }\n\n if (handlerSource.includes('ctx.html(')) {\n responses['200'] = {\n description: 'Successful HTML response',\n content: { 'text/html': { schema: { type: 'string' } } }\n };\n }\n\n if (handlerSource.includes('ctx.jsx(')) {\n responses['200'] = {\n description: 'Successful HTML response (Rendered JSX)',\n content: { 'text/html': { schema: { type: 'string' } } }\n };\n }\n\n if (handlerSource.includes('ctx.text(')) {\n responses['200'] = {\n description: 'Successful text response',\n content: { 'text/plain': { schema: { type: 'string' } } }\n };\n }\n\n if (handlerSource.includes('ctx.file(')) {\n responses['200'] = {\n description: 'File download',\n content: { 'application/octet-stream': { schema: { type: 'string', format: 'binary' } } }\n };\n }\n\n if (handlerSource.includes('ctx.redirect(')) {\n let hasSpecificRedirect = false;\n const redirectMatches = Array.from(handlerSource.matchAll(/ctx\\.redirect\\([^,]+,\\s*(\\d{3})\\)/g));\n for (const match of redirectMatches) {\n const status = match[1];\n // Ensure the status is a valid redirect code\n if (/^30[12378]$/.test(status)) {\n responses[status] = { description: `Redirect (${status})` };\n hasSpecificRedirect = true;\n }\n }\n\n if (!hasSpecificRedirect) {\n responses['302'] = { description: 'Redirect' };\n }\n }\n\n // Fallback to JSON for plain object returns\n if (!responses['200'] && /return\\s+\\{/.test(handlerSource)) {\n responses['200'] = {\n description: 'Successful response',\n content: { 'application/json': { schema: { type: 'object' } } }\n };\n }\n\n // Detect Error Responses\n const errorStatusMatches = Array.from(handlerSource.matchAll(REGEX_PATTERNS.ERROR_STATUS));\n for (const match of errorStatusMatches) {\n const statusCode = match[1];\n if (statusCode && statusCode !== '200') {\n responses[statusCode] = { description: `Error response (${statusCode})` };\n }\n }\n\n if (Object.keys(responses).length > 0) {\n inferredSpec.responses = responses;\n }\n\n return { inferredSpec };\n}\n\n/**\n * Gets deduped AST routes if available.\n */\n\n/**\n * Statically generate an OpenAPI spec from a ShokupanRouter instance.\n * \n * @param rootRouter - The root router instance to generate the spec tree from.\n * @param options - Optional OpenAPI configuration options.\n * @returns The generated OpenAPI spec.\n */\nexport async function generateOpenApi<T extends Record<string, any>>(rootRouter: ShokupanRouter<T>, options: OpenAPIOptions = {}): Promise<any> {\n const paths: Record<string, any> = {};\n const tagGroups = new Map<string, Set<string>>();\n\n const defaultTagGroup = options.defaultTagGroup || \"General\";\n const defaultTagName = options.defaultTag || \"Application\";\n\n // Attempt to run AST Analysis\n let astRoutes: any[] = [];\n let astMiddlewareRegistry: Record<string, any> = {};\n let applications: any[] = [];\n try {\n const { OpenAPIAnalyzer } = await import('./analyzer');\n // Use the application entrypoint if available to restrict analysis scope\n const entrypoint = rootRouter.metadata?.file;\n const analyzer = new OpenAPIAnalyzer(process.cwd(), entrypoint);\n const analysisResult = await analyzer.analyze();\n applications = analysisResult.applications;\n astRoutes = await getAstRoutes(applications);\n\n // Build middleware registry from AST-analyzed applications\n let middlewareId = 0;\n for (const app of applications) {\n if (app.middleware && app.middleware.length > 0) {\n for (const mw of app.middleware) {\n const id = `middleware-${middlewareId++}`;\n astMiddlewareRegistry[id] = {\n ...mw,\n id,\n usedBy: [] // Will be populated when processing routes\n };\n }\n }\n }\n } catch (e) {\n // Silently fail if analysis cannot run (e.g. runtime environment issues)\n // console.warn(\"OpenAPI AST analysis skipped:\", e);\n if (options.warnings) {\n options.warnings.push({\n type: 'ast-analysis-failed',\n message: 'AST Analysis failed or skipped',\n detail: e.message\n });\n }\n }\n\n const collect = (router: ShokupanRouter<T>, prefix = \"\", currentGroup = defaultTagGroup, defaultTag = defaultTagName, inheritedMiddleware: any[] = [], isRootLevel = true) => {\n let group = currentGroup;\n let tag = defaultTag;\n\n if (router.config?.group) group = router.config.group;\n if (router.config?.name) {\n tag = router.config.name;\n }\n else {\n const mountPath = router[$mountPath];\n // Only create a new tag from mountPath if this is a root-level router (or direct child of root)\n // Otherwise, inherit the tag from the parent\n const isDirectChild = (router as any)[$parent] === rootRouter;\n if ((isRootLevel || isDirectChild) && mountPath && mountPath !== \"/\") {\n const segments = mountPath.split(\"/\").filter(Boolean);\n if (segments.length > 0) {\n const lastSegment = segments[segments.length - 1];\n tag = lastSegment.replace(/[-_]/g, ' ').replace(/\\b\\w/g, c => c.toUpperCase());\n }\n }\n }\n\n let isBuiltinPlugin = false;\n let pluginName = '';\n\n // Detect builtin plugins\n if ((router.metadata as any)?.pluginName) {\n isBuiltinPlugin = true;\n pluginName = (router.metadata as any).pluginName;\n tag = pluginName.replace(/[-_]/g, ' ').replace(/\\b\\w/g, c => c.toUpperCase());\n }\n else if (router.metadata?.file && router.metadata.file.includes('plugins/application/') && !router.metadata.file.match(/\\.(spec|test)\\.ts$/)) {\n isBuiltinPlugin = true;\n // Extract plugin name from path .../plugins/application/<name>/...\n const match = router.metadata.file.match(/plugins\\/application\\/([^/]+)/);\n if (match) {\n pluginName = match[1].replace(/\\.(ts|js|mjs|mts|cjs)$/, '');\n // Override tag for builtin plugins to group them properly\n tag = pluginName.replace(/[-_]/g, ' ').replace(/\\b\\w/g, c => c.toUpperCase());\n }\n }\n\n if (!tagGroups.has(group)) tagGroups.set(group, new Set());\n\n const routerMiddleware = router.middleware || [];\n\n const routes = (router as any)[$routes] || [];\n\n for (const route of routes) {\n // Filter out non-HTTP methods (e.g. AsyncAPI PUB/SUB events)\n if (!['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'].includes(route.method.toUpperCase())) {\n continue;\n }\n\n const routeGroup = route.group || group;\n const cleanPrefix = prefix.endsWith(\"/\") ? prefix.slice(0, -1) : prefix;\n const cleanSubPath = route.path.startsWith(\"/\") ? route.path : \"/\" + route.path;\n let fullPath = (cleanPrefix + cleanSubPath) || \"/\";\n\n if (fullPath.length > 1 && fullPath.endsWith('/')) {\n fullPath = fullPath.slice(0, -1);\n }\n\n // Convert Express-style :param to OpenAPI-style {param}\n fullPath = fullPath.replace(/:([a-zA-Z0-9_]+)/g, '{$1}');\n\n if (!paths[fullPath]) paths[fullPath] = {};\n\n const operation: any = {\n responses: { '200': { description: \"Successful response\" } },\n tags: [tag]\n };\n\n // Collect Middleware - both runtime and AST-analyzed\n const routeMiddleware = route.middleware || [];\n const allMiddleware = [...inheritedMiddleware, ...routerMiddleware, ...routeMiddleware];\n\n // Find matching AST middleware for this route's path and method\n const astMiddlewareForRoute: any[] = [];\n for (const [mwId, mw] of Object.entries(astMiddlewareRegistry)) {\n // For now, associate all middleware from the same app with all routes from that app\n // In a more sophisticated implementation, we'd track router-level vs global vs route-level scope\n const appForRoute = applications.find((app: any) =>\n app.routes?.some((r: any) => r.path === fullPath && r.method === route.method.toUpperCase())\n );\n const appForMiddleware = applications.find((app: any) =>\n app.middleware?.some((m: any) => m.name === mw.name && m.file === mw.file)\n );\n\n if (appForRoute && appForMiddleware && appForRoute.filePath === appForMiddleware.filePath) {\n astMiddlewareForRoute.push({ ...mw, id: mwId });\n // Track which routes use this middleware\n if (!mw.usedBy.includes(fullPath)) {\n mw.usedBy.push(fullPath);\n }\n }\n }\n\n // Merge middleware responses into operation\n for (const astMw of astMiddlewareForRoute) {\n if (astMw.responseTypes) {\n for (const [statusCode, responseSpec] of Object.entries(astMw.responseTypes)) {\n // Don't override existing responses, middleware responses have lower priority\n if (!operation.responses[statusCode]) {\n operation.responses[statusCode] = responseSpec;\n }\n }\n }\n }\n\n if (allMiddleware.length > 0 || astMiddlewareForRoute.length > 0) {\n operation['x-shokupan-middleware'] = [\n ...allMiddleware.map(mw => ({\n name: mw.name || 'middleware',\n metadata: mw.metadata\n })),\n ...astMiddlewareForRoute.map(mw => ({\n id: mw.id,\n name: mw.name,\n responses: mw.responseTypes,\n headers: mw.headers,\n file: mw.file,\n line: mw.startLine\n }))\n ];\n }\n\n if (route.guards) {\n for (const guard of route.guards) {\n if (guard.spec) {\n if (guard.spec.security) {\n const existing = operation.security || [];\n for (const req of guard.spec.security) {\n const reqStr = JSON.stringify(req);\n if (!existing.some((e: any) => JSON.stringify(e) === reqStr)) {\n existing.push(req);\n }\n }\n operation.security = existing;\n }\n if (guard.spec.responses) {\n operation.responses = { ...operation.responses, ...guard.spec.responses };\n }\n }\n }\n }\n\n // Match with AST routes\n let astMatch = astRoutes.find(r =>\n r.method.toUpperCase() === route.method.toUpperCase() &&\n r.path === fullPath\n );\n\n\n\n if (!astMatch) {\n // Heuristic matching based on source code similarity\n const runtimeSource = ((route.handler as any).originalHandler || route.handler).toString();\n const runtimeHandlerSrc = runtimeSource.replace(/\\s+/g, ' ');\n\n const sameMethodRoutes = astRoutes.filter(r => r.method.toUpperCase() === route.method.toUpperCase());\n\n astMatch = sameMethodRoutes.find(r => {\n const astHandlerSrc = (r.handlerSource || r.handlerName || '').replace(/\\s+/g, ' ');\n if (!astHandlerSrc || astHandlerSrc.length < 20) return false;\n return runtimeHandlerSrc.includes(astHandlerSrc) ||\n astHandlerSrc.includes(runtimeHandlerSrc) ||\n (r.handlerSource && runtimeHandlerSrc.includes(r.handlerSource.substring(0, 50)));\n });\n }\n\n if (astMatch) {\n if (astMatch.summary) operation.summary = astMatch.summary;\n if (astMatch.description) operation.description = astMatch.description;\n if (astMatch.tags) operation.tags = astMatch.tags;\n if (astMatch.operationId) operation.operationId = astMatch.operationId;\n\n // Add source info\n if (astMatch.sourceContext) {\n const sc = astMatch.sourceContext;\n operation[\"x-source-info\"] = {\n file: sc.file,\n line: sc.startLine,\n snippet: sc.snippet || astMatch.handlerSource, // Fallback\n offset: sc.snippetStartLine || sc.startLine,\n highlightLines: [sc.startLine, sc.endLine],\n highlights: sc.highlights\n };\n\n // Add x-shokupan-source for standard frontend handling\n operation[\"x-shokupan-source\"] = {\n file: sc.file,\n line: sc.startLine,\n code: sc.snippet || astMatch.handlerSource || ''\n };\n\n // Removed markdown source block per request\n }\n\n\n\n if (astMatch.requestTypes?.body) {\n operation.requestBody = {\n content: { 'application/json': { schema: astMatch.requestTypes.body } }\n };\n }\n\n if (astMatch.responseSchema) {\n operation.responses['200'] = {\n description: 'Successful response',\n content: { 'application/json': { schema: astMatch.responseSchema } }\n };\n\n // Add warning if schema has unknown fields\n if (astMatch.hasUnknownFields) {\n if (options.warnings) {\n options.warnings.push({\n type: 'unknown-fields',\n message: 'Response contains fields with unknown types',\n detail: `Route: ${fullPath} [${route.method}]`,\n location: { file: astMatch.sourceContext?.file, line: astMatch.sourceContext?.startLine }\n });\n }\n operation['x-warning'] = true;\n operation['x-warning-reason'] = 'Response contains fields with unknown types that could not be statically analyzed';\n }\n } else if (astMatch.responseType) {\n let contentType = 'application/json';\n if (astMatch.responseType === 'string') contentType = 'text/plain';\n else if (astMatch.responseType === 'html') contentType = 'text/html';\n\n operation.responses['200'] = {\n description: 'Successful response',\n content: { [contentType]: { schema: { type: 'string' } } }\n };\n }\n\n const params: any[] = [];\n if (astMatch.requestTypes?.query) {\n for (const [name, _type] of Object.entries(astMatch.requestTypes.query)) {\n let type = 'string';\n let format: string | undefined;\n if (_type === 'integer') { type = 'integer'; format = 'int32'; }\n else if (_type === 'number') { type = 'number'; format = 'float'; }\n else if (_type === 'boolean') type = 'boolean';\n\n const schema: any = { type };\n if (format) schema.format = format;\n\n params.push({ name, in: 'query', schema });\n }\n }\n\n if (astMatch.requestTypes?.params) {\n for (const [name, _type] of Object.entries(astMatch.requestTypes.params)) {\n let type = 'string';\n let format: string | undefined;\n if (_type === 'integer') { type = 'integer'; format = 'int32'; }\n else if (_type === 'number') { type = 'number'; format = 'float'; }\n else if (_type === 'boolean') type = 'boolean';\n\n const schema: any = { type };\n if (format) schema.format = format;\n\n // Path params are always required\n params.push({ name, in: 'path', required: true, schema });\n }\n }\n\n if (astMatch.requestTypes?.headers) {\n for (const [name, _type] of Object.entries(astMatch.requestTypes.headers)) {\n params.push({ name, in: 'header', schema: { type: 'string' } });\n }\n }\n\n if (params.length > 0) {\n operation.parameters = params;\n }\n } else {\n // No static analysis match - Add Warning and Runtime Source\n if (options.warnings) {\n options.warnings.push({\n type: 'route-not-found',\n message: 'Route could not be statically analyzed',\n detail: `Route: ${fullPath} [${route.method}]`,\n location: route.metadata ? { file: route.metadata.file, line: route.metadata.line } : undefined\n });\n }\n const runtimeSource = ((route.handler as any).originalHandler || route.handler).toString();\n // Removed markdown source block and warning per request (or simplified)\n // Minimal warning\n // operation.description = (operation.description || '') + \"\\n\\n> [!WARNING]\\n> **Static Analysis Failed**\";\n\n // Extract file/line from Error stack if available\n let file: string | undefined;\n let line: number | undefined;\n\n // Try to get source info from route metadata if present\n if (route.metadata?.file) {\n file = route.metadata.file;\n line = route.metadata.line || 1;\n }\n\n // Provide x-source-info with available metadata\n operation[\"x-source-info\"] = {\n snippet: runtimeSource,\n isRuntime: true,\n ...(file ? { file, line: line || 1 } : {})\n };\n\n // If we have file info, add it to x-shokupan-source for the API Explorer\n if (file) {\n operation[\"x-shokupan-source\"] = {\n file,\n line: line || 1,\n code: runtimeSource,\n pluginName: (route.handler as any).pluginName // Inject pluginName from handler\n };\n }\n }\n\n if (isBuiltinPlugin) {\n operation[\"x-shokupan-builtin\"] = true;\n }\n\n // Explicitly set plugin name if available on handler (even if not builtin, or overriding builtin guess)\n if ((route.handler as any).pluginName) {\n operation[\"x-shokupan-plugin-name\"] = (route.handler as any).pluginName;\n if (!operation[\"x-shokupan-source\"]) operation[\"x-shokupan-source\"] = {};\n operation[\"x-shokupan-source\"].pluginName = (route.handler as any).pluginName;\n } else if (pluginName) {\n // Fallback to inferred plugin name\n operation[\"x-shokupan-plugin-name\"] = pluginName;\n }\n\n // Path pattern params\n if (route.keys.length > 0) {\n const pathParams = route.keys.map((key: string) => ({\n name: key,\n in: \"path\",\n required: true,\n schema: { type: \"string\" }\n }));\n const existingParams = operation.parameters || [];\n const mergedParams = [...existingParams];\n\n pathParams.forEach(p => {\n const idx = mergedParams.findIndex(ep => ep.in === 'path' && ep.name === p.name);\n if (idx === -1) {\n mergedParams.push(p);\n }\n // If it exists (from AST), preserve AST version as it has richer type info\n });\n operation.parameters = mergedParams;\n }\n\n // Runtime analysis\n const { inferredSpec } = analyzeHandler(route.handler);\n if (inferredSpec) {\n if (inferredSpec.parameters) {\n const existingParams = operation.parameters || [];\n const mergedParams = [...existingParams];\n\n for (const p of inferredSpec.parameters) {\n const idx = mergedParams.findIndex((ep: any) => ep.name === p.name && ep.in === p.in);\n if (idx >= 0) {\n mergedParams[idx] = deepMerge(mergedParams[idx], p);\n } else {\n mergedParams.push(p);\n }\n }\n operation.parameters = mergedParams;\n delete inferredSpec.parameters;\n }\n deepMerge(operation, inferredSpec);\n }\n\n if (route.handlerSpec) {\n deepMerge(operation, route.handlerSpec);\n }\n\n if (!operation.tags || operation.tags.length === 0) operation.tags = [tag];\n\n if (operation.tags) {\n operation.tags = Array.from(new Set(operation.tags));\n for (const t of operation.tags) {\n if (!tagGroups.has(routeGroup)) tagGroups.set(routeGroup, new Set());\n tagGroups.get(routeGroup)?.add(t);\n }\n }\n\n const methodLower = route.method.toLowerCase();\n if (methodLower === \"all\") {\n [\"get\", \"post\", \"put\", \"delete\", \"patch\"].forEach(m => {\n if (!paths[fullPath][m]) paths[fullPath][m] = { ...operation };\n });\n } else {\n paths[fullPath][methodLower] = operation;\n }\n }\n\n const controllers = router[$childControllers];\n for (const controller of controllers) {\n const controllerName = controller.constructor.name || \"UnknownController\";\n tagGroups.get(group)?.add(controllerName);\n }\n\n const childRouters = router[$childRouters];\n for (const child of childRouters) {\n const mountPath = child[$mountPath];\n const cleanPrefix = prefix.endsWith(\"/\") ? prefix.slice(0, -1) : prefix;\n const cleanMount = mountPath.startsWith(\"/\") ? mountPath : \"/\" + mountPath;\n const nextPrefix = (cleanPrefix + cleanMount) || \"/\";\n // Pass false for isRootLevel since these are child routers\n collect(child, nextPrefix, group, tag, [...inheritedMiddleware, ...routerMiddleware], false);\n }\n };\n\n collect(rootRouter);\n\n const xTagGroups: { name: string; tags: string[]; }[] = [];\n for (const [name, tags] of tagGroups.entries()) {\n xTagGroups.push({ name, tags: Array.from(tags).sort() });\n }\n\n\n // Add virtual middleware paths (if middleware tracking is active)\n if (!options.compliant) {\n for (const [id, mw] of Object.entries(astMiddlewareRegistry || {}) as any[]) {\n const virtualPath = `/_middleware/${id}`;\n paths[virtualPath] = {\n get: {\n tags: ['System', 'Middleware'],\n summary: `Middleware: ${mw.name}`,\n description: `Virtual endpoint for middleware analysis.\n**File**: ${mw.file}\n**Line**: ${mw.startLine}`,\n operationId: `getMiddleware_${id}`,\n parameters: [],\n responses: {\n '200': {\n description: \"Middleware Analysis\",\n content: {\n 'application/json': {\n schema: { type: 'object' }\n }\n }\n }\n },\n 'x-middleware-metadata': mw,\n 'x-virtual': true,\n 'x-middleware-detail': true,\n 'x-source-info': {\n file: mw.file,\n line: mw.startLine,\n code: mw.snippet\n },\n \"x-shokupan-source\": {\n file: mw.file,\n line: mw.startLine,\n code: mw.snippet\n }\n }\n };\n }\n }\n\n const spec: any = {\n openapi: \"3.1.0\",\n info: { title: \"Shokupan API\", version: \"1.0.0\", ...options.info },\n paths,\n components: options.components,\n servers: options.servers,\n tags: options.tags,\n externalDocs: options.externalDocs,\n \"x-tagGroups\": xTagGroups,\n \"x-middleware-registry\": astMiddlewareRegistry\n };\n\n if (options.compliant) {\n spec[\"x-tagGroups\"] = undefined;\n spec[\"x-middleware-registry\"] = undefined;\n\n // Recursive strip function\n const stripExtensions = (obj: any) => {\n if (!obj || typeof obj !== 'object') return;\n if (Array.isArray(obj)) {\n obj.forEach(stripExtensions);\n return;\n }\n for (const key of Object.keys(obj)) {\n if (key.startsWith('x-')) {\n delete obj[key];\n } else {\n stripExtensions(obj[key]);\n }\n }\n };\n\n stripExtensions(spec);\n }\n\n return spec;\n}\n\n","import { Eta } from 'eta';\nimport { readdir, stat } from 'fs/promises';\nimport { basename, join, resolve, sep } from 'path';\nimport type { ShokupanContext } from '../../context';\nimport type { Middleware, StaticServeOptions } from '../../util/types';\n\nconst eta = new Eta();\n\nexport function serveStatic<T extends Record<string, any>>(config: StaticServeOptions<T>, prefix: string) {\n const rootPath = resolve(config.root || \".\");\n const normalizedPrefix = prefix.endsWith('/') && prefix !== '/' ? prefix.slice(0, -1) : prefix;\n\n const serveStaticMiddleware: Middleware = async (ctx: ShokupanContext<any>) => {\n // 1. Calculate relative path\n // ctx.path is full path.\n // If prefix is /static, and path is /static/foo.css, relative is /foo.css\n let relative = ctx.path.slice(normalizedPrefix.length);\n if (!relative.startsWith('/') && relative.length > 0) relative = '/' + relative;\n if (relative.length === 0) relative = '/';\n\n // Security: Check for null bytes BEFORE decoding\n if (relative.includes('\\0')) {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n\n // Decode URI components\n try {\n relative = decodeURIComponent(relative);\n } catch (e) {\n // Invalid URL encoding\n return ctx.json({ error: 'Bad Request' }, 400);\n }\n\n // Security: Check for null bytes AFTER decoding\n if (relative.includes('\\0')) {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n\n // Security: Check for directory traversal patterns\n if (relative.includes('../') || relative.includes('..\\\\')) {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n\n // Security: Prevent directory traversal with proper path normalization\n const requestPath = resolve(join(rootPath, relative));\n const normalizedRoot = resolve(rootPath);\n\n // Ensure the resolved path is within the root directory\n // Use separator to prevent partial matching (e.g., /var/www vs /var/www-evil)\n if (!requestPath.startsWith(normalizedRoot + sep) && requestPath !== normalizedRoot) {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n\n // Hooks: onRequest\n if (config.hooks?.onRequest) {\n const res = await config.hooks.onRequest(ctx);\n if (res) return res;\n }\n\n // Check Excludes\n if (config.exclude) {\n for (let i = 0; i < config.exclude.length; i++) {\n const pattern = config.exclude[i];\n if (pattern instanceof RegExp) {\n if (pattern.test(relative)) return ctx.json({ error: 'Forbidden' }, 403);\n } else if (typeof pattern === 'string') {\n if (relative.includes(pattern)) return ctx.json({ error: 'Forbidden' }, 403);\n }\n }\n }\n\n // Dotfiles\n if (basename(requestPath).startsWith('.')) {\n const behavior = config.dotfiles || 'ignore';\n if (behavior === 'deny') return ctx.json({ error: 'Forbidden' }, 403);\n if (behavior === 'ignore') return ctx.json({ error: 'Not Found' }, 404);\n }\n\n let finalPath = requestPath;\n let stats;\n\n try {\n stats = await stat(requestPath);\n } catch (e) {\n // Path not found. Try extensions.\n if (config.extensions) {\n for (let i = 0; i < config.extensions.length; i++) {\n const ext = config.extensions[i];\n const p = requestPath + (ext.startsWith('.') ? ext : '.' + ext);\n try {\n const s = await stat(p);\n if (s.isFile()) {\n finalPath = p;\n stats = s;\n break;\n }\n } catch { }\n }\n }\n if (!stats) return ctx.json({ error: 'Not Found' }, 404);\n }\n\n // Directory handling\n if (stats.isDirectory()) {\n // Return 302 Redirect to add trailing slash if missing and not root\n // This ensures relative paths in served files work correctly.\n if (!ctx.path.endsWith('/')) {\n const query = ctx.url.search;\n return ctx.redirect(ctx.path + '/' + query, 302);\n }\n\n // Try indexes\n let indexes: string[] = [];\n if (config.index === undefined) {\n indexes = ['index.html', 'index.htm'];\n }\n else if (Array.isArray(config.index)) {\n indexes = config.index;\n }\n else if (config.index) {\n indexes = [config.index];\n }\n\n let foundIndex = false;\n for (let i = 0; i < indexes.length; i++) {\n const idx = indexes[i];\n const idxPath = join(finalPath, idx);\n try {\n const idxStats = await stat(idxPath);\n if (idxStats.isFile()) {\n finalPath = idxPath;\n foundIndex = true;\n break;\n }\n } catch { }\n }\n\n if (!foundIndex) {\n if (config.listDirectory) {\n // List directory\n try {\n const files = await readdir(requestPath);\n // Simple HTML listing\n const listing = eta.renderString(`\n <!DOCTYPE html>\n <html>\n <head>\n <title>Index of <%= it.relative %></title>\n <style>\n body { font-family: system-ui, -apple-system, sans-serif; padding: 2rem; max-width: 800px; margin: 0 auto; }\n ul { list-style: none; padding: 0; }\n li { padding: 0.5rem 0; border-bottom: 1px solid #eee; }\n a { text-decoration: none; color: #0066cc; }\n a:hover { text-decoration: underline; }\n h1 { font-size: 1.5rem; margin-bottom: 1rem; }\n </style>\n </head>\n <body>\n <h1>Index of <%= it.relative %></h1>\n <ul>\n <% if (it.relative !== '/') { %>\n <li><a href=\"../\">../</a></li>\n <% } %>\n <% it.files.forEach(function(f) { %>\n <li><a href=\"<%= f %>\"><%= f %></a></li>\n <% }) %>\n </ul>\n </body>\n </html>\n `, { relative, files, join });\n return new Response(listing, { headers: { 'Content-Type': 'text/html' } });\n } catch (e) {\n return ctx.json({ error: 'Internal Server Error' }, 500);\n }\n } else {\n // If no index and no listing, it's 404 or 403. typically 404/403.\n // Nginx returns 403 Forbidden.\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n }\n }\n\n // Serving File\n // @ts-ignore\n let response: Response;\n\n if (typeof Bun !== \"undefined\") {\n response = new Response(Bun.file(finalPath));\n } else {\n // Node.js fallback using fs\n // Stream the file instead of buffering to avoid memory spikes\n const { createReadStream } = await import('node:fs');\n const { Readable } = await import('node:stream');\n\n const fileStream = createReadStream(finalPath);\n // Convert node stream to web stream\n const webStream = Readable.toWeb(fileStream);\n\n response = new Response(webStream as any);\n }\n\n if (config.hooks?.onResponse) {\n const hooked = await config.hooks.onResponse(ctx, response);\n if (hooked) response = hooked;\n }\n return response;\n };\n\n serveStaticMiddleware.isBuiltin = true;\n serveStaticMiddleware.pluginName = 'ServeStatic';\n\n return serveStaticMiddleware;\n}\n","\nimport { ShokupanContext } from \"../../../context\";\nimport type { Shokupan } from \"../../../shokupan\";\nimport type { Middleware, ShokupanHandler, ShokupanPlugin } from \"../../../util/types\";\n\nexport interface OpenTelemetryOptions {\n /**\n * Service name for traces\n */\n serviceName?: string;\n /**\n * Enable auto-instrumentation\n * @default true\n */\n enableAutoInstrumentation?: boolean;\n /**\n * OTLP Endpoint (e.g. http://localhost:4318)\n */\n otlpEndpoint?: string;\n}\n\nexport class OpenTelemetryPlugin implements ShokupanPlugin {\n private api: typeof import(\"@opentelemetry/api\");\n private sdk: any;\n\n constructor(private options: OpenTelemetryOptions = {}) { }\n\n async onInit(app: Shokupan) {\n try {\n this.api = await import(\"@opentelemetry/api\");\n // If we wanted to initialize a full NodeSDK here, we would need @opentelemetry/sdk-node\n // which might not be installed. For now we just provide the API wrapper and middleware.\n // In a real expanded plugin, we'd try to import sdk-node and start it if configured.\n } catch (e) {\n console.warn(\"OpenTelemetry API not found. OpenTelemetryPlugin will be disabled.\");\n return;\n }\n\n if (this.options.enableAutoInstrumentation !== false) {\n app.use(this.middleware());\n }\n }\n\n middleware(): Middleware {\n return async (ctx: ShokupanContext, next: () => Promise<any>) => {\n if (!this.api) return next();\n\n const tracer = this.api.trace.getTracer(\"shokupan\");\n\n // Extract context from headers (propagated from upstream)\n // const activeContext = this.api.propagation.extract(this.api.context.active(), ctx.req.headers);\n\n return tracer.startActiveSpan(`${ctx.req.method} ${ctx.req.path}`, {\n kind: this.api.SpanKind.SERVER,\n attributes: {\n \"http.method\": ctx.req.method,\n \"http.url\": ctx.req.url,\n \"http.host\": ctx.req.host,\n \"http.user_agent\": ctx.req.headers.get(\"user-agent\") || undefined\n }\n }, async (span: any) => {\n try {\n const res = await next();\n span.setAttributes({\n \"http.status_code\": ctx.res.status\n });\n if (ctx.res.status >= 500) {\n span.setStatus({ code: this.api.SpanStatusCode.ERROR });\n } else {\n span.setStatus({ code: this.api.SpanStatusCode.OK });\n }\n return res;\n } catch (err: any) {\n span.recordException(err);\n span.setStatus({ code: this.api.SpanStatusCode.ERROR, message: err.message });\n throw err;\n } finally {\n span.end();\n }\n });\n };\n }\n}\n\n/**\n * Wraps a middleware function with an OpenTelemetry span.\n */\nexport function traceMiddleware(fn: Middleware, name?: string): Middleware {\n let api: typeof import(\"@opentelemetry/api\");\n try { api = require('@opentelemetry/api'); } catch { }\n\n if (!api) return fn;\n\n const tracer = api.trace.getTracer(\"shokupan.middleware\");\n const middlewareName = name || fn.name || \"anonymous middleware\";\n\n return async (ctx, next) => {\n return tracer.startActiveSpan(`middleware - ${middlewareName}`, {\n kind: api.SpanKind.INTERNAL,\n attributes: {\n \"code.function\": middlewareName,\n \"component\": \"shokupan.middleware\"\n }\n }, async (span: any) => {\n try {\n const result = await fn(ctx, next);\n return result;\n }\n catch (err: any) {\n span.recordException(err);\n span.setStatus({ code: api.SpanStatusCode.ERROR, message: err.message });\n throw err;\n }\n finally {\n span.end();\n }\n });\n };\n}\n\n/**\n * Wraps a route handler with an OpenTelemetry span.\n */\nexport function traceHandler(fn: ShokupanHandler | ((...args: any[]) => any), name: string): ShokupanHandler {\n let api: typeof import(\"@opentelemetry/api\");\n try { api = require('@opentelemetry/api'); } catch { }\n\n if (!api) return fn as ShokupanHandler;\n\n const tracer = api.trace.getTracer(\"shokupan.middleware\");\n\n return async function (this: any, ...args: any[]) {\n return tracer.startActiveSpan(`route handler - ${name}`, {\n kind: api.SpanKind.INTERNAL,\n attributes: {\n \"http.route\": name,\n \"component\": \"shokupan.route\"\n }\n }, async (span: any) => {\n try {\n const result = await (fn as Function).apply(this, args);\n return result;\n }\n catch (err: any) {\n span.recordException(err);\n span.setStatus({ code: api.SpanStatusCode.ERROR, message: err.message });\n throw err;\n }\n finally {\n span.end();\n }\n });\n };\n}\n","import { bulkhead, circuitBreaker, ConsecutiveBreaker, ConstantBackoff, ExponentialBackoff, fallback, handleAll, retry, timeout, TimeoutStrategy, wrap, type IPolicy } from 'cockatiel';\nimport type { ResilienceConfig } from './decorators';\n\nexport class ResilienceFactory {\n static createPolicy(config: ResilienceConfig): IPolicy {\n const policies: IPolicy[] = [];\n\n // 5. Retry\n if (config.retry) {\n // handleAll is a PolicyBuilder object in this version\n const builder = handleAll;\n\n // Basic retry policy configuration\n // Cockatiel maxAttempts treats value as number of RETRIES (additional attempts).\n // So for N total attempts, we pass N-1.\n let retries = (config.retry.attempts ?? 3) - 1;\n if (retries < 0) retries = 0;\n\n let retryPolicy;\n if (config.retry.backoff === 'exponential') {\n retryPolicy = retry(builder, {\n maxAttempts: retries,\n backoff: new ExponentialBackoff({\n initialDelay: config.retry.delay || 1000,\n maxDelay: config.retry.maxDelay || 30000\n })\n });\n } else {\n retryPolicy = retry(builder, {\n maxAttempts: retries,\n backoff: new ConstantBackoff(config.retry.delay || 1000)\n });\n }\n policies.push(retryPolicy);\n }\n\n // 4. CircuitBreaker\n if (config.circuitBreaker) {\n const builder = handleAll;\n const breaker = circuitBreaker(builder, {\n halfOpenAfter: config.circuitBreaker.resetTimeout || 10000,\n breaker: new ConsecutiveBreaker(config.circuitBreaker.threshold || 5),\n });\n policies.push(breaker);\n }\n\n // 3. Timeout\n if (config.timeout) {\n policies.push(timeout(config.timeout, { strategy: TimeoutStrategy.Aggressive, abortOnReturn: true }));\n }\n\n // 2. Bulkhead\n if (config.bulkhead) {\n policies.push(bulkhead(config.bulkhead));\n }\n\n // 1. Fallback\n if (config.fallback !== undefined) {\n const builder = handleAll;\n const fb = fallback(builder, config.fallback);\n policies.push(fb as any);\n }\n\n // wrap takes arguments from outer to inner.\n // We constructed policies from inner to outer (Retry -> ... -> Fallback)\n // Wait, did we?\n // - Push Retry (Pushed 1st)\n // - Push Breaker (Pushed 2nd)\n // - ...\n // - Push Fallback (Pushed last)\n\n // policies = [Retry, Breaker, Timeout, Bulkhead, Fallback]\n\n // We want execution flow: Fallback -> Bulkhead -> Timeout -> Breaker -> Retry -> Function\n // wrap(Fallback, Bulkhead, Timeout, Breaker, Retry).execute()\n // This means Fallback wraps everything else.\n\n // So we need to reverse the array? NO.\n // policies.reverse() -> [Fallback, Bulkhead, Timeout, Breaker, Retry]\n // This looks correct order for wrap arguments.\n\n if (policies.length === 0) {\n return { execute: (fn: any) => fn() } as any;\n }\n\n return wrap(...policies.reverse());\n }\n}\n","\n/**\n * Lightweight Polyfill for Reflect Metadata API.\n * \n * Replaces the need for 'reflect-metadata' package to reduce bundle size\n * while maintaining compatibility with TypeScript's emitDecoratorMetadata.\n */\n\nconst metadataStore = new WeakMap<any, Map<string | symbol, any>>();\n\nexport function defineMetadata(key: string | symbol, value: any, target: any, propertyKey?: string | symbol) {\n let targetMetadata = metadataStore.get(target);\n if (!targetMetadata) {\n targetMetadata = new Map();\n metadataStore.set(target, targetMetadata);\n }\n\n // Composite key for property metadata: \"propertyKey:metadataKey\"\n const storageKey = propertyKey ? `${String(propertyKey)}:${String(key)}` : key;\n targetMetadata.set(storageKey, value);\n}\n\nexport function getMetadata(key: string | symbol, target: any, propertyKey?: string | symbol): any {\n const targetMetadata = metadataStore.get(target);\n if (!targetMetadata) return undefined;\n\n const storageKey = propertyKey ? `${String(propertyKey)}:${String(key)}` : key;\n return targetMetadata.get(storageKey);\n}\n\n// Polyfill global Reflect object\nif (typeof Reflect === \"object\") {\n if (!(Reflect as any).defineMetadata) {\n (Reflect as any).defineMetadata = defineMetadata;\n }\n if (!(Reflect as any).getMetadata) {\n (Reflect as any).getMetadata = getMetadata;\n }\n if (!(Reflect as any).metadata) {\n (Reflect as any).metadata = function (metadataKey: any, metadataValue: any) {\n return function decorator(target: any, propertyKey?: string | symbol) {\n defineMetadata(metadataKey, metadataValue, target, propertyKey);\n };\n };\n }\n}\n\ndeclare global {\n namespace Reflect {\n function defineMetadata(metadataKey: any, metadataValue: any, target: Object, propertyKey?: string | symbol): void;\n function getMetadata(metadataKey: any, target: Object, propertyKey?: string | symbol): any;\n function metadata(metadataKey: any, metadataValue: any): {\n (target: Function): void;\n (target: Object, propertyKey: string | symbol): void;\n };\n }\n}\n","import './metadata'; // Apply polyfill\n\n\n/**\n * Simple Dependency Injection Container\n */\nexport class Container {\n private static services = new Map<any, any>();\n\n public static register<T>(target: new (...args: any[]) => T, instance: T) {\n this.services.set(target, instance);\n }\n\n public static get<T>(target: new (...args: any[]) => T): T | undefined {\n return this.services.get(target);\n }\n\n public static has(target: any): boolean {\n return this.services.has(target);\n }\n\n private static cache = new Map<any, { scope: string, dependencies: any[]; }>();\n\n private static resolvingStack = new Set<any>();\n\n public static resolve<T>(target: new (...args: any[]) => T): T {\n // 1. Check if it's a singleton already instantiated\n if (this.services.has(target)) {\n return this.services.get(target);\n }\n\n // 2. Cycle Detection\n if (this.resolvingStack.has(target)) {\n const cycle = Array.from(this.resolvingStack);\n cycle.push(target);\n throw new Error(`Circular dependency detected: ${cycle.map(t => t.name || t).join(' -> ')}`);\n }\n this.resolvingStack.add(target);\n\n try {\n // 3. Check metadata cache\n let meta = this.cache.get(target);\n if (!meta) {\n const scope = Reflect.getMetadata('di:scope', target) || 'singleton';\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || [];\n const manualTokens = Reflect.getMetadata('di:constructor:params', target) || [];\n\n const dependencies = paramTypes.map((param: any, index: number) => {\n const manual = manualTokens.find((t: any) => t.index === index);\n if (manual && manual.token) return manual.token;\n if (param === String || param === Number || param === Boolean || param === Object || param === undefined) return undefined;\n return param;\n });\n\n meta = { scope, dependencies };\n this.cache.set(target, meta);\n }\n\n // 4. Resolve dependencies from cache\n const args = meta.dependencies.map(dep => dep ? Container.resolve(dep) : undefined);\n\n // 5. Instantiate\n const instance = new target(...args);\n\n // 6. Lifecycle: onInit\n if (typeof (instance as any).onInit === 'function') {\n (instance as any).onInit();\n }\n\n // 7. Store if singleton\n if (meta.scope === 'singleton') {\n this.services.set(target, instance);\n }\n\n return instance;\n } finally {\n this.resolvingStack.delete(target);\n }\n }\n\n public static async teardown() {\n for (const [target, instance] of this.services.entries()) {\n if (typeof instance.onDestroy === 'function') {\n await instance.onDestroy();\n }\n }\n this.services.clear();\n this.cache.clear();\n }\n}\n","/**\n * Captures the file and line number of the caller.\n * Use skipFrames to skip helper functions in the stack trace.\n */\nexport function getCallerInfo(skipFrames = 1): { file: string; line: number; } {\n let file = 'unknown';\n let line = 0;\n\n try {\n const err = new Error();\n const stack = err.stack?.split('\\n') || [];\n // Skip Error line and requested frames\n // Bun stack traces usually look like:\n // Error\n // at getCallerInfo (...)\n // at callingFunction (...)\n //\n // Standard Bun Stack Line: \"at functionName (/path/to/file.ts:123:45)\" or \"at /path/to/file.ts:123:45\"\n\n let found = 0;\n for (let i = 1; i < stack.length; i++) {\n const l = stack[i];\n\n // Ignore internals - These should NEVER be returned as caller info\n if (!l.includes(':')) continue; // likely not File:Line context\n if (l.includes('node_modules')) continue;\n if (l.includes('bun:main')) continue;\n if (l.includes('bun:wrap')) continue;\n if (l.includes('src/util/stack.ts')) continue; // Ignore self\n if (l.includes('src/router.ts')) continue; // Ignore router internals\n if (l.includes('src/util/decorators.ts')) continue; // Ignore decorators\n if (l.includes('src/shokupan.ts')) continue; // Ignore framework internals\n if (l.includes('src/plugins/application/openapi/openapi.ts')) continue; // Ignore openapi internals\n\n found++;\n if (found >= skipFrames) {\n // Parse this line\n const match = l.match(/\\((.*):(\\d+):(\\d+)\\)/) || l.match(/at (.*):(\\d+):(\\d+)/);\n if (match) {\n file = match[1];\n line = parseInt(match[2], 10);\n return { file, line };\n }\n }\n }\n\n } catch (e) { }\n\n return { file, line };\n}\n","import type { OpenAPI } from '@scalar/openapi-types';\nimport type { Server } from 'bun';\nimport type { Server as NodeServer } from 'node:http';\nimport type { ConnectOptions, Engines } from 'surrealdb';\nimport type { ShokupanContext } from '../context';\nimport type { ServerAdapter } from './adapter';\nimport type { FileSystemAdapter } from './adapter/filesystem';\nimport { $isRouter } from \"./symbol\";\n\nexport type HeadersInit = Headers | Record<string, string> | [string, string][];\n\nexport interface ShokupanPluginOptions {\n path?: string;\n}\n\nexport interface ShokupanPlugin {\n onInit: (app: any, options?: ShokupanPluginOptions) => void | Promise<void>;\n}\n\nexport type DeepPartial<T> = T extends Function ? T : T extends object ? {\n [P in keyof T]?: DeepPartial<T[P]>;\n} : T;\n\n/**\n * Helper type for applications that don't use ctx.state.\n * Prevents accidental property access on state.\n * \n * @example\n * ```typescript\n * const app = new Shokupan<EmptyState>();\n * ```\n */\nexport type EmptyState = Record<string, never>;\n\n/**\n * Default state type that allows any properties.\n * This is the default if no state type is specified.\n * \n * @example\n * ```typescript\n * const app = new Shokupan<DefaultState>();\n * // Equivalent to: new Shokupan();\n * ```\n */\nexport type DefaultState = Record<string, any>;\n\n// Utility type to extract parameter names from a route path\n// Example: \"/users/:id/posts/:postId\" => { id: string, postId: string }\ntype ParsePathParams<Path extends string> =\n Path extends `${infer _Start}:${infer Param}/${infer Rest}`\n ? { [K in Param | keyof ParsePathParams<`/${Rest}`>]: string }\n : Path extends `${infer _Start}:${infer Param}`\n ? { [K in Param]: string }\n : {};\n\n// Helper type for route parameters\n// Falls back to Record<string, string> if no params are detected\nexport type RouteParams<Path extends string> =\n string extends Path\n ? Record<string, string>\n : ParsePathParams<Path> extends Record<string, never>\n ? Record<string, string>\n : ParsePathParams<Path>;\n\nexport interface RouteMetadata {\n file: string;\n line: number;\n name?: string;\n isBuiltin?: boolean;\n pluginName?: string;\n}\n\nexport type MethodAPISpec = OpenAPI.Operation;\nexport type GuardAPISpec = DeepPartial<OpenAPI.Operation>;\nexport type RouterAPISpec = OpenAPI.Operation & Pick<Required<OpenAPI.Operation>, 'tags'> & { group: string; };\n\nexport interface OpenAPIOptions {\n info?: OpenAPI.Document['info'];\n servers?: OpenAPI.Document['servers'];\n components?: OpenAPI.Document['components'];\n tags?: OpenAPI.Document['tags'];\n externalDocs?: OpenAPI.Document['externalDocs'];\n defaultTagGroup?: string;\n defaultTag?: string;\n /**\n * Whether to generate a strictly compliant OpenAPI spec (stripping x- extensions).\n * @default false\n */\n compliant?: boolean;\n /**\n * Array to collect warnings during generation.\n */\n warnings?: any[];\n}\n\nexport interface AsyncAPIOptions {\n info?: {\n title: string;\n version: string;\n description?: string;\n };\n defaultTag?: string;\n /**\n * Array to collect warnings during generation.\n */\n warnings?: any[];\n}\n\nexport interface AsyncAPISpec {\n type?: 'publish' | 'subscribe';\n summary?: string;\n description?: string;\n tags?: string[];\n message?: {\n name?: string;\n title?: string;\n summary?: string;\n payload?: any;\n headers?: any;\n };\n}\n\nexport interface ShokupanHooks<T = any> {\n onError?: (ctx: ShokupanContext<T>, error: unknown) => void | Promise<void>;\n onRequestStart?: (ctx: ShokupanContext<T>) => void | Promise<void>;\n onRequestEnd?: (ctx: ShokupanContext<T>) => void | Promise<void>;\n onResponseStart?: (ctx: ShokupanContext<T>, response: Response) => void | Promise<void>;\n onResponseEnd?: (ctx: ShokupanContext<T>, response: Response) => void | Promise<void>;\n beforeValidate?: (ctx: ShokupanContext<T>, data: any) => void | Promise<void>;\n afterValidate?: (ctx: ShokupanContext<T>, data: any) => void | Promise<void>;\n onReadTimeout?: (ctx: ShokupanContext<T>) => void | Promise<void>;\n onWriteTimeout?: (ctx: ShokupanContext<T>) => void | Promise<void>;\n onRequestTimeout?: (ctx: ShokupanContext<T>) => void | Promise<void>;\n}\n\nexport interface CookieOptions {\n maxAge?: number;\n expires?: Date;\n httpOnly?: boolean;\n secure?: boolean;\n domain?: string;\n path?: string;\n sameSite?: boolean | 'lax' | 'strict' | 'none' | 'Lax' | 'Strict' | 'None';\n priority?: 'low' | 'medium' | 'high' | 'Low' | 'Medium' | 'High';\n}\n\n/**\n * Helper interface for generic streaming operations.\n * Provides methods to write data, pipe streams, and handle abort events.\n */\nexport interface StreamHelper {\n /**\n * Write data to the stream.\n * @param data Data to write (Uint8Array or string, strings are auto-encoded to UTF-8)\n */\n write(data: Uint8Array | string): Promise<void>;\n /**\n * Pipe a ReadableStream to this stream.\n * @param stream ReadableStream to pipe\n */\n pipe(stream: ReadableStream): Promise<void>;\n /**\n * Sleep for a specified duration.\n * @param ms Milliseconds to sleep\n */\n sleep(ms: number): Promise<void>;\n /**\n * Register a callback to be executed when the stream is aborted.\n * @param callback Callback function\n */\n onAbort(callback: () => void): void;\n}\n\n/**\n * Helper interface for text streaming operations.\n * Provides methods to write text with or without newlines.\n */\nexport interface TextStreamHelper {\n /**\n * Write text to the stream without a newline.\n * @param text Text to write\n */\n write(text: string): Promise<void>;\n /**\n * Write text to the stream with a newline.\n * @param text Text to write\n */\n writeln(text: string): Promise<void>;\n /**\n * Sleep for a specified duration.\n * @param ms Milliseconds to sleep\n */\n sleep(ms: number): Promise<void>;\n /**\n * Register a callback to be executed when the stream is aborted.\n * @param callback Callback function\n */\n onAbort(callback: () => void): void;\n}\n\n/**\n * Helper interface for Server-Sent Events (SSE) streaming.\n * Provides methods to write SSE-formatted messages.\n */\nexport interface SSEStreamHelper {\n /**\n * Write a Server-Sent Event message.\n * @param message SSE message with data, event, id, and retry fields\n */\n writeSSE(message: SSEMessage): Promise<void>;\n /**\n * Sleep for a specified duration.\n * @param ms Milliseconds to sleep\n */\n sleep(ms: number): Promise<void>;\n /**\n * Register a callback to be executed when the stream is aborted.\n * @param callback Callback function\n */\n onAbort(callback: () => void): void;\n}\n\n/**\n * Server-Sent Event message format.\n */\nexport interface SSEMessage {\n /**\n * The data payload of the event.\n */\n data: string;\n /**\n * Optional event type.\n */\n event?: string;\n /**\n * Optional event ID.\n */\n id?: string;\n /**\n * Optional reconnection time in milliseconds.\n */\n retry?: number;\n}\n\n/**\n * Error handler for stream operations.\n */\nexport type StreamErrorHandler = (err: Error, stream: StreamHelper) => void | Promise<void>;\n\n/**\n * Error handler for text stream operations.\n */\nexport type TextStreamErrorHandler = (err: Error, stream: TextStreamHelper) => void | Promise<void>;\n\n/**\n * Error handler for SSE stream operations.\n */\nexport type SSEStreamErrorHandler = (err: Error, stream: SSEStreamHelper) => void | Promise<void>;\n\n\n\nexport type ShokupanHandler<\n State extends Record<string, any> = Record<string, any>,\n Params extends Record<string, string> = Record<string, string>\n> = ((ctx: ShokupanContext<State, Params>, next?: NextFn) => Promise<any> | any) & { originalHandler?: ShokupanHandler<State, Params>; };\nexport const HTTPMethods = [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"HEAD\", \"OPTIONS\", \"ALL\"];\nexport type Method = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"OPTIONS\" | \"HEAD\" | \"ALL\";\n\nexport enum RouteParamType {\n BODY = \"BODY\",\n PARAM = \"PARAM\",\n QUERY = \"QUERY\",\n HEADER = \"HEADER\",\n REQUEST = \"REQUEST\",\n CONTEXT = \"CONTEXT\",\n SERVICE = \"SERVICE\"\n}\n\nexport interface ServerFactory {\n (options: any): Server<any> | Promise<Server<any>> | NodeServer | Promise<NodeServer>;\n}\n\nexport type NextFn = () => Promise<any>;\nexport type Middleware = ((ctx: ShokupanContext<unknown>, next: NextFn) => Promise<any> | any) & {\n isBuiltin?: boolean;\n pluginName?: string;\n metadata?: RouteMetadata;\n order?: number;\n};\nexport type JSXRenderer = (element: any, args?: unknown) => string | Promise<string>;\n\nexport type ShokupanRouteConfig = DeepPartial<{\n name: string;\n group: string;\n /**\n * Timeout for this specific route (milliseconds).\n */\n requestTimeout: number;\n openapi: DeepPartial<OpenAPI.Operation>;\n /**\n * Custom renderer for this route.\n */\n renderer: JSXRenderer;\n\n /**\n * Hooks for this route/router.\n */\n hooks: ShokupanHooks | ShokupanHooks[];\n /**\n * Whether to enforce that only controller classes (constructors) are accepted by the router.\n * @default false\n */\n controllersOnly: boolean;\n\n /**\n * Whether to enable automatic backpressure based on system CPU load.\n * @default false\n */\n autoBackpressureFeedback: boolean;\n /**\n * The CPU usage percentage threshold (0-100) at which to start rejecting requests.\n */\n autoBackpressureLevel: number;\n}>;\n\nexport type ShokupanRoute = {\n /**\n * HTTP method\n */\n method: Method;\n /**\n * Route path\n */\n path: string;\n /**\n * Compiled regex for the route\n */\n regex: RegExp;\n /**\n * Route parameters\n */\n keys: string[];\n /**\n * Route handler\n */\n handler: ShokupanHandler;\n /**\n * Optimization: Handler with hooks baked in.\n * Used by runtime router, while `handler` is used by OpenAPI generator.\n */\n bakedHandler?: ShokupanHandler;\n /**\n * OpenAPI spec for the route\n */\n handlerSpec?: MethodAPISpec | AsyncAPISpec;\n /**\n * Group for the route\n */\n group?: string;\n /**\n * Guards for the route\n */\n guards?: {\n /**\n * Guard handler\n */\n handler: ShokupanHandler;\n /**\n * Guard OpenAPI spec\n */\n spec?: GuardAPISpec;\n }[];\n /**\n * Timeout for this specific route (milliseconds).\n */\n requestTimeout?: number;\n /**\n * Custom JSX renderer for this route.\n */\n renderer?: JSXRenderer;\n /**\n * Hooks from the router/route definition\n */\n hooks?: ShokupanHooks;\n /**\n * Source metadata\n */\n metadata?: RouteMetadata;\n /**\n * Order of the middleware\n */\n order?: number;\n /**\n * Controller instance this route belongs to\n */\n controller?: any;\n /**\n * Middleware stack metadata for this route (Controller/Method level)\n */\n middleware?: Middleware[];\n};\n\nexport type ShokupanConfig<T extends Record<string, any> = Record<string, any>> = Partial<{\n /**\n * The port to be used for the server.\n * @default 3000\n */\n port: number;\n /**\n * The hostname to be used for the server.\n * @default \"localhost\"\n */\n hostname: string;\n /**\n * Whether to run in development mode.\n * @default process.env.NODE_ENV !== \"production\"\n */\n development: boolean;\n /**\n * Whether to enable AsyncLocalStorage.\n * (Request local storage)\n * @default false\n */\n enableAsyncLocalStorage: boolean;\n /**\n * Whether to enable OpenAPI generation.\n * @default true\n */\n enableOpenApiGen: boolean;\n /**\n * Whether to enable monkeypatching of the global Promise constructor.\n * When enabled, Promises created within an async context will carry that context\n * (including `requestId`) and the creation stack trace. This increases memory and\n * cpu usage, but provides richer logging for unhandled rejections.\n * @default false\n */\n enablePromiseMonkeypatch: boolean;\n /**\n * Whether to block server startup until OpenAPI generation completes.\n * Only applies when enableOpenApiGen is true.\n * When false, OpenAPI generation happens asynchronously in the background.\n * @default true\n */\n blockOnOpenApiGen: boolean;\n /**\n * Whether to enable AsyncAPI generation.\n * @default false\n */\n enableAsyncApiGen: boolean;\n /**\n * Whether to block server startup until AsyncAPI generation completes.\n * Only applies when enableAsyncApiGen is true.\n * When false, AsyncAPI generation happens asynchronously in the background.\n * @default true\n */\n blockOnAsyncApiGen: boolean;\n /**\n * Whether to reuse the port.\n * @default false\n */\n reusePort: boolean;\n /**\n * Whether to enforce that only controller classes (constructors) are accepted by the router.\n * @default false\n */\n controllersOnly: boolean;\n /**\n * Whether to enable OpenTelemetry tracing.\n * @default false\n */\n enableTracing?: boolean;\n\n /**\n * Query parser mode.\n * - `extended`: Arrays for duplicate keys (default).\n * - `simple`: First value only for duplicate keys.\n * - `strict`: Throws 400 error on duplicate keys.\n * @default 'extended'\n */\n queryParserMode?: 'extended' | 'simple' | 'strict';\n\n /**\n * JSON parser to use for parsing request bodies.\n * \n * Options:\n * - `'native'`: Use the built-in JSON.parse (fastest, default)\n * - `'parse-json'`: Use the parse-json library for better error messages with minimal performance overhead (~5% slower than native)\n * - `'secure-json-parse'`: Use secure-json-parse for protection against prototype pollution (20-30% slower than native)\n * \n * Performance implications based on benchmarks:\n * - `native`: Fastest option, excellent for production\n * - `parse-json`: Nearly identical performance to native with better error messages, good for development\n * - `secure-json-parse`: Provides security at the cost of performance, use only for untrusted input\n * \n * @default 'native'\n */\n jsonParser?: 'native' | 'parse-json' | 'secure-json-parse';\n\n /**\n * Whether to enable automatic backpressure based on system CPU load.\n * @default false\n */\n autoBackpressureFeedback?: boolean;\n /**\n * The CPU usage percentage threshold (0-100) at which to start rejecting requests (429).\n * @default 60\n */\n autoBackpressureLevel?: number;\n\n /**\n * Whether to enable middleware and handler tracking.\n * When enabled, `ctx.handlerStack` will be populated with the handlers the request has passed through.\n * Also, `ctx.state` will be a Proxy that tracks changes made by each handler.\n * @default false\n */\n enableMiddlewareTracking: boolean;\n /**\n * Maximum number of middleware executions to store in the datastore.\n * Only applies when enableMiddlewareTracking is true.\n * @default 10000\n */\n middlewareTrackingMaxCapacity?: number;\n /**\n * Whether to enable the HTTP bridge for WebSocket.\n * This enables websocket messages to run through the HTTP server.\n * e.g. \n * ```json\n * {\n * \"method\": \"POST\",\n * \"path\": \"/api/v1/myHttpEndpoint\",\n * \"headers\": {},\n * \"body\": {\n * \"type\": \"text\",\n * \"data\": \"Hello, world!\"\n * }\n * }\n * ```\n * @default false\n */\n enableHTTPBridge?: boolean;\n /**\n * Handler for WebSocket events that throw an exception.\n */\n websocketErrorHandler?: (err: any, ctx: ShokupanContext<T>) => void | Promise<void>;\n /**\n * Unique ID generator function for requests.\n * @default nanoid\n */\n idGenerator?: () => string;\n /**\n * Time-to-live for middleware tracking entries in milliseconds.\n * Entries older than this will be cleaned up.\n * Only applies when enableMiddlewareTracking is true.\n * @default 86400000 (1 day)\n */\n middlewareTrackingTTL?: number;\n /**\n * HTTP logger function.\n */\n httpLogger: (ctx: ShokupanContext<T>) => void;\n /**\n * Logger object.\n */\n logger: {\n verbose: boolean;\n info: (msg: string, props: Record<string, any>) => void;\n debug: (msg: string, props: Record<string, any>) => void;\n warning: (msg: string, props: Record<string, any>) => void;\n error: (msg: string, props: Record<string, any>) => void;\n /**\n * Something fatally went wrong and the application cannot continue.\n */\n fatal: (msg: string, props: Record<string, any>) => void;\n };\n /**\n * Timeout for reading the request body (milliseconds).\n * Maps to Bun's `idleTimeout`.\n * @default 30000\n */\n readTimeout: number;\n\n /**\n * Maximum allowed request body size in bytes.\n * Requests larger than this will be rejected with 413 Payload Too Large.\n * @default 10485760 (10MB)\n */\n maxBodySize?: number;\n\n /**\n * Timeout for processing the request (milliseconds).\n * Maps to `server.timeout(req, seconds)`.\n * @default 0 (disabled)\n */\n requestTimeout: number;\n /**\n * Timeout for writing the response (milliseconds).\n * Not currently supported by Bun.serve natively.\n * @experimental\n */\n writeTimeout: number;\n\n /**\n * JSX Rendering function.\n */\n renderer: JSXRenderer;\n\n /**\n * Factory function to create the server instance.\n * Defaults to Bun.serve.\n * @deprecated Use `adapter` instead.\n */\n serverFactory: ServerFactory;\n\n /**\n * The server adapter to use.\n * overrides `serverFactory`.\n */\n adapter?: 'bun' | 'node' | 'wintercg' | ServerAdapter;\n\n /**\n * The file system adapter to use for `ctx.file`.\n */\n fileSystem?: FileSystemAdapter;\n\n /**\n * Lifecycle hooks.\n */\n hooks: ShokupanHooks<T> | ShokupanHooks<T>[];\n\n /**\n * Whether to validate response status codes.\n * @default true\n */\n validateStatusCodes: boolean;\n\n /**\n * Configuration for SurrealDB.\n */\n surreal?: {\n /**\n * SurrealDB engines.\n * @default Embedded\n */\n engines?: Engines;\n /**\n * SurrealDB connection URL.\n * @default 'rocksdb://database'\n */\n url?: string;\n /**\n * SurrealDB connection options.\n */\n connectOptions?: ConnectOptions;\n /**\n * SurrealDB namespace.\n */\n namespace?: string;\n /**\n * SurrealDB database.\n */\n database?: string;\n };\n\n /**\n * Configuration for the AI Plugin manifest (.well-known/ai-plugin.json).\n * If enabled, Shokupan will serve the manifest at the standard location.\n */\n aiPlugin?: {\n enabled?: boolean;\n name_for_human?: string;\n name_for_model?: string;\n description_for_human?: string;\n description_for_model?: string;\n auth?: {\n type: 'none' | 'service_http' | 'user_http' | 'oauth';\n [key: string]: any;\n };\n api?: {\n type: 'openapi';\n url?: string;\n is_user_authenticated?: boolean;\n };\n logo_url?: string;\n contact_email?: string;\n legal_info_url?: string;\n };\n\n /**\n * Configuration for the API Catalog (.well-known/api-catalog).\n * If enabled, Shokupan will serve the catalog at the standard location.\n */\n apiCatalog?: {\n enabled?: boolean;\n versions?: Array<{\n name: string;\n url: string;\n spec_url: string;\n }>;\n };\n\n /**\n * Configuration for Security Headers.\n * Can be a boolean to enable/disable defaults, or an object options.\n * @default false\n */\n defaultSecurityHeaders?: boolean | any;\n\n /**\n * Any other config options are allowed, but will be ignored. \n * @deprecated\n */\n [key: string]: any;\n}>;\n\n\nexport interface RequestOptions {\n path?: string;\n url?: string;\n method?: Method;\n headers?: Record<string, string>;\n body?: any;\n query?: Record<string, string>;\n}\n\nexport interface ProcessResult {\n status: number;\n headers: Record<string, string>;\n data: any;\n}\n\nexport type ShokupanController<T = any> = (new (...args: any[]) => T) & {\n [$isRouter]?: undefined;\n};\n\nexport interface StaticServeHooks<T extends Record<string, any>> {\n onRequest?: (ctx: ShokupanContext<T>) => Promise<Response | void> | Response | void;\n onResponse?: (ctx: ShokupanContext<T>, response: Response) => Promise<Response> | Response;\n}\n\nexport interface StaticServeOptions<T extends Record<string, any>> {\n /**\n * Root directory to serve files from.\n * Can be an absolute path or relative to the CWD.\n */\n root?: string;\n /**\n * Whether to list directory contents if no index file is found.\n * \n * Security Note: Directory listing is disabled by default to prevent information disclosure.\n * Enable this only if you specifically need it and understand the security implications.\n * \n * @default false\n */\n listDirectory?: boolean;\n /**\n * Index file(s) to look for when a directory is requested.\n * @default ['index.html', 'index.htm']\n */\n index?: string | string[];\n /**\n * Hooks to intercept requests/responses.\n */\n hooks?: StaticServeHooks<T>;\n /**\n * How to treat dotfiles (files starting with .)\n * 'allow': Serve them\n * 'deny': Return 403\n * 'ignore': Return 404\n * @default 'ignore'\n */\n dotfiles?: 'allow' | 'deny' | 'ignore';\n /**\n * Regex or glob patterns to exclude\n */\n exclude?: (string | RegExp)[];\n /**\n * Try to append these extensions to the path if the file is not found.\n * e.g. ['html', 'htm']\n */\n extensions?: string[];\n /**\n * OpenAPI specification for the static route.\n */\n openapi?: MethodAPISpec;\n}\n","\nimport { ShokupanContext } from '../context';\nimport { compose } from '../middleware';\nimport { traceHandler } from '../plugins/application/opentelemetry';\nimport { ResilienceFactory } from '../plugins/resilience/factory';\nimport type { ShokupanRouter } from '../router';\nimport { Container } from './di';\nimport { getCallerInfo } from './stack';\nimport {\n $controllerPath,\n $eventMethods,\n $isMounted,\n $mcpPrompts,\n $mcpResources,\n $mcpTools,\n $middleware,\n $mountPath,\n $resilienceConfig,\n $routeArgs,\n $routeMethods,\n $routeSpec\n} from './symbol';\nimport { HTTPMethods, type Method, RouteParamType } from './types';\n\nexport class ControllerScanner {\n public static scan<T extends Record<string, any>>(router: ShokupanRouter<T>, prefix: string, controller: any) {\n let instance = controller;\n if (typeof controller === 'function') {\n // DI Resolution\n instance = Container.resolve(controller as any);\n\n // Controller Parameter Decorator (@Controller('prefix'))\n const controllerPath = (controller as any)[$controllerPath];\n if (controllerPath !== undefined) {\n // Combine mount prefix + controller path\n const p1 = prefix.endsWith(\"/\") ? prefix.slice(0, -1) : prefix;\n const p2 = controllerPath.startsWith(\"/\") ? controllerPath : \"/\" + controllerPath;\n prefix = (p1 + p2);\n // Normalize\n if (!prefix) prefix = \"/\";\n }\n }\n else {\n // Controller is an instance, read metadata from constructor\n const ctor = instance.constructor;\n const controllerPath = (ctor as any)[$controllerPath];\n if (controllerPath !== undefined) {\n const p1 = prefix.endsWith(\"/\") ? prefix.slice(0, -1) : prefix;\n const p2 = controllerPath.startsWith(\"/\") ? controllerPath : \"/\" + controllerPath;\n prefix = (p1 + p2);\n if (!prefix) prefix = \"/\";\n }\n }\n\n instance[$mountPath] = prefix;\n\n // Capture metadata for controller instance\n const info = getCallerInfo();\n (instance as any).metadata = {\n file: info.file,\n line: info.line,\n name: instance.constructor.name\n };\n\n router.bindController(instance);\n\n // Get Middleware for Controller\n const controllerMiddleware = (typeof controller === 'function' ? (controller as any)[$middleware] : (instance as any)[$middleware]) || [];\n\n // Get all method names from the prototype (for classes)\n const proto = Object.getPrototypeOf(instance);\n const methods = new Set<string>();\n\n // Scan prototype chain\n let current = proto;\n while (current !== undefined && current !== Object.prototype) {\n Object.getOwnPropertyNames(current).forEach(name => methods.add(name));\n current = Object.getPrototypeOf(current);\n }\n // Also scan own properties (for objects or bound methods)\n Object.getOwnPropertyNames(instance).forEach(name => methods.add(name));\n\n const decoratedRoutes = (instance as any)[$routeMethods] || (proto && (proto as any)[$routeMethods]);\n const decoratedArgs = (instance as any)[$routeArgs] || (proto && (proto as any)[$routeArgs]);\n const methodMiddlewareMap = (instance as any)[$middleware] || (proto && (proto as any)[$middleware]);\n const decoratedEvents = (instance as any)[$eventMethods] || (proto && (proto as any)[$eventMethods]);\n const mcpTools = (instance as any)[$mcpTools] || (proto && (proto as any)[$mcpTools]);\n const mcpPrompts = (instance as any)[$mcpPrompts] || (proto && (proto as any)[$mcpPrompts]);\n\n const mcpResources = (instance as any)[$mcpResources] || (proto && (proto as any)[$mcpResources]);\n const resilienceConfigMap = (instance as any)[$resilienceConfig] || (proto && (proto as any)[$resilienceConfig]);\n\n let routesAttached = 0;\n for (let i = 0; i < Array.from(methods).length; i++) {\n const name = Array.from(methods)[i];\n if (name === \"constructor\") continue;\n if ([\"arguments\", \"caller\", \"callee\"].includes(name)) continue;\n\n const originalHandler = (instance as any)[name];\n if (typeof originalHandler !== \"function\") continue;\n\n let method: Method | undefined;\n let subPath = \"\";\n\n // 1. Check for Decorator Metadata\n let methodSource: { file: string, line: number; } | undefined;\n\n const routeConfig = decoratedRoutes?.get(name);\n if (routeConfig !== undefined) {\n method = routeConfig.method;\n subPath = routeConfig.path;\n methodSource = routeConfig.source;\n }\n // 2. Fallback to Convention\n else {\n // Check if name starts with HTTP verb\n for (let j = 0; j < HTTPMethods.length; j++) {\n const m = HTTPMethods[j];\n if (name.toUpperCase().startsWith(m)) {\n method = m as Method;\n const rest = name.slice(m.length);\n if (rest.length === 0) {\n subPath = \"/\";\n }\n else {\n subPath = \"\";\n let buffer = \"\";\n const flush = () => {\n if (buffer.length > 0) {\n subPath += \"/\" + buffer.toLowerCase();\n buffer = \"\";\n }\n };\n for (let i = 0; i < rest.length; i++) {\n const char = rest[i];\n if (char === \"$\") {\n flush();\n subPath += \"/:\";\n continue;\n }\n buffer += char;\n }\n if (buffer.length > 0) flush();\n\n subPath = rest\n .replace(/\\$/g, \"/:\") // $id -> /:id\n .replace(/([a-z0-9])([A-Z])/g, \"$1/$2\") // camelCase -> camel/Case\n .toLowerCase();\n\n if (!subPath.startsWith(\"/\")) {\n subPath = \"/\" + subPath;\n }\n }\n break;\n }\n }\n }\n\n // Skip empty methods\n if (method !== undefined && (method as any) !== '') {\n routesAttached++;\n const cleanPrefix = prefix.endsWith(\"/\") ? prefix.slice(0, -1) : prefix;\n const cleanSubPath = subPath === \"/\" ? \"\" : subPath;\n\n let joined: string;\n if (cleanSubPath.length === 0) {\n joined = cleanPrefix;\n }\n else if (cleanSubPath.startsWith(\"/\")) {\n joined = cleanPrefix + cleanSubPath;\n }\n else {\n joined = cleanPrefix + \"/\" + cleanSubPath;\n }\n\n const fullPath = joined || \"/\";\n const normalizedPath = fullPath.replace(/\\/+/g, \"/\");\n\n // -- Compose Handler with Middleware and Param Resolution --\n const methodMw = (methodMiddlewareMap instanceof Map) ? (methodMiddlewareMap.get(name) || []) : [];\n const allMiddleware = [...controllerMiddleware, ...methodMw];\n\n // Check for Args\n const routeArgs = decoratedArgs && decoratedArgs.get(name);\n\n // Create Wrapper\n const wrappedHandler = async (ctx: ShokupanContext<T>) => {\n // Resolve Arguments\n let args: any[] = [ctx];\n\n if (routeArgs?.length > 0) {\n args = [];\n // Sort by index\n const sortedArgs = [...routeArgs].sort((a: any, b: any) => a.index - b.index);\n\n // Fill args array\n for (let k = 0; k < sortedArgs.length; k++) {\n const arg = sortedArgs[k];\n switch (arg.type) {\n case RouteParamType.BODY:\n args[arg.index] = await ctx.body();\n break;\n case RouteParamType.PARAM:\n args[arg.index] = arg.name ? ctx.params[arg.name] : ctx.params;\n break;\n case RouteParamType.QUERY: {\n const url = new URL(ctx.req.url);\n if (arg.name) {\n const vals = url.searchParams.getAll(arg.name);\n args[arg.index] = vals.length > 1 ? vals : vals[0];\n } else {\n const query: Record<string, any> = {};\n const keys = Object.keys(url.searchParams);\n for (let k = 0; k < keys.length; k++) {\n const key = keys[k];\n const vals = url.searchParams.getAll(key);\n query[key] = vals.length > 1 ? vals : vals[0];\n }\n args[arg.index] = query;\n }\n break;\n }\n case RouteParamType.HEADER:\n args[arg.index] = arg.name ? ctx.req.headers.get(arg.name) : ctx.req.headers;\n break;\n case RouteParamType.REQUEST:\n args[arg.index] = ctx.req;\n break;\n case RouteParamType.CONTEXT:\n args[arg.index] = ctx;\n break;\n case RouteParamType.SERVICE:\n args[arg.index] = Container.resolve(arg.token);\n break;\n }\n }\n }\n\n const tracedOriginalHandler = ctx.app?.applicationConfig.enableTracing\n ? traceHandler(originalHandler, normalizedPath)\n : originalHandler;\n\n return tracedOriginalHandler.apply(instance, args);\n };\n\n // Apply Middleware wrapping\n let finalHandler = wrappedHandler;\n if (allMiddleware.length > 0) {\n const composed = compose(allMiddleware);\n finalHandler = async (ctx) => {\n return composed(ctx, () => wrappedHandler(ctx));\n };\n }\n\n // Resilience Policy Wrapping\n const config = resilienceConfigMap?.get(name);\n if (config) {\n const policy = ResilienceFactory.createPolicy(config);\n const baseHandler = finalHandler;\n finalHandler = async (ctx) => {\n return policy.execute(() => baseHandler(ctx));\n };\n }\n\n (finalHandler as any).originalHandler = originalHandler;\n if (finalHandler !== wrappedHandler) {\n (wrappedHandler as any).originalHandler = originalHandler;\n }\n\n // Inject Controller Name as Tag\n const tagName = instance.constructor.name;\n\n // Retrieve @Spec metadata\n const decoratedSpecs = (instance as any)[$routeSpec] || (proto && (proto as any)[$routeSpec]);\n const userSpec = decoratedSpecs && decoratedSpecs.get(name);\n\n // Merge with existing spec from decorator if available\n const spec = { tags: [tagName], ...userSpec };\n\n router.add({\n method,\n path: normalizedPath,\n handler: finalHandler,\n spec,\n controller: instance,\n metadata: methodSource || (instance as any).metadata,\n middleware: allMiddleware\n });\n }\n\n // 3. Check for Event Decorator\n const eventConfig = decoratedEvents?.get(name);\n if (eventConfig !== undefined) {\n routesAttached++;\n const routeArgs = decoratedArgs?.get(name);\n\n const wrappedHandler = async (ctx: ShokupanContext<T>) => {\n let args: any[] = [ctx];\n if (routeArgs?.length > 0) {\n args = [];\n const sortedArgs = [...routeArgs].sort((a: any, b: any) => a.index - b.index);\n for (let k = 0; k < sortedArgs.length; k++) {\n const arg = sortedArgs[k];\n switch (arg.type) {\n case RouteParamType.BODY:\n args[arg.index] = await ctx.body();\n break;\n case RouteParamType.CONTEXT:\n args[arg.index] = ctx;\n break;\n case RouteParamType.REQUEST:\n args[arg.index] = ctx.req;\n break;\n case RouteParamType.HEADER:\n args[arg.index] = arg.name ? ctx.req.headers.get(arg.name) : ctx.req.headers;\n break;\n default:\n args[arg.index] = undefined;\n }\n }\n }\n return originalHandler.apply(instance, args);\n };\n\n // Attach metadata to the handler for AsyncAPI generator\n const decoratedSpecs = (instance as any)[$routeSpec] || (proto && (proto as any)[$routeSpec]);\n const userSpec = decoratedSpecs && decoratedSpecs.get(name);\n\n const spec = { tags: [{ name: instance.constructor.name }], ...userSpec };\n (wrappedHandler as any).spec = spec;\n (wrappedHandler as any).originalHandler = originalHandler;\n\n router.event(eventConfig.eventName, wrappedHandler);\n }\n\n // 4. Check for MCP Tools\n const toolConfig = mcpTools?.get(name);\n if (toolConfig) {\n const handler = originalHandler.bind(instance);\n router.tool(toolConfig.name || name, toolConfig.inputSchema, handler);\n }\n\n // 5. Check for MCP Prompts\n const promptConfig = mcpPrompts?.get(name);\n if (promptConfig) {\n const handler = originalHandler.bind(instance);\n router.prompt(promptConfig.name || name, promptConfig.arguments, handler);\n }\n\n // 6. Check for MCP Resources\n const resourceConfig = mcpResources?.get(name);\n if (resourceConfig) {\n const handler = originalHandler.bind(instance);\n router.resource(resourceConfig.uri, {\n name: resourceConfig.name || name,\n description: resourceConfig.description,\n mimeType: resourceConfig.mimeType\n }, handler);\n }\n }\n\n if (routesAttached === 0) {\n console.warn(`No routes attached to controller ${instance.constructor.name}`);\n }\n instance[$isMounted] = true;\n }\n}\n","/**\n * Standard HTTP Error class with status code.\n * This standardizes on the `status` property instead of dual `status`/`statusCode`.\n */\nexport class HttpError extends Error {\n public readonly status: number;\n\n constructor(message: string, status: number) {\n super(message);\n this.name = 'HttpError';\n this.status = status;\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, HttpError);\n }\n }\n}\n\n/**\n * Extracts HTTP status code from an error object.\n * Supports both `status` and `statusCode` properties for backward compatibility.\n * Defaults to 500 (Internal Server Error) if no status is found.\n * \n * @param err - Error object (may have `status` or `statusCode` property)\n * @returns HTTP status code\n */\nexport function getErrorStatus(err: any): number {\n // Handle null/undefined\n if (!err || typeof err !== 'object') {\n return 500;\n }\n\n // Prioritize `status` over `statusCode` to encourage standardization\n if (typeof err.status === 'number') {\n return err.status;\n }\n if (typeof err.statusCode === 'number') {\n return err.statusCode;\n }\n // Default to 500 Internal Server Error\n return 500;\n}\n\n/**\n * Common HTTP Errors\n */\n\nexport class BadRequestError extends HttpError {\n constructor(message: string = 'Bad Request') {\n super(message, 400);\n this.name = 'BadRequestError';\n }\n}\n\nexport class UnauthorizedError extends HttpError {\n constructor(message: string = 'Unauthorized') {\n super(message, 401);\n this.name = 'UnauthorizedError';\n }\n}\n\nexport class ForbiddenError extends HttpError {\n constructor(message: string = 'Forbidden') {\n super(message, 403);\n this.name = 'ForbiddenError';\n }\n}\n\nexport class NotFoundError extends HttpError {\n constructor(message: string = 'Not Found') {\n super(message, 404);\n this.name = 'NotFoundError';\n }\n}\n\nexport class InternalServerError extends HttpError {\n constructor(message: string = 'Internal Server Error') {\n super(message, 500);\n this.name = 'InternalServerError';\n }\n}\n\nexport class EventError extends HttpError {\n constructor(message: string = 'Event Error') {\n super(message, 500);\n this.name = 'EventError';\n }\n}\n","\nexport interface JsonRpcRequest {\n jsonrpc: \"2.0\";\n id?: string | number | null;\n method: string;\n params?: any;\n}\n\nexport interface JsonRpcResponse {\n jsonrpc: \"2.0\";\n id: string | number | null;\n result?: any;\n error?: {\n code: number;\n message: string;\n data?: any;\n };\n}\n\nexport interface McpTool {\n name: string;\n description?: string;\n inputSchema?: any;\n handler: (args: any) => Promise<any> | any;\n}\n\nexport interface McpPrompt {\n name: string;\n description?: string;\n arguments?: {\n name: string;\n description?: string;\n required?: boolean;\n }[];\n handler: (args: any) => Promise<any> | any;\n}\n\nexport interface McpResource {\n uri: string; // glob pattern or direct uri\n name?: string;\n description?: string;\n mimeType?: string;\n handler: (uri: string, args?: any) => Promise<any> | any;\n}\n\nexport class McpProtocol {\n private tools = new Map<string, McpTool>();\n private prompts = new Map<string, McpPrompt>();\n private resources = new Map<string, McpResource>();\n\n constructor(\n tools: McpTool[] = [],\n prompts: McpPrompt[] = [],\n resources: McpResource[] = []\n ) {\n tools.forEach(t => this.tools.set(t.name, t));\n prompts.forEach(p => this.prompts.set(p.name, p));\n resources.forEach(r => this.resources.set(r.uri, r));\n }\n\n public addTool(tool: McpTool) {\n this.tools.set(tool.name, tool);\n }\n\n public addPrompt(prompt: McpPrompt) {\n this.prompts.set(prompt.name, prompt);\n }\n\n public addResource(resource: McpResource) {\n this.resources.set(resource.uri, resource);\n }\n\n public merge(other: McpProtocol) {\n other.tools.forEach(t => this.tools.set(t.name, t));\n other.prompts.forEach(p => this.prompts.set(p.name, p));\n other.resources.forEach(r => this.resources.set(r.uri, r));\n }\n\n public async handleMessage(message: JsonRpcRequest): Promise<JsonRpcResponse | null> {\n if (message.jsonrpc !== \"2.0\") {\n return this.error(message.id, -32600, \"Invalid Request\");\n }\n\n try {\n switch (message.method) {\n case \"initialize\":\n return this.success(message.id, {\n protocolVersion: \"2024-11-05\",\n serverInfo: {\n name: \"Shokupan MCP\",\n version: \"1.0.0\"\n },\n capabilities: {\n tools: this.tools.size > 0 ? {} : undefined,\n prompts: this.prompts.size > 0 ? {} : undefined,\n resources: this.resources.size > 0 ? {} : undefined,\n }\n });\n\n case \"ping\":\n return this.success(message.id, {});\n\n case \"tools/list\":\n if (this.tools.size === 0) return this.success(message.id, { tools: [] });\n return this.success(message.id, {\n tools: Array.from(this.tools.values()).map(t => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema || { type: \"object\", properties: {} }\n }))\n });\n\n case \"tools/call\": {\n if (!message.params || !message.params.name) {\n return this.error(message.id, -32602, \"Invalid params: name required\");\n }\n const tool = this.tools.get(message.params.name);\n if (!tool) {\n return this.error(message.id, -32601, `Tool not found: ${message.params.name}`);\n }\n try {\n const result = await tool.handler(message.params.arguments || {});\n return this.success(message.id, result);\n } catch (e: any) {\n return {\n jsonrpc: \"2.0\",\n id: message.id ?? null,\n result: {\n isError: true,\n content: [{ type: \"text\", text: e.message || String(e) }]\n }\n };\n }\n }\n\n case \"prompts/list\":\n if (this.prompts.size === 0) return this.success(message.id, { prompts: [] });\n return this.success(message.id, {\n prompts: Array.from(this.prompts.values()).map(p => ({\n name: p.name,\n description: p.description,\n arguments: p.arguments\n }))\n });\n\n case \"prompts/get\": {\n if (!message.params || !message.params.name) {\n return this.error(message.id, -32602, \"Invalid params: name required\");\n }\n const prompt = this.prompts.get(message.params.name);\n if (!prompt) {\n return this.error(message.id, -32601, `Prompt not found: ${message.params.name}`);\n }\n const result = await prompt.handler(message.params.arguments || {});\n return this.success(message.id, result);\n }\n\n case \"resources/list\":\n if (this.resources.size === 0) return this.success(message.id, { resources: [] });\n return this.success(message.id, {\n resources: Array.from(this.resources.values()).map(r => ({\n uri: r.uri,\n name: r.name,\n description: r.description,\n mimeType: r.mimeType\n }))\n });\n\n case \"resources/read\": {\n if (!message.params || !message.params.uri) {\n return this.error(message.id, -32602, \"Invalid params: uri required\");\n }\n // For now, exact match or simple check. Glob matching would require explicit support.\n // Assuming simplified implementation where we iterate and find handler.\n let resource = this.resources.get(message.params.uri);\n\n // Fallback to finding a matching handler if glob (simplified)\n // In a real implementation we might want a better router for resources\n // But here we rely on the registration.\n\n if (!resource) {\n return this.error(message.id, -32601, `Resource not found: ${message.params.uri}`);\n }\n\n const result = await resource.handler(message.params.uri);\n return this.success(message.id, result);\n }\n\n default:\n // Notifications (no id) should just return null\n if (message.id === undefined) return null;\n return this.error(message.id, -32601, \"Method not found\");\n }\n } catch (err: any) {\n return this.error(message.id, -32603, \"Internal Error\", err.message);\n }\n }\n\n private success(id: string | number | undefined | null, result: any): JsonRpcResponse {\n return {\n jsonrpc: \"2.0\",\n id: id ?? null,\n result\n };\n }\n\n private error(id: string | number | undefined | null, code: number, message: string, data?: any): JsonRpcResponse {\n return {\n jsonrpc: \"2.0\",\n id: id ?? null,\n error: { code, message, data }\n };\n }\n}\n","\nimport type { Middleware, ShokupanHandler } from '../util/types';\n\nexport class MiddlewareTracker {\n public static wrap(\n handler: Middleware | ShokupanHandler<any>,\n context: { file: string, line: number, name?: string, isBuiltin?: boolean, pluginName?: string; }\n ): any {\n const { file, line, name, isBuiltin, pluginName } = context;\n const handlerName = name || handler.name || 'anonymous';\n\n // Direct Metadata Attachment (No Layout/Wrapper Overhead)\n // We mutate the handler if possible to avoid creating a closure.\n // If the handler is reused, the last registration's metadata wins.\n try {\n (handler as any).metadata = context;\n\n // Allow name to be set if configurable\n if (!handler.name || handler.name === 'anonymous') {\n try {\n Object.defineProperty(handler, 'name', { value: handlerName, configurable: true });\n } catch (e) { }\n }\n } catch (e) {\n // Function might be frozen or non-extensible\n // In this rare case, we might return a lightweight wrapper or proxy,\n // but for now, let's just return it as is or log a warning.\n // A lightweight wrapper using bind might work:\n const wrapped = handler.bind(null);\n (wrapped as any).metadata = context;\n Object.defineProperty(wrapped, 'name', { value: handlerName });\n (wrapped as any).originalHandler = (handler as any).originalHandler || handler;\n return wrapped;\n }\n\n return handler;\n }\n}\n","import type { Method } from './types';\n\nexport type ShokupanRequestProps = {\n method: Method;\n url: string;\n headers: Headers | Record<string, string>;\n body: any;\n};\n\n/**\n * This class is used to create a request object.\n * It is used to make requests to the router.\n */\nclass ShokupanRequestBase {\n method: Method;\n url: string;\n headers: Headers;\n body: any;\n\n async json(): Promise<any> { return JSON.parse(this.body); }\n async text(): Promise<string> { return this.body; }\n async formData(): Promise<FormData> {\n if (this.body instanceof FormData) {\n return this.body;\n }\n return new Response(this.body, { headers: this.headers }).formData() as any;\n }\n\n constructor(props: ShokupanRequestProps) {\n Object.assign(this, props);\n if (!(this.headers instanceof Headers)) {\n this.headers = new Headers(this.headers);\n }\n }\n\n clone(): ShokupanRequest<any> {\n return new ShokupanRequest({\n method: this.method,\n url: this.url,\n headers: new Headers(this.headers),\n body: this.body // Shallow copy of body, might need deep copy if object\n });\n }\n}\n\n/**\n * This type is used to add properties to the request object.\n */\nexport type ShokupanRequest<T> = ShokupanRequestBase & T;\n\ninterface ShokupanConstructor {\n new <T extends Record<string, any>>(props: ShokupanRequestProps): ShokupanRequest<T>;\n}\n\n/**\n * This class is used to create a request object.\n * It is used to make requests to the router.\n */\nexport const ShokupanRequest = ShokupanRequestBase as ShokupanConstructor;\n","import type { Method, ShokupanHandler } from './types';\n\nexport interface RouteMatch<T = any> {\n handler: ShokupanHandler<T>;\n params: Record<string, string>;\n // Reference to the baked handler if strictly needed, \n // but typically we insert the optimal handler (baked) into the trie.\n}\n\ninterface Node<T> {\n // Static path segments\n children: Record<string, Node<T>>;\n\n // Parameter segment (e.g. :id)\n paramChild?: Node<T>;\n paramName?: string;\n\n // Wildcard segment (*)\n wildcardChild?: Node<T>;\n\n // Recursive segment (**)\n recursiveChild?: Node<T>;\n\n // Handlers stored at this node\n handlers?: Record<string, ShokupanHandler<T>>;\n\n // Optional: Keep track of path pattern for debugging\n pathPattern?: string;\n}\n\nexport class RouterTrie<T = any> {\n private root: Node<T>;\n\n constructor() {\n this.root = this.createNode();\n }\n\n private createNode(): Node<T> {\n return {\n children: {},\n };\n }\n\n public insert(method: Method, path: string, handler: ShokupanHandler<T>) {\n let node = this.root;\n const segments = this.splitPath(path);\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n if (segment === '**') {\n if (!node.recursiveChild) {\n node.recursiveChild = this.createNode();\n }\n node = node.recursiveChild;\n }\n else if (segment === '*') {\n if (!node.wildcardChild) {\n node.wildcardChild = this.createNode();\n }\n node = node.wildcardChild;\n }\n else if (segment.startsWith(':')) {\n const paramName = segment.slice(1);\n if (!node.paramChild) {\n node.paramChild = this.createNode();\n node.paramChild.paramName = paramName;\n }\n node = node.paramChild;\n node.paramName = paramName;\n }\n else {\n if (!node.children[segment]) {\n node.children[segment] = this.createNode();\n }\n node = node.children[segment];\n }\n }\n\n if (!node.handlers) {\n node.handlers = {};\n }\n node.handlers[method] = handler;\n }\n\n public search(method: string, path: string): RouteMatch<T> | null {\n const segments = this.splitPath(path);\n const params: Record<string, string> = {};\n\n const match = this.findNode(this.root, segments, 0, params);\n\n if (match && match.handlers) {\n const handler = match.handlers[method] || match.handlers['ALL'];\n if (handler) {\n return { handler, params };\n }\n if (method === 'HEAD' && match.handlers['GET']) {\n return { handler: match.handlers['GET'], params };\n }\n }\n\n return null;\n }\n\n private findNode(node: Node<T>, segments: string[], index: number, params: Record<string, string>): Node<T> | null {\n // Base case: verified all segments\n if (index === segments.length) {\n if (node.handlers) return node;\n\n // If we are at the end, checks if we have a recursive child that matches empty?\n // e.g. /files/** matches /files\n if (node.recursiveChild && node.recursiveChild.handlers) {\n return node.recursiveChild;\n }\n return null;\n }\n\n const segment = segments[index];\n\n // 1. Static Match\n const child = node.children[segment];\n if (child) {\n const result = this.findNode(child, segments, index + 1, params);\n if (result) return result;\n }\n\n // 2. Param Match\n if (node.paramChild) {\n params[node.paramChild.paramName!] = segment;\n const result = this.findNode(node.paramChild, segments, index + 1, params);\n if (result) return result;\n delete params[node.paramChild.paramName!];\n }\n\n // 3. Single Wildcard Match (*)\n if (node.wildcardChild) {\n // Strictly match one segment\n const result = this.findNode(node.wildcardChild, segments, index + 1, params);\n if (result) return result;\n }\n\n // 4. Recursive Wildcard Match (**)\n if (node.recursiveChild) {\n // Greedy or non-greedy?\n // We need to match 'remaining segments' against recursive child.\n // But recursive child is a Node that might have further structure OR be terminal.\n\n // Try matching 0 to N segments.\n // We iterate from N down to 0 (greedy) or 0 to N?\n // Standard is usually longest match wins? Or first match?\n // \"Correct\" catch-all usually means it consumes as much as needed.\n // Let's try consuming k segments.\n\n const remaining = segments.length - index;\n for (let k = 0; k <= remaining; k++) {\n // Skip k segments\n const result = this.findNode(node.recursiveChild, segments, index + k, params);\n if (result) return result;\n }\n }\n\n return null;\n }\n\n private splitPath(path: string): string[] {\n if (path === '/' || path === '') return [];\n const s = path.startsWith('/') ? path.slice(1) : path;\n if (s === '') return [];\n return s.split('/');\n }\n}\n","import { ShokupanContext } from './context';\nimport { compose } from './middleware';\nimport { generateOpenApi } from './plugins/application/openapi/openapi';\nimport { serveStatic } from './plugins/middleware/serve-static';\nimport type { Shokupan } from './shokupan';\nimport { ControllerScanner } from './util/controller-scanner';\nimport { EventError, getErrorStatus } from './util/http-error';\nimport { HTTP_STATUS } from './util/http-status';\nimport { McpProtocol, type McpPrompt } from './util/mcp-protocol';\nimport { MiddlewareTracker } from './util/middleware-tracker';\nimport { ShokupanRequest } from './util/request';\nimport { getCallerInfo } from './util/stack';\nimport { $appRoot, $childControllers, $childRouters, $debug, $dispatch, $isApplication, $isMounted, $isRouter, $mountPath, $parent, $routes } from './util/symbol';\nimport { RouterTrie } from './util/trie';\nimport { type GuardAPISpec, type HeadersInit, type JSXRenderer, type Method, type MethodAPISpec, type Middleware, type OpenAPIOptions, type ProcessResult, type RequestOptions, type RouteMetadata, type RouteParams, type ShokupanController, type ShokupanHandler, type ShokupanHooks, type ShokupanRoute, type ShokupanRouteConfig, type StaticServeOptions } from './util/types';\n\n\nexport const RouterRegistry = new Map<string, ShokupanRouter<any>>();\n\nexport const ShokupanApplicationTree = {};\n\n/**\n * Shokupan Router\n * \n * A router for organizing and grouping routes with shared middleware and configuration.\n * \n * @template State - The shape of `ctx.state` for all routes in this router.\n * Provides type safety for state management within the router's middleware and handlers.\n * \n * @example Basic Router\n * ```typescript\n * const router = new ShokupanRouter();\n * router.get('/users', (ctx) => ctx.json({ users: [] }));\n * \n * app.mount('/api', router);\n * // Routes: GET /api/users\n * ```\n * \n * @example Typed State Router\n * ```typescript\n * interface AuthState {\n * userId: string;\n * isAuthenticated: boolean;\n * }\n * \n * class AuthRouter extends ShokupanRouter<AuthState> {\n * constructor() {\n * super();\n * \n * // Router middleware has typed state\n * this.use((ctx, next) => {\n * ctx.state.userId = 'user-123';\n * ctx.state.isAuthenticated = true;\n * return next();\n * });\n * \n * this.get('/me', (ctx) => {\n * // State is fully typed\n * return ctx.json({ userId: ctx.state.userId });\n * });\n * }\n * }\n * \n * app.mount('/auth', new AuthRouter());\n * ```\n * \n * @example Router with Middleware\n * ```typescript\n * const apiRouter = new ShokupanRouter();\n * \n * // Router-level middleware\n * apiRouter.use(async (ctx, next) => {\n * console.log(`API request: ${ctx.method} ${ctx.path}`);\n * return next();\n * });\n * \n * apiRouter.get('/status', (ctx) => ctx.json({ status: 'ok' }));\n * app.mount('/api', apiRouter);\n * ```\n */\nexport class ShokupanRouter<T extends Record<string, any> = Record<string, any>> {\n // Internal marker to identify Router vs. Application\n private [$isApplication]: boolean = false;\n private [$isMounted]: boolean = false;\n private [$isRouter]: true = true;\n private [$appRoot]: Shokupan;\n public [$mountPath]: string = \"/\"; // Public via Symbol for OpenAPI generator\n\n private [$parent]: ShokupanRouter<T> | null = null;\n public [$childRouters]: ShokupanRouter<T>[] = [];\n public [$childControllers]: ShokupanController[] = [];\n\n private _hasOnResponseEndHook: boolean;\n private _hasOnRequestStartHook: boolean;\n private _hasOnRequestEndHook: boolean;\n private _hasOnResponseStartHook: boolean;\n private _hasOnErrorHook: boolean;\n private _hasOnRequestTimeoutHook: boolean;\n private _hasOnReadTimeoutHook: boolean;\n private _hasOnWriteTimeoutHook: boolean;\n private _hasBeforeValidateHook: boolean;\n private _hasAfterValidateHook: boolean;\n get hasOnResponseEndHook() { return this._hasOnResponseEndHook; };\n get hasOnRequestStartHook() { return this._hasOnRequestStartHook; };\n get hasOnRequestEndHook() { return this._hasOnRequestEndHook; };\n get hasOnResponseStartHook() { return this._hasOnResponseStartHook; };\n get hasOnErrorHook() { return this._hasOnErrorHook; };\n get hasOnRequestTimeoutHook() { return this._hasOnRequestTimeoutHook; };\n get hasOnReadTimeoutHook() { return this._hasOnReadTimeoutHook; };\n get hasOnWriteTimeoutHook() { return this._hasOnWriteTimeoutHook; };\n get hasBeforeValidateHook() { return this._hasBeforeValidateHook; };\n get hasAfterValidateHook() { return this._hasAfterValidateHook; };\n\n public requestTimeout?: number;\n\n\n\n private hookCache = new Map<keyof ShokupanHooks, Function[]>();\n private hooksInitialized: boolean = false;\n\n public middleware: Middleware[] = [];\n\n get rootConfig() {\n return this[$appRoot]?.applicationConfig;\n }\n get root() {\n return this[$appRoot];\n }\n\n public [$routes]: ShokupanRoute[] = []; // Public via Symbol for OpenAPI generator\n private trie = new RouterTrie<T>();\n public metadata?: RouteMetadata; // Metadata for the router itself\n\n public mcpProtocol = new McpProtocol();\n\n private currentGuards: { handler: ShokupanHandler<T>; spec?: GuardAPISpec; }[] = [];\n private eventHandlers = new Map<string, ShokupanHandler<T>[]>();\n\n /**\n * Registers middleware for this router.\n * Middleware will run for all routes matched by this router.\n */\n public use(middleware: Middleware) {\n // Basic middleware registration\n this.middleware.push(middleware);\n return this;\n }\n\n\n // Registry Accessor\n public get registry(): {\n metadata: RouteMetadata,\n middleware: { name: string, metadata: RouteMetadata, order: number, _fn: Middleware; }[],\n routes: { type: 'route', path: string, method: Method, metadata: RouteMetadata, handlerName: string, tags: string[], order: number, _fn: ShokupanHandler<T>; }[],\n routers: { type: 'router', path: string, metadata: RouteMetadata, children: { routes: any[]; }; }[],\n controllers: { type: 'controller', path: string, name: string, metadata: RouteMetadata; children: { routes: any[]; }; }[];\n events: { type: 'event', name: string, handlerName: string, metadata: RouteMetadata; _fn: ShokupanHandler<T>; }[];\n } {\n // Separation logic: Group routes by controller instance\n const controllerRoutesMap = new Map<any, any[]>();\n const localRoutes: any[] = [];\n\n for (let i = 0; i < this[$routes].length; i++) {\n const r = this[$routes][i];\n const entry = {\n type: 'route' as 'route',\n path: r.path.startsWith('/') ? r.path : '/' + r.path,\n method: r.method,\n metadata: r.metadata,\n handlerName: r.handler.name,\n tags: r.handlerSpec?.tags,\n order: r.order,\n _fn: r.handler\n };\n\n if (r.controller) {\n if (!controllerRoutesMap.has(r.controller)) {\n controllerRoutesMap.set(r.controller, []);\n }\n controllerRoutesMap.get(r.controller)!.push(entry);\n } else {\n localRoutes.push(entry);\n }\n }\n\n // Collect middleware (if exists, e.g. on Shokupan app)\n const mw = this.middleware;\n const middleware = mw ? mw.map(m => ({\n name: m.name || 'middleware',\n metadata: m.metadata,\n order: m.order,\n _fn: m // Expose function for debugging instrumentation\n })) : [];\n\n // Collect child routers\n const routers = this[$childRouters].map((r: ShokupanRouter<T>) => ({\n type: 'router' as 'router',\n path: r[$mountPath].startsWith('/') ? r[$mountPath] : '/' + r[$mountPath],\n metadata: r.metadata,\n children: r.registry\n }));\n\n // Collect child controllers\n const controllers = this[$childControllers].map((c: ShokupanController<T>) => {\n const routes = controllerRoutesMap.get(c) || [];\n return {\n type: 'controller' as 'controller',\n path: (c as any)[$mountPath] || '/',\n name: c.constructor.name,\n metadata: (c as any).metadata,\n children: { routes }\n };\n });\n\n // Collect event handlers\n const events: any[] = [];\n this.eventHandlers.forEach((handlers, name) => {\n handlers.forEach(h => {\n events.push({\n type: 'event',\n name,\n handlerName: h.name,\n metadata: (h as any).source ? { file: (h as any).source.file, line: (h as any).source.line } : undefined,\n _fn: h\n });\n });\n });\n\n return {\n metadata: this.metadata,\n middleware,\n routes: localRoutes,\n routers,\n controllers,\n events\n };\n }\n\n constructor(\n public readonly config?: ShokupanRouteConfig\n ) {\n if (config?.requestTimeout) {\n this.requestTimeout = config.requestTimeout;\n }\n if (config?.hooks) {\n this.ensureHooksInitialized();\n }\n }\n\n private isRouterInstance(target: any): target is ShokupanRouter<T> {\n // Check if it's an object and has your specific symbol\n return typeof target === 'object' && target !== null && $isRouter in target;\n }\n\n /**\n * Registers an event handler for WebSocket.\n */\n public event(name: string, handler: ShokupanHandler<T>) {\n const info = getCallerInfo();\n (handler as any).source = { file: info.file, line: info.line };\n\n if (this.eventHandlers.has(name)) {\n const err = new EventError(`Event handler \\`${name}\\` already exists.`);\n console.warn(err);\n const handlers = this.eventHandlers.get(name)!;\n handlers.push(handler);\n this.eventHandlers.set(name, handlers);\n }\n else {\n this.eventHandlers.set(name, [handler]);\n }\n return this;\n }\n\n /**\n * Registers a lifecycle hook dynamically.\n */\n public hook(name: keyof ShokupanHooks, handler: Function) {\n if (!this.hooksInitialized) {\n this.ensureHooksInitialized();\n }\n\n let handlers = this.hookCache.get(name);\n if (!handlers) {\n handlers = [];\n this.hookCache.set(name, handlers);\n\n // Set the has hooks flags\n this._hasOnErrorHook ||= name === 'onError';\n this._hasOnRequestStartHook ||= name === 'onRequestStart';\n this._hasOnRequestEndHook ||= name === 'onRequestEnd';\n this._hasOnResponseStartHook ||= name === 'onResponseStart';\n this._hasOnResponseEndHook ||= name === 'onResponseEnd';\n this._hasOnRequestTimeoutHook ||= name === 'onRequestTimeout';\n this._hasOnReadTimeoutHook ||= name === 'onReadTimeout';\n this._hasOnWriteTimeoutHook ||= name === 'onWriteTimeout';\n this._hasBeforeValidateHook ||= name === 'beforeValidate';\n this._hasAfterValidateHook ||= name === 'afterValidate';\n }\n handlers.push(handler);\n return this;\n }\n\n /**\n * Registers an MCP Tool.\n */\n public tool(name: string, schema: any, handler: Function) {\n this.mcpProtocol.addTool({\n name,\n inputSchema: schema,\n handler: handler as any\n });\n return this;\n }\n\n /**\n * Registers an MCP Prompt.\n */\n public prompt(name: string, args: McpPrompt['arguments'], handler: Function) {\n this.mcpProtocol.addPrompt({\n name,\n arguments: args,\n handler: handler as any\n });\n return this;\n }\n\n /**\n * Registers an MCP Resource.\n */\n public resource(uri: string, options: { name?: string; description?: string; mimeType?: string; }, handler: Function) {\n this.mcpProtocol.addResource({\n uri,\n handler: handler as any,\n ...options\n });\n return this;\n }\n\n /**\n * Finds an event handler(s) by name.\n */\n public findEvent(name: string): ShokupanHandler<T>[] | null {\n // Check local\n const handlers = this.eventHandlers.get(name);\n if (handlers !== undefined) {\n return handlers;\n }\n\n // Check children\n for (const child of this[$childRouters]) {\n const handler = child.findEvent(name);\n if (handler) return handler;\n }\n\n return null;\n }\n\n /**\n * Registers a controller instance to the router.\n */\n public bindController(controller: any) {\n this[$childControllers].push(controller);\n }\n\n /**\n * Returns all registered event handlers.\n */\n public getEventHandlers(): Map<string, ShokupanHandler<T>[]> {\n return this.eventHandlers;\n }\n\n /**\n * Mounts a controller instance to a path prefix.\n * \n * Controller can be a convection router or an arbitrary class.\n * \n * Routes are derived from method names:\n * - get(ctx) -> GET /prefix/\n * - getUsers(ctx) -> GET /prefix/users\n * - postCreate(ctx) -> POST /prefix/create\n */\n public mount(prefix: string, controller: ShokupanController | ShokupanController<T> | ShokupanRouter | ShokupanRouter<T> | Record<string, any>) {\n // strict controller check\n const isRouter = this.isRouterInstance(controller);\n const isFunction = typeof controller === 'function';\n const controllersOnly = this.config?.controllersOnly ?? this.rootConfig?.controllersOnly ?? false;\n\n if (controllersOnly && !isFunction && !isRouter) {\n throw new Error(`[Shokupan] strict controller check failed: ${controller.constructor.name || typeof controller} is not a class constructor.`);\n }\n\n if (this.isRouterInstance(controller)) {\n this.mountRouter(prefix, controller);\n }\n // Controller is an arbitrary class\n else {\n ControllerScanner.scan(this, prefix, controller);\n }\n\n return this;\n }\n\n /**\n * Returns all routes attached to this router and its descendants.\n */\n public getRoutes(): { method: Method, path: string, handler: ShokupanHandler<T>; }[] {\n const routes = this[$routes].map(r => ({\n method: r.method,\n path: r.path,\n handler: r.handler\n }));\n\n for (let i = 0; i < this[$childRouters].length; i++) {\n const child = this[$childRouters][i];\n const childRoutes = child.getRoutes();\n for (let j = 0; j < childRoutes.length; j++) {\n const route = childRoutes[j];\n const cleanPrefix = child[$mountPath].endsWith(\"/\") ? child[$mountPath].slice(0, -1) : child[$mountPath];\n const cleanPath = route.path.startsWith(\"/\") ? route.path : \"/\" + route.path;\n const fullPath = (cleanPrefix + cleanPath) || \"/\";\n\n routes.push({\n method: route.method as Method,\n path: fullPath,\n handler: route.handler\n });\n }\n }\n return routes;\n }\n\n /**\n * Makes an internal request through this router's full routing pipeline.\n * This is useful for calling other routes internally and supports streaming responses.\n * @param options The request options.\n * @returns The raw Response object.\n */\n public async internalRequest(arg: {\n path: string;\n method?: Method;\n headers?: HeadersInit;\n body?: any;\n } | string): Promise<Response> {\n const options = typeof arg === \"string\" ? { path: arg } : arg;\n\n let url = options.path;\n // If path is relative, make it absolute (required by Request constructor)\n if (!url.startsWith(\"http\")) {\n const base = `http://${this.rootConfig?.hostname || \"localhost\"}:${this.rootConfig.port || 3000}`;\n\n // Ensure path starts with /\n const path = url.startsWith(\"/\") ? url : \"/\" + url;\n url = base + path;\n }\n\n const req = new ShokupanRequest({\n method: options.method || \"GET\",\n url,\n headers: options.headers as any,\n body: options.body ? JSON.stringify(options.body) : undefined\n });\n\n return this.root[$dispatch](req);\n }\n\n /**\n * Processes a request for testing purposes.\n * Returns a simplified { status, headers, data } object instead of a Response.\n */\n public async testRequest(options: RequestOptions): Promise<ProcessResult> {\n let url = options.url || options.path || \"/\";\n if (!url.startsWith(\"http\")) {\n const base = `http://${this.rootConfig?.hostname || \"localhost\"}:${this.rootConfig?.port || 3000}`;\n const path = url.startsWith(\"/\") ? url : \"/\" + url;\n url = base + path;\n }\n\n // Handle query params in options\n if (options.query) {\n const u = new URL(url);\n const entries = Object.entries(options.query);\n for (let i = 0; i < entries.length; i++) {\n const [k, v] = entries[i];\n u.searchParams.set(k, v);\n }\n url = u.toString();\n }\n\n const req = new ShokupanRequest({\n method: (options.method || \"GET\") as Method,\n url,\n headers: options.headers as any,\n body: options.body && typeof options.body === \"object\" ? JSON.stringify(options.body) : options.body\n });\n\n // Basic Dispatch Logic (moved/duplicated from Shokupan.handleRequest but simpler for pure Router)\n // Note: Pure Routers don't have global middleware usually, but if we call processRequest on them, \n // we just run their routing logic.\n // HOWEVER, Shokupan.override will invoke middleware.\n\n const ctx = new ShokupanContext<T>(req);\n\n let result: any = null;\n let status: number = HTTP_STATUS.OK;\n const headers: Record<string, string> = {};\n\n const match = this.find(req.method, ctx.path);\n if (match) {\n ctx.params = match.params;\n try {\n result = await match.handler(ctx);\n } catch (err: any) {\n console.error(err);\n status = getErrorStatus(err);\n result = { error: err.message || \"Internal Server Error\" };\n if (err.errors) result.errors = err.errors;\n }\n }\n else {\n status = HTTP_STATUS.NOT_FOUND;\n result = \"Not Found\";\n }\n\n // Normalize Result\n // If result is Response object, we need to read it back to ProcessResult?\n // The user wants { status, headers, data }.\n // If handler returns Response, we extract data.\n\n if (result instanceof Response) {\n status = result.status;\n result.headers.forEach((v, k) => headers[k] = v);\n\n if (headers['content-type']?.includes('application/json')) {\n result = await result.json();\n }\n else {\n result = await result.text();\n }\n }\n\n return {\n status,\n headers,\n data: result\n };\n }\n\n private wrapWithHooks(handler: ShokupanHandler<T>) {\n // Ensure hooks are initialized before checking the cache\n if (!this.hooksInitialized) {\n this.ensureHooksInitialized();\n }\n\n const hasStart = this.hookCache.get('onRequestStart')?.length > 0;\n const hasEnd = this.hookCache.get('onRequestEnd')?.length > 0;\n const hasError = this.hookCache.get('onError')?.length > 0;\n\n if (!hasStart && !hasEnd && !hasError) return handler;\n\n const originalHandler = handler;\n\n const wrapped = async (ctx: ShokupanContext<T>) => {\n await this.runHooks(\"onRequestStart\", ctx);\n\n const debug = ctx[$debug];\n let debugId: string | undefined;\n let previousNode: string | undefined;\n\n if (debug) {\n // @ts-ignore\n debugId = originalHandler._debugId || originalHandler.name || 'handler';\n previousNode = debug.getCurrentNode();\n debug.trackEdge(previousNode, debugId);\n debug.setNode(debugId!);\n }\n\n const start = performance.now();\n try {\n const res = await originalHandler(ctx);\n debug?.trackStep(debugId, 'handler', performance.now() - start, 'success');\n\n await this.runHooks(\"onRequestEnd\", ctx);\n return res;\n } catch (err) {\n debug?.trackStep(debugId, 'handler', performance.now() - start, 'error', err);\n\n await this.runHooks(\"onError\", ctx, err);\n throw err;\n } finally {\n if (debug && previousNode) debug.setNode(previousNode);\n }\n };\n // Preserve original handler reference for analysis if needed\n (wrapped as any).originalHandler = (originalHandler as any).originalHandler ?? originalHandler;\n return wrapped;\n }\n\n private mountRouter(prefix: string, router: ShokupanRouter<T>) {\n if (router[$isMounted]) {\n throw new Error(\"Router is already mounted\");\n }\n\n router[$mountPath] = prefix;\n\n // Capture mount location if not already present\n if (!router.metadata) {\n const info = getCallerInfo();\n router.metadata = {\n file: info.file,\n line: info.line,\n name: 'MountedRouter'\n };\n }\n this[$childRouters].push(router);\n\n /**\n * Descendants are defined first, then mounted backwards up to the application root.\n * Thus, we have to recurse through the children and assign the root reference.\n */\n router[$parent] = this;\n\n const setRouterContext = (router: ShokupanRouter<T>) => {\n router[$appRoot] = this.root;\n router[$childRouters].forEach((child) => setRouterContext(child));\n };\n setRouterContext(router);\n\n router[$appRoot] = this.root;\n router[$isMounted] = true;\n }\n\n\n /**\n * Find a route matching the given method and path.\n * @param method HTTP method\n * @param path Request path\n * @returns Route handler and parameters if found, otherwise null\n */\n public find(method: string, path: string): { handler: ShokupanHandler<T>; params: Record<string, string>; } | null {\n // console.log(`[Router] find ${method} ${path} (routes: ${this.routes.length}, children: ${this[$childRouters].length})`);\n\n\n // 1. Check local routes\n let result = this.trie.search(method, path);\n if (result) return result;\n\n // Fallback: If HEAD not found, try GET\n if (method === \"HEAD\") {\n result = this.trie.search(\"GET\", path);\n if (result) return result;\n }\n\n // 2. Check child routers\n for (let i = 0; i < this[$childRouters].length; i++) {\n const child = this[$childRouters][i];\n const prefix = child[$mountPath];\n\n if (path === prefix || path.startsWith(prefix + \"/\")) {\n const subPath = path.slice(prefix.length) || \"/\";\n const match = child.find(method, subPath);\n // Child router handlers are already wrapped with child hooks\n // Just return them as-is (parent hooks are applied at the app level in handleRequest)\n if (match) return match;\n }\n // Handle case where prefix ends with /\n if (prefix.endsWith(\"/\")) {\n if (path.startsWith(prefix)) {\n const subPath = path.slice(prefix.length) || \"/\";\n const match = child.find(method, subPath);\n if (match) return match;\n }\n }\n }\n\n return null; // Not found\n }\n\n private parsePath(path: string): { regex: RegExp; keys: string[]; } {\n if (typeof path !== 'string') {\n throw new Error(`Route path must be a string or regexp, received ${typeof path == \"function\" ? (path['name'] || path['constructor']?.['name'] || 'function') : typeof path}. Dynamic paths are **highly** discouraged.`);\n }\n\n const keys: string[] = [];\n\n // Security: Validate path length to prevent ReDoS\n if (path.length > 2048) {\n throw new Error('Path too long');\n }\n\n const pattern = path\n .replace(/:([a-zA-Z0-9_]+)/g, (_, key) => {\n keys.push(key);\n // Security: Add length limit to prevent ReDoS\n return \"([^/]{1,255})\";\n })\n // Security: Limit recursive wildcard to prevent ReDoS\n .replace(/\\*\\*/g, \".{0,1000}\")\n // Security: Limit single segment wildcard to prevent ReDoS \n .replace(/\\*/g, \"[^/]{1,255}\");\n\n return {\n regex: new RegExp(`^${pattern}$`),\n keys\n };\n }\n\n /**\n * Adds a route to the router.\n * \n * @param arg - Route configuration object\n * @param arg.method - HTTP method\n * @param arg.path - URL path\n * @param arg.spec - OpenAPI specification for the route\n * @param arg.handler - Route handler function\n * @param arg.regex - Custom regex for path matching\n * @param arg.group - Group for the route\n * @param arg.requestTimeout - Timeout for this route in milliseconds\n * @param arg.renderer - JSX renderer for the route\n * @param arg.controller - Controller for the route\n */\n public add({ method, path, spec, handler, regex: customRegex, group, requestTimeout, renderer, controller, metadata, middleware }: {\n method: Method,\n path: string,\n spec?: MethodAPISpec,\n handler: ShokupanHandler<T>;\n regex?: RegExp;\n group?: string;\n requestTimeout?: number;\n renderer?: JSXRenderer;\n controller?: any;\n middleware?: Middleware[];\n }) {\n const { regex, keys } = customRegex\n ? { regex: customRegex, keys: [] }\n : this.parsePath(path);\n\n // Merge specs from guards\n if (this.currentGuards.length > 0) {\n spec = spec || {};\n for (let i = 0; i < this.currentGuards.length; i++) {\n const guard = this.currentGuards[i];\n if (guard.spec) {\n // Merge Responses\n if (guard.spec.responses) {\n spec.responses = spec.responses || {};\n Object.assign(spec.responses, guard.spec.responses);\n }\n\n // Merge Security\n if (guard.spec.security) {\n spec.security = spec.security || [];\n spec.security.push(...guard.spec.security);\n }\n }\n }\n }\n\n // --- Flattened Route Execution Wrapper ---\n const effectiveTimeout = requestTimeout ?? this.requestTimeout ?? this.rootConfig?.requestTimeout;\n const effectiveRenderer = renderer ?? this.config?.renderer ?? this.rootConfig?.renderer;\n const routeGuards = [...this.currentGuards];\n\n let wrappedHandler = handler;\n\n // Optimization: Only create a wrapper closure if we actually have features to apply\n if ((effectiveTimeout && effectiveTimeout > 0) || effectiveRenderer || routeGuards.length > 0) {\n const originalHandler = handler;\n wrappedHandler = async (ctx: ShokupanContext<T>) => {\n // 1. Timeout\n if (effectiveTimeout && effectiveTimeout > 0 && ctx.server) {\n ctx.server.timeout(ctx.req as unknown as Request, effectiveTimeout / 1000);\n }\n\n // 2. Renderer\n if (effectiveRenderer) {\n ctx.setRenderer(effectiveRenderer);\n }\n\n // 3. Guards\n // Execute guards in order\n if (routeGuards.length > 0) {\n for (let i = 0; i < routeGuards.length; i++) {\n const guard = routeGuards[i];\n let guardPassed = false;\n let nextCalled = false;\n const next = () => {\n nextCalled = true;\n return Promise.resolve();\n };\n\n try {\n const result = await guard.handler(ctx, next);\n if (result === true || nextCalled) {\n guardPassed = true;\n } else if (result !== undefined && result !== null && result !== false) {\n return result;\n } else {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n } catch (error) {\n throw error;\n }\n\n if (!guardPassed) {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n }\n }\n\n // 4. Handler\n return originalHandler(ctx);\n };\n (wrappedHandler as any).originalHandler = (handler as any).originalHandler || handler;\n }\n\n // --- Middleware Tracking Logic ---\n // If metadata is provided (e.g. from controller), use it. Otherwise capture caller info.\n const { file, line } = metadata || getCallerInfo();\n\n wrappedHandler = MiddlewareTracker.wrap(wrappedHandler, {\n file,\n line,\n name: handler.name || 'anonymous',\n isBuiltin: (handler as any).isBuiltin,\n pluginName: (handler as any).pluginName\n });\n\n // Bake in Hooks if present (Optimization)\n let bakedHandler = wrappedHandler;\n if (this.config?.hooks) {\n bakedHandler = this.wrapWithHooks(wrappedHandler);\n }\n\n // Store for OpenAPI (still use list)\n this[$routes].push({\n method,\n path,\n regex: regex ?? new RegExp(''),\n keys: keys ?? [],\n handler,\n bakedHandler,\n handlerSpec: spec,\n group,\n hooks: this.config?.hooks as any,\n requestTimeout,\n renderer,\n metadata: {\n file,\n line\n },\n controller,\n middleware: middleware || []\n });\n\n // Insert into Trie\n this.trie.insert(method, path, bakedHandler);\n\n return this;\n }\n\n /**\n * Adds a GET route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public get<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a GET route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public get<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public get(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"GET\", path, ...args);\n return this;\n }\n\n /**\n * Adds a POST route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public post<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a POST route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public post<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public post(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"POST\", path, ...args);\n return this;\n }\n\n /**\n * Adds a PUT route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public put<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a PUT route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public put<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public put(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"PUT\", path, ...args);\n return this;\n }\n\n /**\n * Adds a DELETE route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public delete<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a DELETE route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public delete<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public delete(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"DELETE\", path, ...args);\n return this;\n }\n\n /**\n * Adds a PATCH route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public patch<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a PATCH route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public patch<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public patch(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"PATCH\", path, ...args);\n return this;\n }\n\n /**\n * Adds a OPTIONS route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public options<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a OPTIONS route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public options<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public options(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"OPTIONS\", path, ...args);\n return this;\n }\n\n /**\n * Adds a HEAD route to the router.\n * \n * @param path - URL path \n * @param handlers - Route handler functions \n */\n public head<Path extends string>(path: Path, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n /**\n * Adds a HEAD route to the router.\n * \n * @param path - URL path \n * @param spec - OpenAPI specification for the route\n * @param handlers - Route handler functions \n */\n public head<Path extends string>(path: Path, spec: MethodAPISpec, handler: ShokupanHandler<T, RouteParams<Path>>, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]);\n public head(path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n this.attachVerb(\"HEAD\", path, ...args);\n return this;\n }\n\n /**\n * Adds a guard to the router that applies to all routes added **after** this point.\n * Guards must return true or call `ctx.next()` to allow the request to continue.\n * \n * @param handler - Guard handler function \n */\n public guard(handler: ShokupanHandler<T>): void;\n /**\n * Adds a guard to the router that applies to all routes added **after** this point.\n * Guards must return true or call `ctx.next()` to allow the request to continue.\n \n * @param spec - OpenAPI specification for the guard\n * @param handler - Guard handler function \n */\n public guard(spec: GuardAPISpec, handler: ShokupanHandler<T>);\n public guard(specOrHandler: GuardAPISpec | ShokupanHandler<T>, handler?: ShokupanHandler<T>) {\n const spec = typeof specOrHandler === \"function\" ? undefined : specOrHandler as GuardAPISpec;\n const guardHandler = typeof specOrHandler === \"function\" ? specOrHandler as ShokupanHandler<T> : handler as ShokupanHandler<T>;\n\n // --- Middleware Tracking Logic ---\n let file = 'unknown';\n let line = 0;\n try {\n const err = new Error();\n const stack = err.stack?.split('\\n') || [];\n const callerLine = stack.find(l =>\n l.includes(':') &&\n !l.includes('router.ts') &&\n !l.includes('shokupan.ts') &&\n !l.includes('node_modules') &&\n !l.includes('bun:main')\n );\n if (callerLine) {\n // Regex should prevent regex DoS attacks\n const match = callerLine.match(/\\((.{0,1000}):(\\d{1,10}):(?:\\d{1,10})\\)/) ||\n callerLine.match(/at (.{0,1000}):(\\d{1,10}):(?:\\d{1,10})/);\n if (match) {\n file = match[1];\n line = parseInt(match[2], 10);\n }\n }\n } catch (e) { }\n\n const trackedGuard = MiddlewareTracker.wrap(guardHandler, {\n file,\n line,\n name: guardHandler.name || 'guard'\n });\n\n this.currentGuards.push({ handler: trackedGuard, spec });\n\n return this;\n }\n\n /**\n * Statically serves a directory with standard options.\n * @param uriPath URL path prefix\n * @param options Configuration options or root directory string\n */\n public static(uriPath: string, options: string | StaticServeOptions<T>) {\n const config: StaticServeOptions<T> = typeof options === 'string' ? { root: options } : options;\n // Normalize path prefix to ensure it has leading slash and no trailing slash for consistent matching\n const prefix = uriPath.startsWith('/') ? uriPath : '/' + uriPath;\n const normalizedPrefix = prefix.endsWith('/') && prefix !== '/' ? prefix.slice(0, -1) : prefix;\n\n // Correct usage of the new plugin:\n const handlerMiddleware = serveStatic(config, prefix);\n\n const routeHandler = async (ctx: ShokupanContext<T>) => {\n return handlerMiddleware(ctx, async () => { });\n };\n\n // Derive Group/Tag name from the path's last segment\n // e.g. /assets -> Assets\n let groupName = \"Static\";\n const segments = normalizedPrefix.split('/').filter(Boolean);\n if (segments.length > 0) {\n const last = segments[segments.length - 1];\n groupName = last.charAt(0).toUpperCase() + last.slice(1);\n }\n\n const defaultSpec = {\n summary: \"Static Content\",\n description: \"Serves static files from \" + normalizedPrefix,\n tags: [groupName]\n };\n const spec = config.openapi ? config.openapi : defaultSpec;\n if (!spec.tags) spec.tags = [groupName];\n else if (!spec.tags.includes(groupName)) spec.tags.push(groupName);\n\n const pattern = `^${normalizedPrefix}(/.*)?$`;\n const regex = new RegExp(pattern);\n\n // Display path in OpenAPI as /prefix/*\n const displayPath = normalizedPrefix === '/' ? '/*' : normalizedPrefix + '/*';\n\n this.add({ method: 'GET', path: displayPath, handler: routeHandler, spec, regex });\n this.add({ method: 'HEAD', path: displayPath, handler: routeHandler, spec, regex });\n\n return this;\n }\n\n\n /**\n * Attach the verb routes with their overload signatures.\n * Use compose to handle multiple handlers (middleware).\n */\n private attachVerb(method: Method, path: string, ...args: (MethodAPISpec | ShokupanHandler<T>)[]) {\n let spec: MethodAPISpec | undefined;\n let handlers: ShokupanHandler<T>[] = [];\n\n if (args.length > 0) {\n // Check if first arg is an object (Spec) and NOT a ShokupanHandler (function)\n if (typeof args[0] === 'object' && args[0] !== null) {\n spec = args[0] as MethodAPISpec;\n handlers = args.slice(1) as ShokupanHandler<T>[];\n } else {\n handlers = args as ShokupanHandler<T>[];\n }\n }\n\n if (handlers.length === 0) {\n // Should potentially throw or warn?\n return;\n }\n\n let finalHandler = handlers[handlers.length - 1];\n\n if (handlers.length > 1) {\n // Since handlers are [ctx, next?], they fit Strict Middleware signature.\n // compose takes Middleware[].\n // We assume ALL provided handlers are valid middleware/handlers.\n const fn = compose(handlers as any);\n finalHandler = (ctx) => fn(ctx);\n }\n\n this.add({\n method,\n path,\n spec,\n handler: finalHandler,\n middleware: handlers.slice(0, handlers.length - 1) as Middleware[]\n });\n }\n\n /**\n * Generates an OpenAPI 3.1 Document by recursing through the router and its descendants.\n * Now includes runtime analysis of handler functions to infer request/response types.\n */\n public generateApiSpec(options: OpenAPIOptions = {}): Promise<any> {\n return generateOpenApi(this, options);\n }\n\n public hasHooks(name: keyof ShokupanHooks): boolean {\n if (!this.hooksInitialized) {\n this.ensureHooksInitialized();\n }\n const hooks = this.hookCache.get(name);\n return hooks !== undefined && hooks.length > 0;\n }\n\n private ensureHooksInitialized() {\n const hooks = this.config?.hooks;\n if (hooks) {\n const hookList = Array.isArray(hooks) ? hooks : [hooks];\n\n // Pre-compute lookup for each hook type\n const hookTypes: (keyof ShokupanHooks)[] = [\n 'onRequestStart', 'onRequestEnd',\n 'onResponseStart', 'onResponseEnd',\n 'onError',\n 'beforeValidate', 'afterValidate',\n 'onRequestTimeout', 'onReadTimeout', 'onWriteTimeout'\n ];\n\n for (let i = 0; i < hookTypes.length; i++) {\n const type = hookTypes[i];\n const fns: Function[] = [];\n for (let j = 0; j < hookList.length; j++) {\n const h = hookList[j];\n if (h[type]) fns.push(h[type]!);\n }\n if (fns.length > 0) {\n // console.log(`[Router] Found hook ${type} (${fns.length}) for router ${this.constructor.name}`);\n // Set the has hooks flags for much faster check\n this._hasOnErrorHook ||= type === 'onError';\n this._hasOnRequestStartHook ||= type === 'onRequestStart';\n this._hasOnRequestEndHook ||= type === 'onRequestEnd';\n this._hasOnResponseStartHook ||= type === 'onResponseStart';\n this._hasOnResponseEndHook ||= type === 'onResponseEnd';\n this._hasOnRequestTimeoutHook ||= type === 'onRequestTimeout';\n this._hasOnReadTimeoutHook ||= type === 'onReadTimeout';\n this._hasOnWriteTimeoutHook ||= type === 'onWriteTimeout';\n this._hasBeforeValidateHook ||= type === 'beforeValidate';\n this._hasAfterValidateHook ||= type === 'afterValidate';\n\n this.hookCache.set(type, fns);\n }\n }\n }\n this.hooksInitialized = true;\n }\n\n public runHooks(name: keyof ShokupanHooks, ...args: any[]): void | Promise<void[]> {\n // Optimization: Use hasHook check before calling this usually\n // But we ensure initialized here too just in case\n if (!this.hooksInitialized) {\n this.ensureHooksInitialized();\n }\n const fns = this.hookCache.get(name);\n if (!fns) return;\n\n // Check if debug tracking is enabled (ctx is typically the first argument for most hooks)\n const ctx = args?.[0] instanceof ShokupanContext ? args[0] : undefined;\n const debug = ctx?.[$debug];\n\n if (debug) {\n // Track each hook individually with debug timing\n return Promise.all(fns.map(async (fn, index) => {\n const hookId = `hook_${name}_${fn.name || index}`;\n const previousNode = debug.getCurrentNode();\n\n debug.trackEdge(previousNode, hookId);\n debug.setNode(hookId);\n\n const start = performance.now();\n try {\n await fn(...args);\n const duration = performance.now() - start;\n debug.trackStep(hookId, 'hook', duration, 'success');\n } catch (error) {\n const duration = performance.now() - start;\n debug.trackStep(hookId, 'hook', duration, 'error', error);\n throw error;\n } finally {\n if (previousNode) debug.setNode(previousNode);\n }\n }));\n } else {\n // Fast path: no debug tracking\n return Promise.all(fns.map(fn => fn(...args)));\n }\n }\n}\n","\nimport type { Server } from \"bun\";\nimport { ShokupanContext } from \"../../context\";\nimport { compose } from \"../../middleware\";\nimport type { Shokupan } from \"../../shokupan\";\nimport { ShokupanRequest } from \"../request\";\nimport { $ws } from \"../symbol\";\nimport type { ServerAdapter } from \"./interface\";\n\nexport class BunAdapter implements ServerAdapter {\n private server?: Server<any>;\n\n async listen(port: number, app: Shokupan): Promise<Server<any>> {\n // @ts-ignore\n if (typeof Bun === \"undefined\") {\n throw new Error(\"BunAdapter requires the Bun runtime.\");\n }\n\n const serveOptions = {\n port: port,\n hostname: app.applicationConfig.hostname,\n development: app.applicationConfig.development,\n fetch: app.fetch.bind(app),\n reusePort: app.applicationConfig.reusePort,\n idleTimeout: app.applicationConfig.readTimeout ? app.applicationConfig.readTimeout / 1000 : undefined,\n websocket: {\n // @ts-ignore\n open(ws) {\n ws.data?.handler?.open?.(ws);\n },\n // @ts-ignore\n async message(ws, message) {\n if (ws.data?.handler?.message) {\n return ws.data.handler.message(ws, message);\n }\n\n // Buffer vs Uint8Array handling for cross-platform compatibility\n let msgString: string = \"\";\n if (typeof message === \"string\") {\n msgString = message;\n } else if (message instanceof Uint8Array || message instanceof ArrayBuffer) {\n msgString = new TextDecoder().decode(message);\n } else if (typeof Buffer !== \"undefined\" && message instanceof Buffer) {\n // @ts-ignore\n msgString = message.toString();\n } else {\n return; // Unknown format\n }\n\n if (typeof msgString !== \"string\") return;\n\n let payload: any;\n let isJSONPayload = false;\n if (msgString.startsWith('{')) {\n try {\n payload = JSON.parse(msgString);\n isJSONPayload = true;\n } catch { /* Ignore JSON parsing errors */ }\n }\n\n if (payload) {\n const self = app;\n // HTTP Bridge\n if (isJSONPayload && self.applicationConfig['enableHttpBridge'] && payload.type === 'HTTP') {\n const { id, method, path, headers, body } = payload;\n const url = new URL(path, `http://${self.applicationConfig.hostname || 'localhost'}:${port}`);\n\n const req = new Request(url.toString(), {\n method,\n headers,\n body: typeof body === 'object' ? JSON.stringify(body) : body\n });\n\n const res = await self.fetch(req);\n\n const resBody: any = await res.json()\n .catch(err => res.text());\n\n const resHeaders: Record<string, string> = {};\n res.headers.forEach((v, k) => resHeaders[k] = v);\n\n ws.send(JSON.stringify({\n type: 'RESPONSE',\n id,\n status: res.status,\n headers: resHeaders,\n body: resBody\n }));\n return;\n }\n\n // Event Handling\n const eventName = payload.event || (payload.type === 'EVENT' ? payload.name : undefined);\n if (eventName) {\n const handlers = self.findEvent(eventName);\n const handler = handlers?.length == 1 ? handlers[0] : compose(handlers || []);\n if (handler) {\n const data = payload.data || payload.body || payload.payload || payload;\n\n // Construct a Context that mocks a Request\n const req = new ShokupanRequest({\n url: `http://${self.applicationConfig.hostname || 'localhost'}/event/${eventName}`,\n method: 'POST',\n headers: new Headers({ 'content-type': 'application/json' }),\n body: JSON.stringify(data)\n });\n\n const ctx = new ShokupanContext(\n // @ts-ignore\n req,\n // @ts-ignore\n self.server,\n {},\n self,\n null,\n self.applicationConfig.enableMiddlewareTracking,\n payload.id\n );\n // Expose socket on context for reply\n (ctx as any)[$ws] = ws;\n\n // Link context to socket for disconnect hooks\n ws.data ??= {} as any;\n ws.data['ctx'] = ctx;\n\n try {\n await handler(ctx as any);\n } catch (err) {\n if (self.applicationConfig['websocketErrorHandler']) {\n await self.applicationConfig['websocketErrorHandler'](err, ctx as any);\n } else {\n console.error(`Error in event ${eventName}:`, err);\n }\n }\n }\n }\n }\n },\n // @ts-ignore\n drain(ws) {\n ws.data?.handler?.drain?.(ws);\n },\n // @ts-ignore\n close(ws, code, reason) {\n ws.data?.handler?.close?.(ws, code, reason);\n // Shokupan Disconnect Hooks\n const ctx: any = ws.data?.['ctx'];\n if (ctx && typeof ctx.getDisconnectCallbacks === 'function') {\n const callbacks = ctx.getDisconnectCallbacks();\n if (Array.isArray(callbacks) && callbacks.length > 0) {\n Promise.all(callbacks.map((cb: Function) => cb())).catch(err => {\n console.error(\"Error executing socket disconnect hook:\", err);\n });\n }\n }\n }\n }\n };\n\n // @ts-ignore\n this.server = Bun.serve(serveOptions);\n return this.server!;\n }\n\n async stop() {\n if (this.server) {\n this.server.stop();\n }\n }\n}\n","\nimport type { Server } from \"bun\";\nimport * as http from \"node:http\";\nimport * as https from \"node:https\";\nimport type { Shokupan } from \"../../shokupan\";\nimport type { ServerAdapter } from \"./interface\";\n\nexport class NodeAdapter implements ServerAdapter {\n private server?: any;\n\n async listen(port: number, app: Shokupan): Promise<Server<any>> {\n const factory = app.applicationConfig.serverFactory;\n\n let nodeServer: http.Server | https.Server;\n\n if (factory) {\n // If a custom factory is provided, use it (it returns a promise of a server like object)\n // But we need to standardize this.\n // For now, support existing factory pattern if needed, or assume it's just handled here.\n // Actually, the old code called `factory({ ... })`.\n // We can defer to it.\n const serveOptions = {\n port: port,\n hostname: app.applicationConfig.hostname,\n development: app.applicationConfig.development,\n fetch: app.fetch.bind(app),\n reusePort: app.applicationConfig.reusePort,\n };\n this.server = await factory(serveOptions);\n return this.server;\n }\n\n // Standard Node.js implementation\n nodeServer = http.createServer(async (req, res) => {\n const url = new URL(req.url!, `http://${req.headers.host}`);\n const request = new Request(url.toString(), {\n method: req.method,\n headers: req.headers as any,\n body: ['GET', 'HEAD'].includes(req.method!) ? undefined : new ReadableStream({\n start(controller) {\n req.on('data', chunk => controller.enqueue(chunk));\n req.on('end', () => controller.close());\n req.on('error', err => controller.error(err));\n }\n }) as any,\n // Required for Node.js undici when sending a body\n // @ts-ignore\n duplex: 'half'\n } as any);\n\n const response = await app.fetch(request, fauxServer);\n\n res.statusCode = response.status;\n response.headers.forEach((v, k) => res.setHeader(k, v));\n\n if (response.body) {\n // Optimize: Use arrayBuffer for direct conversion\n const buffer = await response.arrayBuffer();\n res.end(Buffer.from(buffer));\n } else {\n res.end();\n }\n });\n\n // Store reference\n this.server = nodeServer;\n\n // Create faux server object to match Bun.Server interface\n const fauxServer: Server<any> = {\n stop: () => {\n nodeServer.close();\n return Promise.resolve();\n },\n upgrade(req, options) {\n return false;\n },\n reload(options) {\n return fauxServer as any;\n },\n get port() {\n const addr = nodeServer.address();\n if (typeof addr === 'object' && addr !== null) {\n return addr.port;\n }\n return port;\n },\n hostname: app.applicationConfig.hostname || 'localhost',\n development: app.applicationConfig.development || false,\n pendingRequests: 0,\n requestIP: (req) => null,\n publish: () => 0,\n subscriberCount: () => 0,\n url: new URL(`http://${app.applicationConfig.hostname || 'localhost'}:${port}`),\n // Expose the raw Node.js server\n // @ts-ignore\n nodeServer: nodeServer\n } as unknown as Server<any>;\n\n // Listen\n return new Promise((resolve) => {\n nodeServer.listen(port, app.applicationConfig.hostname, () => {\n resolve(fauxServer);\n });\n });\n }\n\n async stop() {\n if (this.server?.stop) {\n await this.server.stop();\n } else if (this.server?.close) {\n // If we stored the raw node server\n this.server.close();\n }\n }\n}\n","\nimport type { Shokupan } from './shokupan';\nimport { BunAdapter, NodeAdapter, type ServerAdapter } from './util/adapter';\n\n/**\n * Shokupan Server\n * \n * Responsible for the lifecycle of the HTTP server (listen, stop)\n * and managing the underlying adapter (Bun, Node, etc).\n */\nexport class ShokupanServer {\n private server?: any;\n private adapter?: ServerAdapter;\n\n constructor(private app: Shokupan) { }\n\n /**\n * Starts the application server.\n * @param port The port to listen on.\n */\n public async listen(port?: number) {\n const config = this.app.applicationConfig;\n const finalPort = port ?? config.port ?? 3000;\n\n if (finalPort < 0 || finalPort > 65535 || finalPort % 1 !== 0) {\n throw new Error(\"Invalid port number\");\n }\n\n // Initialize App (Hooks, OpenAPI, etc)\n await this.app.start();\n\n // Use Adapter\n let adapterName = config.adapter;\n let adapter: ServerAdapter;\n\n if (!adapterName) {\n // Auto-detect\n // @ts-ignore\n if (typeof Bun !== \"undefined\") {\n config.adapter = 'bun';\n adapter = new BunAdapter();\n } else {\n config.adapter = 'node';\n adapter = new NodeAdapter();\n }\n } else if (adapterName === 'bun') {\n adapter = new BunAdapter();\n } else if (adapterName === 'node') {\n adapter = new NodeAdapter();\n } else if (adapterName === 'wintercg') {\n throw new Error(\"WinterCG adapter does not support listen(). Use fetch directly.\");\n } else {\n // Default/Fallback\n adapter = new NodeAdapter();\n }\n\n this.adapter = adapter;\n\n // Compile Routes (Flattening Optimization) if not done\n this.app.compile();\n\n // Start Server\n this.server = await adapter.listen(finalPort, this.app);\n\n // Update config port if 0 was used\n if (finalPort === 0 && this.server?.port) {\n config.port = this.server.port;\n }\n\n return this.server;\n }\n\n /**\n * Stops the server.\n */\n public async stop(closeActiveConnections?: boolean) {\n if (this.adapter?.stop) {\n await this.adapter.stop();\n } else if (this.server?.stop) {\n await this.server.stop(closeActiveConnections);\n }\n this.server = undefined;\n }\n}\n","\nexport interface FileSystemAdapter {\n readFile(path: string): Promise<Uint8Array | string | ReadableStream>;\n stat?(path: string): Promise<{ size: number; mtime: Date; }>;\n}\n\nlet fs: typeof import(\"node:fs/promises\") | undefined;\n\n/**\n * Default file system adapter that uses Bun.file for Bun and Node.js fs.promises for Node.js.\n */\nexport class DefaultFileSystemAdapter implements FileSystemAdapter {\n async readFile(path: string): Promise<Uint8Array | string | ReadableStream> {\n // @ts-ignore\n if (typeof Bun !== \"undefined\") {\n // @ts-ignore\n return Bun.file(path);\n } else {\n // Dynamic import for Node.js compatibility without top-level import\n fs ??= await import('node:fs/promises');\n return fs.readFile(path);\n }\n }\n\n async stat(path: string): Promise<{ size: number; mtime: Date; }> {\n // @ts-ignore\n if (typeof Bun !== \"undefined\") {\n // @ts-ignore\n const file = Bun.file(path);\n return {\n size: file.size,\n mtime: new Date(file.lastModified)\n };\n } else {\n fs ??= await import('node:fs/promises');\n const stats = await fs.stat(path);\n return {\n size: stats.size,\n mtime: stats.mtime\n };\n }\n }\n}\n\nexport class NoOpFileSystemAdapter implements FileSystemAdapter {\n async readFile(path: string): Promise<Uint8Array | string | ReadableStream> {\n throw new Error(\"File system access is not supported in this environment (NoOpFileSystemAdapter).\");\n }\n}\n","\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\n\nimport type { Span } from \"@opentelemetry/api\";\n\nexport class RequestContextStore {\n request?: Request;\n span?: Span;\n [key: string]: any;\n}\n\nexport const asyncContext = new AsyncLocalStorage<RequestContextStore>();\n\nexport function runInContext<T>(callback: () => T, initialStore = new RequestContextStore()): T {\n return asyncContext.run(initialStore, callback);\n}\n","// import * as os from 'node:os';\ntype CpuInfo = { times: { user: number; nice: number; sys: number; idle: number; irq: number; }; };\n\nexport class SystemCpuMonitor {\n private interval: Timer | null = null;\n private lastCpus: CpuInfo[] = [];\n private currentUsage: number = 0;\n private osStub: any = null;\n\n constructor(private readonly intervalMs: number = 1000) {\n this.init();\n }\n\n private async init() {\n try {\n // @ts-ignore\n if (typeof process !== \"undefined\" && process.versions && process.versions.node) {\n this.osStub = await import('node:os');\n }\n } catch (e) {\n // Ignore\n }\n }\n\n public start() {\n if (this.interval) return;\n if (!this.osStub) return; // silent failure in unsupported envs\n\n this.lastCpus = this.osStub.cpus();\n this.interval = setInterval(() => this.update(), this.intervalMs);\n }\n\n public stop() {\n if (this.interval) {\n clearInterval(this.interval);\n this.interval = null;\n }\n }\n\n public getUsage(): number {\n return this.currentUsage;\n }\n\n private update() {\n if (!this.osStub) return;\n\n const cpus = this.osStub.cpus();\n let idle = 0;\n let total = 0;\n\n for (let i = 0; i < cpus.length; i++) {\n const cpu = cpus[i];\n const prev = this.lastCpus[i];\n\n if (!prev) continue;\n\n let type: keyof typeof cpu.times;\n for (type in cpu.times) {\n const ticks = cpu.times[type];\n const prevTicks = prev.times[type];\n const diff = ticks - prevTicks;\n total += diff;\n if (type === 'idle') {\n idle += diff;\n }\n }\n }\n\n this.lastCpus = cpus;\n this.currentUsage = total === 0 ? 0 : (1 - idle / total) * 100;\n }\n}\n","import { RecordId, Surreal, type RecordIdRange, type Table } from 'surrealdb';\n\n\nexport class SurrealDatastore {\n constructor(\n private readonly db: Surreal\n ) {\n process.on(\"exit\", async () => {\n await this.disconnect();\n });\n }\n\n createSchema() {\n this.db.query(`\n DEFINE TABLE OVERWRITE failed_requests SCHEMALESS COMMENT \"Created by Shokupan\";\n DEFINE TABLE OVERWRITE sessions SCHEMALESS COMMENT \"Created by Shokupan\";\n DEFINE TABLE OVERWRITE users SCHEMALESS COMMENT \"Created by Shokupan\";\n DEFINE TABLE OVERWRITE idempotency_keys SCHEMALESS COMMENT \"Created by Shokupan\";\n DEFINE TABLE OVERWRITE middleware_tracking SCHEMALESS COMMENT \"Created by Shokupan\";\n DEFINE TABLE OVERWRITE requests SCHEMALESS COMMENT \"Created by Shokupan\";\n DEFINE TABLE OVERWRITE metrics SCHEMALESS COMMENT \"Created by Shokupan\";\n `).collect();\n }\n\n /**\n * Select a record or contents of a table by its ID.\n */\n async select<T = unknown>(id: RecordId | RecordIdRange | Table) {\n return this.db.select<T>(id as any);\n }\n\n /**\n * Merge update data into a record by its ID.\n */\n async merge<T extends Record<string, any>>(id: RecordId, data: T) {\n return this.db.update<T>(id).merge(data).catch((err: any) => {\n if (err.message.includes('This transaction can be retried')) {\n return this.db.update<T>(id).merge(data);\n }\n throw err;\n });\n }\n\n /**\n * Create a record by its ID.\n */\n async create<T extends Record<string, any>>(id: RecordId, data: Omit<T, 'id'>) {\n return this.db.create(id).content(data).catch((err: any) => {\n if (err.message.includes('This transaction can be retried')) {\n return this.db.create(id).content(data);\n }\n throw err;\n });\n }\n\n /**\n * Upsert a record by its ID.\n */\n async upsert<T extends Record<string, any>>(id: RecordId, data: T) {\n return this.db.upsert<T>(id).content(data).catch((err: any) => {\n if (err.message.includes('This transaction can be retried')) {\n return this.db.upsert<T>(id).content(data);\n }\n throw err;\n });\n }\n\n /**\n * Delete a record by its ID.\n */\n async delete(id: RecordId) {\n return this.db.delete(id).catch((err: any) => {\n if (err.message.includes('This transaction can be retried')) {\n return this.db.delete(id);\n }\n throw err;\n });\n }\n\n /**\n * Run a SurrealDB query.\n */\n async query<T extends Array<unknown>>(query: string, vars?: Record<string, any>) {\n return this.db.query(query, vars).collect<T>().catch((err: any) => {\n if (err.message.includes('This transaction can be retried')) {\n return this.db.query(query, vars).collect<T>();\n }\n throw err;\n });\n }\n\n /**\n * Create a relationship between two records.\n */\n async relate(fromId, edgeId, toId, data?: Record<string, any>) {\n return this.db.relate(fromId, edgeId, toId, data).catch((err: any) => {\n if (err.message.includes('This transaction can be retried')) {\n return this.db.relate(fromId, edgeId, toId, data);\n }\n throw err;\n });\n }\n\n\n disconnect() {\n return this.db.close();\n }\n}\n","import { asyncContext, RequestContextStore } from \"./async-hooks\";\n\nexport const kContext = Symbol(\"kContext\");\n\nexport interface PatchedPromise extends Promise<any> {\n [kContext]?: {\n store?: RequestContextStore;\n stack: string;\n };\n}\n\nlet patched = false;\n\n/**\n * Monkeypatches the global Promise constructor to attach the current AsyncLocalStorage store\n * and a snapshot of the stack trace to every new Promise instance.\n * \n * This enables the application to trace unhandled rejections back to the original request\n * and see where the dangling promise was created.\n */\nexport function enablePromisePatch() {\n if (patched) return;\n patched = true;\n\n const OriginalPromise = global.Promise;\n\n // @ts-ignore\n global.Promise = class PatchedPromise<T> extends OriginalPromise<T> {\n [kContext]: {\n store?: RequestContextStore;\n stack: string;\n };\n\n constructor(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) {\n // Capture context and stack before calling super (executor runs synchronously)\n const store = asyncContext.getStore();\n const stack = new Error().stack || \"No parent stack\";\n\n super(executor);\n\n this[kContext] = {\n store,\n stack\n };\n }\n } as any; // Cast to any to avoid strict signature compatibility issues with global.Promise\n\n // Restore static methods that might be lost or need rebinding\n // However, extending OriginalPromise usually handles this for standard methods.\n // If standard static methods (all, race, etc.) create new Promises, they will use our overridden constructor\n // because `this` in static methods refers to the class.\n\n // We can copy over static properties just in case there are custom ones or if extension doesn't cover everything in this env\n for (const prop of Object.getOwnPropertyNames(OriginalPromise)) {\n if (prop !== 'prototype' && prop !== 'length' && prop !== 'name') {\n // @ts-ignore\n if (typeof OriginalPromise[prop] === 'function') {\n // @ts-ignore\n global.Promise[prop] = OriginalPromise[prop];\n }\n }\n }\n}\n","import type { Server } from 'bun';\nimport { nanoid } from 'nanoid';\nimport { RecordId, Surreal } from 'surrealdb';\nimport { ShokupanContext } from \"./context\";\nimport { compose } from \"./middleware\";\nimport { generateOpenApi } from \"./plugins/application/openapi/openapi\";\nimport { ShokupanRouter } from './router';\nimport { ShokupanServer } from './server';\nimport { DefaultFileSystemAdapter } from './util/adapter/filesystem';\nimport { asyncContext, RequestContextStore } from \"./util/async-hooks\";\nimport { SystemCpuMonitor } from \"./util/cpu-monitor\";\nimport { SurrealDatastore } from './util/datastore';\nimport { getErrorStatus, NotFoundError } from \"./util/http-error\";\nimport { HTTP_STATUS } from \"./util/http-status\";\n\nimport { MiddlewareTracker } from './util/middleware-tracker';\nimport { enablePromisePatch, kContext } from './util/promise';\nimport { ShokupanRequest } from './util/request';\nimport { getCallerInfo } from './util/stack';\nimport { $appRoot, $childRouters, $dispatch, $finalResponse, $isApplication, $mountPath, $routeMatched, $routes } from './util/symbol';\nimport { RouterTrie } from './util/trie';\nimport type { Method, Middleware, ProcessResult, RequestOptions, ShokupanConfig, ShokupanPlugin } from './util/types';\n\n\nconst defaults: ShokupanConfig = {\n port: 3000,\n hostname: \"localhost\",\n development: process.env.NODE_ENV !== \"production\",\n enableAsyncLocalStorage: false,\n enableHttpBridge: false,\n enableOpenApiGen: true,\n reusePort: false,\n};\n\n\n/**\n * Shokupan Application\n * \n * The main application class for creating a Shokupan web server.\n * \n * @template State - The shape of `ctx.state` for all routes in the application.\n * Use this to provide type safety for state management across middleware and handlers.\n * \n * @example Basic Usage\n * ```typescript\n * const app = new Shokupan();\n * app.get('/hello', (ctx) => ctx.json({ message: 'Hello' }));\n * await app.listen(3000);\n * ```\n * \n * @example Typed State\n * ```typescript\n * interface AppState {\n * userId: string;\n * tenant: string;\n * requestId: string;\n * }\n * \n * const app = new Shokupan<AppState>();\n * \n * // Middleware has typed state access\n * app.use((ctx, next) => {\n * ctx.state.userId = 'user-123'; // ✓ Type-safe\n * ctx.state.requestId = crypto.randomUUID();\n * return next();\n * });\n * \n * // Handlers have typed state access\n * app.get('/profile', (ctx) => {\n * const { userId, tenant } = ctx.state; // ✓ TypeScript knows these exist\n * return ctx.json({ userId, tenant });\n * });\n * ```\n * \n * @example Empty State (No State Management)\n * ```typescript\n * import { EmptyState } from 'shokupan';\n * \n * const app = new Shokupan<EmptyState>();\n * // ctx.state will be an empty object with no properties\n * ```\n * \n * @example Combining Path Params and State\n * ```typescript\n * interface RequestState {\n * userId: string;\n * permissions: string[];\n * }\n * \n * const app = new Shokupan<RequestState>();\n * \n * app.get('/users/:userId/posts/:postId', (ctx) => {\n * // Both params and state are fully typed!\n * const { userId, postId } = ctx.params; // ✓ Path params typed\n * const { permissions } = ctx.state; // ✓ State typed\n * return ctx.json({ userId, postId, permissions });\n * });\n * ```\n */\nexport class Shokupan<T = any> extends ShokupanRouter<T> {\n readonly applicationConfig: ShokupanConfig = {};\n public openApiSpec?: any;\n public asyncApiSpec?: any;\n private openApiSpecPromise?: Promise<any>;\n private asyncApiSpecPromise?: Promise<any>;\n private composedMiddleware?: Middleware;\n private cpuMonitor?: SystemCpuMonitor;\n public server?: Server<any>;\n private httpServer?: ShokupanServer;\n private datastore?: SurrealDatastore;\n public dbPromise?: Promise<any>;\n\n // Performance: Flattened Router Trie\n private rootTrie?: RouterTrie<T>;\n\n public get db(): SurrealDatastore | undefined {\n return this.datastore;\n }\n\n get logger() {\n return this.applicationConfig.logger;\n }\n\n\n constructor(\n applicationConfig: ShokupanConfig = {}\n ) {\n const config = Object.assign({}, defaults, applicationConfig);\n\n // Initialize Default FileSystem Adapter if not provided\n config.fileSystem ??= new DefaultFileSystemAdapter();\n\n // Exclude hooks from the router config passed to super() to avoid double execution\n // The application handles app-level hooks in handleRequest()\n const { hooks, ...routerConfig } = config;\n super({ ...routerConfig, hooks });\n\n this[$isApplication] = true;\n this[$appRoot] = this;\n this.applicationConfig = config;\n\n // Capture metadata for the application instance\n const { file, line } = getCallerInfo();\n this.metadata = {\n file,\n line,\n name: 'ShokupanApplication'\n };\n\n // Security: Apply default security headers\n if (this.applicationConfig.defaultSecurityHeaders) {\n const { SecurityHeaders } = require(\"./plugins/middleware/security-headers\");\n this.use(SecurityHeaders(this.applicationConfig.defaultSecurityHeaders === true ? {} : this.applicationConfig.defaultSecurityHeaders));\n }\n\n if (this.applicationConfig.adapter !== 'wintercg') {\n this.dbPromise = this.initDatastore().catch(err => {\n // Log but don't crash if optional datastore init fails\n this.logger?.debug(\"Failed to initialize default datastore\", { error: err });\n });\n }\n\n if (this.applicationConfig.enablePromiseMonkeypatch) {\n enablePromisePatch();\n\n // Register global handler for unhandled rejections to log with context\n // We use process.prependListener if available to try to catch it before others, \n // or just on() \n // Note: In Bun, unhandledRejection might behave slightly differently than Node.\n const processRef = typeof process !== 'undefined' ? process : undefined;\n if (processRef && processRef.on) {\n processRef.on('unhandledRejection', (reason: any, promise: any) => {\n const ctx = promise?.[kContext];\n // Check if this promise belongs to this app's context\n if (ctx && ctx.store && ctx.store.app === this) {\n const { requestId } = ctx.store;\n this.logger.error(\"Unhandled Rejection in Shokupan Request\", {\n error: reason,\n requestId,\n creationStack: ctx.stack\n });\n }\n });\n }\n }\n }\n\n private async initDatastore() {\n let engines = this.applicationConfig.surreal?.engines;\n\n if (!engines && !this.applicationConfig.surreal?.url?.match(/^(?:wss?|https?):\\/\\//)) {\n engines = (await import('@surrealdb/node')).createNodeEngines();\n }\n\n const db = new Surreal({ engines });\n this.datastore = new SurrealDatastore(db);\n\n await db.connect(\n this.applicationConfig.surreal?.url ?? (process.env.NODE_ENV === 'test' ? 'mem://' : 'surrealkv://database'),\n this.applicationConfig.surreal?.connectOptions\n ).catch(err => {\n this.logger?.error(\"Failed to connect to SurrealDB\", { error: err });\n });\n\n await db.use({\n namespace: this.applicationConfig.surreal?.namespace ?? \"vendor\",\n database: this.applicationConfig.surreal?.database ?? \"shokupan\"\n });\n\n await db.query(\"DEFINE TABLE OVERWRITE request;\");\n await db.query(\"DEFINE TABLE OVERWRITE failed_request;\");\n await db.query(\"DEFINE TABLE OVERWRITE metric;\");\n\n }\n\n /**\n * Adds middleware to the application.\n */\n /**\n * Adds middleware to the application.\n */\n public override use(middleware: Middleware) {\n\n // --- Middleware Tracking Logic ---\n const { file, line } = getCallerInfo();\n\n const wrapped = MiddlewareTracker.wrap(middleware, {\n file,\n line,\n name: middleware.name || 'middleware',\n isBuiltin: (middleware as any).isBuiltin,\n pluginName: (middleware as any).pluginName\n });\n\n if (this.applicationConfig.enableMiddlewareTracking) {\n (wrapped as any).order = this.middleware.length;\n this.middleware.push(wrapped);\n } else {\n this.middleware.push(middleware);\n }\n\n return this;\n }\n\n /**\n * Registers a plugin.\n */\n public register(plugin: ShokupanPlugin, options?: { path?: string; }) {\n plugin.onInit(this, options);\n return this;\n }\n\n private startupHooks: (() => Promise<void> | void)[] = [];\n\n /**\n * Registers a callback to be executed before the server starts listening.\n */\n public onStart(callback: () => Promise<void> | void) {\n this.startupHooks.push(callback);\n return this;\n }\n\n private specAvailableHooks: ((spec: any) => void | Promise<void>)[] = [];\n\n /**\n * Registers a callback to be executed when the OpenAPI spec is available.\n * This happens after generateOpenApi() but before the server starts listening (or at least before it finishes startup if async).\n */\n public onSpecAvailable(callback: (spec: any) => void | Promise<void>) {\n this.specAvailableHooks.push(callback);\n return this;\n }\n\n /**\n * Starts the application server.\n * \n * @param port - The port to listen on. If not specified, the port from the configuration is used. If that is not specified, port 3000 is used.\n * @returns The server instance.\n */\n /**\n * Prepare the application for listening.\n * Use this if you want to initialize the app without starting the server immediately.\n */\n public async start() {\n // Run startup hooks\n await Promise.all(this.startupHooks.map(hook => hook()));\n\n if (this.applicationConfig.enableOpenApiGen) {\n // --- Well-Known Files Implementation ---\n\n // 1. .well-known/openapi.yaml\n this.get(\"/.well-known/openapi.yaml\", async (ctx) => {\n try {\n // Wait for spec if not ready yet\n await this.openApiSpecPromise;\n const { dump } = await import('js-yaml');\n const yaml = dump(this.openApiSpec);\n return ctx.send(yaml, { status: 200, headers: { 'content-type': 'application/yaml' } });\n } catch (e) {\n this.logger?.error(\"Failed to generate OpenAPI YAML\", { error: e });\n return ctx.text(\"Internal Server Error\", 500);\n }\n });\n\n // 2. .well-known/ai-plugin.json\n if (this.applicationConfig.aiPlugin?.enabled !== false) {\n this.get(\"/.well-known/ai-plugin.json\", async (ctx) => {\n // Wait for spec if not ready yet\n await this.openApiSpecPromise;\n\n const config = this.applicationConfig.aiPlugin || {};\n let pkg: any = {};\n try {\n pkg = await Bun.file(\"package.json\").json();\n } catch (e) { }\n\n const manifest = {\n schema_version: \"v1\",\n name_for_human: config.name_for_human || this.openApiSpec.info.title || pkg.name || \"Shokupan App\",\n name_for_model: config.name_for_model || this.openApiSpec.info.title || pkg.name || \"Shokupan App\",\n description_for_human: config.description_for_human || this.openApiSpec.info.description || pkg.description || \"Shokupan Application\",\n description_for_model: config.description_for_model || this.openApiSpec.info.description || pkg.description || \"Shokupan Application\",\n auth: config.auth || { type: \"none\" },\n api: config.api || {\n type: \"openapi\",\n url: `${this.applicationConfig.hostname === 'localhost' ? 'http' : 'https'}://${this.applicationConfig.hostname}:${this.applicationConfig.port}/.well-known/openapi.yaml`,\n is_user_authenticated: false\n },\n logo_url: config.logo_url || `${this.applicationConfig.hostname === 'localhost' ? 'http' : 'https'}://${this.applicationConfig.hostname}:${this.applicationConfig.port}/logo.png`, // Placeholder default\n contact_email: config.contact_email || pkg.author?.email || \"support@example.com\",\n legal_info_url: config.legal_info_url || `${this.applicationConfig.hostname === 'localhost' ? 'http' : 'https'}://${this.applicationConfig.hostname}:${this.applicationConfig.port}/legal`\n };\n\n return ctx.json(manifest);\n });\n }\n\n // 3. .well-known/api-catalog\n if (this.applicationConfig.apiCatalog?.enabled !== false) {\n this.get(\"/.well-known/api-catalog\", async (ctx) => {\n // Wait for spec if not ready yet\n await this.openApiSpecPromise;\n\n const config = this.applicationConfig.apiCatalog || {};\n const catalog = {\n versions: config.versions || [\n {\n name: this.openApiSpec.info.version || \"v1\",\n url: `${this.applicationConfig.hostname === 'localhost' ? 'http' : 'https'}://${this.applicationConfig.hostname}:${this.applicationConfig.port}/`,\n spec_url: `${this.applicationConfig.hostname === 'localhost' ? 'http' : 'https'}://${this.applicationConfig.hostname}:${this.applicationConfig.port}/.well-known/openapi.yaml`\n }\n ]\n };\n return ctx.json(catalog);\n });\n }\n\n // Create the generation promise\n this.openApiSpecPromise = generateOpenApi(this).then(spec => {\n this.openApiSpec = spec;\n return spec;\n });\n\n // Decide whether to block or not\n const shouldBlock = this.applicationConfig.blockOnOpenApiGen !== false;\n\n if (shouldBlock) {\n // Wait for generation to complete before proceeding\n await this.openApiSpecPromise;\n }\n\n // Run spec available hooks (either now after blocking, or later after async completion)\n if (shouldBlock) {\n await Promise.all(this.specAvailableHooks.map(hook => hook(this.openApiSpec)));\n } else {\n // Run hooks after async generation completes\n this.openApiSpecPromise.then(spec => {\n return Promise.all(this.specAvailableHooks.map(hook => hook(spec)));\n }).catch(err => {\n this.logger?.error(\"Error running spec available hooks\", { error: err });\n });\n }\n }\n\n if (this.applicationConfig.enableAsyncApiGen) {\n const { generateAsyncApi } = await import(\"./plugins/application/asyncapi/generator\");\n\n // Create the generation promise\n this.asyncApiSpecPromise = generateAsyncApi(this).then(spec => {\n this.asyncApiSpec = spec;\n return spec;\n });\n\n // Decide whether to block or not\n const shouldBlock = this.applicationConfig.blockOnAsyncApiGen !== false;\n\n if (shouldBlock) {\n await this.asyncApiSpecPromise;\n }\n }\n\n\n\n if (this.applicationConfig.autoBackpressureFeedback === true) {\n this.cpuMonitor = new SystemCpuMonitor();\n this.cpuMonitor.start();\n }\n }\n\n /**\n * Starts the application server.\n * \n * @param port - The port to listen on. If not specified, the port from the configuration is used. If that is not specified, port 3000 is used.\n * @returns The server instance.\n */\n public async listen(port?: number) {\n this.httpServer = new ShokupanServer(this);\n this.server = await this.httpServer.listen(port);\n return this.server;\n }\n\n\n /**\n * Stops the application server.\n * \n * This method gracefully shuts down the server and stops any running monitors.\n * Works transparently in both Bun and Node.js runtimes.\n * \n * @returns A promise that resolves when the server has been stopped.\n * \n * @example\n * ```typescript\n * const app = new Shokupan();\n * const server = await app.listen(3000);\n * \n * // Later, when you want to stop the server\n * await app.stop();\n * ```\n * @param closeActiveConnections — Immediately terminate in-flight requests, websockets, and stop accepting new connections.\n */\n public async stop(closeActiveConnections?: boolean): Promise<void> {\n // Stop CPU monitor if running\n if (this.cpuMonitor) {\n this.cpuMonitor.stop();\n this.cpuMonitor = undefined;\n }\n\n // Stop the server if it exists\n if (this.httpServer !== undefined) {\n await this.httpServer.stop(closeActiveConnections);\n } else if (this.server?.stop) {\n // Fallback\n await this.server.stop(closeActiveConnections);\n }\n this.server = undefined;\n\n // Teardown DI Container\n const { Container } = await import(\"./util/di\");\n await Container.teardown();\n }\n\n public [$dispatch](req: ShokupanRequest<T>) {\n return this.fetch(req as unknown as Request);\n }\n\n /**\n * Processes a request by wrapping the standard fetch method.\n */\n public override async testRequest(options: RequestOptions): Promise<ProcessResult> {\n if (!this.rootTrie) {\n this.compile();\n }\n\n let url = options.url || options.path || \"/\";\n if (!url.startsWith(\"http\")) {\n const base = `http://${this.applicationConfig.hostname || \"localhost\"}:${this.applicationConfig.port || 3000}`;\n const path = url.startsWith(\"/\") ? url : \"/\" + url;\n url = base + path;\n }\n\n if (options.query) {\n const u = new URL(url);\n const entries = Object.entries(options.query);\n for (let i = 0; i < entries.length; i++) {\n const [k, v] = entries[i];\n u.searchParams.set(k, v);\n }\n url = u.toString();\n }\n\n // Create Request to pass to fetch\n const reqBody = options.body && typeof options.body === \"object\" ? JSON.stringify(options.body) : options.body;\n const reqHeaders = new Headers(options.headers as any);\n if (typeof options.body === \"object\" && !reqHeaders.has(\"content-type\")) {\n reqHeaders.set(\"content-type\", \"application/json\");\n }\n\n const req = new ShokupanRequest({\n method: (options.method || \"GET\") as Method,\n url,\n headers: reqHeaders,\n body: reqBody\n }) as unknown as ShokupanRequest<T>;\n\n const res = await this.fetch(req as unknown as Request);\n\n // Convert Response to ProcessResult\n const status = res.status;\n const headers: Record<string, string> = {};\n res.headers.forEach((v, k) => headers[k] = v);\n\n let data: any;\n if (headers['content-type']?.includes('application/json')) {\n data = await res.json();\n }\n else {\n data = await res.text();\n }\n\n return {\n status,\n headers,\n data\n };\n }\n\n /**\n * Handles an incoming request (Bun.serve interface).\n * This logic contains the middleware chain and router dispatch.\n * \n * @param req - The request to handle.\n * @param server - The server instance.\n * @returns The response to send.\n */\n public async fetch(req: Request, server?: Server<any>): Promise<Response> {\n\n\n if (this.applicationConfig.enableTracing) {\n // Dynamic import to avoid hard dependency\n const { trace, context } = await import('@opentelemetry/api');\n const tracer = trace.getTracer(\"shokupan.application\");\n const store = asyncContext.getStore();\n\n const attrs = {\n attributes: {\n \"http.url\": req.url,\n \"http.method\": req.method\n }\n };\n\n const parent = store?.span;\n const ctx = parent ? trace.setSpan(context.active(), parent) : undefined;\n return tracer.startActiveSpan(`${req.method} ${new URL(req.url).pathname}`, attrs, ctx, span => {\n const ctxStore = new RequestContextStore();\n ctxStore.span = span;\n ctxStore.request = req;\n\n return asyncContext.run(ctxStore, () => this.handleRequest(req, server).finally(() => span.end()));\n });\n }\n\n // If ALS is enabled but tracing is not\n if (this.applicationConfig.enableAsyncLocalStorage) {\n const requestId = this.applicationConfig.idGenerator?.() ?? nanoid();\n const ctxStore = new RequestContextStore();\n ctxStore.request = req;\n ctxStore['requestId'] = requestId;\n ctxStore['app'] = this;\n return asyncContext.run(ctxStore, () => this.handleRequest(req, server, requestId));\n }\n\n return this.handleRequest(req, server);\n }\n\n private async handleRequest(req: Request, server?: Server<any>, requestId?: string): Promise<Response> {\n // Cast to ShokupanRequest if needed, though at runtime it's just a Request\n // But ShokupanContext expects ShokupanRequest.\n const request = req as unknown as ShokupanRequest<T>;\n\n const controller = new AbortController();\n const ctx = new ShokupanContext<T>(request, server, undefined, this, controller.signal, this.applicationConfig.enableMiddlewareTracking, requestId);\n\n const handle = async () => {\n\n // Auto-Backpressure Check\n if (this.cpuMonitor && this.cpuMonitor.getUsage() > (this.applicationConfig.autoBackpressureLevel ?? 60)) {\n // Return 429 immediately\n const msg = \"Too Many Requests (CPU Backpressure)\";\n const res = ctx.text(msg, 429);\n // Trigger hooks so metrics are recorded\n if (this.hasOnResponseEndHook) await this.runHooks('onResponseEnd', ctx, res);\n return res;\n }\n\n try {\n // Request Start Hook\n if (this.hasOnRequestStartHook) await this.runHooks('onRequestStart', ctx);\n\n // Compose middleware + router dispatch\n const fn = this.composedMiddleware ??= compose(this.middleware);\n\n // Object.defineProperty(fn, 'name', { value: \"middleware chain\", configurable: false });\n\n // The \"next\" at the end of the middleware chain is the router dispatch\n const result = await fn(ctx, async () => {\n // Start body parsing early for applicable HTTP methods to overlap with route lookup\n let bodyParsing: Promise<void> | undefined;\n if (req.method !== 'GET' && req.method !== 'HEAD') {\n // For POST/PUT/PATCH/DELETE, start parsing\n bodyParsing = ctx.parseBody();\n }\n\n const match = this.find(req.method, ctx.path);\n\n\n if (match) {\n ctx[$routeMatched] = true;\n ctx.params = match.params;\n\n // Ensure body is parsed before handler executes\n if (bodyParsing) await bodyParsing;\n\n // --- Manual Tracking for Route Handler ---\n if (this.applicationConfig.enableMiddlewareTracking) {\n const handler = match.handler;\n const meta = (handler as any).metadata;\n\n if (meta) {\n const trackingStartTime = performance.now();\n const handlerName = meta.name || handler.name || 'anonymous';\n\n ctx.handlerStack.push({\n name: handlerName,\n file: meta.file,\n line: meta.line,\n isBuiltin: meta.isBuiltin,\n startTime: trackingStartTime,\n duration: -1\n });\n\n try {\n const res = await handler(ctx);\n\n const duration = performance.now() - trackingStartTime;\n const stackItem = ctx.handlerStack[ctx.handlerStack.length - 1];\n if (stackItem) stackItem.duration = duration;\n\n Promise.resolve().then(async () => {\n try {\n const db = this.db;\n if (!db) return;\n\n const timestamp = Date.now();\n await db.upsert(new RecordId('middleware_tracking', {\n timestamp,\n name: handlerName\n }), {\n name: handlerName,\n path: ctx.path,\n timestamp,\n duration,\n file: meta.file,\n line: meta.line,\n error: undefined,\n metadata: {\n isBuiltin: meta.isBuiltin,\n pluginName: meta.pluginName\n }\n });\n } catch (e) { }\n });\n\n return res;\n } catch (err) {\n const duration = performance.now() - trackingStartTime;\n const stackItem = ctx.handlerStack[ctx.handlerStack.length - 1];\n if (stackItem) stackItem.duration = duration;\n\n Promise.resolve().then(async () => {\n try {\n const db = this.db;\n if (!db) return;\n\n const timestamp = Date.now();\n await db.upsert(new RecordId('middleware_tracking', {\n timestamp,\n name: handlerName\n }), {\n name: handlerName,\n path: ctx.path,\n timestamp,\n duration,\n file: meta.file,\n line: meta.line,\n error: String(err),\n metadata: {\n isBuiltin: meta.isBuiltin,\n pluginName: meta.pluginName\n }\n });\n } catch (e) { }\n });\n throw err;\n }\n }\n }\n\n return match.handler(ctx);\n }\n\n // Fallback: If no route matched, check if it's a WebSocket upgrade request that can be handled by default handlers\n // This supports Shokupan's Native WebSocket Events if no specific middleware/route handled it\n if (ctx.upgrade()) {\n return undefined as unknown as Response;\n }\n\n // No route matched - return 404 Not Found\n // Exception: If middleware manually changed the status from default 200,\n // respect that (e.g., auth middleware set 401)\n if (ctx.response.status !== HTTP_STATUS.OK) {\n return ctx.send(null, { status: ctx.response.status, headers: ctx.response.headers });\n }\n\n throw new NotFoundError();\n });\n\n let response: Response | Promise<Response>;\n if (result instanceof Response) {\n response = result;\n }\n // Check explicit void return but response set in context\n else if ((result === null || result === undefined) && ctx[$finalResponse] instanceof Response) {\n response = ctx[$finalResponse];\n }\n else if (result === null || result === undefined) {\n // Handler returned nothing (void/null/undefined)\n\n if (ctx[$finalResponse] instanceof Response) {\n response = ctx[$finalResponse];\n }\n else if (ctx.isUpgraded) {\n // Request was successfully upgraded to WebSocket\n return undefined as unknown as Response;\n }\n else if (ctx[$routeMatched]) {\n // A route WAS matched but returned nothing.\n // Default to 204 No Content (unless user set status manually via ctx.response.status)\n let status = ctx.response.status;\n if (status === HTTP_STATUS.OK) {\n status = HTTP_STATUS.NO_CONTENT;\n }\n // We send an empty response with the determined status\n response = ctx.send(null, { status, headers: ctx.response.headers });\n } else {\n // Should have been thrown inside the middleware chain\n throw new NotFoundError();\n }\n }\n else if (typeof result === \"object\") {\n response = ctx.json(result);\n }\n else {\n response = ctx.text(String(result));\n }\n\n // Request End Hook - Processing finished, response ready\n if (this.hasOnRequestEndHook) await this.runHooks('onRequestEnd', ctx);\n\n if (response instanceof Promise) {\n response = await response;\n }\n\n // Response Start Hook - About to send response\n if (this.hasOnResponseStartHook) await this.runHooks('onResponseStart', ctx, response);\n\n return response;\n\n }\n catch (err: any) {\n const span = asyncContext.getStore()?.span;\n if (span) span.setStatus({ code: 2 }); // Error\n\n // Extract status from error object (supports both .status and .statusCode)\n let status = getErrorStatus(err);\n\n // Handle JSON Parse errors specifically\n if (err instanceof SyntaxError && err.message.includes('JSON')) {\n status = 400;\n }\n\n // Mask error details in production\n const isDev = this.applicationConfig.development !== false;\n const message = isDev ? (err.message || \"Internal Server Error\") : \"Internal Server Error\";\n\n const body: any = { error: message };\n if (isDev && err.errors) body.errors = err.errors;\n if (isDev && err.stack) body.stack = err.stack;\n\n // Error Hook\n if (this.hasOnErrorHook) await this.runHooks('onError', ctx, err);\n\n return ctx.json(body, status);\n }\n };\n\n // Timeout Logic\n let executionPromise = handle();\n const timeoutMs = this.applicationConfig.requestTimeout;\n\n if (timeoutMs && timeoutMs > 0) {\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(async () => {\n controller.abort(); // Signal cancellation to handlers\n await this.runHooks('onRequestTimeout', ctx);\n reject(new Error(\"Request Timeout\"));\n }, timeoutMs);\n });\n\n executionPromise = Promise.race([executionPromise, timeoutPromise])\n .finally(() => clearTimeout(timeoutId));\n }\n\n return executionPromise\n .catch((err) => {\n if (err.message === \"Request Timeout\") {\n return ctx.text(\"Request Timeout\", HTTP_STATUS.REQUEST_TIMEOUT);\n }\n console.error(\"Unexpected error in request execution:\", err);\n return ctx.text(\"Internal Server Error\", HTTP_STATUS.INTERNAL_SERVER_ERROR);\n })\n .then(async (res) => {\n // Response End Hook - Response returned\n // Note: We can't guarantee it's fully sent to client here, but it's handed off to Bun\n await this.runHooks('onResponseEnd', ctx, res);\n return res;\n });\n };\n\n /**\n * Compiles all routes into a master Trie for O(1) router lookup.\n * Use this if adding routes dynamically after start (not recommended but possible).\n */\n public compile() {\n this.rootTrie = new RouterTrie<T>();\n this.flattenRoutes(this.rootTrie, this, \"\", []);\n // Trigger generic instrumentation?\n }\n\n private flattenRoutes(\n trie: RouterTrie<T>,\n router: ShokupanRouter<T>,\n prefix: string,\n middlewareStack: Middleware[]\n ) {\n // 1. Determine Stack for this level\n // If router is THIS (application), we do NOT add its middleware to the stack\n // because it is already executed globally in handleRequest.\n // If router is a child, we MUST add its middleware.\n let effectiveStack = middlewareStack;\n if (router !== this as any) {\n effectiveStack = [...middlewareStack, ...router.middleware];\n }\n\n // Helper to join paths correctly, ensuring no double slashes or accidental trailing slashes\n const joinPath = (base: string, segment: string) => {\n let b = base;\n // Normalize base: remove trailing slash unless it's root\n if (b !== '/' && b.endsWith('/')) {\n b = b.slice(0, -1);\n }\n\n let s = segment;\n\n // For root segment, return base directly (no trailing slash)\n if (s === '/') {\n return b;\n }\n\n if (s === '') {\n return b;\n }\n\n // Ensure separator\n if (!s.startsWith('/')) {\n s = '/' + s;\n }\n\n // If base is root '/', return s directly (s starts with /)\n if (b === '/') {\n return s;\n }\n\n return b + s;\n };\n\n // 2. Add local routes\n for (const route of router[$routes]) {\n const fullPath = joinPath(prefix, route.path);\n\n // Wrap Handler with Middleware Stack\n let handler = route.bakedHandler || route.handler;\n if (effectiveStack.length > 0) {\n const fn = compose(effectiveStack);\n const originalHandler = handler;\n handler = async (ctx) => {\n // Middleware stack needs \"next\" to proceed to handler\n // Handler is the terminal \"next\"\n return fn(ctx, () => originalHandler(ctx));\n };\n // Preserve metadata if any\n (handler as any).originalHandler = (originalHandler as any).originalHandler || originalHandler;\n }\n\n trie.insert(route.method, fullPath, handler);\n\n // Handle Trailing Slash Ambiguity for Root Routes\n // If the route is effectively the \"index\" of the mount point (e.g. /docs or /asyncapi),\n // we register BOTH /docs and /docs/ to ensure maximum compatibility.\n if ((route.path === '/' || route.path === '') && fullPath !== '/') {\n trie.insert(route.method, fullPath + '/', handler);\n }\n }\n\n // 3. Recurse children\n for (const child of router[$childRouters]) {\n const mountPath = child[$mountPath];\n const childPrefix = joinPath(prefix, mountPath);\n this.flattenRoutes(trie, child, childPrefix, effectiveStack);\n }\n }\n\n public override find(method: string, path: string) {\n if (this.rootTrie) {\n const result = this.rootTrie.search(method, path);\n if (result) return result;\n\n // Fallback HEAD -> GET\n if (method === \"HEAD\") {\n return this.rootTrie.search(\"GET\", path);\n }\n return null;\n }\n return super.find(method, path);\n }\n}\n","import type { ShokupanContext } from \"../../context\";\nimport type { Middleware, NextFn } from \"../../util/types\";\n\nexport interface RateLimitOptions {\n /**\n * Window in milliseconds\n */\n windowMs?: number;\n /**\n * Maximum number of requests allowed in the window\n */\n max?: number;\n /**\n * Alias for max\n */\n limit?: number;\n /**\n * Message to send when rate limited\n */\n message?: string | object | ((ctx: ShokupanContext, key: string) => string | object);\n /**\n * Status code to send when rate limited\n */\n statusCode?: number;\n /**\n * Whether to include X-RateLimit headers in the response\n */\n headers?: boolean;\n /**\n * Function to generate a unique key for each request\n * This is used to identify the user or source of the request\n * Defaults to the request's ip address.\n */\n keyGenerator?: (ctx: ShokupanContext) => string;\n /**\n * Function to execute when a request is rate limited\n */\n onRateLimited?: (ctx: ShokupanContext, key: string) => void | Response | Promise<void | Response>;\n /**\n * Function to determine whether to skip rate limiting\n */\n skip?: (ctx: ShokupanContext) => boolean;\n /**\n * Mode to use for rate limiting\n * - user: Rate limit per user (generated key, defaults to ip address)\n * - absolute: Rate limit for all users\n */\n mode?: 'user' | 'absolute';\n /**\n * List of trusted proxy IPs\n */\n trustedProxies?: string[];\n /**\n * Interval in milliseconds to clean up expired entries.\n * Defaults to windowMs.\n */\n cleanupInterval?: number;\n}\n\ninterface HitRecord {\n hits: number;\n resetTime: number;\n}\n\n/**\n * Rate limit middleware.\n * @param options Rate limit options\n * @returns Middleware function\n */\nexport function RateLimitMiddleware(options: RateLimitOptions = {}): Middleware {\n const windowMs = options.windowMs || 60 * 1000; // 1 minute\n const max = options.limit || options.max || 5; // 5 requests per window\n const message = options.message || \"Too many requests, please try again later.\";\n const statusCode = options.statusCode || 429;\n const headers = options.headers !== false;\n const mode = options.mode || 'user';\n const trustedProxies = options.trustedProxies || [];\n const cleanupInterval = options.cleanupInterval || windowMs;\n\n const keyGenerator = options.keyGenerator || ((ctx) => {\n if (mode === 'absolute') {\n return 'global';\n }\n\n // Security: Use proper IP detection with trusted proxy support\n const xForwardedFor = ctx.headers.get(\"x-forwarded-for\");\n\n if (xForwardedFor && trustedProxies.length > 0) {\n // Parse X-Forwarded-For from right to left (most recent proxy first)\n const ips = xForwardedFor.split(',').map(ip => ip.trim());\n\n // Get the rightmost IP that is not in trusted proxies\n for (let i = ips.length - 1; i >= 0; i--) {\n const ip = ips[i];\n if (!trustedProxies.includes(ip)) {\n // Validate IP format (basic check)\n if (/^[\\d.:a-fA-F]+$/.test(ip)) {\n return ip;\n }\n }\n }\n }\n\n // Fallback to server IP detection\n return (ctx.server as any)?.requestIP?.(ctx.request)?.address || \"unknown\";\n });\n const skip = options.skip || (() => false);\n\n // In-memory store\n const hits = new Map<string, HitRecord>();\n\n // Cleanup interval\n const interval = setInterval(() => {\n const now = Date.now();\n const entries = Array.from(hits.entries());\n for (let i = 0; i < entries.length; i++) {\n const [key, record] = entries[i];\n if (record.resetTime <= now) {\n hits.delete(key);\n }\n }\n }, cleanupInterval);\n\n // Ensure interval doesn't block process exit\n if (interval.unref) interval.unref();\n\n const rateLimitMiddleware: Middleware = async function RateLimitMiddleware(ctx: ShokupanContext, next: NextFn) {\n if (skip(ctx)) return next();\n\n const key = keyGenerator(ctx);\n const now = Date.now();\n let record = hits.get(key);\n\n // Initialize record if not exists or expired\n if (!record || record.resetTime <= now) {\n record = {\n hits: 0,\n resetTime: now + windowMs\n };\n hits.set(key, record);\n }\n\n record.hits++;\n\n const remaining = Math.max(0, max - record.hits);\n const resetTime = Math.ceil(record.resetTime / 1000); // Epoch seconds\n const retryAfter = Math.ceil((record.resetTime - now) / 1000); // Seconds until reset\n\n // Helper to set headers\n const setHeaders = (res: Response | any) => {\n if (!headers || !res || !res.headers) return;\n try {\n res.headers.set(\"X-RateLimit-Limit\", String(max));\n res.headers.set(\"X-RateLimit-Remaining\", String(remaining));\n res.headers.set(\"X-RateLimit-Reset\", String(resetTime));\n } catch (e) { /* ignore */ }\n };\n\n if (record.hits > max) {\n\n if (options.onRateLimited) {\n const result = await options.onRateLimited(ctx, key);\n if (result instanceof Response) {\n return result;\n }\n }\n\n // Dispatch 429\n const msg = typeof message === 'function' ? message(ctx, key) : message;\n const res = await (typeof msg === 'object' ? ctx.json(msg, statusCode) : ctx.text(String(msg), statusCode));\n\n if (headers) {\n setHeaders(res);\n res.headers.set(\"Retry-After\", String(retryAfter));\n }\n\n return res;\n }\n\n const response = await next();\n\n // If response is a Response object, attach headers\n if (response instanceof Response && headers) {\n setHeaders(response);\n }\n\n return response;\n };\n\n rateLimitMiddleware.isBuiltin = true;\n rateLimitMiddleware.pluginName = 'RateLimit';\n\n return rateLimitMiddleware;\n}\n","import { RateLimitMiddleware, type RateLimitOptions } from \"../plugins/middleware/rate-limit\";\nimport { Container } from \"./di\";\nimport './metadata';\nimport { getCallerInfo } from \"./stack\";\nimport { $controllerPath, $eventMethods, $mcpPrompts, $mcpResources, $mcpTools, $middleware, $routeArgs, $routeMethods, $routeSpec } from \"./symbol\";\nimport type { AsyncAPISpec, GuardAPISpec, MethodAPISpec } from \"./types\";\nimport { type Method, type Middleware, RouteParamType } from \"./types\";\n\n/**\n * Class Decorator: Defines the base path for a controller.\n */\nexport function Controller(path: string = \"/\") {\n return (target: any) => {\n target[$controllerPath] = path;\n };\n}\n\n/**\n * Registers this class as a **Singleton** service.\n * A single instance will be created and shared across the process.\n */\nexport function Injectable(scope: 'singleton'): ClassDecorator;\n\n/**\n * Registers this class as an **Instanced** (Transient) service.\n * A new instance will be created every time dependency is resolved.\n */\nexport function Injectable(scope: 'instanced'): ClassDecorator;\n\n/**\n * Registers this class as a Service (defaults to Singleton).\n */\nexport function Injectable(scope: 'singleton' | 'instanced' = 'singleton'): ClassDecorator {\n return (target: any) => {\n Reflect.defineMetadata('di:scope', scope, target);\n };\n}\n\n/**\n * Property/Parameter Decorator: Injects a service.\n * Used on class properties or constructor parameters.\n */\nexport function Inject(token: any): PropertyDecorator & ParameterDecorator {\n return (target: any, propertyKey: string | symbol | undefined, indexOrDescriptor?: number | PropertyDescriptor) => {\n // Property Decorator\n if (typeof indexOrDescriptor === 'undefined' || (typeof indexOrDescriptor === 'object' && indexOrDescriptor !== null)) {\n const key = String(propertyKey);\n Object.defineProperty(target, key, {\n get: () => Container.resolve(token),\n enumerable: true,\n configurable: true\n });\n return;\n }\n\n // Parameter Decorator (Constructor only typically supported via Metadata, purely adding metadata here)\n if (typeof indexOrDescriptor === 'number') {\n const index = indexOrDescriptor;\n // target is Constructor\n const existing = Reflect.getMetadata('di:constructor:params', target) || [];\n existing.push({ index, token });\n Reflect.defineMetadata('di:constructor:params', existing, target);\n }\n };\n}\n\n/**\n * Decorator: Applies middleware OR injects dependencies.\n * - Class/Method: Middleware\n * - Property/Parameter: Dependency Injection\n */\nexport function Use(tokenOrMiddleware?: any | Middleware, ...moreMiddleware: Middleware[]) {\n return (target: any, propertyKey?: string, indexOrDescriptor?: PropertyDescriptor | number) => {\n // 1. Parameter Decorator (DI)\n if (typeof indexOrDescriptor === 'number') {\n const index = indexOrDescriptor;\n if (!propertyKey) {\n // Constructor parameter injection\n let token = tokenOrMiddleware;\n // target is the Constructor for constructor parameters\n\n // If token is missing, try to infer? \n // Constructor params 'design:paramtypes' are on the class (target).\n if (!token) {\n const paramTypes = Reflect.getMetadata(\"design:paramtypes\", target);\n if (paramTypes && paramTypes[index]) {\n token = paramTypes[index];\n }\n }\n\n const existing = Reflect.getMetadata('di:constructor:params', target) || [];\n existing.push({ index, token });\n Reflect.defineMetadata('di:constructor:params', existing, target);\n return;\n }\n // Method parameter\n if (!target[$routeArgs]) target[$routeArgs] = new Map();\n if (!target[$routeArgs].has(propertyKey)) target[$routeArgs].set(propertyKey, []);\n\n // If token is not provided (null/undefined), infer from design:paramtypes\n // But decorators run before we can really check? \n // In TS, we can get param types:\n let token = tokenOrMiddleware;\n if (!token) {\n const paramTypes = Reflect.getMetadata(\"design:paramtypes\", target, propertyKey);\n if (paramTypes && paramTypes[index]) {\n token = paramTypes[index];\n }\n }\n\n target[$routeArgs].get(propertyKey).push({\n index: index,\n type: RouteParamType.SERVICE,\n token: token\n });\n return;\n }\n\n // 2. Property Decorator (DI)\n // If propertyKey is defined and descriptor is undefined (or null) - Standard property decorator logic\n // But TS is tricky. \n if (typeof propertyKey === 'string' && indexOrDescriptor === undefined) {\n let token = tokenOrMiddleware;\n // Try to infer type\n if (!token) {\n token = Reflect.getMetadata(\"design:type\", target, propertyKey);\n }\n\n // We need to lazy resolve because Container might not be fully populated yet?\n // Or just use a getter.\n Object.defineProperty(target, propertyKey, {\n get: () => {\n // Circular dep check?\n if (!token) throw new Error(`Cannot resolve dependency for ${target.constructor.name}.${propertyKey} - no token provided and types unavailable.`);\n return Container.resolve(token);\n // Actually `Container` is in `di.ts`. Decorators imports symbols.\n // We can import Container here if we are careful.\n },\n enumerable: true,\n configurable: true\n });\n // Wait, modifying the prototype getter is one way.\n // But existing `Use` implementation for middleware didn't do this.\n // Let's defer Container import or rely on global?\n // Since `decorators.ts` is util, `di.ts` is util.\n // Let's implement property injection logic cleanly.\n return;\n }\n\n\n // 3. Class/Method Decorator (Middleware)\n // Fallback to original middleware logic\n const middleware = [tokenOrMiddleware, ...moreMiddleware];\n\n // If propertyKey is undefined, it's a class decorator\n if (!propertyKey) {\n const existing = target[$middleware] || [];\n target[$middleware] = [...existing, ...middleware];\n }\n // Method decorator\n else {\n if (!target[$middleware]) {\n target[$middleware] = new Map();\n }\n const existing = target[$middleware].get(propertyKey) || [];\n target[$middleware].set(propertyKey, [...existing, ...middleware]);\n }\n };\n}\n\n// --- Parameter Decorators ---\n\nfunction createParamDecorator(type: RouteParamType) {\n return (name?: string) => {\n return (target: any, propertyKey: string, parameterIndex: number) => {\n if (!target[$routeArgs]) {\n target[$routeArgs] = new Map();\n }\n if (!target[$routeArgs].has(propertyKey)) {\n target[$routeArgs].set(propertyKey, []);\n }\n target[$routeArgs].get(propertyKey).push({\n index: parameterIndex,\n type,\n name\n });\n };\n };\n}\n\n/**\n * Decorator: Binds a parameter to the request body.\n */\nexport const Body = createParamDecorator(RouteParamType.BODY);\n\n/**\n * Decorator: Binds a parameter to the request parameters.\n */\nexport const Param = createParamDecorator(RouteParamType.PARAM);\n\n/**\n * Decorator: Binds a parameter to the request query string.\n */\nexport const Query = createParamDecorator(RouteParamType.QUERY);\n\n/**\n * Decorator: Binds a parameter to the request headers.\n */\nexport const Headers = createParamDecorator(RouteParamType.HEADER);\n\n/**\n * Decorator: Binds a parameter to the request object.\n */\nexport const Req = createParamDecorator(RouteParamType.REQUEST);\n\n/**\n * Decorator: Binds a parameter to the request context.\n */\nexport const Ctx = createParamDecorator(RouteParamType.CONTEXT);\n\n\n/**\n * Decorator: Overrides the OpenAPI specification for a route.\n */\nexport function Spec(spec: MethodAPISpec | GuardAPISpec | AsyncAPISpec) {\n return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {\n if (!target[$routeSpec]) {\n target[$routeSpec] = new Map();\n }\n target[$routeSpec].set(propertyKey, spec);\n };\n}\n\n/**\n * Creates a method decorator for a specific HTTP verb.\n */\nfunction createMethodDecorator(method: Method) {\n return (path: string = \"/\") => {\n return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {\n if (!target[$routeMethods]) {\n target[$routeMethods] = new Map();\n }\n\n target[$routeMethods].set(propertyKey, {\n method,\n path,\n source: getCallerInfo(2)\n });\n if (path.includes('/user')) {\n console.log(`[Decorator] Captured source for ${propertyKey}:`, getCallerInfo());\n }\n };\n };\n}\n\n/**\n * Decorator: Binds a method to the GET HTTP verb.\n */\nexport const Get = createMethodDecorator(\"GET\");\n\n/**\n * Decorator: Binds a method to the POST HTTP verb.\n */\nexport const Post = createMethodDecorator(\"POST\");\n\n/**\n * Decorator: Binds a method to the PUT HTTP verb.\n */\nexport const Put = createMethodDecorator(\"PUT\");\n\n/**\n * Decorator: Binds a method to the DELETE HTTP verb.\n */\nexport const Delete = createMethodDecorator(\"DELETE\");\n\n/**\n * Decorator: Binds a method to the PATCH HTTP verb.\n */\nexport const Patch = createMethodDecorator(\"PATCH\");\n\n/**\n * Decorator: Binds a method to the OPTIONS HTTP verb.\n */\nexport const Options = createMethodDecorator(\"OPTIONS\");\n\n/**\n * Decorator: Binds a method to the HEAD HTTP verb.\n */\nexport const Head = createMethodDecorator(\"HEAD\");\n\n/**\n * Decorator: Binds a method to ANY HTTP verb.\n */\nexport const All = createMethodDecorator(\"ALL\");\n\n/**\n * Decorator: Binds a method to the WebSocket event.\n * @param eventName The name of the event to listen for.\n */\nexport function Event(eventName: string) {\n return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {\n target[$eventMethods] ??= new Map();\n target[$eventMethods].set(propertyKey, {\n eventName\n });\n };\n}\n\n/**\n * Decorator: Applies a rate limit to a class or method.\n */\nexport function RateLimit(options: RateLimitOptions) {\n return Use(RateLimitMiddleware(options));\n}\n\n/**\n * Decorator: Registers a method as an MCP Tool.\n * @param name The name of the tool (defaults to method name if not provided)\n * @param description Optional description\n * @param inputSchema Optional JSON Schema for input arguments\n */\nexport function Tool(options?: { name?: string; description?: string; inputSchema?: any; }) {\n return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {\n target[$mcpTools] ??= new Map();\n target[$mcpTools].set(propertyKey, {\n name: options?.name,\n description: options?.description,\n inputSchema: options?.inputSchema\n });\n };\n}\n\n/**\n * Decorator: Registers a method as an MCP Prompt.\n * @param name The name of the prompt\n * @param description Optional description\n * @param args Optional list of arguments\n */\nexport function Prompt(options?: { name?: string; description?: string; arguments?: { name: string; description?: string; required?: boolean; }[]; }) {\n return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {\n target[$mcpPrompts] ??= new Map();\n target[$mcpPrompts].set(propertyKey, {\n name: options?.name,\n description: options?.description,\n arguments: options?.arguments\n });\n };\n}\n\n/**\n * Decorator: Registers a method as an MCP Resource handler.\n * @param uri The URI pattern for the resource\n * @param name Optional name\n * @param description Optional description\n * @param mimeType Optional MIME type\n */\nexport function Resource(uri: string, options?: { name?: string; description?: string; mimeType?: string; }) {\n return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {\n target[$mcpResources] ??= new Map();\n target[$mcpResources].set(propertyKey, {\n uri,\n name: options?.name,\n description: options?.description,\n mimeType: options?.mimeType\n });\n };\n}\n","\n\n// Type definitions for better clarity\ninterface Route {\n method: string;\n path: string;\n op: any;\n}\n\ninterface GroupNode {\n name: string;\n type: 'group' | 'subgroup' | 'route';\n routes?: Route[];\n children?: GroupNode[];\n path?: string;\n isBuiltin?: boolean;\n}\n\nexport function ApiExplorerApp({ spec, base, asyncSpec, config }: any) {\n // Build hierarchy: router -> controller -> routes\n const hierarchy = new Map<string, Route[]>();\n\n // Helper to add route to hierarchy\n const addRoute = (groupKey: string, route: Route) => {\n if (!hierarchy.has(groupKey)) {\n hierarchy.set(groupKey, []);\n }\n hierarchy.get(groupKey)!.push(route);\n };\n\n // Helper to determine group key (controller/router)\n const getGroupKey = (op: any, source: any): string => {\n // 1. Prefer explicit tags if they look like \"titles\" (not paths)\n if (op.tags && op.tags.length > 0) {\n const tag = typeof op.tags[0] === 'string' ? op.tags[0] : op.tags[0].name;\n if (!tag.startsWith('/')) return tag;\n }\n\n // 2. Class Name (Controller)\n if (source?.className) return source.className;\n\n // 3. File Name (Router - Pretty)\n if (source?.file) {\n const parts = source.file.split('/');\n const filename = parts[parts.length - 1].replace(/\\.(ts|js)$/, '');\n // Convert snake_case or kebab-case to Title Case\n return filename.split(/[-_]/).map((w: string) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');\n }\n\n // 4. Fallback to path tag if we ignored it in step 1\n if (op.tags && op.tags.length > 0) {\n const tag = typeof op.tags[0] === 'string' ? op.tags[0] : op.tags[0].name;\n return tag;\n }\n\n return 'Ungrouped';\n };\n\n // Helper to find the longest common prefix of all paths in a group\n const findCommonPrefix = (routes: Route[]): string[] => {\n if (routes.length === 0) return [];\n\n const allSegments = routes.map(r => {\n const cleaned = r.path.replace(/^\\/|\\/$/g, '');\n return cleaned.split('/');\n });\n\n // Find the shortest path length\n const minLength = Math.min(...allSegments.map(s => s.length));\n\n const commonPrefix: string[] = [];\n for (let i = 0; i < minLength; i++) {\n const segment = allSegments[0][i];\n if (allSegments.every(segments => segments[i] === segment)) {\n commonPrefix.push(segment);\n } else {\n break;\n }\n }\n\n return commonPrefix;\n };\n\n // Recursive function to create subgroups based on path prefixes\n // Only creates subgroups when 3+ routes share a common prefix AND have diverging subpaths\n const createSubgroups = (routes: Route[], depth: number = 0, commonPrefixLength: number = 0): GroupNode[] => {\n if (routes.length < 3 || depth > 5) {\n // Don't create subgroups if less than 3 routes or too deep\n return routes.map(route => ({\n name: route.path,\n type: 'route' as const,\n path: route.path,\n routes: [route]\n }));\n }\n\n // Analyze path structure to find common prefixes\n const pathSegments = routes.map(r => {\n // Remove leading/trailing slashes and split\n const cleaned = r.path.replace(/^\\/|\\/$/g, '');\n const segments = cleaned.split('/');\n // Strip the common prefix for this group\n return segments.slice(commonPrefixLength);\n });\n\n // Find common prefix groups\n const prefixGroups = new Map<string, Route[]>();\n const ungrouped: Route[] = [];\n\n routes.forEach((route, idx) => {\n const segments = pathSegments[idx];\n if (segments.length <= depth) {\n ungrouped.push(route);\n return;\n }\n\n // Use the segment at current depth as prefix\n const prefix = segments.slice(0, depth + 1).join('/');\n if (!prefixGroups.has(prefix)) {\n prefixGroups.set(prefix, []);\n }\n prefixGroups.get(prefix)!.push(route);\n });\n\n // Create subgroups for prefixes with 3+ routes that actually diverge\n const result: GroupNode[] = [];\n\n prefixGroups.forEach((groupRoutes, prefix) => {\n if (groupRoutes.length >= 3) {\n // Check if routes diverge after this prefix\n // If all routes in this group have the same next segment, don't create a subgroup yet\n const nextSegments = new Set<string>();\n groupRoutes.forEach((route, idx) => {\n const routeIdx = routes.indexOf(route);\n const segments = pathSegments[routeIdx];\n if (segments.length > depth + 1) {\n nextSegments.add(segments[depth + 1]);\n }\n });\n\n // Only create a subgroup if there are diverging paths (2+ different next segments)\n // OR if we're at terminal paths (no more segments)\n const hasDivergingPaths = nextSegments.size >= 2;\n const allTerminal = groupRoutes.every((route, idx) => {\n const routeIdx = routes.indexOf(route);\n return pathSegments[routeIdx].length === depth + 1;\n });\n\n if (hasDivergingPaths || allTerminal) {\n // Create a subgroup and recurse\n const prefixName = prefix.split('/').pop() || prefix;\n result.push({\n name: prefixName,\n type: 'subgroup' as const,\n path: '/' + prefix,\n children: createSubgroups(groupRoutes, depth + 1, commonPrefixLength)\n });\n } else {\n // Don't create a subgroup, just recurse with increased depth\n // This flattens the common mount path\n result.push(...createSubgroups(groupRoutes, depth + 1, commonPrefixLength));\n }\n } else {\n // Add to ungrouped\n ungrouped.push(...groupRoutes);\n }\n });\n\n // Add ungrouped routes as individual items\n ungrouped.forEach(route => {\n result.push({\n name: route.path,\n type: 'route' as const,\n path: route.path,\n routes: [route]\n });\n });\n\n // Sort: subgroups first, then routes\n result.sort((a, b) => {\n if (a.type === 'subgroup' && b.type !== 'subgroup') return -1;\n if (a.type !== 'subgroup' && b.type === 'subgroup') return 1;\n return a.name.localeCompare(b.name);\n });\n\n return result;\n };\n\n // Process OpenAPI paths\n Object.entries(spec.paths || {}).forEach(([path, methods]: [string, any]) => {\n Object.entries(methods).forEach(([method, op]: [string, any]) => {\n if (!op.operationId) {\n op.operationId = `${method}-${path.replace(/\\//g, '-').replace(/[{}:]/g, '')}`;\n }\n\n const route: Route = { method, path, op };\n const source = (op as any)['x-shokupan-source'];\n const groupKey = getGroupKey(op, source);\n\n addRoute(groupKey, route);\n });\n });\n\n // Skip AsyncAPI channels - they should only appear in the AsyncAPI plugin\n // Object.entries(asyncSpec?.channels || {}).forEach(([name, ch]: [string, any]) => {\n // const operations = [];\n // if (ch.publish) operations.push({ method: 'recv', op: ch.publish });\n // if (ch.subscribe) operations.push({ method: 'send', op: ch.subscribe });\n\n // operations.forEach(({ method, op }) => {\n // if (!op.operationId) op.operationId = `${method}-${name.replace(/[^a-zA-Z0-9]/g, '-')}`;\n\n // const route: Route = { method, path: name, op };\n // const source = (op as any)['x-shokupan-source'] || (op as any)['x-source-info'];\n // const groupKey = getGroupKey(op, source);\n\n // addRoute(groupKey, route);\n // });\n // });\n\n // Build hierarchical groups with subgroups\n const hierarchicalGroups = Array.from(hierarchy.entries())\n .map(([name, routes]) => {\n // Sort routes by path\n routes.sort((a, b) => a.path.localeCompare(b.path));\n\n // Find the common prefix for all routes in this group\n const commonPrefix = findCommonPrefix(routes);\n const commonPrefixPath = '/' + commonPrefix.join('/');\n\n // Create subgroups recursively, stripping the common prefix\n const children = createSubgroups(routes, 0, commonPrefix.length);\n\n // Find middleware for this group by matching router/controller names\n const groupMiddleware: any[] = [];\n if (spec['x-middleware-registry']) {\n Object.entries(spec['x-middleware-registry']).forEach(([id, mw]: [string, any]) => {\n // Match middleware to this group based on file path\n const firstRoute = routes[0];\n const routeSource = firstRoute?.op?.['x-shokupan-source'];\n\n const mwFile = mw.file?.split('/').pop();\n const routeFile = routeSource?.file?.split('/').pop();\n\n // Include middleware if it comes from the same file as the routes in this group\n if (mwFile && routeFile && mwFile === routeFile && mw.scope !== 'global') {\n groupMiddleware.push({ ...mw, id, type: 'middleware' });\n }\n });\n }\n\n const isBuiltin = routes.some(r => r.op['x-shokupan-builtin'] === true);\n\n return {\n name,\n type: 'group' as const,\n children,\n middleware: groupMiddleware,\n commonPrefixPath, // Store for display stripping\n isBuiltin\n };\n });\n\n // Add Global Middleware group\n if (spec['x-middleware-registry']) {\n const allGroupMiddleware = hierarchicalGroups.flatMap((g: any) => g.middleware || []).map((m: any) => m.id);\n const globalMiddleware = Object.entries(spec['x-middleware-registry'])\n .filter(([id]) => !allGroupMiddleware.includes(id))\n .map(([id, mw]: [string, any]) => ({ ...mw, id, type: 'middleware' }));\n\n if (globalMiddleware.length > 0) {\n hierarchicalGroups.push({\n name: 'Global Middleware',\n type: 'group' as const,\n children: [],\n middleware: globalMiddleware,\n commonPrefixPath: '',\n isBuiltin: false\n });\n }\n }\n\n // Sort groups\n hierarchicalGroups.sort((a, b) => {\n if (a.name === 'Ungrouped') return 1;\n if (b.name === 'Ungrouped') return -1;\n if (a.name === 'Global Middleware') return 1;\n if (b.name === 'Global Middleware') return -1;\n return a.name.localeCompare(b.name);\n });\n\n // Flatten for client-side data (keep all routes in flat structure for main content)\n const allRoutes = Array.from(hierarchy.values()).flat();\n\n return (\n <html lang=\"en\">\n <head>\n <meta charSet=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>{spec.info?.title || 'API Explorer'}</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin=\"anonymous\" />\n <link href=\"https://fonts.googleapis.com/css2?family=Google+Sans+Code:ital,wght@0,300..800;1,300..800&family=Vend+Sans:ital,wght@0,300..700;1,300..700&display=swap\" rel=\"stylesheet\" />\n <link rel=\"stylesheet\" href={`${base}/style.css`} />\n <link rel=\"stylesheet\" href={`${base}/theme.css`} />\n <script src=\"https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js\"></script>\n <script src=\"https://cdn.jsdelivr.net/npm/monaco-editor@0.45.0/min/vs/loader.js\"></script>\n <script dangerouslySetInnerHTML={{\n __html: `\n (function() {\n if (!window.location.pathname.endsWith('/') && !window.location.pathname.split('/').pop().includes('.')) {\n var newUrl = window.location.pathname + '/' + window.location.search + window.location.hash;\n window.history.replaceState(null, null, newUrl);\n window.location.reload(); \n }\n })();\n `}}></script>\n </head>\n <body class=\"dark-theme\">\n <div id=\"app\">\n <Sidebar spec={spec} hierarchicalGroups={hierarchicalGroups} />\n <MainContent allRoutes={allRoutes} config={config} spec={spec} />\n </div>\n <script src={`${base}/explorer-client.mjs`} type=\"module\"></script>\n </body>\n </html>\n );\n}\n\n\nfunction Sidebar({ spec, hierarchicalGroups }: any) {\n // Helper to strip common prefix from path for display\n const stripPrefix = (path: string, prefix: string): string => {\n if (!prefix || prefix === '/') return path;\n if (path.startsWith(prefix)) {\n const stripped = path.substring(prefix.length);\n return stripped || '/';\n }\n return path;\n };\n\n // Helper to convert OpenAPI params to original format and highlight them\n const formatAndHighlightPath = (path: string): string => {\n // Convert {param} to :param\n const converted = path.replace(/\\{([^}]+)\\}/g, ':$1');\n\n // Highlight :param with color\n return converted.replace(/:([a-zA-Z0-9_]+)/g, '<span class=\"param-highlight\">:$1</span>');\n };\n\n // Recursive function to render navigation nodes\n const renderNavNode = (node: GroupNode, depth: number = 0, commonPrefix: string = ''): any => {\n if (node.type === 'route') {\n const route = node.routes![0];\n const source = route.op['x-shokupan-source'] || route.op['x-source-info'];\n const isRuntime = route.op['x-source-info']?.isRuntime;\n const displayPath = stripPrefix(route.path, commonPrefix);\n const highlightedPath = formatAndHighlightPath(displayPath);\n\n return (\n <div class=\"nav-item-wrapper\" style={`padding-left: ${depth * 12}px;`}>\n <a\n key={route.op.operationId}\n href={`#${route.op.operationId}`}\n class=\"nav-item\"\n data-id={route.op.operationId}\n title={route.path}\n >\n <span class={`badge badge-${route.method.toUpperCase()}`}>{route.method.toUpperCase()}</span>\n <span class=\"nav-label\" dangerouslySetInnerHTML={{ __html: highlightedPath }}></span>\n {isRuntime && (\n <span class=\"nav-warning\" title=\"Static Analysis Failed\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"></path>\n <line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"></line>\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"></line>\n </svg>\n </span>\n )}\n </a>\n {source?.file && (\n <a\n href={`vscode://file/${source.file}:${source.line || 1}`}\n class=\"nav-source-link\"\n title={`${source.file}:${source.line || 1}`}\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polyline points=\"16 18 22 12 16 6\"></polyline>\n <polyline points=\"8 6 2 12 8 18\"></polyline>\n </svg>\n </a>\n )}\n </div>\n );\n } else if (node.type === 'subgroup') {\n return (\n <div class=\"nav-subgroup collapsed\" style={`padding-left: ${depth * 12}px;`}>\n <div class=\"nav-subgroup-title\">\n <span class=\"chevron\">\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </span>\n <span>{node.name}</span>\n </div>\n <div class=\"nav-subgroup-items\">\n {node.children?.map((child: GroupNode) => renderNavNode(child, depth + 1, commonPrefix))}\n </div>\n </div>\n );\n }\n };\n\n return (\n <aside class=\"sidebar\">\n <div class=\"resize-handle\"></div>\n <header class=\"sidebar-header\">\n <button class=\"toggle-sidebar\">☰</button>\n <h1>{spec.info?.title}</h1>\n <div class=\"version\">{spec.info?.version}</div>\n </header>\n <div class=\"sidebar-collapse-trigger\">➔</div>\n <nav class=\"nav-groups\">\n {hierarchicalGroups.map((group: any) => (\n <div class={`nav-group collapsed ${group.isBuiltin ? 'builtin-group' : ''}`} key={group.name}>\n <div class=\"nav-group-title\">\n <span class=\"chevron\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </span>\n {group.isBuiltin && (\n <span class=\"builtin-icon\" title=\"Built-in Plugin\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"5\" ry=\"5\"></rect>\n <path d=\"M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z\"></path>\n <line x1=\"17.5\" y1=\"6.5\" x2=\"17.51\" y2=\"6.5\"></line>\n </svg>\n </span>\n )}\n {group.name}\n </div>\n <div class=\"nav-items\">\n {/* Render middleware first if any */}\n {group.middleware && group.middleware.length > 0 && (\n <div class=\"group-middleware\">\n {group.middleware.map((mw: any) => (\n <a\n key={mw.id}\n href={`#middleware-${mw.id}`}\n class=\"nav-item middleware-nav-item\"\n data-middleware-id={mw.id}\n title={mw.name}\n >\n <span class=\"middleware-icon\">⚙</span>\n <span class=\"nav-label\">{mw.name}</span>\n {mw.usedBy && mw.usedBy.length > 0 && (\n <span class=\"middleware-badge\" title={`Used by ${mw.usedBy.length} routes`}>{mw.usedBy.length}</span>\n )}\n {mw.file && (\n <a\n href={`vscode://file/${mw.file}:${mw.startLine || 1}`}\n class=\"nav-source-link\"\n title={`${mw.file}:${mw.startLine || 1}`}\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polyline points=\"16 18 22 12 16 6\"></polyline>\n <polyline points=\"8 6 2 12 8 18\"></polyline>\n </svg>\n </a>\n )}\n </a>\n ))}\n </div>\n )}\n {/* Then render routes */}\n {group.children?.map((child: GroupNode) => renderNavNode(child, 0, group.commonPrefixPath || ''))}\n </div>\n </div>\n ))}\n </nav>\n\n\n </aside>\n );\n}\n\nfunction MainContent({ allRoutes, config, spec }: any) {\n // Serialize data for client-side consumption\n const explorerData = JSON.stringify({\n routes: allRoutes,\n config,\n info: spec.info,\n middlewareRegistry: spec['x-middleware-registry'] || {}\n });\n\n const safeJson = explorerData.replace(/<\\/script>/g, '<\\\\/script>');\n\n return (\n <main class=\"content\" id=\"main-content\">\n <div id=\"ide-container\">\n <div class=\"empty-state\">Select a request to view details</div>\n </div>\n <script id=\"explorer-data\" type=\"application/json\" dangerouslySetInnerHTML={{ __html: safeJson }}></script>\n </main>\n );\n}\n","import { readFile } from 'fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport renderToString from 'preact-render-to-string';\nimport { ShokupanRouter } from '../../../router';\nimport type { Shokupan } from '../../../shokupan.ts';\nimport type { ShokupanPlugin, ShokupanPluginOptions } from '../../../util/types.ts';\nimport { ApiExplorerApp } from './components.tsx';\n\nexport interface ApiExplorerOptions {\n baseDocument?: any;\n path?: string;\n}\n\nexport class ApiExplorerPlugin extends ShokupanRouter implements ShokupanPlugin {\n\n constructor(private readonly pluginOptions: ApiExplorerOptions = {}) {\n console.log('ApiExplorerPlugin: CONSTRUCTOR CALLED');\n super({ renderer: renderToString });\n pluginOptions.path ??= '/explorer';\n\n // Metadata\n this.metadata = {\n file: import.meta.file,\n line: 1,\n name: 'ApiExplorerPlugin',\n pluginName: 'ApiExplorer'\n };\n\n this.init();\n }\n\n onInit(app: Shokupan, options?: ShokupanPluginOptions) {\n const path = this.pluginOptions.path || options?.path || '/apiexplorer';\n app.mount(path, this);\n\n // Ensure async api gen is enabled if this plugin is used\n if (app.applicationConfig.enableOpenApiGen !== true) {\n console.warn('ApiExplorerPlugin: enableOpenApiGen is disabled. ApiExplorerPlugin will not generate spec.');\n }\n }\n\n private static getBasePath() {\n const dir = dirname(fileURLToPath(import.meta.url));\n // In production (dist/), files are in dist/plugins/application/api-explorer/\n if (dir.endsWith('dist')) {\n return dir + '/plugins/application/api-explorer';\n }\n // In dev mode (src/plugins/application/api-explorer/), files are in same directory\n return dir;\n }\n\n init() {\n\n const serveFile = async (ctx: any, file: string, type: string) => {\n const content = await readFile(join(ApiExplorerPlugin.getBasePath(), 'static', file), 'utf-8');\n ctx.set('Content-Type', type);\n return ctx.send(content);\n };\n\n const stripSourceCode = (spec: any) => {\n if (!spec || !spec.paths) return spec;\n Object.values(spec.paths).forEach((methods: any) => {\n Object.values(methods).forEach((op: any) => {\n if (op['x-source-info']?.snippet) {\n delete op['x-source-info'].snippet;\n }\n if (op['x-shokupan-source']?.code) {\n console.log('Deleting x-shokupan-source.code');\n delete op['x-shokupan-source'].code;\n }\n });\n });\n return spec;\n };\n\n this.get('/style.css', ctx => serveFile(ctx, 'style.css', 'text/css'));\n this.get('/theme.css', ctx => serveFile(ctx, 'theme.css', 'text/css'));\n this.get('/explorer-client.mjs', ctx => serveFile(ctx, 'explorer-client.mjs', 'application/javascript'));\n\n this.get('/_source', async (ctx) => {\n const file = ctx.query['file'];\n if (!file) return ctx.text('Missing file parameter', 400);\n\n // Security: Validate path is within project root\n const { resolve, normalize, isAbsolute } = await import('node:path');\n const cwd = process.cwd();\n const resolvedPath = resolve(cwd, file);\n\n // Ensure the resolved path starts with the cwd\n // This prevents ../ traversal.\n // We DO NOT resolve symlinks (no fs.realpath), so we trust the logical path structure.\n if (!resolvedPath.startsWith(cwd)) {\n return ctx.text('Forbidden: File must be within project root', 403);\n }\n\n try {\n const content = await readFile(resolvedPath, 'utf-8');\n return ctx.text(content);\n } catch (err) {\n return ctx.text('File not found', 404);\n }\n });\n\n this.get('/openapi.json', async (ctx) => {\n const spec = (this.root as any).openApiSpec\n ? structuredClone((this.root as any).openApiSpec)\n : await (this.root || this).generateApiSpec();\n return ctx.json(stripSourceCode(spec));\n });\n\n this.get('/', async (ctx) => {\n const spec = (this.root as any).openApiSpec\n ? structuredClone((this.root as any).openApiSpec)\n : await (this.root || this).generateApiSpec();\n const asyncSpec = (ctx.app as any).asyncApiSpec;\n const base = this.pluginOptions.path!;\n const element = ApiExplorerApp({ spec: stripSourceCode(spec), base, asyncSpec });\n const html = renderToString(element);\n if (html.length === 0) throw new Error('ApiExplorerPlugin: rendered page is blank.');\n return ctx.html(html);\n });\n }\n}\n","\n\n\n\nexport function AsyncApiApp({ spec, serverUrl, base, disableSourceView, navTree }: any) {\n return (\n <html lang=\"en\">\n <head>\n <meta charSet=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Shokupan AsyncAPI</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin=\"anonymous\" />\n <link href=\"https://fonts.googleapis.com/css2?family=Google+Sans+Code:ital,wght@0,300..800;1,300..800&family=Vend+Sans:ital,wght@0,300..700;1,300..700&display=swap\" rel=\"stylesheet\" />\n <link rel=\"stylesheet\" href={`${base}/theme.css`} />\n <link rel=\"stylesheet\" href={`${base}/style.css`} />\n <script dangerouslySetInnerHTML={{\n __html: `\n window.INITIAL_SPEC = ${JSON.stringify(spec)};\n window.INITIAL_SERVER_URL = \"${serverUrl}\";\n window.DISABLE_SOURCE_VIEW = ${JSON.stringify(disableSourceView)};\n window.BASE_PATH = \"${base}\";\n `}} />\n </head>\n <body>\n <div class=\"app-container\">\n <Sidebar navTree={navTree} disableSourceView={disableSourceView} />\n\n <div class=\"resizer\" id=\"resizer-left\"></div>\n\n <MainContent />\n\n <div class=\"resizer\" id=\"resizer-right\"></div>\n\n <ConsolePanel serverUrl={serverUrl} />\n </div>\n\n <script src=\"https://cdn.socket.io/4.7.4/socket.io.min.js\"></script>\n <script src=\"https://cdn.jsdelivr.net/npm/monaco-editor@0.45.0/min/vs/loader.js\"></script>\n <script src={`${base}/asyncapi-client.mjs`} type=\"module\"></script>\n </body>\n </html>\n );\n}\n\nfunction Sidebar({ navTree, disableSourceView }: any) {\n return (\n <div class=\"sidebar\" id=\"sidebar\">\n <div class=\"sidebar-header\" style=\"display:flex; justify-content:space-between; align-items:center;\">\n <h2>AsyncAPI</h2>\n <button id=\"btn-collapse-nav\" class=\"btn-icon\" title=\"Collapse Sidebar\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polyline points=\"15 18 9 12 15 6\"></polyline>\n </svg>\n </button>\n </div>\n <div class=\"nav-list scroller\" id=\"nav-list\">\n <NavNode node={navTree} level={0} disableSourceView={disableSourceView} />\n </div>\n </div>\n );\n}\n\nfunction NavNode({ node, level, disableSourceView }: any) {\n // Sort children\n const sortedEntries = Object.entries(node.children || {}).sort((a, b) => {\n const [aKey, aItem] = a as [string, any];\n const [bKey, bItem] = b as [string, any];\n\n // Prioritize Warnings\n const isWarningA = aItem.data?.op?.['x-warning'];\n const isWarningB = bItem.data?.op?.['x-warning'];\n if (isWarningA && !isWarningB) return -1;\n if (!isWarningA && isWarningB) return 1;\n\n if (aKey === bKey) return 0;\n if (aKey === 'Warning' || aKey === 'Warnings') return -1;\n if (bKey === 'Warning' || bKey === 'Warnings') return 1;\n if (aKey === 'Application') return -1;\n if (bKey === 'Application') return 1;\n\n // Directories/Groups first? Original code seemed to just sort by string, \n // with specific exceptions.\n if (aKey[0] === '/') return 1;\n if (bKey[0] === '/') return -1;\n\n return aKey.localeCompare(bKey);\n });\n\n return (\n <>\n {sortedEntries.map(([key, item]: [string, any]) => {\n const hasChildren = Object.keys(item.children || {}).length > 0;\n\n if (level === 0) {\n // Top Level Group\n return (\n <div key={key}>\n <div class=\"group-label\">{key}</div>\n {hasChildren && (\n <div class=\"tree-node\" style=\"margin-left: 0\">\n <NavNode node={item} level={level + 1} disableSourceView={disableSourceView} />\n </div>\n )}\n </div>\n );\n }\n\n // Nested Nodes\n const isLeaf = item.isLeaf;\n\n return (\n <div key={key}>\n {isLeaf ? (\n <LeafNode item={item} label={key} disableSourceView={disableSourceView} />\n ) : (\n <div class=\"tree-item\" style=\"color: var(--text-muted)\">\n <span class=\"tree-label\">{key}</span>\n </div>\n )}\n\n {hasChildren && (\n <div class=\"tree-node\">\n <NavNode node={item} level={level + 1} disableSourceView={disableSourceView} />\n </div>\n )}\n </div>\n );\n })}\n </>\n );\n}\n\nfunction LeafNode({ item, label, disableSourceView }: any) {\n const isWarning = item.data?.op?.['x-warning'];\n const opId = item.data?.name; // Using name as ID for referencing\n const sourceInfo = item.data?.op?.['x-source-info'];\n\n let content;\n if (isWarning) {\n content = (\n <>\n <span style=\"margin-right: 6px;\">⚠️</span>\n <span class=\"tree-label\">{label}</span>\n </>\n );\n } else {\n const badgeText = item.data.type === 'publish' ? 'SEND' : 'RECV';\n const isPlugin = item.data.op?.['x-shokupan-plugin-name'] || sourceInfo?.pluginName;\n\n content = (\n <>\n <span class={`badge badge-${badgeText}`}>{badgeText}</span>\n {isPlugin && (\n <span class=\"builtin-icon\" title=\"Built-in Plugin\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"5\" ry=\"5\"></rect>\n <path d=\"M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z\"></path>\n <line x1=\"17.5\" y1=\"6.5\" x2=\"17.51\" y2=\"6.5\"></line>\n </svg>\n </span>\n )}\n <span class=\"tree-label\">{label}</span>\n </>\n );\n }\n\n return (\n <div class=\"tree-item\" data-event={opId} style={isWarning ? \"color: #fbbf24\" : \"\"}>\n {content}\n {sourceInfo && !disableSourceView && (\n <a href={`vscode://file/${sourceInfo.file}:${sourceInfo.line}`}\n class=\"source-link\"\n onClick={(e) => { e.stopPropagation(); }} // This won't work in SSR string, handled in client script\n title={`${sourceInfo.file}:${sourceInfo.line}`}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" style=\"display:block\">\n <polyline points=\"16 18 22 12 16 6\"></polyline><polyline points=\"8 6 2 12 8 18\"></polyline>\n </svg>\n </a>\n )}\n </div>\n );\n}\n\n\nfunction MainContent() {\n return (\n <div id=\"main-wrapper\" style=\"flex: 1; min-width: 0; position: relative; overflow: hidden;\">\n <button id=\"btn-expand-nav\" class=\"btn-icon floating-toggle left\" title=\"Expand Sidebar\" style=\"display:none;\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </button>\n <button id=\"btn-expand-console\" class=\"btn-icon floating-toggle right\" title=\"Expand Console\" style=\"display:none;\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polyline points=\"15 18 9 12 15 6\"></polyline>\n </svg>\n </button>\n\n <main class=\"main-content scroller\" id=\"doc-panel\" style=\"height: 100%;\">\n <div class=\"empty-state\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\">\n <path d=\"M4 19.5A2.5 2.5 0 0 1 6.5 17H20\"></path>\n <path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z\"></path>\n </svg>\n <h3>Select an event to view details</h3>\n </div>\n </main>\n </div>\n );\n}\n\nfunction ConsolePanel({ serverUrl }: any) {\n return (\n <div class=\"console-panel\" id=\"console-panel\">\n <div class=\"console-header\">\n <div style=\"display:flex; justify-content:space-between; align-items:center; margin-bottom: 8px;\">\n <h3 style=\"margin:0; font-size:1rem;\">Console</h3>\n <div style=\"display:flex; gap: 4px;\">\n <button id=\"btn-maximize-console\" class=\"btn-icon\" title=\"Maximize Console\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect>\n </svg>\n </button>\n <button id=\"btn-collapse-console\" class=\"btn-icon\" title=\"Collapse Console\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </button>\n </div>\n </div>\n <div class=\"connection-bar\">\n <select id=\"protocol\">\n <option value=\"ws\">WS</option>\n <option value=\"wss\">WSS</option>\n <option value=\"socket.io\">Socket.IO</option>\n </select>\n <div style=\"width: 1px; background: rgba(255,255,255,0.1); margin: 2px 0;\"></div>\n <input type=\"text\" id=\"url\" value={serverUrl} />\n </div>\n <div style=\"display: grid; grid-template-columns: 1fr auto; gap: 8px;\">\n <button id=\"connect-btn\" class=\"btn\">Connect</button>\n <button id=\"clear-logs-btn\" class=\"btn secondary\" title=\"Clear Logs\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"></path>\n </svg>\n </button>\n </div>\n <div class=\"status-indicator\">\n <div id=\"status-dot\" class=\"dot\"></div>\n <span id=\"connection-status\">Disconnected</span>\n </div>\n </div>\n\n <div class=\"logs-container scroller\" id=\"logs\">\n <div class=\"log-shim\" id=\"log-shim\"></div>\n </div>\n\n <div class=\"compose-area\">\n <div class=\"compose-header\">\n <span>Payload</span>\n <span id=\"target-event\" style=\"color: var(--primary);\">--</span>\n </div>\n <div id=\"editor-container\"></div>\n <div class=\"send-bar\">\n <button id=\"send-btn\" class=\"btn\">Send Message</button>\n </div>\n </div>\n </div>\n );\n}\n\n// Logic to build the tree from spec\nexport function buildNavTree(spec: any) {\n if (!spec || !spec.channels) return { children: {} };\n\n const root: any = { children: {} };\n\n Object.keys(spec.channels).forEach(name => {\n const ch = spec.channels[name];\n const op = ch.publish || ch.subscribe;\n const type = ch.publish ? 'publish' : 'subscribe';\n\n // Get Tag (Controller Name)\n const tag = (op.tags && op.tags.length > 0) ? op.tags[0].name : 'General';\n\n // Ensure Tag Group Exists\n if (!root.children[tag]) root.children[tag] = { children: {} };\n\n const parts = name.split(/[\\.\\/]/);\n let current = root.children[tag];\n\n parts.forEach((part, i) => {\n if (!current.children[part]) current.children[part] = { children: {} };\n current = current.children[part];\n\n if (i === parts.length - 1) {\n current.isLeaf = true;\n current.data = { name, op, type };\n }\n });\n });\n\n return root;\n}\n","\nimport type { ShokupanRouter } from '../../../router';\nimport { $childRouters, $isApplication, $mountPath, $routes } from '../../../util/symbol';\nimport type { AsyncAPIOptions } from '../../../util/types';\nimport { getAstRoutes } from '../shared/ast-utils';\n\n/**\n * Regex patterns for detecting emit calls.\n */\n\n/**\n * Check if a schema contains fields with unknown types\n */\nfunction hasUnknownFields(schema: any): boolean {\n if (!schema) return false;\n if (schema['x-unknown']) return true;\n\n if (schema.type === 'object' && schema.properties) {\n return Object.values(schema.properties).some((prop: any) =>\n hasUnknownFields(prop)\n );\n }\n\n if (schema.type === 'array' && schema.items) {\n return hasUnknownFields(schema.items);\n }\n\n return false;\n}\n\n/**\n * Gets deduped AST routes if available.\n * Duplicated from openapi.ts to avoid cross-module dependency issues.\n */\n\nexport async function generateAsyncApi<T extends Record<string, any>>(rootRouter: ShokupanRouter<T>, options: AsyncAPIOptions = {}): Promise<any> {\n const channels: Record<string, any> = {};\n\n // Attempt to run AST Analysis\n let astRoutes: any[] = [];\n let astMiddlewareRegistry: Record<string, any> = {};\n let applications: any[] = [];\n try {\n const { OpenAPIAnalyzer } = await import('../openapi/analyzer');\n const entrypoint = (globalThis as any).Bun?.main || require.main?.filename || process.argv[1];\n const analyzer = new OpenAPIAnalyzer(process.cwd(), entrypoint);\n const analysisResult = await analyzer.analyze();\n applications = analysisResult.applications;\n astRoutes = await getAstRoutes(applications, {\n includePrefix: false,\n pathTransform: (p) => p.startsWith('/') ? p.slice(1) : p\n });\n\n // Build middleware registry from AST-analyzed applications\n let middlewareId = 0;\n for (const app of applications) {\n if (app.middleware && app.middleware.length > 0) {\n for (const mw of app.middleware) {\n const id = `middleware-${middlewareId++}`;\n astMiddlewareRegistry[id] = {\n ...mw,\n id,\n usedBy: [] // Will be populated when processing events\n };\n }\n }\n }\n } catch (e) {\n // Silently fail if analysis cannot run\n if (options.warnings) {\n options.warnings.push({\n type: 'ast-analysis-failed',\n message: 'AST Analysis failed or skipped',\n detail: e.message\n });\n }\n }\n\n const matchedAstRoutes = new Set<any>();\n\n const collect = async (router: ShokupanRouter<T>, prefix = \"\") => {\n // Collect Event Handlers (Client -> Server)\n const eventHandlers = router.getEventHandlers();\n\n // Determine Router Tag\n let routerTag = \"Other\";\n if ((router as any)[$isApplication]) {\n routerTag = \"Application\";\n } else if (router.constructor.name && router.constructor.name !== \"ShokupanRouter\") {\n routerTag = router.constructor.name;\n } else {\n routerTag = (router as any)[$mountPath] || \"Router\";\n }\n\n if (eventHandlers) {\n for (const [eventName, handlers] of eventHandlers.entries()) {\n // Iterate through all handlers to accumulate source info\n for (const handler of handlers) {\n const specName = `event/${eventName}`;\n\n // Check for @Spec metadata\n const userSpec = (handler as any).spec;\n\n // Determine tags: Use userSpec tags (from decorators) or fallback to Router context\n let tags = userSpec?.tags;\n if (!tags && routerTag) {\n tags = [{ name: routerTag }];\n }\n\n // Match with AST route to find emits and source info\n let astMatch = astRoutes.find(r =>\n (r.method === 'EVENT' || r.method === 'ON') &&\n r.path === eventName\n );\n\n if (!astMatch) {\n // Heuristic matching\n const runtimeSource = ((handler as any).originalHandler || handler).toString();\n const stripComments = (s: string) => s.replace(/\\/\\*[\\s\\S]*?\\*\\/|([^\\\\:]|^)\\/\\/.*$/gm, '$1');\n const normalize = (s: string) => stripComments(s).replace(/\\s+/g, '');\n\n const runtimeHandlerSrc = normalize(runtimeSource);\n\n const eventRoutes = astRoutes.filter(r => r.method === 'EVENT' || r.method === 'ON');\n\n astMatch = eventRoutes.find(r => {\n const astHandlerSrc = normalize(r.handlerSource || r.handlerName || '');\n\n if (!astHandlerSrc || astHandlerSrc.length < 5) return false;\n return runtimeHandlerSrc.includes(astHandlerSrc) ||\n astHandlerSrc.includes(runtimeHandlerSrc) ||\n (r.handlerSource && runtimeHandlerSrc.includes(normalize(r.handlerSource).substring(0, 50)));\n });\n }\n\n if (astMatch) matchedAstRoutes.add(astMatch);\n\n const sourceInfo = ((handler as any).source || astMatch?.sourceContext) ? {\n file: (handler as any).source?.file || astMatch?.sourceContext?.file,\n line: (handler as any).source?.line || astMatch?.sourceContext?.startLine,\n startLine: (handler as any).source?.line || astMatch?.sourceContext?.startLine,\n endLine: astMatch?.sourceContext?.endLine,\n highlightLines: astMatch?.sourceContext ? [astMatch.sourceContext.startLine, astMatch.sourceContext.endLine] : undefined\n } : undefined;\n\n const message = {\n ...(userSpec?.message || {})\n };\n let inferenceFailed = false;\n\n if (!message.payload) {\n if (astMatch) {\n if (astMatch.requestTypes?.body) {\n message.payload = astMatch.requestTypes.body;\n // Check if generic object\n if (message.payload.type === 'object' &&\n !message.payload.properties &&\n !message.payload.additionalProperties &&\n Object.keys(message.payload).length === 1) {\n inferenceFailed = true;\n }\n } else {\n // Valid AST match but no body usage -> Payload is unused\n }\n } else {\n // Default to object if no AST and no user spec\n message.payload = { type: 'object' };\n inferenceFailed = true;\n }\n }\n\n if (!channels[eventName]) {\n const publishOp = {\n operationId: `on${eventName.charAt(0).toUpperCase() + eventName.slice(1)}`,\n tags,\n message,\n ...(userSpec?.type === 'publish' ? userSpec : {}),\n \"x-source-info\": sourceInfo ? [sourceInfo] : [],\n \"x-shokupan-source\": {\n ...sourceInfo,\n pluginName: (handler as any).pluginName\n }\n };\n\n if (inferenceFailed) {\n (publishOp as any)['x-warning'] = true;\n if (!publishOp.summary) publishOp.summary = \"Payload Inference Failed\";\n if (!publishOp.description) publishOp.description = \"The payload format could not be statically inferred from the source code. Please add a type assertion or @Spec decorator.\";\n }\n\n // Apply user-defined summary/description if not already set by inferenceFailed warning\n if (userSpec?.summary && !publishOp.summary) publishOp.summary = userSpec.summary;\n if (userSpec?.description && !publishOp.description) publishOp.description = userSpec.description;\n\n channels[eventName] = {\n publish: publishOp\n };\n } else {\n // Accumulate source info from additional handlers\n if (sourceInfo) {\n if (!channels[eventName].publish[\"x-source-info\"]) {\n channels[eventName].publish[\"x-source-info\"] = [];\n }\n const exists = channels[eventName].publish[\"x-source-info\"].some((s: any) =>\n s.file === sourceInfo.file && s.line === sourceInfo.line\n );\n if (!exists) {\n channels[eventName].publish[\"x-source-info\"].push(sourceInfo);\n }\n }\n }\n\n // Analyze for outgoing events\n let emits = astMatch?.emits || [];\n\n for (const emit of emits) {\n if (emit.event === '__DYNAMIC_EMIT__') {\n const warningKey = `${eventName}/Dynamic Emit`;\n if (options.warnings) {\n options.warnings.push({\n type: 'dynamic-emit',\n message: 'Dynamic emit detected',\n detail: `Event: ${eventName}`,\n location: { file: astMatch?.sourceContext?.file, line: emit.location?.startLine }\n });\n }\n channels[warningKey] = {\n subscribe: {\n operationId: `dynamicEmitWarning${eventName}`,\n summary: \"Dynamic Emit Detected\",\n description: \"This handler emits an event with a dynamic name that could not be determined statically.\",\n tags: tags,\n \"x-warning\": true,\n \"x-source-info\": {\n file: astMatch?.sourceContext?.file,\n line: emit.location?.startLine,\n startLine: emit.location?.startLine,\n endLine: emit.location?.endLine,\n highlightLines: emit.location ? [emit.location.startLine, emit.location.endLine] : undefined\n },\n \"x-shokupan-source\": {\n file: astMatch?.sourceContext?.file,\n line: emit.location?.startLine,\n },\n message: { payload: { type: 'object' } }\n }\n };\n continue;\n }\n\n const emitStart = emit.location?.startLine;\n const emitEnd = emit.location?.endLine;\n\n const newSourceInfo = (sourceInfo && emitStart) ? {\n file: sourceInfo.file,\n line: emitStart,\n startLine: emitStart,\n endLine: emitEnd,\n highlightLines: sourceInfo.highlightLines,\n emitHighlightLines: [emitStart, emitEnd]\n } : undefined;\n\n if (!channels[emit.event]) {\n const payload = emit.payload || { type: 'object' };\n const warning = hasUnknownFields(payload);\n\n channels[emit.event] = {\n subscribe: {\n operationId: `emit${emit.event.charAt(0).toUpperCase() + emit.event.slice(1)}`,\n tags,\n message: {\n payload\n },\n ...(warning ? {\n 'x-warning': true,\n 'x-warning-reason': 'Payload contains fields with unknown types that could not be statically analyzed'\n } : {}),\n \"x-source-info\": newSourceInfo ? [newSourceInfo] : [],\n \"x-shokupan-source\": (sourceInfo && emitStart) ? {\n file: sourceInfo.file,\n line: emitStart,\n pluginName: (handler as any).pluginName\n } : undefined\n }\n };\n } else {\n if (newSourceInfo) {\n if (!channels[emit.event].subscribe[\"x-source-info\"]) {\n channels[emit.event].subscribe[\"x-source-info\"] = [];\n }\n const existing = channels[emit.event].subscribe[\"x-source-info\"];\n const exists = existing.some((s: any) =>\n s.file === newSourceInfo.file && s.line === newSourceInfo.line\n );\n if (!exists) {\n existing.push(newSourceInfo);\n }\n }\n }\n }\n }\n } // end for handler\n }; // end for eventHandlers\n\n // Collect HTTP Routes (Server -> Client Emits Only)\n const httpRoutes = router[$routes];\n if (httpRoutes) {\n for (const route of httpRoutes) {\n const handler = route.handler;\n\n // Determine tags\n let tags = route.handlerSpec?.tags;\n if (!tags && routerTag) {\n tags = [{ name: routerTag }];\n }\n\n // Find AST match\n const methodUpper = route.method.toUpperCase();\n let astMatch = astRoutes.find(r =>\n r.method === methodUpper &&\n (r.path === route.path || r.path === '/' + route.path)\n );\n\n if (!astMatch) {\n const runtimeSource = ((handler as any).originalHandler || handler).toString();\n const runtimeHandlerSrc = runtimeSource.replace(/\\s+/g, ' ');\n const sameMethodRoutes = astRoutes.filter(r => r.method === methodUpper);\n\n astMatch = sameMethodRoutes.find(r => {\n const astHandlerSrc = (r.handlerSource || r.handlerName || '').replace(/\\s+/g, ' ');\n if (!astHandlerSrc || astHandlerSrc.length < 20) return false;\n return runtimeHandlerSrc.includes(astHandlerSrc) ||\n astHandlerSrc.includes(runtimeHandlerSrc) ||\n (r.handlerSource && runtimeHandlerSrc.includes(r.handlerSource.substring(0, 50)));\n });\n }\n\n // Reconstruct SourceInfo for reuse\n const sourceInfo = ((handler as any).source || astMatch?.sourceContext) ? {\n file: (handler as any).source?.file || astMatch?.sourceContext?.file,\n line: (handler as any).source?.line || astMatch?.sourceContext?.startLine,\n startLine: (handler as any).source?.line || astMatch?.sourceContext?.startLine,\n endLine: astMatch?.sourceContext?.endLine,\n highlightLines: astMatch?.sourceContext ? [astMatch.sourceContext.startLine, astMatch.sourceContext.endLine] : undefined\n } : undefined;\n\n let emits = astMatch?.emits || [];\n\n for (const emit of emits) {\n const emitStart = emit.location?.startLine;\n const emitEnd = emit.location?.endLine;\n\n const newSourceInfo = (sourceInfo && emitStart) ? {\n file: sourceInfo.file,\n line: emitStart,\n startLine: emitStart,\n endLine: emitEnd,\n highlightLines: sourceInfo.highlightLines,\n emitHighlightLines: [emitStart, emitEnd]\n } : undefined;\n\n // Only add if not already defined\n if (!channels[emit.event]) {\n const payload = emit.payload || { type: 'object' };\n const warning = hasUnknownFields(payload);\n\n channels[emit.event] = {\n subscribe: {\n operationId: `emit${emit.event.charAt(0).toUpperCase() + emit.event.slice(1)}`,\n tags,\n message: {\n payload\n },\n ...(warning ? {\n 'x-warning': true,\n 'x-warning-reason': 'Payload contains fields with unknown types that could not be statically analyzed'\n } : {}),\n \"x-source-info\": newSourceInfo ? [newSourceInfo] : [],\n \"x-shokupan-source\": (sourceInfo && emitStart) ? {\n file: sourceInfo.file,\n line: emitStart,\n } : undefined\n }\n };\n } else {\n if (newSourceInfo) {\n if (!channels[emit.event].subscribe[\"x-source-info\"]) {\n channels[emit.event].subscribe[\"x-source-info\"] = [];\n }\n const existing = channels[emit.event].subscribe[\"x-source-info\"];\n const exists = existing.some((s: any) =>\n s.file === newSourceInfo.file && s.line === newSourceInfo.line\n );\n if (!exists) {\n existing.push(newSourceInfo);\n }\n }\n }\n }\n }\n }\n\n // Recursively check children\n const childRouters = router[$childRouters];\n for (const child of childRouters) {\n await collect(child);\n }\n };\n\n await collect(rootRouter);\n\n\n // Process detected dynamic/unknown events from AST that weren't matched\n const dynamicEvents = astRoutes.filter(r => r.path === '__DYNAMIC_EVENT__' && !matchedAstRoutes.has(r));\n dynamicEvents.forEach((r, i) => {\n // Try to identify context\n let prefix = \"Anonymous\";\n if (r.handlerName && !r.handlerName.includes('=>') && !r.handlerName.includes('{')) {\n const parts = r.handlerName.split('.');\n if (parts.length > 0) prefix = parts[0];\n }\n\n const key = `${prefix}.Dynamic Event ${i + 1}`;\n if (options.warnings) {\n options.warnings.push({\n type: 'dynamic-event',\n message: 'Dynamic event listener detected',\n detail: `Event listener with dynamic name`,\n location: { file: r.sourceContext?.file, line: r.sourceContext?.startLine }\n });\n }\n\n channels[key] = {\n publish: {\n operationId: `dynamicEventWarning${i}`,\n summary: \"Dynamic Event Detected\",\n description: `A dynamic event listener was detected in your source code but the event name could not be determined statically.`,\n tags: [{ name: \"Warnings\" }],\n \"x-warning\": true,\n \"x-source-info\": {\n file: r.sourceContext?.file,\n line: r.sourceContext?.startLine,\n startLine: r.sourceContext?.startLine,\n endLine: r.sourceContext?.endLine,\n highlightLines: r.sourceContext ? [r.sourceContext.startLine, r.sourceContext.endLine] : undefined\n },\n \"x-shokupan-source\": {\n file: r.sourceContext?.file,\n line: r.sourceContext?.startLine,\n },\n message: { payload: { type: 'object' } }\n }\n };\n });\n\n return {\n asyncapi: \"3.0.0\",\n info: { title: \"Shokupan AsyncAPI\", version: \"1.0.0\", ...options.info },\n channels,\n \"x-middleware-registry\": astMiddlewareRegistry\n };\n};\n","import { readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport renderToString from 'preact-render-to-string';\nimport { ShokupanRouter } from '../../../router';\nimport type { Shokupan } from '../../../shokupan';\nimport { deepMerge } from '../../../util/deep-merge';\nimport type { DeepPartial, ShokupanPlugin, ShokupanPluginOptions } from '../../../util/types';\nimport { AsyncApiApp, buildNavTree } from './components.tsx';\nimport { generateAsyncApi } from './generator';\n\nexport interface AsyncApiPluginOptions {\n path?: string;\n spec?: DeepPartial<any>;\n disableSourceView?: boolean;\n}\n\nexport class AsyncApiPlugin extends ShokupanRouter<any> implements ShokupanPlugin {\n\n private static getBasePath() {\n const dir = dirname(fileURLToPath(import.meta.url));\n // In production (dist/), files are in dist/plugins/application/asyncapi/\n if (dir.endsWith('dist')) {\n return dir + '/plugins/application/asyncapi';\n }\n // In dev mode (src/plugins/application/asyncapi/), files are in same directory\n return dir;\n }\n\n constructor(private pluginOptions: AsyncApiPluginOptions = {}) {\n super({ renderer: renderToString });\n this.pluginOptions.path ??= '/asyncapi';\n\n // Metadata\n this.metadata = {\n file: import.meta.file,\n line: 1,\n name: 'AsyncApiPlugin',\n pluginName: 'AsyncAPI'\n };\n\n this.init();\n }\n\n onInit(app: Shokupan, options?: ShokupanPluginOptions) {\n const path = this.pluginOptions.path || options?.path || '/asyncapi';\n app.mount(path, this);\n\n // Ensure async api gen is enabled if this plugin is used\n if (app.applicationConfig.enableAsyncApiGen !== true) {\n console.warn('AsyncApiPlugin: enableAsyncApiGen is disabled. AsyncApiPlugin will not generate spec.');\n }\n }\n\n private init() {\n const serveFile = async (ctx: any, file: string, type: string) => {\n const content = await readFile(join(AsyncApiPlugin.getBasePath(), 'static', file), 'utf-8');\n ctx.set('Content-Type', type);\n return ctx.send(content);\n };\n\n this.get('/style.css', ctx => serveFile(ctx, 'style.css', 'text/css'));\n this.get('/theme.css', ctx => serveFile(ctx, 'theme.css', 'text/css'));\n this.get('/asyncapi-client.mjs', ctx => serveFile(ctx, 'asyncapi-client.mjs', 'application/javascript'));\n\n this.get('/', async ctx => {\n let spec = ctx.app?.asyncApiSpec;\n if (!spec) {\n spec = await generateAsyncApi(ctx.app!);\n }\n if (this.pluginOptions.spec) {\n deepMerge(spec, this.pluginOptions.spec);\n }\n\n const serverUrl = `${ctx.hostname}:${ctx.app?.applicationConfig.port}`;\n const base = this.pluginOptions.path!;\n\n const disableSourceView = this.pluginOptions.disableSourceView;\n\n // Build navigation tree from spec\n const navTree = buildNavTree(spec);\n\n return ctx.jsx(AsyncApiApp({ spec, serverUrl, base, disableSourceView, navTree }));\n });\n\n this.get('/json', async ctx => {\n let spec = ctx.app?.asyncApiSpec;\n if (!spec) {\n // Fallback generation\n spec = await generateAsyncApi(ctx.app!);\n }\n\n if (this.pluginOptions.spec) {\n deepMerge(spec, this.pluginOptions.spec);\n }\n return ctx.json(spec);\n });\n\n this.get('/_code', async ctx => {\n const file = ctx.query['file'];\n if (!file || typeof file !== 'string') {\n return ctx.text('Missing file parameter', 400);\n }\n\n // Security: Validate path is within project root\n const { resolve } = await import('node:path');\n const cwd = process.cwd();\n const resolvedPath = resolve(cwd, file);\n\n if (!resolvedPath.startsWith(cwd)) {\n return ctx.text('Forbidden: File must be within project root', 403);\n }\n\n try {\n const content = await readFile(resolvedPath, 'utf8');\n return ctx.text(content);\n } catch (e: any) {\n return ctx.text('File not found: ' + e.message, 404);\n }\n });\n }\n}\n","\nimport { ShokupanContext } from \"../../context\";\nimport { ShokupanRouter } from \"../../router\";\nimport type { Shokupan } from \"../../shokupan\";\nimport type { ShokupanPlugin, ShokupanPluginOptions } from \"../../util/types\";\n\nexport interface AuthUser {\n id: string;\n email?: string;\n name?: string;\n picture?: string;\n provider: string;\n raw?: any;\n}\n\nexport interface ProviderConfig {\n /**\n * Client ID\n */\n clientId: string;\n /**\n * Client secret\n */\n clientSecret: string;\n /**\n * Redirect URI\n */\n redirectUri: string; // Must be absolute\n /**\n * Scopes\n */\n scopes?: string[];\n /**\n * Tenant ID (MSFT AD)\n */\n tenantId?: string;\n /**\n * Domain (Auth0, Okta)\n */\n domain?: string;\n /**\n * Team ID (Apple)\n */\n teamId?: string;\n /**\n * Key ID (Apple)\n */\n keyId?: string;\n /**\n * Auth URL (Generic OAuth2)\n */\n authUrl?: string;\n /**\n * Token URL (Generic OAuth2)\n */\n tokenUrl?: string;\n /**\n * User info URL (Generic OAuth2)\n */\n userInfoUrl?: string;\n}\n\nexport interface AuthConfig {\n /**\n * JWT secret\n */\n jwtSecret: string | Uint8Array;\n /**\n * JWT expiration\n */\n jwtExpiration?: string; // e.g. \"2h\"\n /**\n * JWT algorithm\n * @default 'HS256'\n */\n jwtAlgorithm?: string;\n /**\n * Cookie options\n */\n cookieOptions?: {\n /**\n * HTTP only\n */\n httpOnly?: boolean;\n /**\n * Secure\n */\n secure?: boolean;\n /**\n * Same site\n */\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n /**\n * Path\n */\n path?: string;\n /**\n * Max age\n */\n maxAge?: number;\n };\n /**\n * Success callback\n */\n onSuccess?: (user: AuthUser, ctx: ShokupanContext) => Promise<any> | any;\n /**\n * Providers\n */\n providers: {\n github?: ProviderConfig;\n google?: ProviderConfig;\n microsoft?: ProviderConfig;\n apple?: ProviderConfig;\n auth0?: ProviderConfig;\n okta?: ProviderConfig;\n oauth2?: ProviderConfig;\n [key: string]: ProviderConfig | undefined;\n };\n}\n\n/**\n * Authentication plugin\n */\nexport class AuthPlugin extends ShokupanRouter<any> implements ShokupanPlugin {\n private secret: Uint8Array;\n private arctic!: typeof import(\"arctic\");\n private jose!: typeof import(\"jose\");\n\n constructor(private authConfig: AuthConfig) {\n super();\n this.secret = typeof authConfig.jwtSecret === 'string'\n ? new TextEncoder().encode(authConfig.jwtSecret)\n : authConfig.jwtSecret;\n }\n\n async onInit(app: Shokupan, options?: ShokupanPluginOptions) {\n // Load dependencies asynchronously\n this.arctic = await import(\"arctic\");\n this.jose = await import(\"jose\");\n\n // Initialize routes\n this.init();\n\n // If registered via app.register(), mount it to root or specified path\n if (options?.path) {\n app.mount(options.path, this);\n } else {\n app.mount(options.path ?? '/', this);\n }\n }\n\n private getProviderInstance(name: string, p: ProviderConfig) {\n const { GitHub, Google, MicrosoftEntraId, Apple, Auth0, Okta, OAuth2Client } = this.arctic;\n\n switch (name) {\n case 'github':\n return new GitHub(p.clientId, p.clientSecret, p.redirectUri);\n case 'google':\n return new Google(p.clientId, p.clientSecret, p.redirectUri);\n case 'microsoft':\n return new MicrosoftEntraId(p.tenantId!, p.clientId, p.clientSecret, p.redirectUri);\n case 'apple':\n // TODO: There is a type issue, requires testing.\n return new Apple(\n p.clientId,\n p.teamId!,\n p.keyId!,\n p.clientSecret as any,\n p.redirectUri\n );\n case 'auth0':\n return new Auth0(p.domain!, p.clientId, p.clientSecret, p.redirectUri);\n case 'okta':\n return new Okta(p.domain!, p.authUrl, p.clientId, p.clientSecret, p.redirectUri);\n case 'oauth2':\n return new OAuth2Client(p.clientId, p.clientSecret, p.redirectUri);\n default:\n return null;\n }\n }\n\n private async createSession(user: AuthUser, ctx: ShokupanContext) {\n const alg = this.authConfig.jwtAlgorithm || 'HS256';\n const jwt = await new this.jose.SignJWT({ ...user })\n .setProtectedHeader({ alg })\n .setIssuedAt()\n .setExpirationTime(this.authConfig.jwtExpiration || '24h')\n .sign(this.secret);\n\n // Set cookie\n const opts = this.authConfig.cookieOptions || {};\n let cookie = `auth_token=${jwt}; Path=${opts.path || '/'}; HttpOnly`;\n if (opts.secure) cookie += '; Secure';\n if (opts.sameSite) cookie += `; SameSite=${opts.sameSite}`;\n if (opts.maxAge) cookie += `; Max-Age=${opts.maxAge}`;\n\n ctx.set('Set-Cookie', cookie);\n\n return jwt;\n }\n\n private init() {\n const { generateState, generateCodeVerifier, GitHub, Google, MicrosoftEntraId, Apple, Auth0, Okta, OAuth2Client } = this.arctic;\n const providerEntries = Object.entries(this.authConfig.providers);\n\n for (let i = 0; i < providerEntries.length; i++) {\n const [providerName, providerConfig] = providerEntries[i];\n if (!providerConfig) continue;\n\n const provider = this.getProviderInstance(providerName, providerConfig);\n if (!provider) {\n continue;\n }\n\n // Login Route\n this.get(`/auth/${providerName}/login`, async (ctx) => {\n const state = generateState();\n const codeVerifier = (providerName === 'google' || providerName === 'microsoft' || providerName === 'auth0' || providerName === 'okta')\n ? generateCodeVerifier() : undefined; // PKCE for some\n\n // Store state/verifier in cookie for verification\n const scopes = providerConfig.scopes || [];\n let url: URL;\n\n if (provider instanceof GitHub) {\n url = await provider.createAuthorizationURL(state, scopes);\n } else if (provider instanceof Google || provider instanceof MicrosoftEntraId || provider instanceof Auth0 || provider instanceof Okta) {\n // These all support PKCE in recent versions\n // Types might vary slightly but usually createAuthorizationURL(state, codeVerifier, scopes)\n url = await (provider as any).createAuthorizationURL(state, codeVerifier!, scopes);\n } else if (provider instanceof Apple) {\n url = await provider.createAuthorizationURL(state, scopes);\n } else if (provider instanceof OAuth2Client) {\n if (!providerConfig.authUrl) return ctx.text(\"Config error: authUrl required for oauth2\", 500);\n url = await provider.createAuthorizationURL(providerConfig.authUrl, state, scopes);\n } else {\n return ctx.text(\"Provider config error\", 500);\n }\n\n // Security: Set secure cookies with SameSite=Lax to prevent CSRF attacks\n const isSecure = ctx.secure;\n ctx.res.headers.set(\"Set-Cookie\", `oauth_state=${state}; Path=/; HttpOnly; SameSite=Lax${isSecure ? '; Secure' : ''}; Max-Age=600`);\n if (codeVerifier) {\n ctx.res.headers.append(\"Set-Cookie\", `oauth_verifier=${codeVerifier}; Path=/; HttpOnly; SameSite=Lax${isSecure ? '; Secure' : ''}; Max-Age=600`);\n }\n\n return ctx.redirect(url.toString());\n });\n\n // Callback Route\n this.get(`/auth/${providerName}/callback`, async (ctx) => {\n const url = new URL(ctx.req.url);\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n\n const cookieHeader = ctx.req.headers.get(\"Cookie\");\n const storedState = cookieHeader?.match(/oauth_state=([^;]+)/)?.[1];\n const storedVerifier = cookieHeader?.match(/oauth_verifier=([^;]+)/)?.[1];\n\n if (!code || !state || !storedState || state !== storedState) {\n return ctx.text(\"Invalid state or code\", 400);\n }\n\n try {\n let tokens: any;\n let idToken: string | undefined;\n\n if (provider instanceof GitHub) {\n tokens = await provider.validateAuthorizationCode(code);\n } else if (provider instanceof Google || provider instanceof MicrosoftEntraId) {\n if (!storedVerifier) return ctx.text(\"Missing verifier\", 400);\n tokens = await provider.validateAuthorizationCode(code, storedVerifier);\n } else if (provider instanceof Auth0 || provider instanceof Okta) {\n tokens = await (provider as any).validateAuthorizationCode(code, storedVerifier || \"\");\n } else if (provider instanceof Apple) {\n tokens = await provider.validateAuthorizationCode(code);\n idToken = tokens.idToken;\n } else if (provider instanceof OAuth2Client) {\n if (!providerConfig.tokenUrl) return ctx.text(\"Config error: tokenUrl required for oauth2\", 500);\n tokens = await provider.validateAuthorizationCode(providerConfig.tokenUrl, code, null);\n }\n\n const accessToken = tokens.accessToken || tokens.access_token;\n const user = await this.fetchUser(providerName, accessToken, providerConfig, idToken);\n\n if (this.authConfig.onSuccess) {\n const res = await this.authConfig.onSuccess(user, ctx);\n if (res) return res; // Allow override response\n }\n\n // Default behavior: create encoded session and returning it or redirect\n const jwt = await this.createSession(user, ctx);\n return ctx.json({ token: jwt, user });\n\n } catch (e: any) {\n // Security: Log detailed errors server-side, return generic message to client\n console.error(\"Auth Error\", e);\n return ctx.text(\"Authentication failed. Please try again.\", 500);\n }\n });\n }\n }\n\n private async fetchUser(provider: string, token: string, config: ProviderConfig, idToken?: string): Promise<AuthUser> {\n let user: AuthUser = { id: 'unknown', provider };\n\n if (provider === 'github') {\n const res = await fetch(\"https://api.github.com/user\", {\n headers: { Authorization: `Bearer ${token}` }\n });\n const data = await res.json() as any;\n user = {\n id: String(data.id),\n name: data.name || data.login,\n email: data.email,\n picture: data.avatar_url,\n provider,\n raw: data\n };\n }\n else if (provider === 'google') {\n const res = await fetch(\"https://openidconnect.googleapis.com/v1/userinfo\", {\n headers: { Authorization: `Bearer ${token}` }\n });\n const data = await res.json() as any;\n user = {\n id: data.sub,\n name: data.name,\n email: data.email,\n picture: data.picture,\n provider,\n raw: data\n };\n }\n else if (provider === 'microsoft') {\n const res = await fetch(\"https://graph.microsoft.com/v1.0/me\", {\n headers: { Authorization: `Bearer ${token}` }\n });\n const data = await res.json() as any;\n user = {\n id: data.id,\n name: data.displayName,\n email: data.mail || data.userPrincipalName,\n provider,\n raw: data\n };\n }\n else if (provider === 'auth0' || provider === 'okta') {\n const domain = config.domain!.startsWith('http') ? config.domain! : `https://${config.domain}`;\n const endpoint = provider === 'auth0' ? `${domain}/userinfo` : `${domain}/oauth2/v1/userinfo`;\n\n const res = await fetch(endpoint, {\n headers: { Authorization: `Bearer ${token}` }\n });\n const data = await res.json() as any;\n user = {\n id: data.sub,\n name: data.name,\n email: data.email,\n picture: data.picture,\n provider,\n raw: data\n };\n }\n else if (provider === 'apple') {\n // Apple user info is in the ID Token\n if (idToken) {\n const payload = this.jose.decodeJwt(idToken);\n user = {\n id: payload.sub!,\n email: payload['email'] as string,\n provider,\n raw: payload\n };\n }\n }\n else if (provider === 'oauth2') {\n if (config.userInfoUrl) {\n const res = await fetch(config.userInfoUrl, {\n headers: { Authorization: `Bearer ${token}` }\n });\n const data = await res.json() as any;\n user = {\n id: data.id || data.sub || 'unknown',\n name: data.name,\n email: data.email,\n picture: data.picture,\n provider,\n raw: data\n };\n }\n }\n\n return user;\n }\n\n /**\n * Middleware to verify JWT\n */\n public getMiddleware() {\n return async (ctx: ShokupanContext, next: () => Promise<any>) => {\n if (!this.jose) {\n // Try to load jose if not already loaded (e.g. middleware used without full plugin init?)\n // Ideally onInit should have run.\n this.jose = await import(\"jose\");\n }\n\n const authHeader = ctx.req.headers.get(\"Authorization\");\n let token = authHeader?.startsWith(\"Bearer \") ? authHeader.substring(7) : null;\n\n if (!token) {\n // Try cookie\n const cookieHeader = ctx.req.headers.get(\"Cookie\");\n token = cookieHeader?.match(/auth_token=([^;]+)/)?.[1] || null;\n }\n\n if (token) {\n try {\n const { payload } = await this.jose.jwtVerify(token, this.secret);\n (ctx as any).user = payload;\n } catch {\n // Invalid token, just proceed without user or throw?\n // Usually proceed, let guard handle it if required\n }\n }\n return next();\n };\n }\n}\n","import cluster from 'node:cluster';\nimport net from 'node:net';\nimport os from 'node:os';\nimport type { Shokupan } from '../../shokupan';\nimport type { ShokupanPlugin } from '../../util/types';\n\nexport interface ClusterOptions {\n /**\n * Number of workers to spawn.\n * Set to -1 or 'auto' to spawn one worker per available CPU.\n * @default 'auto'\n */\n workers?: number | 'auto';\n\n /**\n * Whether to pipe stdout/stderr to the parent process.\n * @default false\n */\n silent?: boolean;\n\n /**\n * Enable sticky sessions (useful for Socket.io).\n * Currently only supported in Node.js runtime.\n * @default false\n */\n sticky?: boolean;\n}\n\n/**\n * Cluster Plugin\n * \n * Automatically manages clustering for Node.js and Bun.\n */\nexport class ClusterPlugin implements ShokupanPlugin {\n constructor(private options: ClusterOptions = {}) { }\n\n onInit(app: Shokupan) {\n const originalListen = app.listen.bind(app);\n const { workers = 'auto', silent = false, sticky = false } = this.options;\n const isBun = typeof Bun !== 'undefined';\n const numCPUs = os.cpus().length;\n const numWorkers = (workers === 'auto' || workers === -1) ? numCPUs : workers;\n\n if (numWorkers <= 1) {\n // No clustering needed\n return;\n }\n\n app.listen = async (port?: number) => {\n const finalPort = port ?? app.applicationConfig.port ?? 3000;\n\n if (isBun) {\n return this.handleBun(app, finalPort, numWorkers, originalListen);\n } else {\n return this.handleNode(app, finalPort, numWorkers, originalListen, silent, sticky);\n }\n };\n }\n\n private async handleBun(app: Shokupan, port: number, workers: number, originalListen: Function) {\n // We use Bun's native behavior where multiple processes share the port via SO_REUSEPORT (reusePort: true).\n\n // Check if we are a worker\n const workerId = process.env['SHOKUPAN_WORKER_ID'];\n\n if (workerId) {\n // WORKER MODE\n // Force reusePort to true\n app.applicationConfig.reusePort = true;\n return originalListen(port);\n }\n\n // PRIMARY MODE\n console.log(`[Cluster] Starting ${workers} Bun workers on port ${port}...`);\n\n const spawnWorker = (id: string) => {\n // In Bun, we re-run the same script.\n // We must ensure arguments are passed correctly.\n Bun.spawn([process.argv0, ...process.argv.slice(1)], {\n env: { ...process.env, SHOKUPAN_WORKER_ID: id },\n stdio: ['inherit', 'inherit', 'inherit'],\n onExit(proc, exitCode, signalCode, error) {\n console.log(`[Cluster] Worker ${id} died (code: ${exitCode}). Restarting...`);\n spawnWorker(id);\n }\n });\n };\n\n for (let i = 0; i < workers; i++) {\n spawnWorker(process.pid + '_' + i + 1);\n }\n\n // Keep primary alive\n // in Bun, if simply returning, the script might exit if no event loop.\n // We just set an interval to ensure Bun doesn't exit.\n setInterval(() => { }, 1000 * 60 * 60);\n\n // Return a dummy object to satisfy Promise<Server> signature if needed, \n // though app.listen returns Server.\n return {\n stop: () => { },\n port\n } as any;\n }\n\n private async handleNode(app: Shokupan, port: number, workers: number, originalListen: Function, silent: boolean, sticky: boolean) {\n if (cluster.isPrimary) {\n console.log(`[Cluster] Master ${process.pid} is running`);\n\n // Fork workers\n const fork = () => cluster.fork(process.env);\n\n for (let i = 0; i < workers; i++) {\n fork();\n }\n\n cluster.on('exit', (worker, code, signal) => {\n console.log(`[Cluster] Worker ${worker.process.pid} died. Restarting...`);\n fork();\n });\n\n if (sticky) {\n // Sticky Session Master Logic\n // Create a net server to pause connections and distribute them\n const server = net.createServer({ pauseOnConnect: true }, (connection) => {\n const remote = connection.remoteAddress || '';\n // Simple hash\n let hash = 0;\n for (let i = 0; i < remote.length; i++) {\n hash = (hash << 5) - hash + remote.charCodeAt(i);\n hash |= 0;\n }\n const index = Math.abs(hash) % workers;\n\n // Get worker\n const worker = Object.values(cluster.workers!)[index];\n if (worker) {\n worker.send('sticky-session:connection', connection);\n } else {\n connection.end();\n }\n });\n\n server.listen(port, () => {\n console.log(`[Cluster] Sticky Load Balancer listening on port ${port}`);\n });\n\n // Return dummy server\n return {\n close: () => server.close(),\n port\n } as any;\n } else {\n // Standard Cluster (Round Robin by Node)\n // Master doesn't need to listen, workers will listen on the same port.\n // Node cluster handles the port sharing.\n return {\n close: () => { }, // Master controls\n port\n } as any;\n }\n\n } else {\n // WORKER MODE\n if (sticky) {\n // Sticky Worker Logic\n // We shouldn't listen on the PORT, because the master does.\n // We listen on 0 (random/ephemeral) just to initialize the internal http server.\n // Then we intercept messages.\n\n // Call listen with 0 to start server without binding public port\n const server = await originalListen(0);\n\n process.on('message', (message, handle) => {\n if (message !== 'sticky-session:connection') return;\n if (!handle) return;\n\n // Emulate connection \n (server as any).emit('connection', handle);\n // Connection was paused by master, resume it\n (handle as any).resume();\n });\n return server;\n } else {\n // Standard Worker\n return originalListen(port);\n }\n }\n }\n}\n","// @ts-nocheck\n\n\n\nexport function DashboardApp({ metrics, uptime, integrations, base, getRequestHeadersSource, rootPath, linkPattern, ignorePaths }: any) {\n return (\n <html lang=\"en\">\n <head>\n <meta charSet=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Shokupan Debug Dashboard</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin=\"anonymous\" />\n <link href=\"https://fonts.googleapis.com/css2?family=Google+Sans+Code:ital,wght@0,300..800;1,300..800&family=Vend+Sans:ital,wght@0,300..700;1,300..700&display=swap\" rel=\"stylesheet\" />\n <link href=\"https://unpkg.com/tabulator-tables@5.5.0/dist/css/tabulator_bootstrap5.min.css\" rel=\"stylesheet\" />\n <link rel=\"stylesheet\" href=\"https://esm.sh/@xyflow/react@12.3.6/dist/style.css\" />\n\n <link rel=\"stylesheet\" href={`${base}/theme.css`} />\n <link rel=\"stylesheet\" href={`${base}/styles.css`} />\n <link rel=\"stylesheet\" href={`${base}/reactflow.css`} />\n <link rel=\"stylesheet\" href={`${base}/registry.css`} />\n <link rel=\"stylesheet\" href={`${base}/tabulator.css`} />\n\n <script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script>\n <script type=\"text/javascript\" src=\"https://unpkg.com/tabulator-tables@5.5.0/dist/js/tabulator.min.js\"></script>\n {/* Monaco Editor Loader */}\n <script src=\"https://cdn.jsdelivr.net/npm/monaco-editor@0.44.0/min/vs/loader.js\"></script>\n </head>\n <body>\n <div class=\"container\">\n <header>\n <div>\n <h1>Shokupan</h1>\n </div>\n <div style=\"margin-left: 8px\">\n <span style=\"color: var(--text-secondary)\">Uptime: <span id=\"uptime\">{uptime}</span></span>\n <span id=\"ws-status\" title=\"WebSocket: Disconnected\" style=\"width: 10px; height: 10px; border-radius: 50%; background: #6b7280; display: inline-block; margin-left: 10px;\"></span>\n </div>\n <div style=\"flex: 1;\"></div>\n <div class=\"tabs\">\n <button class=\"tab-btn active\" onclick=\"switchTab('overview')\">Overview</button>\n <button class=\"tab-btn\" onclick=\"switchTab('application')\">Application</button>\n <button class=\"tab-btn\" onclick=\"switchTab('network')\">Network</button>\n {integrations.scalar && (\n <button class=\"tab-btn\" onclick=\"switchTab('scalar')\">Scalar</button>\n )}\n {integrations.apiExplorer && (\n <button class=\"tab-btn\" onclick=\"switchTab('api-explorer')\">REST API</button>\n )}\n {integrations.asyncapi && (\n <button class=\"tab-btn\" onclick=\"switchTab('asyncapi')\">WS API</button>\n )}\n </div>\n </header>\n <div class=\"contents\">\n {/* Overview Tab */}\n <div id=\"tab-overview\" class=\"tab-content active\">\n <MetricsGrid metrics={metrics} />\n\n <div id=\"chart-container\" style=\"display: flex; flex-direction: column; gap: 1rem;\">\n <div style=\"display: flex; justify-content: flex-end;\">\n <select id=\"time-range-selector\" onchange=\"updateCharts(); updateDashboard(); fetchTopStats();\" style=\"background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--card-border); padding: 5px; border-radius: 4px;\">\n <option value=\"1m\">1 Minute</option>\n <option value=\"5m\">5 Minutes</option>\n <option value=\"30m\">30 Minutes</option>\n <option value=\"1h\">1 Hour</option>\n <option value=\"2h\">2 Hours</option>\n <option value=\"6h\">6 Hours</option>\n <option value=\"12h\">12 Hours</option>\n <option value=\"1d\">1 Day</option>\n <option value=\"3d\">3 Days</option>\n <option value=\"7d\">7 Days</option>\n <option value=\"30d\">30 Days</option>\n </select>\n </div>\n\n <div class=\"card-container\">\n <ChartCard title=\"Response Time\" id=\"latencyChart\" />\n <ChartCard title=\"Requests / Second\" id=\"rpsChart\" />\n <ChartCard title=\"CPU & Load\" id=\"cpuChart\" />\n <ChartCard title=\"Memory\" id=\"memoryChart\" />\n <ChartCard title=\"Heap Usage\" id=\"heapChart\" />\n <ChartCard title=\"Event Loop Latency\" id=\"eventLoopChart\" />\n <ChartCard title=\"Error Rate\" id=\"errorRateChart\" />\n </div>\n\n <div class=\"card-title\" style=\"margin-top: 1rem;\">Top Statistics</div>\n <div class=\"card-container\">\n <Card title=\"Top Requests\" contentId=\"top-requests-table\" />\n <Card title=\"Top Errors\" contentId=\"top-errors-table\" />\n <Card title=\"Most Frequent Failures\" contentId=\"failing-requests-table\" />\n <Card title=\"Slowest Requests\" contentId=\"slowest-requests-table\" />\n </div>\n\n <div id=\"table-container\" style=\"padding: 0; margin-top: 1rem;\">\n <div id=\"requests-table\" class=\"table-dark\"></div>\n </div>\n </div>\n <div style=\"height: 2rem\"></div>\n </div>\n\n {/* Application Tab */}\n <div id=\"tab-application\" class=\"tab-content\">\n <div style=\"margin: 2rem 2rem 0 2rem; display: flex; gap: 1rem; align-items: center;\">\n <div class=\"button-group\">\n <button class=\"view-btn active\" onclick=\"switchApplicationView('registry')\">Registry</button>\n <button class=\"view-btn\" onclick=\"switchApplicationView('graph')\">Graph</button>\n </div>\n </div>\n {/* Registry Sub-View */}\n <div id=\"app-view-registry\" class=\"app-view active\" style=\"max-width: 1200px; align-self: center; margin: 0 auto\">\n <div id=\"registry-container\" class=\"card\" style=\"margin: 2rem; margin-top: 1rem;\">\n <div class=\"card-title\">Component Registry</div>\n <div id=\"registry-tree\" style=\"padding: 0 1rem 1rem 1rem; font-family: monospace; font-size: 0.9rem;\"></div>\n </div>\n <div style=\"height: .1px\"></div>\n </div>\n\n {/* Graph Sub-View */}\n <div id=\"app-view-graph\" class=\"app-view\" style=\"height: 100%;\">\n <div class=\"card\" style=\"margin: 1rem 2rem;\">\n <div style=\"display: flex; gap: 1rem;\">\n <input type=\"text\" id=\"graph-search\" placeholder=\"Search routes or middleware...\" aria-label=\"Search routes or middleware\" style=\"flex:1; padding: 0.5rem; border-radius: 0.5rem; background: var(--bg-primary); border: 1px solid var(--card-border); color: var(--text-primary);\" />\n </div>\n </div>\n <div id=\"cy\" style=\"margin: 0 2rem; height: calc(100% - 10rem);\"></div>\n </div>\n </div>\n\n {/* Network Tab */}\n <div id=\"tab-network\" class=\"tab-content\">\n <div style=\"margin: 1rem 2rem 0 2rem;\">\n {/* Filter Bar will be injected by requests.js */}\n <div id=\"network-filter-bar\" class=\"card\" style=\"margin-bottom: 1rem; padding: 0.5rem; display: flex; gap: 0.5rem; flex-wrap: wrap; flex-direction: row\">\n {/* Placeholder for filters */}\n <div style=\"display: flex; background: var(--bg-secondary); border: 1px solid var(--card-border); border-radius: 4px; overflow: hidden;\">\n <button class=\"filter-direction active\" data-value=\"all\" style=\"padding: 4px 12px; border: none; background: var(--bg-primary); color: var(--text-primary); cursor: pointer; border-right: 1px solid var(--card-border);\">All</button>\n <button class=\"filter-direction\" data-value=\"inbound\" style=\"padding: 4px 12px; border: none; background: transparent; color: var(--text-secondary); cursor: pointer; border-right: 1px solid var(--card-border);\">Inbound</button>\n <button class=\"filter-direction\" data-value=\"outbound\" style=\"padding: 4px 12px; border: none; background: transparent; color: var(--text-secondary); cursor: pointer;\">Outbound</button>\n </div>\n <input type=\"text\" id=\"network-filter-text\" placeholder=\"Filter...\" style=\"background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--card-border); padding: 4px 8px; border-radius: 4px; flex: 1;\" />\n <select id=\"network-filter-type\" style=\"background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--card-border); borderRadius: 4px;\">\n <option value=\"all\">All Types</option>\n <option value=\"xhr\">XHR/Fetch</option>\n <option value=\"fetch\">Outbound</option>\n <option value=\"ws\">WS</option>\n <option value=\"other\">Other</option>\n </select>\n <div style=\"display: flex; align-items: center; gap: 4px; background: var(--bg-primary); padding: 0 8px; border: 1px solid var(--card-border); border-radius: 4px; color: var(--text-primary);\">\n <input type=\"checkbox\" id=\"network-filter-ignore\" checked />\n <label for=\"network-filter-ignore\" style=\"cursor: pointer; font-size: 0.9em; user-select: none;\">Excl. Ignored</label>\n </div>\n <button onclick=\"fetchRequests()\" style=\"background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--card-border); padding: 4px 8px; border-radius: 4px; cursor: pointer;\">Refresh</button>\n <button onclick=\"purgeRequests()\" style=\"background: var(--bg-primary); color: var(--color-error, #ef4444); border: 1px solid var(--card-border); padding: 4px 8px; border-radius: 4px; cursor: pointer;\">Purge</button>\n </div>\n </div>\n\n <div id=\"network-view\" class=\"active\" style=\"display: block; height: 100%; margin-bottom: 2rem; overflow: hidden;\">\n <div style=\"margin: 0 2rem; display: flex; gap: 1rem; height: 100%;\">\n <div id=\"requests-list-container\" style=\"flex: 1; height: 100%; border-radius: 6px; overflow: hidden; border: 1px solid var(--card-border);\"></div>\n\n <div id=\"request-details-container\" class=\"card\" style=\"display: none; width: 500px; height: 100%; overflow: hidden; flex-shrink: 0; background: var(--bg-secondary); border: 1px solid var(--card-border); position: relative;\">\n <div id=\"details-drag-handle\" style=\"position: absolute; left: 0; top: 0; bottom: 0; width: 5px; cursor: col-resize; z-index: 11; background: transparent;\"></div>\n <div style=\"display: flex; justify-content: space-between; align-items: center; position: sticky; top: 0; background: var(--bg-secondary); padding: 0.5rem 1rem; border-bottom: 1px solid var(--border-color); z-index: 10;\">\n <div class=\"card-title\" style=\"margin: 0; padding: 0\">Request Details</div>\n <button onclick=\"closeRequestDetails()\" style=\"background: transparent; border: none; color: var(--text-secondary); cursor: pointer; font-size: 1.2rem;\">×</button>\n </div>\n <div style=\"display: flex; flex-direction: column; overflow: hidden; height: 100%\">\n <div id=\"request-details-content\" style=\"flex: 1; display: flex; flex-direction: column; height: 100%; overflow: hidden\"></div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n {integrations.scalar && (\n <div id=\"tab-scalar\" class=\"tab-content\" style=\"overflow: hidden; height: 100%; width: 100%\">\n <iframe src={integrations.scalar} style=\"width: 100%; height: 100%; border: none;\"></iframe>\n </div>\n )}\n\n {integrations.apiExplorer && (\n <div id=\"tab-api-explorer\" class=\"tab-content\" style=\"overflow: hidden; height: 100%; width: 100%\">\n <iframe src={integrations.apiExplorer} style=\"width: 100%; height: 100%; border: none;\"></iframe>\n </div>\n )}\n\n {integrations.asyncapi && (\n <div id=\"tab-asyncapi\" class=\"tab-content\" style=\"overflow: hidden; height: 100%; width: 100%\">\n <iframe src={integrations.asyncapi} style=\"width: 100%; height: 100%; border: none;\"></iframe>\n </div>\n )}\n </div>\n </div>\n\n <script dangerouslySetInnerHTML={{\n __html: `\n // Injected function from server config\n const getRequestHeaders = ${getRequestHeadersSource};\n window.SHOKUPAN_CONFIG = {\n rootPath: \"${rootPath || \"\"}\",\n linkPattern: \"${linkPattern || \"\"}\",\n ignorePaths: ${JSON.stringify(ignorePaths || [])}\n };\n `}} />\n\n <script src={`${base}/client.js`}></script>\n <script src={`${base}/graph.mjs`} type=\"module\"></script>\n <script src={`${base}/charts.js`}></script>\n <script src={`${base}/tables.js`}></script>\n <script src={`${base}/registry.js`}></script>\n <script src={`${base}/requests.js`}></script>\n <script src={`${base}/tabs.js`}></script>\n </body>\n </html>\n );\n}\n\nfunction MetricsGrid({ metrics }: any) {\n const total = metrics.totalRequests;\n const active = metrics.activeRequests;\n const finished = total - active;\n\n // Safety check div by zero\n const successRate = finished ? Math.round((metrics.successfulRequests / finished) * 100) : 100;\n const failRate = finished ? Math.round((metrics.failedRequests / finished) * 100) : 0;\n\n return (\n <div class=\"metrics-grid\">\n <div class=\"card\">\n <div class=\"card-title\">Total Requests</div>\n <div class=\"card-value\" id=\"total-requests\">\n {metrics.totalRequests}\n </div>\n </div>\n\n <div class=\"card\">\n <div class=\"card-title\">Active Requests</div>\n <div class=\"card-value\" style=\"color: var(--accent)\" id=\"active-requests\">\n {metrics.activeRequests}\n </div>\n </div>\n\n <div class=\"card\">\n <div class=\"card-title\">Success Rate</div>\n <div class=\"card-value text-success\">\n <span id=\"success-rate\">{successRate}%</span>\n </div>\n <div style=\"color: var(--text-secondary); margin-top: 0.5rem\">\n <span id=\"successful-requests\">{metrics.successfulRequests}</span> successful\n </div>\n </div>\n\n <div class=\"card\">\n <div class=\"card-title\">Fail Rate</div>\n <div class=\"card-value text-error\">\n <span id=\"fail-rate\">{failRate}%</span>\n </div>\n <div style=\"color: var(--text-secondary); margin-top: 0.5rem\">\n <span id=\"failed-requests\">{metrics.failedRequests}</span> failed\n </div>\n </div>\n\n <div class=\"card\">\n <div class=\"card-title\">Avg Latency</div>\n <div class=\"card-value\">\n <span id=\"avg-latency\">\n {metrics.averageTotalTime_ms.toFixed(2)}\n </span> <span style=\"font-size: 1rem; color: var(--text-secondary)\">ms</span>\n </div>\n </div>\n </div>\n );\n}\n\nfunction ChartCard({ title, id }: any) {\n return (\n <div class=\"card\" style=\"height: 300px;\">\n <div class=\"card-title\">{title}</div>\n <div class=\"card-chart\">\n <canvas id={id}></canvas>\n </div>\n </div>\n );\n}\n\nfunction Card({ title, contentId }: any) {\n return (\n <div class=\"card\">\n <div class=\"card-title\">{title}</div>\n <div id={contentId}></div>\n </div>\n );\n}\n","import type { IncomingMessage } from 'node:http';\nimport { createRequire } from 'node:module';\nimport { URL } from 'node:url';\n\nconst require = createRequire(import.meta.url);\nconst http = require('node:http');\nconst https = require('node:https');\n\n\n/**\n * Interface representing the details of an intercepted outbound request.\n */\nexport interface OutboundRequestLog {\n /**\n * The HTTP method of the request (e.g., GET, POST).\n */\n method: string;\n /**\n * The full URL of the request.\n */\n url: string;\n /**\n * The request headers.\n */\n requestHeaders: Record<string, string>;\n /**\n * The HTTP status code of the response.\n */\n status: number;\n /**\n * The response headers.\n */\n responseHeaders: Record<string, string>;\n /**\n * The duration of the request in milliseconds.\n */\n duration: number;\n /**\n * The timestamp when the request started.\n */\n startTime: number;\n /**\n * The request body (if any).\n */\n requestBody?: any;\n /**\n * The response body (if any).\n */\n responseBody?: any;\n /**\n * The hostname of the request.\n */\n domain?: string;\n /**\n * The pathname of the request.\n */\n path?: string;\n /**\n * The protocol scheme (http/https) or version (1.1, 2.0).\n */\n protocol?: string;\n /**\n * The protocol scheme (http/https).\n */\n scheme?: string;\n /**\n * The remote IP address (if available).\n */\n remoteIP?: string;\n /**\n * The number of cookies sent.\n */\n cookies?: number;\n /**\n * The estimated transfer size in bytes.\n */\n transferred?: number;\n}\n\n/**\n * A callback function type for handling captured outbound requests.\n */\nexport type OutboundRequestCallback = (log: OutboundRequestLog) => void;\n\n/**\n * A utility class that intercepts calls to `global.fetch` to track outbound HTTP requests.\n * \n * @warning This class monkey-patches the global `fetch` function. While it attempts to transparently\n * pass through all calls, it may have side effects on global state or other libraries that rely on\n * the original `fetch`. Proceed with caution.\n */\nexport class FetchInterceptor {\n private static originalFetch: typeof global.fetch | undefined;\n private static originalHttpRequest: typeof http.request | undefined;\n private static originalHttpsRequest: typeof https.request | undefined;\n\n private originalFetch: typeof global.fetch;\n private originalHttpRequest: typeof http.request;\n private originalHttpsRequest: typeof https.request;\n private callbacks: OutboundRequestCallback[] = [];\n private isPatched: boolean = false;\n\n constructor() {\n // Capture originals on first instantiation if not already captured\n if (!FetchInterceptor.originalFetch) {\n // Prevent capturing already patched fetch if module was reloaded but global stays dirty\n if ((global.fetch as any).__isPatched) {\n // Try to find original fetch if possible, or warn? \n // If we can't find original, we might be stuck.\n // But hopefully we don't reload module while patched.\n // Assuming standard behavior:\n console.warn('[FetchInterceptor] Global fetch is already patched! Cannot capture original.');\n } else {\n FetchInterceptor.originalFetch = global.fetch;\n FetchInterceptor.originalHttpRequest = http.request;\n FetchInterceptor.originalHttpsRequest = https.request;\n }\n }\n\n this.originalFetch = FetchInterceptor.originalFetch || global.fetch;\n this.originalHttpRequest = FetchInterceptor.originalHttpRequest || http.request;\n this.originalHttpsRequest = FetchInterceptor.originalHttpsRequest || https.request;\n }\n\n /**\n * Statically restore the original network methods.\n * Useful for cleaning up in tests.\n */\n /**\n * Statically restore the original network methods.\n * Useful for cleaning up in tests.\n */\n public static restore() {\n if (FetchInterceptor.originalFetch) {\n global.fetch = FetchInterceptor.originalFetch;\n } else if ((global.fetch as any)?.__originalFetch) {\n // Fallback: Restore from attached property if static was lost\n global.fetch = (global.fetch as any).__originalFetch;\n } else if (typeof Bun !== 'undefined' && (Bun as any).fetch) {\n // Fallback: Restore Bun.fetch if in Bun environment (cleans up zombie patches)\n global.fetch = (Bun as any).fetch;\n }\n\n if (FetchInterceptor.originalHttpRequest) {\n http.request = FetchInterceptor.originalHttpRequest;\n }\n if (FetchInterceptor.originalHttpsRequest) {\n https.request = FetchInterceptor.originalHttpsRequest;\n }\n console.log('[FetchInterceptor] Network layer restored (static).');\n }\n\n /**\n * Patches the global `fetch` function to intercept requests.\n * If already patched, this method does nothing.\n */\n public patch() {\n if (this.isPatched) return;\n\n this.patchGlobalFetch();\n this.patchNodeRequests();\n\n this.isPatched = true;\n console.log('[FetchInterceptor] Network layer patched.');\n }\n\n private patchGlobalFetch() {\n const self = this;\n // If we don't have a valid originalFetch (e.g. lost due to reload)\n // and global.fetch is patched, try to recover it from the patched version\n if (!this.originalFetch && (global.fetch as any).__isPatched && (global.fetch as any).__originalFetch) {\n this.originalFetch = (global.fetch as any).__originalFetch;\n }\n\n const newFetch = async function (input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n const startTime = performance.now();\n const timestamp = Date.now();\n\n let url = '';\n let method = 'GET';\n let requestHeaders: Record<string, string> = {};\n\n try {\n if (typeof input === 'string') {\n url = input;\n } else if (input instanceof URL) {\n url = input.toString();\n } else if (input instanceof Request) {\n url = input.url;\n method = input.method;\n input.headers.forEach((v, k) => requestHeaders[k] = v);\n }\n\n if (init) {\n if (init.method) method = init.method.toUpperCase();\n if (init.headers) {\n const h = new Headers(init.headers);\n h.forEach((v, k) => requestHeaders[k] = v);\n }\n }\n } catch (e) { }\n\n try {\n const response = await self.originalFetch.apply(global, [input, init]);\n\n // Clone response to read body without consuming original\n const clone = response.clone();\n const duration = performance.now() - startTime;\n\n // Process response asynchronously to not block\n self.processResponse(clone, {\n method,\n url,\n requestHeaders,\n startTime: timestamp,\n duration,\n status: response.status,\n ...self.extractRequestMeta(url, requestHeaders)\n }).catch(err => console.error(\"[FetchInterceptor] Error processing response:\", err));\n\n return response;\n } catch (error) {\n const duration = performance.now() - startTime;\n self.notify({\n method,\n url,\n requestHeaders,\n status: 0,\n responseHeaders: {},\n startTime: timestamp,\n duration,\n responseBody: `Error: ${error.message}`,\n ...self.extractRequestMeta(url, requestHeaders)\n });\n throw error;\n }\n };\n\n // Attach metadata\n (newFetch as any).__isPatched = true;\n (newFetch as any).__originalFetch = this.originalFetch;\n\n global.fetch = newFetch as any;\n }\n\n\n\n private patchNodeRequests() {\n const self = this;\n const intercept = (module: typeof http | typeof https, original: Function, defaultScheme: string) => {\n // @ts-ignore\n module.request = function (...args: any[]) {\n const startTime = performance.now();\n const timestamp = Date.now();\n let options: any = {};\n let urlObj: URL | undefined;\n\n // Argument normalization\n if (typeof args[0] === 'string' || args[0] instanceof URL) {\n try {\n urlObj = new URL(args[0]);\n options = typeof args[1] === 'object' ? args[1] : {};\n } catch (e) { }\n } else {\n options = args[0] || {};\n try {\n const protocol = options.protocol || defaultScheme + ':';\n const host = options.hostname || options.host || 'localhost';\n const port = options.port ? ':' + options.port : '';\n const path = options.path || '/';\n urlObj = new URL(`${protocol}//${host}${port}${path}`);\n } catch (e) { }\n }\n\n const method = (options.method || 'GET').toUpperCase();\n const url = urlObj ? urlObj.toString() : 'unknown';\n\n // Call original\n const req = original.apply(this, args);\n\n // Helper to get headers\n const getReqHeaders = () => {\n try {\n const h = req.getHeaders();\n // Normalize\n const normalized: Record<string, string> = {};\n for (const k in h) {\n const v = h[k];\n normalized[k] = Array.isArray(v) ? v.join(', ') : String(v);\n }\n return normalized;\n } catch (e) { return {}; }\n };\n\n // Intercept response\n req.on('response', (res: IncomingMessage) => {\n const duration = performance.now() - startTime;\n\n // Normalize response headers\n const resHeaders: Record<string, string> = {};\n if (res.headers) {\n for (const k in res.headers) {\n const v = res.headers[k];\n resHeaders[k] = Array.isArray(v) ? v.join(', ') : String(v || '');\n }\n }\n\n self.notify({\n method,\n url,\n requestHeaders: getReqHeaders(),\n status: res.statusCode || 0,\n responseHeaders: resHeaders,\n startTime: timestamp,\n duration,\n ...self.extractRequestMeta(url, getReqHeaders()),\n protocol: req.httpVersion\n });\n });\n\n req.on('error', (err: Error) => {\n const duration = performance.now() - startTime;\n self.notify({\n method,\n url,\n requestHeaders: getReqHeaders(),\n status: 0,\n responseHeaders: {},\n responseBody: `Error: ${err.message}`, // Capture error\n startTime: timestamp,\n duration\n });\n });\n\n return req;\n };\n };\n\n intercept(http, this.originalHttpRequest, 'http');\n intercept(https, this.originalHttpsRequest, 'https');\n }\n\n /**\n * Restores the original functions.\n */\n public unpatch() {\n if (!this.isPatched) return;\n global.fetch = this.originalFetch;\n http.request = this.originalHttpRequest;\n https.request = this.originalHttpsRequest;\n\n this.isPatched = false;\n console.log('[FetchInterceptor] Network layer restored.');\n }\n\n /**\n * Adds a callback to be notified of outbound requests.\n * @param callback The callback function.\n */\n public on(callback: OutboundRequestCallback) {\n this.callbacks.push(callback);\n }\n\n private extractRequestMeta(urlStr: string, headers: Record<string, string>) {\n try {\n const url = new URL(urlStr);\n const cookiesHeader = headers['cookie'] || headers['Cookie'];\n const cookies = cookiesHeader ? cookiesHeader.split(';').length : 0;\n return {\n domain: url.hostname,\n path: url.pathname,\n scheme: url.protocol.replace(':', ''),\n cookies,\n remoteIP: undefined // Not easily accessible via fetch\n };\n } catch (e) {\n return {};\n }\n }\n\n private async processResponse(response: Response, meta: any) {\n const responseHeaders: Record<string, string> = {};\n response.headers.forEach((v, k) => responseHeaders[k] = v);\n\n let responseBody: any;\n let transferred = 0;\n\n try {\n // Check content type to decide how to read\n const contentType = response.headers.get('content-type') || '';\n let bodyText = '';\n\n if (contentType.includes('application/json') || contentType.includes('text/')) {\n bodyText = await response.text();\n // truncate if too large\n if (bodyText.length > 524288) { // 512KB limit from previous task\n responseBody = bodyText.substring(0, 524288) + '... (truncated)';\n } else {\n responseBody = bodyText;\n }\n } else {\n responseBody = '[Binary Content]';\n // Try to get size from content-length if binary\n const cl = response.headers.get('content-length');\n if (cl) transferred = parseInt(cl, 10);\n }\n\n // Calculate transferred size (headers + body)\n // Approximate headers size\n const headersSize = Object.entries(responseHeaders).reduce((acc, [k, v]) => acc + k.length + v.length + 2, 0);\n if (!transferred && bodyText) {\n transferred = headersSize + bodyText.length;\n } else if (!transferred) {\n transferred = headersSize; // minimal fallback\n }\n\n } catch (e) {\n responseBody = '[Failed to read response body]';\n }\n\n this.notify({\n ...meta,\n responseHeaders,\n responseBody,\n transferred\n });\n }\n\n private notify(log: OutboundRequestLog) {\n this.callbacks.forEach(cb => {\n try {\n cb(log);\n } catch (e) {\n console.error('[FetchInterceptor] Callback failed', e);\n }\n });\n }\n}\n","\nimport * as os from 'node:os';\nimport { monitorEventLoopDelay } from 'node:perf_hooks';\nimport { RecordId } from 'surrealdb';\nimport type { SurrealDatastore } from '../../../util/datastore';\n\ninterface AggregatedMetric {\n timestamp: number;\n interval: string;\n cpu: number;\n memory: {\n used: number;\n total: number;\n heapUsed: number;\n heapTotal: number;\n };\n load: number[];\n eventLoopLatency: {\n min: number;\n max: number;\n mean: number;\n p50: number;\n p95: number;\n p99: number;\n };\n requests: {\n total: number;\n rps: number;\n success: number;\n error: number;\n };\n responseTime: {\n min: number;\n max: number;\n avg: number;\n p50: number;\n p95: number;\n p99: number;\n };\n}\n\nconst INTERVALS = [\n { label: '10s', ms: 10 * 1000 },\n { label: '1m', ms: 60 * 1000 },\n { label: '5m', ms: 5 * 60 * 1000 },\n { label: '1h', ms: 60 * 60 * 1000 },\n { label: '2h', ms: 2 * 60 * 60 * 1000 },\n { label: '6h', ms: 6 * 60 * 60 * 1000 },\n { label: '12h', ms: 12 * 60 * 60 * 1000 },\n { label: '1d', ms: 24 * 60 * 60 * 1000 },\n { label: '3d', ms: 3 * 24 * 60 * 60 * 1000 },\n { label: '7d', ms: 7 * 24 * 60 * 60 * 1000 },\n { label: '30d', ms: 30 * 24 * 60 * 60 * 1000 },\n];\n\nexport class MetricsCollector {\n private currentIntervalStart: Record<string, number> = {};\n private pendingDetails: Record<string, { duration: number, isError: boolean; }[]> = {};\n private eventLoopHistogram = monitorEventLoopDelay({ resolution: 10 });\n private timer: NodeJS.Timeout | null = null;\n\n public db?: SurrealDatastore;\n\n constructor(\n db?: SurrealDatastore,\n private onCollect?: (metric: AggregatedMetric) => void\n ) {\n this.db = db;\n this.eventLoopHistogram.enable();\n // Initialize start times\n const now = Date.now();\n INTERVALS.forEach(int => {\n this.currentIntervalStart[int.label] = this.alignTimestamp(now, int.ms);\n this.pendingDetails[int.label] = [];\n });\n\n // Start collection loop - tick every 10 seconds to process high-res intervals?\n // Actually, for 1m interval, we should tick at least every minute.\n // Let's tick every 10s to be safe and accurate enough.\n this.timer = setInterval(() => this.collect(), 10000);\n }\n\n public recordRequest(duration: number, isError: boolean) {\n INTERVALS.forEach(int => {\n this.pendingDetails[int.label].push({ duration, isError });\n });\n }\n\n private alignTimestamp(ts: number, intervalMs: number): number {\n return Math.floor(ts / intervalMs) * intervalMs;\n }\n\n private async collect() {\n try {\n const now = Date.now();\n // console.log('[MetricsCollector] collect() called at', new Date(now).toISOString());\n\n for (const int of INTERVALS) {\n const start = this.currentIntervalStart[int.label];\n // If we passed the interval boundary\n if (now >= start + int.ms) {\n // console.log(`[MetricsCollector] Flushing ${int.label} interval (boundary crossed)`);\n await this.flushInterval(int.label, start, int.ms);\n // Advance to next interval (could simply be aligning now, but be careful of gaps if app was down)\n // For simplicity, just align now.\n this.currentIntervalStart[int.label] = this.alignTimestamp(now, int.ms);\n }\n }\n } catch (error) {\n console.error('[MetricsCollector] Error in collect():', error);\n }\n }\n\n private async flushInterval(label: string, timestamp: number, durationMs: number) {\n const reqs = this.pendingDetails[label];\n // console.log(`[MetricsCollector] flushInterval(${label}) - ${reqs.length} requests pending`);\n // Reset pending only if we are moving forward. \n // NOTE: In a real concurrent scenario, we'd need locking or atomic swap.\n // Javascript is single threaded so this is safe for CPU-bound stuff, \n // but verify no awaits before clearing.\n this.pendingDetails[label] = [];\n\n if (reqs.length === 0) {\n // console.log(`[MetricsCollector] No requests for ${label}, skipping persist`);\n // Optional: Don't record empty intervals to save space? \n // Or record zeros to show gaps in graphs.\n // Let's record zeros for continuity.\n return; // Don't persist empty intervals\n }\n\n const totalReqs = reqs.length;\n const errorReqs = reqs.filter(r => r.isError).length;\n const successReqs = totalReqs - errorReqs;\n const duratons = reqs.map(r => r.duration).sort((a, b) => a - b);\n\n const rps = totalReqs / (durationMs / 1000);\n\n const sum = duratons.reduce((a, b) => a + b, 0);\n const avg = totalReqs > 0 ? sum / totalReqs : 0;\n\n const getP = (p: number) => {\n if (duratons.length === 0) return 0;\n const idx = Math.floor(duratons.length * p);\n return duratons[idx];\n };\n\n const metric: AggregatedMetric = {\n timestamp,\n interval: label,\n cpu: os.loadavg()[0], // Using load avg for simplicity as per requirements (Load)\n load: os.loadavg(),\n memory: {\n used: process.memoryUsage().rss,\n total: os.totalmem(),\n heapUsed: process.memoryUsage().heapUsed,\n heapTotal: process.memoryUsage().heapTotal,\n },\n eventLoopLatency: {\n min: this.eventLoopHistogram.min / 1e6,\n max: this.eventLoopHistogram.max / 1e6,\n mean: this.eventLoopHistogram.mean / 1e6,\n p50: this.eventLoopHistogram.percentile(50) / 1e6,\n p95: this.eventLoopHistogram.percentile(95) / 1e6,\n p99: this.eventLoopHistogram.percentile(99) / 1e6,\n },\n requests: {\n total: totalReqs,\n rps,\n success: successReqs,\n error: errorReqs,\n },\n responseTime: {\n min: duratons[0] || 0,\n max: duratons[duratons.length - 1] || 0,\n avg,\n p50: getP(0.50),\n p95: getP(0.95),\n p99: getP(0.99),\n }\n };\n\n // console.log(`[MetricsCollector] Persisting ${label} metric at timestamp ${timestamp}`);\n if (!this.db) {\n // console.warn('[MetricsCollector] Skipping collection - No datastore connection');\n return;\n }\n\n try {\n await this.db.upsert(new RecordId(\"metric\", timestamp), metric);\n } catch (e) {\n console.error(`[MetricsCollector] ✗ Failed to save metrics for ${label}:`, e);\n }\n\n // Notify Listeners\n if (this.onCollect) {\n this.onCollect(metric);\n }\n }\n\n // Cleanup if needed\n public stop() {\n if (this.timer) clearInterval(this.timer);\n this.eventLoopHistogram.disable();\n }\n}\n","import type { ServerWebSocket } from 'bun';\nimport { nanoid } from 'nanoid';\nimport { readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport renderToString from 'preact-render-to-string';\nimport { RecordId } from 'surrealdb';\nimport type { DebugCollector } from \"../../../context\";\nimport { ShokupanRouter } from \"../../../router\";\nimport type { Shokupan } from '../../../shokupan';\nimport { $appRoot, $childRouters, $debug, $mountPath } from \"../../../util/symbol\";\nimport type { ShokupanHooks, ShokupanPlugin } from \"../../../util/types\";\nimport { DashboardApp } from './components';\nimport { FetchInterceptor, type OutboundRequestLog } from './fetch-interceptor';\nimport { MetricsCollector } from './metrics-collector';\n\ninterface RequestMetrics {\n totalRequests: number;\n successfulRequests: number;\n failedRequests: number;\n activeRequests: number;\n averageTotalTime_ms: number;\n recentTimings: number[];\n logs: RequestLog[];\n rateLimitedCounts: Record<string, number>;\n\n // Graph Metrics\n nodeMetrics: Record<string, NodeMetric>;\n edgeMetrics: Record<string, number>;\n}\n\ninterface NodeMetric {\n id: string;\n type: string;\n requests: number;\n totalTime: number;\n failures: number;\n name: string;\n}\n\nexport interface RequestLog {\n method: string;\n url: string;\n status: number;\n duration: number;\n timestamp: number;\n handlerStack?: any[];\n body?: any;\n contentType?: string;\n // New fields\n type: 'xhr' | 'fetch' | 'ws';\n direction: 'inbound' | 'outbound';\n size?: number;\n protocol?: string;\n domain?: string;\n path?: string;\n scheme?: string;\n remoteIP?: string;\n cookies?: number;\n transferred?: number;\n requestHeaders?: Record<string, string>;\n responseHeaders?: Record<string, string>;\n requestBody?: any;\n}\n\nexport interface DashboardConfig {\n getRequestHeaders?: () => HeadersInit;\n path?: string;\n /**\n * Glob patterns to ignore in the request list\n */\n ignorePaths?: string[];\n /**\n * Retention time in milliseconds\n */\n retentionMs?: number;\n integrations?: {\n scalar?: boolean | { path?: string; };\n asyncapi?: boolean | { path?: string; };\n apiExplorer?: boolean | { path?: string; };\n };\n /**\n * Strategy for pushing request updates to the dashboard.\n * 'immediate' - pushes every request as soon as it completes.\n * 'batched' - buffers requests and pushes them at the interval specified by updateInterval.\n * @default 'immediate'\n */\n updateStrategy?: 'immediate' | 'batched';\n /**\n * Interval in milliseconds for pushing batched updates.\n * @default 10_000\n */\n updateInterval?: number;\n /**\n * Maximum number of request logs to keep in memory.\n * @default 1000\n */\n maxLogEntries?: number;\n}\n\nclass Collector implements DebugCollector {\n private currentNode: string | undefined;\n\n constructor(private dashboard: Dashboard) { }\n\n trackStep(id: string | undefined, type: string, duration: number, status: 'success' | 'error', error?: any) {\n if (!id) return;\n this.dashboard.recordNodeMetric(id, type, duration, status === 'error');\n }\n\n trackEdge(fromId: string | undefined, toId: string | undefined) {\n if (!fromId || !toId) return;\n this.dashboard.recordEdgeMetric(fromId, toId);\n }\n\n setNode(id: string) {\n this.currentNode = id;\n }\n\n getCurrentNode(): string | undefined {\n return this.currentNode;\n }\n}\n\nexport class Dashboard implements ShokupanPlugin {\n\n private [$appRoot]: Shokupan;\n\n private router = new ShokupanRouter({ renderer: renderToString });\n private metrics: RequestMetrics = {\n totalRequests: 0,\n successfulRequests: 0,\n failedRequests: 0,\n activeRequests: 0,\n averageTotalTime_ms: 0,\n recentTimings: [],\n logs: [],\n rateLimitedCounts: {},\n nodeMetrics: {},\n edgeMetrics: {}\n };\n\n private clients = new Set<ServerWebSocket<any>>();\n private broadcastTimer: any;\n private requestPushTimer: any;\n private requestsBuffer: any[] = [];\n\n private startTime = Date.now();\n private instrumented = false;\n private mountPath = '/dashboard';\n private metricsCollector: MetricsCollector;\n get db() {\n return this[$appRoot].db;\n }\n\n constructor(private readonly dashboardConfig: DashboardConfig = {}) { }\n\n // ShokupanPlugin interface implementation\n public onInit(app: any, options?: { path?: string; }) {\n this[$appRoot] = app;\n\n // Subscribe to MetricsCollector updates\n const onCollect = (metric: any) => {\n this.broadcastMetricUpdate(metric);\n };\n\n this.metricsCollector = new MetricsCollector(this.db, onCollect);\n\n if (app.applicationConfig) {\n // TODO: if instability comment out line below?\n app.applicationConfig.enableMiddlewareTracking = true;\n }\n\n // Initialize Fetch Interceptor\n const fetchInterceptor = new FetchInterceptor();\n // TODO: if instability comment out line below?\n fetchInterceptor.patch();\n fetchInterceptor.on((log: OutboundRequestLog) => {\n // Prevent infinite loop by ignoring DB requests\n // SurrealDB driver uses /rpc endpoint\n if (log.url.includes('/rpc')) return;\n try {\n const u = new URL(log.url);\n if (u.pathname.startsWith(this.mountPath)) return;\n } catch (e) { }\n\n // Store outbound request\n const requestData: RequestLog = {\n method: log.method,\n url: log.url,\n status: log.status,\n duration: log.duration,\n timestamp: log.startTime, // Use startTime as timestamp\n type: 'fetch',\n direction: 'outbound',\n size: log.responseBody ? String(log.responseBody).length : 0,\n contentType: log.responseHeaders['content-type'] || log.responseHeaders['Content-Type'],\n body: log.responseBody,\n requestBody: log.requestBody,\n domain: log.domain,\n path: log.path,\n scheme: log.scheme,\n protocol: log.protocol,\n remoteIP: log.remoteIP,\n cookies: log.cookies,\n transferred: log.transferred,\n requestHeaders: log.requestHeaders,\n responseHeaders: log.responseHeaders,\n // No handler stack for outbound\n };\n\n // Enforce log limit\n const maxLogs = this.dashboardConfig.maxLogEntries ?? 1000;\n if (this.metrics.logs.length >= maxLogs) {\n this.metrics.logs.shift();\n }\n this.metrics.logs.push(requestData);\n\n // Persist\n // We use 'request' table for both inbound and outbound.\n // ID generation: 'req_out_<timestamp>_<random>'\n\n const recordId = new RecordId(\"request\", nanoid());\n const idString = recordId.toString();\n\n // Fire and forget save\n this.db.query('UPSERT $id CONTENT $data', {\n id: recordId,\n data: requestData\n }).catch(e => console.error(\"Failed to save outbound request\", e));\n\n // Broadcast\n const strategy = this.dashboardConfig.updateStrategy || 'immediate';\n if (strategy === 'immediate') {\n this.broadcastRequestUpdates([{ ...requestData, id: idString }]);\n } else {\n this.requestsBuffer.push({ ...requestData, id: idString });\n }\n });\n\n if (app.onStart) {\n app.onStart(async () => {\n if (app.dbPromise) {\n await app.dbPromise;\n if (app.db) {\n this.metricsCollector.db = app.db;\n console.log('[Dashboard] Attached datastore to MetricsCollector');\n }\n }\n });\n }\n this.mountPath = options?.path || this.dashboardConfig.path || '/dashboard';\n\n // Register hooks on the app to track all requests\n const hooks = this.getHooks();\n\n if (hooks.onRequestStart) {\n app.hook('onRequestStart', hooks.onRequestStart);\n }\n\n if (hooks.onResponseEnd) {\n app.hook('onResponseEnd', hooks.onResponseEnd);\n }\n\n // Mount the dashboard router\n app.mount(this.mountPath, this.router);\n\n // Metadata for registry\n this.router.metadata = {\n file: import.meta.file,\n line: 1,\n name: 'DashboardPlugin',\n pluginName: 'Dashboard'\n };\n\n // Set up all routes on the internal router\n this.setupRoutes();\n\n // Start request push timer if batched\n const strategy = this.dashboardConfig.updateStrategy || 'immediate';\n if (strategy === 'batched') {\n this.startRequestPushTimer();\n }\n }\n\n private detectIntegrations() {\n const integrations: Record<string, string | undefined> = {};\n const routers = this[$appRoot]?.[$childRouters] || [];\n // Helper to check config\n const checkConfig = (key: 'scalar' | 'asyncapi' | 'apiExplorer') => {\n const conf = this.dashboardConfig.integrations?.[key];\n if (conf === false) return { enabled: false };\n if (typeof conf === 'object' && conf.path) return { enabled: true, path: conf.path };\n return { enabled: true };\n };\n\n // Scalar\n const scalarConf = checkConfig('scalar');\n if (scalarConf.enabled) {\n if (scalarConf.path) {\n integrations['scalar'] = scalarConf.path;\n } else {\n const plugin = routers.find(r => r.constructor.name === 'ScalarPlugin');\n if (plugin) {\n integrations['scalar'] = (plugin as any)[$mountPath];\n }\n }\n }\n\n // AsyncAPI\n const asyncApiConf = checkConfig('asyncapi');\n if (asyncApiConf.enabled) {\n if (asyncApiConf.path) {\n integrations['asyncapi'] = asyncApiConf.path;\n } else {\n const plugin = routers.find(r => r.constructor.name === 'AsyncApiPlugin');\n if (plugin) {\n integrations['asyncapi'] = (plugin as any)[$mountPath];\n }\n }\n }\n\n const apiExplorerConf = checkConfig('apiExplorer');\n if (apiExplorerConf.enabled) {\n if (apiExplorerConf.path) {\n integrations['apiExplorer'] = apiExplorerConf.path;\n } else {\n const plugin = routers.find(r => r.constructor.name === 'ApiExplorerPlugin');\n if (plugin) {\n integrations['apiExplorer'] = (plugin as any)[$mountPath];\n }\n }\n }\n\n return integrations;\n }\n\n // Get base path for dashboard files - works in both dev (src/) and production (dist/)\n private static getBasePath() {\n const dir = dirname(fileURLToPath(import.meta.url));\n // In production (dist/), files are in dist/plugins/application/dashboard/\n if (dir.endsWith('dist')) {\n return dir + '/plugins/application/dashboard';\n }\n // In dev mode (src/plugins/application/dashboard/), files are in same directory\n return dir;\n }\n\n private setupRoutes() {\n this.router.get(\"/ws\", (ctx) => {\n const success = ctx.upgrade({\n data: {\n handler: {\n open: (ws: ServerWebSocket<any>) => {\n this.clients.add(ws);\n console.log(`[Dashboard] Client connected. Total clients: ${this.clients.size}`);\n // Send default 1m history\n this.sendHistory(ws, '1m');\n },\n close: (ws: ServerWebSocket<any>) => {\n this.clients.delete(ws);\n console.log(`[Dashboard] Client disconnected. Total clients: ${this.clients.size}`);\n },\n message: (ws: ServerWebSocket<any>, message: string) => {\n try {\n const msg = JSON.parse(message);\n if (msg.type === 'get-history') {\n this.sendHistory(ws, msg.interval || '1m');\n }\n } catch (e) { }\n }\n }\n }\n });\n\n if (success) return undefined;\n return ctx.text(\"WebSocket upgrade failed\", 400);\n });\n\n this.router.get(\"/metrics\", async (ctx) => {\n const uptime = this.getUptime();\n const interval = ctx.query['interval'];\n if (interval) {\n const intervalMap: Record<string, number> = {\n '10s': 10 * 1000,\n '1m': 60 * 1000,\n '5m': 5 * 60 * 1000,\n '30m': 30 * 60 * 1000,\n '1h': 60 * 60 * 1000,\n '2h': 2 * 60 * 60 * 1000,\n '6h': 6 * 60 * 60 * 1000,\n '12h': 12 * 60 * 60 * 1000,\n '1d': 24 * 60 * 60 * 1000,\n '3d': 3 * 24 * 60 * 60 * 1000,\n '7d': 7 * 24 * 60 * 60 * 1000,\n '30d': 30 * 24 * 60 * 60 * 1000,\n };\n const ms = intervalMap[interval] || 60 * 1000;\n const startTime = Date.now() - ms;\n\n // For accuracy, query the requests table for the specific window\n let stats;\n try {\n stats = await this.db.query(`\n SELECT \n count() as total,\n count(IF status < 400 THEN 1 END) as success,\n count(IF status >= 400 THEN 1 END) as failed,\n math::mean(duration) as avg_latency\n FROM request \n WHERE timestamp >= $start\n GROUP ALL\n `, { start: startTime });\n } catch (error) {\n console.error('[Dashboard] Query failed at plugin.ts:180-191', {\n error,\n errorMessage: error.message,\n errorStack: error.stack,\n interval,\n startTime,\n query: 'metrics interval stats',\n stack: new Error().stack\n });\n throw error;\n }\n\n const s = stats[0] || { total: 0, success: 0, failed: 0, avg_latency: 0 };\n\n return ctx.json({\n metrics: {\n totalRequests: this.metrics.totalRequests,\n successfulRequests: this.metrics.successfulRequests,\n failedRequests: this.metrics.failedRequests,\n activeRequests: this.metrics.activeRequests,\n averageTotalTime_ms: s.avg_latency || 0,\n recentTimings: this.metrics.recentTimings,\n logs: [],\n rateLimitedCounts: this.metrics.rateLimitedCounts,\n nodeMetrics: this.metrics.nodeMetrics,\n edgeMetrics: this.metrics.edgeMetrics\n },\n uptime\n });\n }\n\n return ctx.json({\n metrics: this.metrics,\n uptime\n });\n });\n this.router.get(\"/metrics/history\", async (ctx) => {\n const interval = ctx.query['interval'] || '1m';\n\n // Map interval to milliseconds\n const intervalMap: Record<string, number> = {\n '10s': 10 * 1000,\n '1m': 60 * 1000,\n '5m': 5 * 60 * 1000,\n '30m': 30 * 60 * 1000,\n '1h': 60 * 60 * 1000,\n '2h': 2 * 60 * 60 * 1000,\n '6h': 6 * 60 * 60 * 1000,\n '12h': 12 * 60 * 60 * 1000,\n '1d': 24 * 60 * 60 * 1000,\n '3d': 3 * 24 * 60 * 60 * 1000,\n '7d': 7 * 24 * 60 * 60 * 1000,\n '30d': 30 * 24 * 60 * 60 * 1000,\n };\n\n const periodMs = intervalMap[interval] || 60 * 1000;\n // Expand window to 3x the requested period to ensure we catch the aligned start points.\n const startTime = Date.now() - (periodMs * 3);\n const endTime = Date.now();\n\n const result = await this.db.query(\n \"SELECT * FROM metrics WHERE timestamp >= $start AND timestamp <= $end AND interval = $interval ORDER BY timestamp ASC\",\n { start: startTime, end: endTime, interval }\n );\n\n return ctx.json({\n metrics: result[0] || [],\n });\n });\n\n const getIntervalStartTime = (interval?: string) => {\n if (!interval) return 0;\n const intervalMap: Record<string, number> = {\n '10s': 10 * 1000,\n '1m': 60 * 1000,\n '5m': 5 * 60 * 1000,\n '30m': 30 * 60 * 1000,\n '1h': 60 * 60 * 1000,\n '2h': 2 * 60 * 60 * 1000,\n '6h': 6 * 60 * 60 * 1000,\n '12h': 12 * 60 * 60 * 1000,\n '1d': 24 * 60 * 60 * 1000,\n '3d': 3 * 24 * 60 * 60 * 1000,\n '7d': 7 * 24 * 60 * 60 * 1000,\n '30d': 30 * 24 * 60 * 60 * 1000,\n };\n const ms = intervalMap[interval] || 0;\n return ms ? Date.now() - ms : 0;\n };\n\n // Top Requests Endpoint\n this.router.get(\"/requests/top\", async (ctx) => {\n const startTime = getIntervalStartTime(ctx.query['interval']);\n const result = await this.db.query(\n \"SELECT method, url, count() as count FROM request WHERE timestamp >= $start GROUP BY method, url ORDER BY count DESC LIMIT 10\",\n { start: startTime }\n );\n return ctx.json({ top: result[0] || [] });\n });\n\n // Top Errors Endpoint\n this.router.get(\"/errors/top\", async (ctx) => {\n const startTime = getIntervalStartTime(ctx.query['interval']);\n const result = await this.db.query(\n \"SELECT status, count() as count FROM failed_request WHERE timestamp >= $start GROUP BY status ORDER BY count DESC LIMIT 10\",\n { start: startTime }\n );\n return ctx.json({ top: result[0] || [] });\n });\n\n // Failing Requests Endpoint\n this.router.get(\"/requests/failing\", async (ctx) => {\n const startTime = getIntervalStartTime(ctx.query['interval']);\n const result = await this.db.query(\n \"SELECT method, url, count() as count FROM failed_request WHERE timestamp >= $start GROUP BY method, url ORDER BY count DESC LIMIT 10\",\n { start: startTime }\n );\n return ctx.json({ top: result[0] || [] });\n });\n\n // Slowest Requests Endpoint\n this.router.get(\"/requests/slowest\", async (ctx) => {\n const startTime = getIntervalStartTime(ctx.query['interval']);\n const result = await this.db.query(\n \"SELECT method, url, duration, status, timestamp FROM request WHERE timestamp >= $start ORDER BY duration DESC LIMIT 10\",\n { start: startTime }\n );\n return ctx.json({ slowest: result[0] || [] });\n });\n\n this.router.get(\"/registry\", (ctx) => {\n const app = this[$appRoot];\n if (!this.instrumented && app) {\n this.instrumentApp(app);\n }\n const registry = app?.registry;\n if (registry) {\n this.assignIdsToRegistry(registry, 'root');\n }\n return ctx.json({ registry: registry || {} });\n });\n\n // Requests Listing Endpoint\n this.router.get(\"/requests\", async (ctx) => {\n console.log(`[Dashboard] Handling /requests from ${ctx.ip} ${ctx.get('User-Agent')}`);\n const result = await this.db.query(\"SELECT * FROM request ORDER BY timestamp DESC LIMIT 100\");\n const items: any[] = result[0] as any[] || [];\n console.log(`[Dashboard] /requests returning ${items.length} items`);\n return ctx.json({ requests: items });\n });\n\n this.router.delete(\"/requests\", async (ctx) => {\n console.log(`[Dashboard] Purging all requests`);\n await this.db.query(\"DELETE request; DELETE failed_request;\");\n this.metrics.logs = [];\n this.metrics.totalRequests = 0;\n this.metrics.activeRequests = 0;\n this.metrics.successfulRequests = 0;\n this.metrics.failedRequests = 0;\n this.metrics.recentTimings = [];\n this.metrics.rateLimitedCounts = {};\n this.metrics.nodeMetrics = {};\n this.metrics.edgeMetrics = {};\n // Broadcast clear event? Or just let next update handle it?\n // Sending an empty list via requests-update might work if client handles it.\n // But we should probably send a specific \"purge\" event or just rely on client refresh.\n // Let's send a requests-update with empty list if validation shows it helps.\n // For now just return success.\n return ctx.json({ success: true });\n });\n\n // Request Details Endpoint\n this.router.get(\"/requests/:id\", async (ctx) => {\n const result = await this.db.query(\"SELECT * FROM request WHERE id = $id\", { id: ctx.params['id'] });\n return ctx.json({ request: result[0]?.[0] });\n });\n\n // Replay/Failed Requests Endpoints\n this.router.get(\"/failures\", async (ctx) => {\n const result = await this.db.query(\"SELECT * FROM failed_request ORDER BY timestamp DESC LIMIT 50\");\n return ctx.json({ failures: result[0] });\n });\n\n this.router.post(\"/replay\", async (ctx) => {\n const body = await ctx.body();\n // Logic to replay request:\n // If direction is outbound, we fetch from the server.\n // If inbound, we process via app.internalRequest.\n\n const direction = body.direction || 'inbound';\n\n if (direction === 'outbound') {\n // Replay outbound request\n const start = performance.now();\n try {\n const res = await fetch(body.url, {\n method: body.method,\n headers: body.headers,\n body: body.body ? (typeof body.body === 'object' ? JSON.stringify(body.body) : body.body) : undefined\n });\n\n // Read response text\n const text = await res.text();\n const duration = performance.now() - start;\n\n const resHeaders: Record<string, string> = {};\n res.headers.forEach((v, k) => resHeaders[k] = v);\n\n return ctx.json({\n status: res.status,\n statusText: res.statusText,\n headers: resHeaders,\n data: text,\n duration\n });\n } catch (e) {\n return ctx.json({ error: String(e) }, 500);\n }\n } else {\n // Replay inbound request against the app\n const app = this[$appRoot];\n if (!app) return unknownError(ctx);\n\n // Construct request\n try {\n // body should contain method, url, headers, body\n const result = await app.internalRequest({\n method: body.method,\n path: body.url, // or path\n headers: body.headers,\n body: body.body\n });\n return ctx.json({\n status: result.status,\n headers: result.headers,\n data: result.body\n });\n } catch (e) {\n return ctx.json({ error: String(e) }, 500);\n }\n }\n });\n\n this.router.get(\"/**\", async (ctx) => {\n // Determine relative path by stripping the mount path\n const mountPath = this.router[$mountPath] || this.dashboardConfig.path || '/dashboard';\n\n let relativePath = ctx.path;\n if (relativePath.startsWith(mountPath)) {\n relativePath = relativePath.slice(mountPath.length);\n }\n // Strip leading slash\n if (relativePath.startsWith('/')) {\n relativePath = relativePath.slice(1);\n }\n\n const path = relativePath;\n\n // Serve static files if they match known extensions/files\n const staticFiles = [\n 'charts.js', 'failures.js', 'graph.mjs', 'client.js',\n 'reactflow.css', 'registry.css', 'registry.js', 'requests.js',\n 'styles.css', 'tables.js', 'tabs.js', 'tabulator.css', 'theme.css'\n ];\n\n if (staticFiles.includes(path)) {\n const content = await readFile(join(Dashboard.getBasePath(), 'static', path), 'utf-8');\n if (path.endsWith('.css')) ctx.set('Content-Type', 'text/css');\n else if (path.endsWith('.js') || path.endsWith('.mjs')) ctx.set('Content-Type', 'application/javascript');\n return ctx.send(content);\n }\n\n // Otherwise serve Dashboard\n const uptime = this.getUptime();\n\n const linkPattern = this.getLinkPattern();\n const integrations = this.detectIntegrations();\n\n const getRequestHeadersSource = this.dashboardConfig.getRequestHeaders ? this.dashboardConfig.getRequestHeaders.toString() : \"undefined\";\n\n const ignorePaths = [\n ...(this.dashboardConfig.ignorePaths || []),\n // Add default ignores for integrations\n ...Object.values(integrations).filter(p => !!p).flatMap(p => {\n const clean = p!.endsWith('/') ? p!.slice(0, -1) : p!;\n return [clean, `${clean}/**`];\n })\n ];\n\n const html = renderToString(DashboardApp({\n metrics: this.metrics,\n uptime,\n rootPath: process.cwd(),\n linkPattern,\n integrations,\n base: mountPath,\n getRequestHeadersSource,\n ignorePaths\n }));\n return ctx.html(`<!DOCTYPE html>${html}`);\n });\n }\n\n private getUptime() {\n const uptimeSeconds = Math.floor((Date.now() - this.startTime) / 1000);\n return `${Math.floor(uptimeSeconds / 3600)}h ${Math.floor((uptimeSeconds % 3600) / 60)}m ${uptimeSeconds % 60}s`;\n }\n\n private getPublicMetrics() {\n return {\n totalRequests: this.metrics.totalRequests,\n successfulRequests: this.metrics.successfulRequests,\n failedRequests: this.metrics.failedRequests,\n activeRequests: this.metrics.activeRequests,\n averageTotalTime_ms: this.metrics.averageTotalTime_ms,\n recentTimings: this.metrics.recentTimings,\n logs: [], // Don't broadcast logs for now to save bandwidth\n rateLimitedCounts: this.metrics.rateLimitedCounts,\n nodeMetrics: this.metrics.nodeMetrics,\n edgeMetrics: this.metrics.edgeMetrics\n };\n }\n\n private broadcastMetricUpdate(metric: any) {\n if (this.clients.size === 0) return;\n // console.log(`[Dashboard] Broadcasting metric update to ${this.clients.size} clients`);\n\n const data = JSON.stringify({\n type: 'metric-update',\n metric\n });\n\n for (const client of this.clients) {\n client.send(data);\n }\n }\n\n private async sendHistory(ws: ServerWebSocket<any>, interval: string) {\n // Map interval to milliseconds\n const intervalMap: Record<string, number> = {\n '10s': 10 * 1000,\n '1m': 60 * 1000,\n '5m': 5 * 60 * 1000,\n '30m': 30 * 60 * 1000,\n '1h': 60 * 60 * 1000,\n '2h': 2 * 60 * 60 * 1000,\n '6h': 6 * 60 * 60 * 1000,\n '12h': 12 * 60 * 60 * 1000,\n '1d': 24 * 60 * 60 * 1000,\n '3d': 3 * 24 * 60 * 60 * 1000,\n '7d': 7 * 24 * 60 * 60 * 1000,\n '30d': 30 * 24 * 60 * 60 * 1000,\n };\n\n const periodMs = intervalMap[interval] || 60 * 1000;\n const startTime = Date.now() - (periodMs * 30); // Get 30 points of history\n const endTime = Date.now();\n\n let history: any[] = [];\n try {\n const result = await this.db.query<[any[]]>(\n \"SELECT * FROM metric WHERE timestamp >= $start AND timestamp <= $end AND interval = $interval ORDER BY timestamp ASC\",\n { start: startTime, end: endTime, interval }\n );\n history = result[0] || [];\n } catch (e) {\n console.error('[Dashboard] Failed to fetch history for WS', e);\n }\n\n ws.send(JSON.stringify({\n type: 'init',\n metrics: { ...this.metrics, logs: [] },\n uptime: this.getUptime(),\n history\n }));\n }\n\n private broadcastMetrics() {\n if (this.clients.size === 0) return;\n console.log(`[Dashboard] Broadcasting metrics to ${this.clients.size} clients`);\n\n const data = JSON.stringify({\n type: 'metrics',\n metrics: this.getPublicMetrics(),\n uptime: this.getUptime()\n });\n\n for (const client of this.clients) {\n client.send(data);\n }\n }\n\n private instrumentApp(app: any) {\n if (!app.getComponentRegistry) return;\n\n const registry = app.getComponentRegistry();\n this.assignIdsToRegistry(registry, 'root');\n this.instrumented = true;\n }\n\n // Traverses registry, generates IDs, and attaches them to the actual function objects\n private assignIdsToRegistry(node: any, parentId: string) {\n if (!node) return;\n\n const makeId = (type: string, parent: string, idx: number, name: string) =>\n `${type}_${parent}_${idx}_${name.replace(/[^a-zA-Z0-9]/g, '')}`;\n\n // Middleware\n node.middleware?.forEach((mw: any, idx: number) => {\n const id = makeId('mw', parentId, idx, mw.name);\n mw.id = id; // Assign to registry object for frontend\n if (mw._fn) (mw._fn as any)._debugId = id; // Assign to function for runtime tracking\n });\n\n // Controllers\n node.controllers?.forEach((ctrl: any, idx: number) => {\n const id = makeId('ctrl', parentId, idx, ctrl.name);\n ctrl.id = id;\n // Controllers don't have a single function. Attributes are on routes.\n // But we can store metadata if needed.\n });\n\n // Routes (in this node/router/controller)\n node.routes?.forEach((r: any, idx: number) => {\n // Route ID: logic?\n // Frontend doesn't explicitly ID route nodes unless they are loose.\n // But we need to track them.\n const id = makeId('route', parentId, idx, r.handlerName || 'handler');\n r.id = id;\n if (r._fn) (r._fn as any)._debugId = id;\n });\n\n // Child Routers\n node.routers?.forEach((r: any, idx: number) => {\n const id = makeId('router', parentId, idx, r.path);\n r.id = id;\n // Does router have a function? wrappedHandler?\n // Routers are containers mainly.\n this.assignIdsToRegistry(r.children, id);\n });\n\n // Events\n node.events?.forEach((e: any, idx: number) => {\n const id = makeId('event', parentId, idx, e.name);\n e.id = id;\n if (e._fn) (e._fn as any)._debugId = id;\n });\n }\n\n public recordNodeMetric(id: string, type: string, duration: number, isError: boolean) {\n if (!this.metrics.nodeMetrics[id]) {\n this.metrics.nodeMetrics[id] = {\n id,\n type,\n requests: 0,\n totalTime: 0,\n failures: 0,\n name: id // simplify\n };\n }\n const m = this.metrics.nodeMetrics[id];\n m.requests++;\n m.totalTime += duration;\n if (isError) m.failures++;\n }\n\n public recordEdgeMetric(from: string, to: string) {\n const key = `${from}|${to}`;\n this.metrics.edgeMetrics[key] = (this.metrics.edgeMetrics[key] || 0) + 1;\n }\n\n private getLinkPattern(): string {\n const term = process.env['TERM_PROGRAM'] || '';\n if (['vscode', 'cursor', 'antigravity'].some(t => term.includes(t))) {\n return 'vscode://file/{{absolute}}:{{line}}';\n }\n\n return 'vscode://file/{{absolute}}:{{line}}';\n }\n\n public getHooks(): ShokupanHooks {\n return {\n onRequestStart: (ctx) => {\n if (ctx.path.startsWith(this.mountPath)) return;\n\n const app = (this as any)[$appRoot];\n if (!this.instrumented && app) {\n this.instrumentApp(app);\n }\n\n this.metrics.totalRequests++; // Starts at 0\n this.metrics.activeRequests++; // INCREMENTS\n (ctx as any)._startTime = performance.now();\n (ctx as any)._reqStartTime = Date.now();\n\n // Attach Collector\n ctx[$debug] = new Collector(this);\n\n // Broadcast immediate update for active requests? \n // Maybe throttle this if high load, but for now direct update is fine for lower loads.\n // Throttling:\n if (!this.broadcastTimer) {\n this.broadcastTimer = setTimeout(() => {\n this.broadcastMetrics();\n this.broadcastTimer = undefined;\n }, 100);\n }\n },\n\n onResponseEnd: async (ctx: any, response: any) => {\n // Ignore dashboard requests to prevent noise and loops\n if (ctx.path.startsWith(this.mountPath)) return;\n\n this.metrics.activeRequests = Math.max(0, this.metrics.activeRequests - 1);\n const duration = (performance.now() - (ctx as any)._startTime) || 0;\n\n // Handle WebSocket upgrade or missing response\n if (!response) {\n if (ctx.isUpgraded) {\n // WebSocket upgrade success, we can log it as 101 or skip\n // Let's create a dummy response object for logging purposes\n response = {\n status: 101,\n headers: {}\n };\n } else {\n // Unknown case, skip\n return;\n }\n }\n\n // Record in MetricsCollector\n const isError = response.status >= 400;\n this.metricsCollector.recordRequest(duration, isError);\n\n // Broadcast updates immediately\n if (!this.broadcastTimer) {\n this.broadcastTimer = setTimeout(() => {\n this.broadcastMetrics();\n this.broadcastTimer = undefined;\n }, 100);\n }\n\n if (response.status >= 400) {\n this.metrics.failedRequests++;\n if (response.status === 429) {\n const path = ctx.path;\n this.metrics.rateLimitedCounts[path] = (this.metrics.rateLimitedCounts[path] || 0) + 1;\n }\n\n // Record failure in Datastore\n try {\n const headers: Record<string, string> = {};\n if (ctx.request.headers && typeof ctx.request.headers.forEach === 'function') {\n ctx.request.headers.forEach((v: string, k: string) => {\n headers[k] = v;\n });\n }\n const resHeaders: Record<string, string> = {};\n if (response.headers && typeof response.headers.forEach === 'function') {\n response.headers.forEach((v: string, k: string) => {\n resHeaders[k] = v;\n });\n }\n\n await this.db.upsert(new RecordId(`failed_request`, ctx.requestId), {\n method: ctx.method,\n url: ctx.url.toString(),\n headers: headers,\n status: response.status,\n timestamp: Date.now(),\n state: ctx.state,\n body: this.serializeBody((ctx as any).bodyData || (ctx as any).requestBody),\n responseHeaders: resHeaders,\n responseBody: this.serializeBody((ctx as any).responseBody)\n });\n } catch (e) {\n console.error(\"Failed to record failed request\", e);\n }\n\n } else {\n this.metrics.successfulRequests++;\n }\n\n // Calculate metadata\n const urlObj = new URL(ctx.url.toString());\n const cookieHeader = ctx.request.headers.get('cookie') || '';\n const cookiesCount = cookieHeader ? cookieHeader.split(';').length : 0;\n\n const headers: Record<string, string> = {};\n if (ctx.request.headers && typeof ctx.request.headers.forEach === 'function') {\n ctx.request.headers.forEach((v: string, k: string) => {\n headers[k] = v;\n });\n }\n const resHeaders: Record<string, string> = {};\n if (response.headers && typeof response.headers.forEach === 'function') {\n response.headers.forEach((v: string, k: string) => {\n resHeaders[k] = v;\n });\n }\n\n const responseHeadersSize = Object.entries(response.headers || {}).reduce((acc, [k, v]) => acc + k.length + String(v).length + 2, 0);\n const responseSize = (ctx as any).responseBody ? String((ctx as any).responseBody).length : 0;\n\n // Try to get remote IP from various headers or socket\n const remoteIP = ctx.request.headers.get('x-forwarded-for') || (ctx.req as any)?.socket?.remoteAddress;\n\n const logEntry: RequestLog = {\n method: ctx.method,\n url: ctx.url.toString(),\n status: response.status,\n duration,\n timestamp: (ctx as any)._reqStartTime || (Date.now() - duration),\n handlerStack: this.serializeHandlerStack((ctx as any).handlerStack),\n body: this.serializeBody((ctx as any).responseBody),\n requestBody: (ctx as any).bodyData || (ctx as any).requestBody, // ShokupanContext usually stores parsed body here if parsed\n contentType: response.headers['content-type'] || response.headers['Content-Type'],\n type: 'xhr',\n direction: 'inbound',\n size: responseSize,\n protocol: (ctx.req as any)?.httpVersion, // Try to get protocol from raw request if available, Bun might expose it\n domain: urlObj.hostname,\n path: urlObj.pathname,\n scheme: urlObj.protocol.replace(':', ''),\n cookies: cookiesCount,\n transferred: responseSize + responseHeadersSize,\n remoteIP,\n requestHeaders: headers,\n responseHeaders: resHeaders\n };\n // console.log(`[Dashboard Debug] Captured ${ctx.method} ${ctx.path} -> Status: ${response.status}`); // Removed debug log\n\n this.metrics.logs.push(logEntry);\n\n // Persist to datastore for detailed view\n // Use query explicitly to avoid driver/RecordId issues\n this.db.create(new RecordId(\"request\", ctx.requestId), {\n ...logEntry,\n direction: \"inbound\"\n }).catch(e => {\n console.error(\"Failed to record request log\", e);\n });\n const retention = this.dashboardConfig.retentionMs ?? 7200000;\n const cutoff = Date.now() - retention;\n if (this.metrics.logs.length > 0 && this.metrics.logs[0].timestamp < cutoff) {\n this.metrics.logs = this.metrics.logs.filter(log => log.timestamp >= cutoff);\n }\n\n const requestData = {\n id: ctx.requestId,\n ...logEntry\n };\n\n const strategy = this.dashboardConfig.updateStrategy || 'immediate';\n\n if (strategy === 'immediate') {\n this.broadcastRequestUpdates([requestData]);\n } else {\n // Buffer request for WS push\n this.requestsBuffer.push(requestData);\n }\n }\n };\n }\n\n private startRequestPushTimer() {\n const interval = this.dashboardConfig.updateInterval || 10000;\n this.requestPushTimer = setInterval(() => {\n if (this.requestsBuffer.length > 0) {\n this.broadcastRequestUpdates();\n }\n }, interval);\n }\n\n private broadcastRequestUpdates(requestsOverride?: any[]) {\n if (this.clients.size === 0) {\n if (!requestsOverride) this.requestsBuffer = [];\n return;\n }\n\n let requests;\n if (requestsOverride) {\n requests = requestsOverride;\n } else {\n requests = [...this.requestsBuffer];\n this.requestsBuffer = []; // Clear buffer\n }\n\n if (requests.length === 0) return;\n\n // Debug log\n console.log(`[Dashboard] Broadcasting ${requests.length} requests. Sample ID: ${requests[0].id}`);\n\n const data = JSON.stringify({\n type: 'requests-update',\n requests\n });\n\n for (const client of this.clients) {\n client.send(data);\n }\n }\n\n private updateTiming(duration: number) {\n const alpha = 0.1;\n if (this.metrics.averageTotalTime_ms === 0) {\n this.metrics.averageTotalTime_ms = duration;\n } else {\n this.metrics.averageTotalTime_ms = (alpha * duration) + ((1 - alpha) * this.metrics.averageTotalTime_ms);\n }\n this.metrics.recentTimings.push(duration);\n if (this.metrics.recentTimings.length > 50) {\n this.metrics.recentTimings.shift();\n }\n }\n private serializeHandlerStack(stack: any[]): any[] {\n if (!stack || !Array.isArray(stack)) return [];\n return stack.map(item => ({\n name: item.name,\n file: item.file,\n line: item.line,\n duration: item.duration,\n startTime: item.startTime,\n isBuiltin: item.isBuiltin,\n // stateChanges: item.stateChanges // Exclude complex objects for now\n }));\n }\n\n private serializeBody(body: any): any {\n if (!body) return undefined;\n\n // Handle strings\n if (typeof body === 'string') {\n if (body.length > 524288) {\n return body.substring(0, 524288) + '... (truncated)';\n }\n return body;\n }\n\n // Handle objects (JSON)\n // If it's already an object, we can return it directly if it's JSON-safe\n // But for safety and to avoid circular deps in logs, let's try to stringify if needed\n // Or better yet, we can store it as object and let the JSON serializer handle it when sending over WS\n // But for DB, we might want it as object too (surrealdb handles json)\n // Let's truncate if too big\n if (typeof body === 'object') {\n try {\n // Check size roughly\n const str = JSON.stringify(body);\n if (str.length > 524288) {\n return str.substring(0, 524288) + '... (truncated)';\n }\n return body;\n } catch (e) {\n return '[Circular or Non-Serializable Body]';\n }\n }\n\n return '[Binary or Unreadable Body]';\n }\n}\nfunction unknownError(ctx: any): any {\n return ctx.json({ error: \"Unknown Error\" }, 500);\n}\n\nexport default function DebugDashboard(config?: DashboardConfig) {\n return new Dashboard(config);\n}\n","// Safe Monkeypatch - Only increases stack trace limit\nlet isPatched = false;\n\ndeclare global {\n interface Error {\n timestamp?: number;\n id?: string;\n scope?: any;\n structuredStack?: NodeJS.CallSite[];\n }\n}\n\nexport function applyMonkeyPatch() {\n if (isPatched) return;\n isPatched = true;\n\n // Increase stack Trace limit\n Error.stackTraceLimit = 50;\n\n // NOTE: We do NOT patch Error.prepareStackTrace as it causes crashes with \n // libraries like Axios that call Error.captureStackTrace(this) in the constructor.\n // Instead, we rely on string-based stack parsing and manual metadata injection.\n}\n","import { file } from 'bun';\n\nexport interface SourceContext {\n lines: {\n line: number;\n code: string;\n isTarget: boolean;\n }[];\n startLine: number;\n file: string;\n}\n\nexport async function readSourceContext(filePath: string | undefined, line: number, contextLines: number = 5): Promise<SourceContext | null> {\n if (!filePath || filePath.startsWith('node:') || filePath.startsWith('bun:') || filePath.includes('node_modules')) {\n return null;\n }\n\n // Remove file:// prefix if present\n const path = filePath.startsWith('file://') ? filePath.slice(7) : filePath;\n\n try {\n const f = file(path);\n if (!await f.exists()) return null;\n\n const content = await f.text();\n const allLines = content.split('\\n');\n\n // Line is 1-indexed in stack trace, but 0-indexed in array\n const targetIndex = line - 1;\n\n if (targetIndex < 0 || targetIndex >= allLines.length) return null;\n\n const start = Math.max(0, targetIndex - contextLines);\n const end = Math.min(allLines.length, targetIndex + contextLines + 1);\n\n const subset = allLines.slice(start, end).map((code, i) => ({\n line: start + i + 1,\n code,\n isTarget: (start + i + 1) === line\n }));\n\n return {\n lines: subset,\n startLine: start + 1,\n file: path\n };\n } catch (e) {\n return null;\n }\n}\n","import type { ShokupanContext } from '../../../../context';\nimport { readSourceContext } from '../util/source-reader';\n\ninterface StackFrame {\n method: string;\n file: string;\n line: number;\n column: number;\n isNative: boolean;\n isInternal: boolean; // node/bun\n isShokupan: boolean;\n isDependency: boolean; // node_modules\n shortFile: string;\n relativeFile: string;\n}\n\nexport async function renderErrorView(ctx: ShokupanContext, error: any) {\n const frames: StackFrame[] = [];\n const cwd = process.cwd();\n\n // Safety check for error object\n const errorName = error?.name || 'Error';\n const errorMessage = error?.message || 'Unknown error occurred';\n\n const errorId = error?.id || ctx.requestId || 'unknown-id';\n const errorTimestamp = error?.timestamp ? new Date(error.timestamp).toISOString() : new Date().toISOString();\n const errorScope = error?.scope || {};\n\n // Parse stack trace (String parsing fallback)\n const lines = (error?.stack || '').split('\\n').slice(1); // skip message\n for (const line of lines) {\n // Support: at method (file:line:col) OR at file:line:col\n const match = line.match(/at (?:(.+?)\\s+\\()?(?:(.+?):(\\d+):(\\d+))\\)?/);\n if (match) {\n const [_, method, file, lineNo, colNo] = match;\n const fileName = file || '';\n\n // Relativize path\n let relativeFile = fileName;\n if (fileName.startsWith(cwd)) {\n relativeFile = fileName.slice(cwd.length + 1); // +1 for slash/separator\n }\n\n // Classification Logic\n // 1. Internals: node:, bun:, or no file (native). Exception for timers.\n let isInternal = fileName.startsWith('node:') || fileName.startsWith('bun:') || fileName === 'undefined' || fileName === '';\n // Exception: setTimeout/setInterval/setImmediate are useful entrypoints\n if (isInternal && (method.includes('setTimeout') || method.includes('setInterval') || method.includes('setImmediate'))) {\n isInternal = false;\n }\n\n // 2. Shokupan: strictly source code or specific package match\n // NOT just matching the name in the path (which catches examples)\n let isShokupan = false;\n if (fileName.includes('node_modules/@dotglitch/shokupan')) {\n isShokupan = true;\n } else if (relativeFile.startsWith('src/') || fileName.includes('/shokupan/dist/')) {\n // In dev mode (monorepo), src/ is framework, but ensure we aren't misclassifying user src?\n // Current CWD is root of repo. 'src/' is framework. 'examples/' is user.\n isShokupan = true;\n }\n\n // 3. Dependencies: node_modules (generic), excluding Shokupan\n const isDependency = fileName.includes('node_modules') && !isShokupan;\n\n // 4. Native/Internal checks\n // (Refined above)\n\n frames.push({\n method: method || '<anonymous>',\n file: fileName,\n line: parseInt(lineNo),\n column: parseInt(colNo),\n isNative: false,\n isInternal,\n isShokupan,\n isDependency,\n shortFile: fileName.split('/').pop() || fileName,\n relativeFile\n });\n }\n }\n\n // Determine \"Best\" Frame for Code Viewer\n let focusFrame = frames.find(f => !f.isInternal && !f.isShokupan && !f.isDependency && !f.isNative);\n if (!focusFrame) focusFrame = frames[0];\n\n // Read Source Context\n let sourceContext = null;\n if (focusFrame && focusFrame.file && !focusFrame.isInternal) {\n sourceContext = await readSourceContext(focusFrame.file, focusFrame.line, 8);\n }\n\n // Render Frames with Hyperlinks\n const renderFrames = frames.map((frame, index) => {\n const classes = [\n 'stack-entry',\n frame.isInternal ? 'internal' : '',\n frame.isShokupan ? 'shokupan' : '',\n frame.isDependency ? 'dependency' : '',\n frame === focusFrame ? 'active' : ''\n ].join(' ');\n\n const fileLink = `vscode://file/${frame.file}:${frame.line}:${frame.column}`;\n\n return `\n <li class=\"${classes}\">\n <a href=\"${fileLink}\" style=\"text-decoration:none; color:inherit; display:block\">\n <div class=\"stack-method\">${frame.method === '<anonymous>' ? 'Anonymous' : frame.method}</div>\n <div class=\"stack-file\">${frame.relativeFile}:${frame.line}</div>\n </a>\n </li>\n `;\n }).join('');\n\n // Code Block\n // Syntax Highlighter (Simple Regex-based)\n const highlightCode = (code: string) => {\n return code\n .replace(/</g, '<').replace(/>/g, '>') // Escape HTML first\n // Strings (double quoted)\n .replace(/(\")(.*?)(\")/g, '<span style=\"color:#a5d6ff\">$1$2$3</span>')\n // Strings (single quoted)\n .replace(/(')(.*?)(')/g, '<span style=\"color:#a5d6ff\">$1$2$3</span>')\n // Strings (backticks - simplistic)\n .replace(/(`)(.*?)(`)/g, '<span style=\"color:#a5d6ff\">$1$2$3</span>')\n // Keywords\n .replace(/\\b(const|let|var|function|class|import|export|from|return|if|else|switch|case|default|break|continue|try|catch|finally|throw|new|async|await|interface|type|extends|implements|public|private|protected|static|readonly|true|false|null|undefined)\\b/g, '<span style=\"color:#ff7b72\">$1</span>')\n // Control flow / operators\n .replace(/(=>|===|==|!=|!==|\\|\\||&&|\\+|\\-|\\*|\\/|%|\\+\\+|\\-\\-)/g, '<span style=\"color:#ff7b72\">$1</span>')\n // Types / Classes (Capitalized words)\n .replace(/\\b([A-Z][a-zA-Z0-9_]*)\\b/g, '<span style=\"color:#79c0ff\">$1</span>')\n // Function calls (word followed by paren)\n .replace(/\\b([a-zA-Z0-9_]+)(?=\\()/g, '<span style=\"color:#d2a8ff\">$1</span>')\n // Comments (double slash) - tricky with regex, simpler to do distinct pass or match carefully. \n // Simple approach for single line comments:\n .replace(/(\\/\\/.*)/g, '<span style=\"color:#8b949e; font-style:italic\">$1</span>');\n };\n\n // Code Block\n let codeBlock = '';\n if (sourceContext) {\n const lines = sourceContext.lines.map(l => `\n <div class=\"code-line ${l.isTarget ? 'target' : ''}\">\n <div class=\"line-number\">${l.line}</div>\n <div class=\"line-content\">${highlightCode(l.code)}</div>\n </div>\n `).join('');\n codeBlock = lines;\n } else {\n codeBlock = `<div style=\"padding: 2rem; color: var(--text-muted); text-align: center;\">Source code not available.</div>`;\n }\n\n // Advanced KV Renderer\n const renderKV = (data: Record<string, any>) => {\n if (!data || Object.keys(data).length === 0) return '<div style=\"color:var(--text-muted)\">None</div>';\n\n return `<table class=\"kv-table\">\n ${Object.entries(data).map(([k, v]) => {\n let displayVal = String(v);\n let valClass = '';\n\n if (typeof v === 'number') {\n valClass = 'kv-val-number';\n } else if (typeof v === 'boolean') {\n valClass = 'kv-val-bool';\n } else if (typeof v === 'object' && v !== null) {\n try {\n displayVal = JSON.stringify(v, null, 2);\n valClass = 'kv-val-json';\n } catch (e) { displayVal = '[Circular]'; }\n }\n\n return `\n <tr>\n <td class=\"kv-key\">${k}</td>\n <td class=\"kv-val ${valClass}\">${displayVal}</td>\n </tr>`;\n }).join('')}\n </table>`;\n };\n\n // Copy Icons\n const ICON_COPY = `<svg class=\"icon\" viewBox=\"0 0 24 24\"><path d=\"M16 1H4C2.9 1 2 1.9 2 3V17H4V3H16V1ZM19 5H8C6.9 5 6 5.9 6 7V21C6 22.1 6.9 23 8 23H19C20.1 23 21 22.1 21 21V7C21 5.9 20.1 5 19 5ZM19 21H8V7H19V21Z\"/></svg>`;\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>${errorName}: ${errorMessage}</title>\n <link href=\"https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-numbers/prism-line-numbers.min.css\" rel=\"stylesheet\" />\n <link href=\"https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-highlight/prism-line-highlight.min.css\" rel=\"stylesheet\" />\n <link href=\"/_shokupan/error-view/prismjs.theme.css\" rel=\"stylesheet\" />\n <link href=\"/_shokupan/error-view/styles.css\" rel=\"stylesheet\" />\n <link href=\"/_shokupan/error-view/theme.css\" rel=\"stylesheet\" />\n\n</head>\n<body class=\"\">\n \n <div class=\"page\">\n <!-- HEADER -->\n <header class=\"chapter-header\">\n <div class=\"chapter-meta\">\n <div class=\"meta-item\">\n <span>${ctx.method}</span>\n </div>\n <div class=\"meta-item\">\n <span>${ctx.url.pathname}</span>\n </div>\n <div class=\"meta-item\">\n <span>${ctx.response.status || 500}</span>\n </div>\n <div class=\"meta-item\" style=\"margin-left:auto\">\n <span class=\"id-badge\" onclick=\"copyText('${errorId}')\" title=\"Copy ID\">ID: ${errorId}</span>\n </div>\n </div>\n \n <h1 class=\"error-title\">${errorName}</h1>\n \n <div class=\"error-message-container\">\n <h2 class=\"error-message\">${errorMessage}</h2>\n <button class=\"action-btn\" onclick=\"copyText('${(errorMessage || '').replace(/'/g, \"\\\\'\")}')\" title=\"Copy Message\" style=\"padding:4px 8px\">\n ${ICON_COPY}\n </button>\n </div>\n \n <div class=\"actions-bar\">\n <button class=\"action-btn\" onclick=\"copyText()\">\n ${ICON_COPY} Copy Error\n </button>\n <button class=\"action-btn\" onclick=\"document.getElementById('raw-modal').style.display='flex'\">\n View Raw Error\n </button>\n </div>\n </header>\n\n <!-- CODE FIGURE -->\n <section class=\"figure\">\n <div class=\"figure-caption\">\n ${focusFrame ? `<a href=\"vscode://file${focusFrame.file}:${focusFrame.line}\" style=\"color:var(--text-muted); text-decoration:none\">${focusFrame ? focusFrame.relativeFile : (sourceContext?.file || 'Unknown Source')}</a>` : ''}\n </div>\n <div class=\"figure-body\">\n ${sourceContext ? `\n <pre class=\"line-numbers\" data-line=\"${sourceContext.lines.find(l => l.isTarget)?.line}\" data-start=\"${sourceContext.lines[0].line}\"><code class=\"language-typescript\">${sourceContext.lines.map(l => l.code.replace(/</g, '<').replace(/>/g, '>')).join('\\n')}</code></pre>\n ` : `<div style=\"padding: 2rem; color: var(--text-muted); text-align: center;\">Source code not available.</div>`}\n </div>\n </section>\n\n <!-- NARRATIVE STACK -->\n <section class=\"narrative\">\n <div class=\"section-title\">\n <span>Stack Trace</span>\n <div class=\"filter-group\">\n <span class=\"badge\" onclick=\"this.classList.toggle('active'); document.body.classList.toggle('show-internals')\">Internals</span>\n <span class=\"badge\" onclick=\"this.classList.toggle('active'); document.body.classList.toggle('show-shokupan')\">Framework</span>\n <span class=\"badge\" onclick=\"this.classList.toggle('active'); document.body.classList.toggle('show-dependencies')\">Dependencies</span>\n </div>\n </div>\n <ul class=\"stack-list\">\n ${renderFrames}\n </ul>\n </section>\n\n <!-- APPENDICES -->\n <section class=\"appendix\">\n <div class=\"section-title\">Context & Environment</div>\n <div class=\"appendix-grid\">\n <div class=\"data-block\">\n <h3>Request</h3>\n ${renderKV({\n id: errorId,\n timestamp: errorTimestamp,\n ... (errorScope || {})\n })}\n </div>\n <div class=\"data-block\">\n <h3>Headers</h3>\n ${renderKV(Object.fromEntries(ctx.headers))}\n </div>\n <div class=\"data-block\">\n <h3>Query & Params</h3>\n ${renderKV({ ...ctx.params, ...ctx.query })}\n </div>\n </div>\n </section>\n </div>\n \n <!-- RAW ERROR MODAL -->\n <div id=\"raw-modal\" class=\"modal-overlay\" onclick=\"if(event.target === this) this.style.display='none'\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <span>Raw Error Object</span>\n <button class=\"action-btn\" onclick=\"document.getElementById('raw-modal').style.display='none'\">Close</button>\n </div>\n <div class=\"modal-body\" id=\"raw-content\"></div>\n </div>\n </div>\n\n <!-- PrismJS Scripts -->\n <script src=\"https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js\"></script>\n <script src=\"https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-typescript.min.js\"></script>\n <script src=\"https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-numbers/prism-line-numbers.min.js\"></script>\n <script src=\"https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-highlight/prism-line-highlight.min.js\"></script>\n\n <script>\n // Prepare Raw Error\n // circular ref safe stringify\n const getCircularReplacer = () => {\n const seen = new WeakSet();\n return (key, value) => {\n if (typeof value === \"object\" && value !== null) {\n if (seen.has(value)) {\n return \"[Circular]\";\n }\n seen.add(value);\n }\n return value;\n };\n };\n \n // Inject error data from SERVER side\n const rawError = ${(() => {\n // Helper to serialize Error objects including non-enumerable properties\n const serializeError = (err: any) => {\n const obj: any = {\n name: err.name,\n message: err.message,\n stack: err.stack,\n ...err // Spread enumerable props\n };\n\n // Explicitly grab other common props if they exist\n if (err.cause) obj.cause = err.cause;\n if (err.code) obj.code = err.code;\n if (err.status) obj.status = err.status;\n if (err.statusCode) obj.statusCode = err.statusCode;\n\n return JSON.stringify(obj, (key, value) => {\n // Filter out redundant large stack\n if (key === 'structuredStack') return undefined;\n return value;\n }, 2);\n };\n // EXECUTE on Server Side\n return serializeError(error);\n })()};\n \n // At this point 'rawError' is an Object in Client JS (because serializeError returned a JSON string)\n const RAW_ERROR_JSON = JSON.stringify(rawError, getCircularReplacer(), 2);\n // \"Normally printed\" usually means standard stacktrace string which includes name/message\n const RAW_ERROR_TEXT = rawError.stack || (rawError.name + ': ' + rawError.message);\n \n document.getElementById('raw-content').innerText = RAW_ERROR_JSON;\n\n function copyText(text) {\n if (!text) text = RAW_ERROR_TEXT; // Default to text representation (Message + Stack)\n navigator.clipboard.writeText(text).then(() => {\n console.log('Copied');\n });\n }\n </script>\n</body>\n</html>`;\n}\n","import type { ShokupanContext } from '../../../../context';\n\nexport function renderStatusView(ctx: ShokupanContext, status: number, error: Error) {\n const title = `${status} ${error.message || 'Error'}`;\n const method = ctx.method;\n const path = ctx.url.pathname;\n\n // Additional CSS to supplement theme\n const css = `\n body {\n background: var(--bg-primary);\n color: var(--text-primary);\n font-family: var(--shokupan-font);\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100vh;\n margin: 0;\n overflow: hidden;\n }\n .container {\n text-align: center;\n animation: fadeIn 0.3s ease-out;\n background: var(--bg-card);\n padding: 3rem 4rem;\n border-radius: 16px;\n border: 1px solid var(--card-border);\n box-shadow: 0 10px 30px rgba(0,0,0,0.3);\n max-width: 600px;\n }\n h1 {\n font-size: 6rem;\n margin: 0;\n color: var(--primary);\n line-height: 1;\n font-weight: 800;\n letter-spacing: -2px;\n text-shadow: 0 4px 20px rgba(255, 179, 128, 0.2); \n }\n h2 {\n font-size: 1.5rem;\n margin: 1rem 0 2rem 0;\n font-weight: 400;\n color: var(--text-secondary);\n }\n .meta {\n color: var(--text-muted);\n font-family: var(--shokupan-font-mono);\n font-size: 1rem;\n background: var(--bg-primary);\n padding: 0.75rem 1.5rem;\n border-radius: 8px;\n display: inline-block;\n border: 1px solid var(--border-color);\n }\n .method {\n font-weight: bold;\n margin-right: 0.5rem;\n padding: 0.2rem 0.5rem;\n border-radius: 4px;\n }\n .path {\n color: var(--text-primary);\n }\n @keyframes fadeIn {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n }\n `;\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${title}</title>\n <link href=\"/_shokupan/error-view/theme.css\" rel=\"stylesheet\" />\n <style>${css}</style>\n</head>\n<body>\n <div class=\"container\">\n <h1>${status}</h1>\n <h2>${error.message || 'An error occurred'}</h2>\n <div class=\"meta\">\n <span class=\"method badge-${method}\">${method}</span>\n <span class=\"path\">${path}</span>\n </div>\n </div>\n</body>\n</html>`;\n}\n","import type { Shokupan } from '../../../shokupan';\nimport { asyncContext } from '../../../util/async-hooks';\nimport { getErrorStatus } from '../../../util/http-error';\nimport type { Middleware, ShokupanPlugin } from '../../../util/types';\nimport { applyMonkeyPatch } from './monkeypatch';\nimport { renderErrorView } from './views/error';\nimport { renderStatusView } from './views/status';\n\nexport interface ErrorViewConfig {\n /**\n * Theme for syntax highlighting (default 'dark')\n */\n theme?: 'light' | 'dark';\n}\n\nexport class ErrorView implements ShokupanPlugin {\n name = 'error-view';\n\n constructor(private config: ErrorViewConfig = {}) { }\n\n async onInit(app: Shokupan) {\n // Apply global patches\n applyMonkeyPatch();\n\n\n // Create middleware\n const errorViewMiddleware: Middleware = async (ctx, next) => {\n try {\n return await next();\n } catch (err: any) {\n // Only handle if client accepts HTML\n const accept = ctx.get('accept') || '';\n if (!accept.includes('text/html')) {\n throw err; // Re-throw for JSON/default handler\n }\n\n // Enhance Error with Metadata (Safe Injection)\n if (!err.timestamp) {\n Object.defineProperty(err, 'timestamp', {\n value: Date.now(),\n enumerable: false,\n writable: true,\n configurable: true\n });\n }\n\n if (!err.id) {\n Object.defineProperty(err, 'id', {\n value: ctx.requestId,\n enumerable: false,\n writable: true,\n configurable: true\n });\n }\n\n if (!err.scope) {\n const store = asyncContext.getStore();\n if (store) {\n Object.defineProperty(err, 'scope', {\n value: { ...store },\n enumerable: false,\n writable: true,\n configurable: true\n });\n }\n }\n\n const status = getErrorStatus(err);\n\n // If it's a 404 (NotFoundError) or other 4xx, use Status View (Simplified)\n if (status === 404 || status === 401 || status === 403) {\n // Pass error to status view to extract message\n const html = await renderStatusView(ctx, status, err);\n return ctx.html(html, status);\n }\n\n // For 500s or others, use full Error View with stack trace\n const html = await renderErrorView(ctx, err);\n return ctx.html(html, status);\n }\n };\n\n // Name it for debugging\n Object.defineProperty(errorViewMiddleware, 'name', { value: 'ErrorViewMiddleware' });\n\n // Register asset routes\n const { join } = await import('path');\n const assetDir = join(import.meta.dir, 'assets');\n\n app.static('/_shokupan/error-view', assetDir);\n\n // Register middleware\n app.use(errorViewMiddleware);\n }\n}\n","import type { ApolloServer } from '@apollo/server';\nimport { ShokupanRouter } from '../../router';\nimport type { Shokupan } from '../../shokupan';\nimport type { ShokupanPlugin, ShokupanPluginOptions } from '../../util/types';\n\nexport interface GraphQLPluginOptions {\n /**\n * Path to mount the GraphQL endpoint to.\n * @default '/graphql'\n */\n path?: string;\n\n /**\n * GraphQL Type Definitions\n */\n typeDefs: any;\n\n /**\n * GraphQL Resolvers\n */\n resolvers: any;\n\n /**\n * Optional Apollo Server configuration\n */\n apolloConfig?: Omit<ConstructorParameters<typeof ApolloServer>[0], 'typeDefs' | 'resolvers'>;\n}\n\n/**\n * GraphQL Apollo Server Plugin for Shokupan.\n * Enables serving GraphQL APIs using Apollo Server 4.\n */\nexport class GraphQLApolloPlugin extends ShokupanRouter<any> implements ShokupanPlugin {\n private apolloServer: ApolloServer<any>; // Use generic any or verify type\n\n constructor(private pluginOptions: GraphQLPluginOptions) {\n super();\n this.pluginOptions.path ??= '/graphql';\n }\n\n async onInit(app: Shokupan, options?: ShokupanPluginOptions) {\n // Load peer dependencies\n const { ApolloServer, HeaderMap } = await import('@apollo/server');\n\n this.apolloServer = new ApolloServer({\n typeDefs: this.pluginOptions.typeDefs,\n resolvers: this.pluginOptions.resolvers,\n ...(this.pluginOptions.apolloConfig || {} as any),\n });\n\n const path = options?.path || this.pluginOptions.path || '/graphql';\n app.mount(path, this);\n\n\n // Ensure Apollo Server is started before handling requests\n // app.onStart() ensures this runs before the server listens\n app.onStart(async () => {\n await this.apolloServer.start();\n });\n\n // Handle POST requests for GraphQL operations\n this.post('/', async (ctx) => {\n // Ensure body is parsed\n const body = await ctx.body();\n\n const httpGraphQLResponse = await this.apolloServer.executeHTTPGraphQLRequest({\n httpGraphQLRequest: {\n body,\n method: ctx.req.method,\n search: ctx.url.search,\n headers: new HeaderMap(ctx.req.headers),\n },\n // Pass the Shokupan Context as the GraphQL Context\n context: async () => ({ ...ctx, shokupan: ctx }),\n });\n\n // Set Headers\n for (const [key, value] of httpGraphQLResponse.headers) {\n ctx.set(key, value);\n }\n\n // Send Response\n if (httpGraphQLResponse.body.kind === 'complete') {\n return ctx.send(httpGraphQLResponse.body.string, {\n status: httpGraphQLResponse.status ?? 200,\n });\n } else {\n // Basic support for chunked responses (e.g. invalid query iterator or future defer/stream)\n // For full stream support, we might need a more advanced stream handler\n let string = '';\n for await (const chunk of httpGraphQLResponse.body.asyncIterator) {\n string += chunk;\n }\n return ctx.send(string, {\n status: httpGraphQLResponse.status ?? 200,\n });\n }\n });\n\n // Handle GET requests (Landing Page / Playground)\n this.get('/', async (ctx) => {\n const httpGraphQLResponse = await this.apolloServer.executeHTTPGraphQLRequest({\n httpGraphQLRequest: {\n body: (Object.keys(ctx.query).length > 0) ? ctx.query : undefined,\n method: ctx.req.method,\n search: ctx.url.search,\n headers: new HeaderMap(ctx.req.headers),\n },\n context: async () => ({ ...ctx, shokupan: ctx }),\n });\n\n // Set Headers\n for (const [key, value] of httpGraphQLResponse.headers) {\n ctx.set(key, value);\n }\n\n if (httpGraphQLResponse.body.kind === 'complete') {\n return ctx.html(httpGraphQLResponse.body.string, httpGraphQLResponse.status ?? 200);\n } else {\n let string = '';\n for await (const chunk of httpGraphQLResponse.body.asyncIterator) {\n string += chunk;\n }\n return ctx.html(string, httpGraphQLResponse.status ?? 200);\n }\n });\n }\n}\n","import type { YogaServerOptions } from 'graphql-yoga';\nimport { ShokupanRouter } from '../../router';\nimport type { Shokupan } from '../../shokupan';\nimport type { ShokupanPlugin, ShokupanPluginOptions } from '../../util/types';\n\nexport interface GraphQLYogaPluginOptions {\n /**\n * Path to mount the GraphQL endpoint to.\n * @default '/graphql'\n */\n path?: string;\n\n /**\n * Yoga Server configuration\n */\n yogaConfig: YogaServerOptions<any, any>;\n}\n\n/**\n * GraphQL Yoga Plugin for Shokupan.\n * Enables serving GraphQL APIs using GraphQL Yoga.\n */\nexport class GraphQLYogaPlugin extends ShokupanRouter<any> implements ShokupanPlugin {\n private yoga: any;\n\n constructor(private pluginOptions: GraphQLYogaPluginOptions) {\n super();\n this.pluginOptions.path ??= '/graphql';\n }\n\n async onInit(app: Shokupan, options?: ShokupanPluginOptions) {\n // Load peer dependency\n const { createYoga } = await import('graphql-yoga');\n\n const path = options?.path || this.pluginOptions.path || '/graphql';\n\n // Initialize Yoga instance\n this.yoga = createYoga({\n ...this.pluginOptions.yogaConfig,\n graphqlEndpoint: path,\n });\n\n app.mount(path, this);\n\n // Handle both GET and POST requests\n const handler = async (ctx: any) => {\n let body: any;\n if (ctx.req.method !== 'GET' && ctx.req.method !== 'HEAD') {\n body = await ctx.body();\n // Yoga expects a string or Buffer for the body in Request\n if (typeof body === 'object' && body !== null) {\n body = JSON.stringify(body);\n }\n }\n\n const response = await this.yoga.fetch(\n new Request(ctx.req.url, {\n method: ctx.req.method,\n headers: ctx.req.headers as any,\n body,\n }),\n {\n ...ctx,\n }\n );\n\n // Set Headers\n response.headers.forEach((value: string, key: string) => {\n ctx.set(key, value);\n });\n\n // Send Response\n const text = await response.text();\n return ctx.send(text, {\n status: response.status,\n });\n };\n\n this.get('/', handler);\n this.post('/', handler);\n this.get('/*', handler);\n this.post('/*', handler);\n }\n}\n","\nimport { ShokupanContext } from \"../../../context\";\nimport type { Shokupan } from \"../../../shokupan\";\nimport type { Middleware, ShokupanPlugin } from \"../../../util/types\";\n\n/**\n * Extends the ShokupanContext interface with HTMX specific helpers.\n */\ndeclare module \"../../../context\" {\n interface ShokupanContext {\n /**\n * Checks if the request is an HTMX request.\n */\n isHtmx: boolean;\n /**\n * Checks if the request is boosting.\n */\n isHtmxBoosted: boolean;\n /**\n * Sets the HX-Trigger header.\n */\n trigger(event: string | Record<string, any>, options?: { after?: 'receive' | 'settle' | 'swap'; }): void;\n /**\n * Sets the HX-Push-Url header.\n */\n pushUrl(url: string | false): void;\n /**\n * Sets the HX-Redirect header.\n */\n htmxRedirect(url: string): void;\n /**\n * Sets the HX-Refresh header.\n */\n refresh(): void;\n }\n}\n\nexport class HtmxPlugin implements ShokupanPlugin {\n async onInit(app: Shokupan) {\n app.use(this.middleware());\n }\n\n middleware(): Middleware {\n return async (ctx: ShokupanContext, next: () => Promise<any>) => {\n // Helpers\n Object.defineProperty(ctx, 'isHtmx', {\n get: () => ctx.req.headers.has('hx-request')\n });\n\n Object.defineProperty(ctx, 'isHtmxBoosted', {\n get: () => ctx.req.headers.has('hx-boosted')\n });\n\n ctx.trigger = (event: string | Record<string, any>, options?: { after?: 'receive' | 'settle' | 'swap'; }) => {\n let headerName = 'HX-Trigger';\n if (options?.after === 'settle') headerName = 'HX-Trigger-After-Settle';\n if (options?.after === 'swap') headerName = 'HX-Trigger-After-Swap';\n\n let value = JSON.stringify(event);\n // If simple string key with no data, can handle differently or just JSON object. \n // HTMX supports simple names or JSON map.\n if (typeof event === 'string') {\n // For single event name, just send it, unless we want to support args? \n // Usually JSON is safest.\n value = event;\n } else {\n value = JSON.stringify(event);\n }\n\n ctx.set(headerName, value);\n };\n\n ctx.pushUrl = (url: string | false) => {\n ctx.set('HX-Push-Url', url === false ? 'false' : url);\n };\n\n ctx.htmxRedirect = (url: string) => {\n ctx.set('HX-Redirect', url);\n };\n\n ctx.refresh = () => {\n ctx.set('HX-Refresh', 'true');\n };\n\n // Process request\n return next();\n };\n }\n}\n","import type { RecordId } from 'surrealdb';\nimport type { ShokupanContext } from \"../../../context\";\nimport { $finalResponse } from '../../../util/symbol';\nimport type { Middleware } from \"../../../util/types\";\n\nexport interface IdempotencyOptions {\n /**\n * Header name to use for the idempotency key.\n * @default \"Idempotency-Key\"\n */\n header?: string;\n /**\n * Time to live for the idempotency key in milliseconds.\n * @default 86400000 (24 hours)\n */\n ttl?: number;\n}\n\ninterface StoredResponse {\n status: number;\n headers: Record<string, string>;\n body: string;\n timestamp: number;\n}\n\n/**\n * Idempotency middleware. This middleware will cache responses based on the idempotency key\n * to prevent duplicate server processing of requests.\n * @param options Idempotency options\n * @returns Middleware\n */\nexport function Idempotency(options: IdempotencyOptions = {}): Middleware {\n const headerName = options.header || \"Idempotency-Key\";\n const ttl = options.ttl || 24 * 60 * 60 * 1000;\n\n let RecordIdClass: typeof RecordId;\n\n const idempotencyMiddleware: Middleware = async function IdempotencyMiddleware(ctx: ShokupanContext, next) {\n const key = ctx.headers.get(headerName);\n\n if (!key) {\n return next();\n }\n\n // Check if key exists\n // Check if key exists\n try {\n if (!RecordIdClass) {\n const mod = await import('surrealdb');\n RecordIdClass = mod.RecordId;\n }\n const stored = await ctx.app.db.select<StoredResponse>(new RecordIdClass('idempotency', key));\n if (stored) {\n // Check TTL (though database cleaning might happen elsewhere, good to check here too if needed, \n // but usually we rely on DB or just return if found. \n // Let's rely on finding it = valid for now, or check timestamp if we care about explicit expiry logic \n // beyond just \"record exists\". SurrealDB might not auto-expire without events, \n // but let's check timestamp manually for safety or just assume if it's there it's valid.\n // Should we implement cleanup? For now, we'll return what we found.\n\n const responseHeaders = new Headers(stored.headers);\n responseHeaders.set('X-Idempotency-Hit', 'true');\n\n // Return stored response\n return new Response(stored.body, {\n status: stored.status,\n headers: responseHeaders\n });\n }\n } catch (e) {\n // If error reading, log and proceed? Or fail?\n console.error(\"Idempotency read error:\", e);\n // safe default: proceed as if new\n }\n\n // Not found, execute\n const result = await next();\n\n let response: Response | undefined;\n\n // Normalization logic mimicking Shokupan.handleRequest\n if (result instanceof Response) {\n response = result;\n } else if ((result === null || result === undefined) && ctx[$finalResponse] instanceof Response) {\n response = ctx[$finalResponse];\n } else if (result !== null && result !== undefined) {\n if (typeof result === 'object') {\n response = await ctx.json(result);\n } else {\n response = await ctx.text(String(result));\n }\n }\n\n // If response is successful (or we want to cache failures too?), store it.\n // Usually we cache 2xx, maybe 4xx.\n // Let's cache everything for strict idempotency.\n\n if (response instanceof Response) {\n // valid key, new response\n // We need to clone the response to read the body without consuming the original stream for the downstream\n const clone = response.clone();\n const bodyText = await clone.text();\n\n const headers: Record<string, string> = {};\n clone.headers.forEach((v, k) => {\n headers[k] = v;\n });\n\n const toStore: StoredResponse = {\n status: clone.status,\n headers,\n body: bodyText,\n timestamp: Date.now()\n };\n\n // Fire and forget storage? Or await?\n // Await to ensure persistence before returning to client (safer for \"guarantee\")\n try {\n await ctx.app.db.upsert(new RecordIdClass('idempotency', key), toStore);\n } catch (e) {\n console.error(\"Idempotency write error:\", e);\n }\n\n return response;\n }\n\n return result;\n };\n\n idempotencyMiddleware.isBuiltin = true;\n idempotencyMiddleware.pluginName = 'Idempotency';\n\n return idempotencyMiddleware;\n}\n","\nimport { ShokupanRouter } from \"../../../router\";\nimport type { Shokupan } from '../../../shokupan';\nimport { $appRoot, $childRouters } from \"../../../util/symbol\";\nimport type { ShokupanPlugin } from \"../../../util/types\";\nimport { OpenAPIAnalyzer } from \"../openapi/analyzer.impl\";\n\nexport interface MCPServerPluginOptions {\n /**\n * The path to mount the MCP server to.\n */\n path?: string;\n /**\n * The root directory to scan for OpenAPI documents.\n */\n rootDir?: string;\n /**\n * Whether to allow the introspection tool.\n */\n allowIntrospection?: boolean;\n /**\n * Whether to allow tool execution.\n */\n allowToolExecution?: boolean;\n}\n\n/**\n * Attaches an MCP server to the application. \n * This MCP server is focus-designed to provide introspection and tool execution capabilities.\n * \n * If your application design requires anything custom, implement your own MCP server.\n */\nexport class MCPServerPlugin implements ShokupanPlugin {\n private router = new ShokupanRouter();\n private analyzer: OpenAPIAnalyzer;\n\n constructor(private options: MCPServerPluginOptions = {}) {\n options.allowIntrospection ??= true;\n options.allowToolExecution ??= true;\n options.path ??= '/mcp';\n if (!options.path.startsWith('/')) {\n options.path = '/' + options.path;\n }\n options.rootDir ??= process.cwd();\n }\n\n public onInit(app: Shokupan) {\n this[$appRoot] = app;\n\n // Initialize Analyzer\n this.analyzer = new OpenAPIAnalyzer(this.options.rootDir);\n\n // Register Tools\n if (this.options.allowIntrospection) {\n this.registerTools();\n this.registerResources();\n this.registerPrompts();\n }\n\n // Register async startup hook\n app.onStart(async () => {\n // Mount the router\n app.mount(this.options.path, this.router);\n\n // Merge App/Router tools into this local router? \n // The request says \"This should also utilize with the previous work we've done\".\n // If the user defines tools on controllers in the main app, they are registered in the main app's routers.\n // But here we are creating a separate router for /mcp endpoint.\n // We need to aggregate tools from the entire app tree into this router's protocol handler,\n // OR make the protocol handler aware of the whole app.\n // For now, let's just make sure tools registered on THIS plugin instances (if any) work.\n // But wait, user wants decorators on controllers to work.\n // Controllers are mounted on `app`.\n // So we need to walk the app tree and collect tools/prompts/resources.\n\n // We can do this on request or at startup.\n // Doing it on request allows dynamic updates but slower.\n // Doing it at startup is better.\n this.collectAppMcpItems(app);\n\n\n // Define Routes for SSE/JSON-RPC\n this.setupRoutes();\n\n // Metadata\n this.router.metadata = {\n file: import.meta.file,\n line: 1,\n name: 'MCPServerPlugin',\n pluginName: 'MCP Server'\n };\n });\n }\n\n private collectAppMcpItems(app: Shokupan) {\n // Simple recursive collector\n const collect = (router: ShokupanRouter) => {\n if (router.mcpProtocol) {\n this.router.mcpProtocol.merge(router.mcpProtocol);\n }\n router[$childRouters]?.forEach(collect);\n };\n collect(app);\n }\n\n private setupRoutes() {\n\n // SSE Endpoint (GET)\n this.router.get('', (ctx) => {\n const endpointUrl = `${ctx.protocol}://${ctx.host}${this.options.path}`;\n const enc = new TextEncoder();\n\n return new Response(\n new ReadableStream({\n start(controller) {\n controller.enqueue(enc.encode(`event: endpoint\\ndata: ${JSON.stringify(endpointUrl)}\\n\\n`));\n // Keep open\n },\n cancel() {\n // Cleanup if needed\n }\n }),\n {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n }\n }\n );\n });\n\n // JSON-RPC Endpoint (POST)\n this.router.post('', async (ctx) => {\n let parsedBody;\n try {\n parsedBody = await ctx.body();\n } catch (e) {\n return ctx.json({\n jsonrpc: \"2.0\",\n id: null,\n error: { code: -32700, message: \"Parse error\" }\n }, 400);\n }\n\n const response = await this.router.mcpProtocol.handleMessage(parsedBody);\n\n if (response) {\n return ctx.json(response);\n }\n // Notification -> 202 Accepted or 204 No Content\n return ctx.text('', 204);\n });\n }\n\n private registerTools() {\n const ensureExecutionAllowed = () => {\n if (!this.options.allowToolExecution) {\n throw new Error(\"Tool execution is disabled.\");\n }\n };\n\n this.router.tool(\n \"list_endpoints\",\n {},\n async () => {\n ensureExecutionAllowed();\n const { applications } = await this.analyzer.analyze();\n const endpoints = applications.flatMap(app =>\n app.routes.map(r => ({\n method: r.method,\n path: r.path,\n handler: r.handlerName,\n summary: r.summary\n }))\n );\n\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(endpoints, null, 2)\n }]\n };\n }\n );\n\n this.router.tool(\n \"get_endpoint_details\",\n {\n type: \"object\",\n properties: {\n method: { type: \"string\" },\n path: { type: \"string\" }\n },\n required: [\"method\", \"path\"]\n },\n async ({ method, path }) => {\n ensureExecutionAllowed();\n const { applications } = await this.analyzer.analyze();\n const route = applications.flatMap(app => app.routes)\n .find(r => r.method.toUpperCase() === method.toUpperCase() && r.path === path);\n\n if (!route) {\n return {\n content: [{ type: \"text\", text: `Endpoint ${method} ${path} not found.` }],\n isError: true\n };\n }\n\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(route, null, 2)\n }]\n };\n }\n );\n }\n\n private registerResources() {\n // Register the full OpenAPI spec\n this.router.resource(\n \"mcp://api/openapi.json\",\n {\n name: \"openapi-spec\",\n mimeType: \"application/json\"\n },\n async (uri) => {\n const { applications } = await this.analyzer.analyze();\n const endpoints = applications.flatMap(app =>\n app.routes.map(r => ({\n method: r.method,\n path: r.path,\n handler: r.handlerName,\n summary: r.summary,\n requestTypes: r.requestTypes,\n responseType: r.responseType\n }))\n );\n\n return {\n contents: [{\n uri: uri,\n text: JSON.stringify(endpoints, null, 2)\n }]\n };\n }\n );\n\n // Register source code access for routes\n this.router.resource(\n \"mcp://api/routes/{method}/{path}/source\",\n {\n name: \"route-source\",\n mimeType: \"text/typescript\"\n },\n async (uri) => {\n // Parse URI manually for now (simplified)\n // uri: mcp://api/routes/GET/users/source\n const parts = uri.replace(\"mcp://\", \"\").split('/');\n // parts: [api, routes, GET, users, source]\n // This simple split fails for paths with slashes.\n // We need regex or simpler matching.\n\n // Assuming format: mcp://api/routes/<METHOD>/<PATH>/source\n // PATH can contain slashes.\n // We'll rely on regex matching later or assume simple case for now to fix compile.\n\n // TODO: Better path matching for resources\n const method = parts[2];\n // Try to reconstruct path?\n // This is brittle.\n\n // Let's use analyzer to find route?\n // The issue is extracting args from URI.\n // Protocol handler supports exact match.\n // Glob matching requires iterating handlers.\n // My simple McpProtocol fallback needs work if we want true params.\n // For now, assuming exact match or client sends exact URI.\n\n throw new Error(\"Dynamic resource reading not fully implemented in lightweight version yet.\");\n }\n );\n }\n\n private registerPrompts() {\n this.router.prompt(\n \"generate-client\",\n [\n { name: \"method\", required: true },\n { name: \"path\", required: true }\n ],\n async ({ method, path }) => {\n const { applications } = await this.analyzer.analyze();\n const route = applications.flatMap(app => app.routes)\n .find(r => r.method.toUpperCase() === method.toUpperCase() && r.path === path);\n\n if (!route) {\n return {\n messages: [{\n role: \"user\",\n content: {\n type: \"text\",\n text: `Start a new task to create a client for ${method} ${path}. The endpoint was not found in the current analysis.`\n }\n }]\n };\n }\n\n return {\n messages: [{\n role: \"user\",\n content: {\n type: \"text\",\n text: `Please generate a TypeScript client function for the following endpoint:\nMethod: ${route.method}\nPath: ${route.path}\nSummary: ${route.summary || 'N/A'}\nRequest Types: ${JSON.stringify(route.requestTypes, null, 2)}\nResponse Type: ${route.responseType || 'unknown'}\n\nUse fetch or axios. Ensure proper typing.`\n }\n }]\n };\n }\n );\n\n // ... (Other prompts omitted for brevity/simplicity, logic is identical)\n }\n}\n","import type { ApiReferenceConfiguration } from '@scalar/api-reference';\nimport type { OpenAPI } from '@scalar/openapi-types';\nimport type { Eta } from 'eta';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { ShokupanRouter } from '../../router';\nimport type { Shokupan } from '../../shokupan';\nimport { deepMerge } from '../../util/deep-merge';\nimport type { DeepPartial, ShokupanPlugin, ShokupanPluginOptions } from '../../util/types';\nimport { OpenAPIAnalyzer } from './openapi/analyzer';\n\n\nexport type ScalarPluginOptions = {\n /**\n * Base document to use for API reference.\n */\n baseDocument?: DeepPartial<OpenAPI.Document>;\n /**\n * Configuration for API reference.\n */\n config?: Partial<ApiReferenceConfiguration>;\n /**\n * Whether to enable static analysis.\n * When this is enabled, the plugin will run static analysis on the entrypoint\n * and generate an OpenAPI document. This is useful for when you want to generate\n * an OpenAPI document without having to manually define it.\n * \n * Only works with TypeScript entrypoints.\n */\n enableStaticAnalysis?: boolean;\n\n /**\n * Path to mount the plugin to.\n * @default '/reference'\n */\n path?: string;\n};\n\n/**\n * Scalar plugin. This plugin provides an API reference interface for your API.\n * @param options Scalar plugin options\n * @returns Scalar plugin instance\n */\nexport class ScalarPlugin extends ShokupanRouter<any> implements ShokupanPlugin {\n private eta: Eta | undefined;\n\n constructor(\n private readonly pluginOptions: ScalarPluginOptions = {}\n ) {\n pluginOptions.config ??= {};\n super();\n\n // Metadata\n this.metadata = {\n file: import.meta.file,\n line: 1,\n name: 'ScalarPlugin',\n pluginName: 'Scalar'\n };\n\n // Initialize routes immediately so the plugin works when mounted directly\n this.initRoutes();\n }\n\n async onInit(app: Shokupan, options?: ShokupanPluginOptions) {\n // Eagerly load Eta during app initialization\n const { Eta } = await import('eta');\n this.eta = new Eta();\n\n const path = options?.path || this.pluginOptions.path || '/reference';\n app.mount(path, this);\n\n // Also run onMount logic if needed\n this.onMount(app);\n }\n\n private async ensureEta() {\n if (!this.eta) {\n const { Eta } = await import('eta');\n this.eta = new Eta();\n }\n }\n\n private initRoutes() {\n const bootId = Date.now().toString();\n\n this.get(\"/_lifecycle\", (ctx) => {\n const success = ctx.upgrade({\n data: {\n bootId,\n handler: {\n open: (ws: any) => {\n ws.send(JSON.stringify({ type: 'hello', bootId }));\n }\n }\n }\n });\n if (success) return undefined;\n return ctx.json({ boot: bootId });\n });\n\n this.get(\"/\", async (ctx) => {\n await this.ensureEta();\n\n let path = ctx.path;\n if (!path.endsWith(\"/\")) path += \"/\";\n\n // Auto-reload script for development mode\n const devScript = ctx.app?.applicationConfig.development ? `\n <script>\n (function() {\n const bootId = \"${bootId}\";\n let ws;\n let reconnectTimer;\n \n function connect() {\n const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n const wsUrl = protocol + '//' + window.location.host + '${path}_lifecycle';\n \n ws = new WebSocket(wsUrl);\n \n ws.onopen = () => {\n console.log('[Scalar] Connected to lifecycle monitor');\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n reconnectTimer = undefined;\n }\n };\n \n ws.onmessage = (event) => {\n try {\n const data = JSON.parse(event.data);\n if (data.type === 'hello') {\n if (data.bootId !== bootId) {\n console.log('[Scalar] Server restarted (timestamp change), reloading...');\n window.location.reload();\n }\n }\n } catch (e) {}\n };\n \n ws.onclose = () => {\n console.log('[Scalar] Lifecycle connection lost');\n ws = undefined;\n scheduleReconnect();\n };\n }\n \n function scheduleReconnect() {\n if (reconnectTimer) return;\n reconnectTimer = setTimeout(() => {\n reconnectTimer = undefined;\n connect();\n }, 2000);\n }\n \n connect();\n })();\n </script>\n ` : '';\n\n // Attempt to read theme.css from src or dist\n let themeCss = '';\n try {\n // Try src location\n try {\n themeCss = readFileSync(join(process.cwd(), 'src/theme.css'), 'utf-8');\n } catch {\n // Try adjacent to main/dist? For now, we rely on src\n }\n } catch (e) { }\n\n if (!this.eta) throw new Error(\"Eta not initialized\");\n\n return ctx.html(this.eta.renderString(`<!doctype html>\n <html lang=\"en\">\n <head>\n <title>API Reference</title>\n <meta charset = \"utf-8\" />\n <meta name=\"viewport\" content = \"width=device-width, initial-scale=1\" />\n <style>\n ${themeCss}\n \n :root {\n --scalar-color-1: var(--primary);\n --scalar-color-2: var(--secondary);\n --scalar-color-3: var(--accent);\n --scalar-color-accent: var(--accent);\n \n --scalar-background-1: var(--bg-primary);\n --scalar-background-2: var(--bg-secondary);\n --scalar-background-3: var(--bg-card);\n \n --scalar-text-1: var(--text-primary);\n --scalar-text-2: var(--text-secondary);\n --scalar-text-3: var(--text-muted);\n \n --scalar-border-color: var(--border-color);\n }\n </style>\n </head>\n\n <body>\n <div id=\"app\"></div>\n <script src=\"https://cdn.jsdelivr.net/npm/@scalar/api-reference\"></script>\n <script>\n Scalar.createApiReference('#app', [{ ...<%~ JSON.stringify(it.config.baseDocument) %>,\n url: \"<%= it.path %>openapi.json\",\n }\n ])\n </script>\n <%~ it.devScript %>\n </body>\n\n </html>`, { path, config: this.pluginOptions, devScript }));\n });\n\n this.get(\"/openapi.json\", async (ctx) => {\n let spec: any;\n // Use pre-generated spec if available (from startup)\n if ((this.root as any).openApiSpec) {\n try {\n spec = structuredClone((this.root as any).openApiSpec);\n } catch (e) {\n // Fallback if structuredClone fails (e.g. non-cloneable types)\n spec = Object.assign({}, (this.root as any).openApiSpec);\n }\n }\n else {\n // Fallback to on-demand generation\n spec = await (this.root || this).generateApiSpec();\n }\n\n // If static analysis ran in onStart, baseDocument is already populated.\n // If NOT (e.g. strict mode or unit test without listen), we might need to lazy load?\n // For now, assume baseDocument has it.\n // But we still need to merge baseDocument (static) + spec (runtime).\n\n if (this.pluginOptions.baseDocument) {\n deepMerge(spec, this.pluginOptions.baseDocument);\n }\n\n return ctx.json(spec);\n });\n }\n\n // New lifecycle method to be called by router.mount\n public onMount(parent: ShokupanRouter<any>) {\n if ((parent as any).onStart) {\n (parent as any).onStart(async () => {\n if (this.pluginOptions.enableStaticAnalysis) {\n try {\n const entrypoint = process.argv[1];\n console.log(`[ScalarPlugin] Running eager static analysis on entrypoint: ${entrypoint}`);\n const analyzer = new OpenAPIAnalyzer(process.cwd(), entrypoint);\n let staticSpec = await analyzer.analyze();\n\n if (!this.pluginOptions.baseDocument) this.pluginOptions.baseDocument = {};\n deepMerge(this.pluginOptions.baseDocument as any, staticSpec);\n console.log('[ScalarPlugin] Static analysis completed successfully.');\n } catch (err) {\n console.error('[ScalarPlugin] Failed to run static analysis:', err);\n }\n }\n });\n }\n }\n}","import type { Server, Socket } from \"socket.io\";\n\nimport { ShokupanContext } from \"../../context\";\nimport type { Shokupan } from \"../../shokupan\";\nimport { ShokupanRequest } from \"../../util/request\";\nimport { $ws } from '../../util/symbol';\n\n/**\n * Attaches the Shokupan HTTP Bridge and Event System to a Socket.IO server.\n * This makes the Shokupan HTTP APIs accessible via Socket.IO events.\n * \n * Send events as `shokupan:request` events with the payload { type: \"http\", id: \"123\", body: {} }.\n * \n * Responses are emitted as `shokupan:response` events with the payload { id, status, body }\n * \n * @param io The Socket.IO server instance\n * @param app The Shokupan application instance\n */\nexport function attachSocketIOBridge(io: Server, app: Shokupan) {\n io.on(\"connection\", (socket: Socket) => {\n\n // 1. Event Handling (Wildcard)\n // ... (lines 15-41 omitted comments for brevity if needed, but keeping logic)\n\n socket.onAny(async (event: string, ...args: any[]) => {\n // 1. Check if it's an HTTP Bridge request\n if (event === 'shokupan:request' || event === 'http') {\n return;\n }\n\n // 2. Lookup Handler\n const handler = app.findEvent(event);\n if (handler) {\n const data = args[0]; // Assume first arg is data\n\n // Construct Context\n const req = new ShokupanRequest({\n url: `socketio://${app.applicationConfig.hostname || 'localhost'}/event/${event}`,\n method: 'POST',\n headers: new Headers({ 'content-type': 'application/json' }),\n body: JSON.stringify(data)\n });\n\n const ctx = new ShokupanContext(req as any, (app as any).server);\n (ctx as any)[$ws] = socket;\n (ctx as any).io = io;\n\n try {\n for (let i = 0; i < handler.length; i++) {\n await handler[i](ctx);\n }\n } catch (e) {\n await app.runHooks('onError', ctx, e);\n\n if (app.applicationConfig['websocketErrorHandler']) {\n await app.applicationConfig['websocketErrorHandler'](e, ctx);\n } else {\n console.error(`Error in event ${event}:`, e);\n }\n }\n }\n });\n\n // 2. HTTP Bridge\n if (app.applicationConfig['enableHttpBridge']) {\n socket.on(\"shokupan:request\", async (payload: any, callback: any) => {\n // ... same logic\n try {\n const { method, path, headers, body } = payload;\n // Validate payload...\n\n const url = new URL(path, `http://${app.applicationConfig.hostname || 'localhost'}:3000`);\n const req = new Request(url.toString(), {\n method,\n headers,\n body: typeof body === 'object' ? JSON.stringify(body) : body\n });\n\n const res = await app.fetch(req);\n\n let resBody: any = await res.text();\n try { resBody = JSON.parse(resBody); } catch { }\n\n const resHeaders: Record<string, string> = {};\n res.headers.forEach((v, k) => resHeaders[k] = v);\n\n if (typeof callback === 'function') {\n await callback({\n status: res.status,\n headers: resHeaders,\n body: resBody\n });\n } else {\n socket.emit(\"shokupan:response\", {\n id: payload.id,\n status: res.status,\n headers: resHeaders,\n body: resBody\n });\n }\n\n } catch (e: any) {\n if (typeof callback === 'function') {\n callback({ status: 500, body: { error: e.message } });\n }\n }\n });\n }\n });\n}\n","import { Readable } from 'node:stream';\nimport * as zlib from \"node:zlib\";\nimport type { ShokupanContext } from \"../../context\";\nimport { $finalResponse, $rawBody } from '../../util/symbol';\nimport type { Middleware, NextFn } from \"../../util/types\";\n\nexport interface CompressionOptions {\n /**\n * Minimum byte size to compress responses\n */\n threshold?: number;\n /**\n * Allowed algorithms for response compression\n */\n allowedAlgorithms?: string[];\n /**\n * Enable request decompression\n * @default true\n */\n decompress?: boolean;\n /**\n * Maximum size of decompressed request body in bytes to prevent zipbomb style attacks\n * @default 10485760 (10MB)\n */\n maxDecompressedSize?: number;\n}\n\n/**\n * Create a transform stream that enforces a size limit\n */\nfunction createLimitStream(maxSize: number) {\n let size = 0;\n return new TransformStream({\n transform(chunk, controller) {\n size += (chunk.byteLength || chunk.length);\n if (size > maxSize) {\n controller.error(new Error(`Decompressed body size exceeded limit of ${maxSize} bytes`));\n } else {\n controller.enqueue(chunk);\n }\n }\n });\n}\n\n/**\n * Compression middleware.\n * @param options Compression options\n * @returns Middleware function\n */\nexport function Compression(options: CompressionOptions = {}): Middleware {\n const threshold = options.threshold ?? 512; // 512 bytes default\n const allowedAlgorithms = new Set(options.allowedAlgorithms ?? ['br', 'gzip', 'zstd', 'deflate']);\n const decompress = options.decompress ?? true;\n const maxDecompressedSize = options.maxDecompressedSize ?? 10 * 1024 * 1024; // 10MB default\n\n const compressionMiddleware: Middleware = async function CompressionMiddleware(ctx: ShokupanContext, next: NextFn) {\n // --- Request Decompression Logic ---\n const requestEncoding = ctx.headers.get(\"content-encoding\");\n if (decompress && requestEncoding && !ctx.headers.get(\"content-encoding\")?.includes(\"identity\") && ctx.req.body) {\n let stream: ReadableStream | null = null;\n\n // Determine decompression method\n if (requestEncoding.includes(\"br\")) {\n const decompressor = zlib.createBrotliDecompress();\n const nodeStream = Readable.fromWeb(ctx.req.body as any);\n stream = Readable.toWeb(nodeStream.pipe(decompressor)) as unknown as ReadableStream;\n } else if (requestEncoding.includes(\"gzip\")) {\n if (typeof DecompressionStream !== 'undefined') {\n stream = ctx.req.body.pipeThrough(new DecompressionStream(\"gzip\"));\n } else {\n const decompressor = zlib.createGunzip();\n const nodeStream = Readable.fromWeb(ctx.req.body as any);\n stream = Readable.toWeb(nodeStream.pipe(decompressor)) as unknown as ReadableStream;\n }\n } else if (requestEncoding.includes(\"deflate\")) {\n if (typeof DecompressionStream !== 'undefined') {\n stream = ctx.req.body.pipeThrough(new DecompressionStream(\"deflate\"));\n } else {\n const decompressor = zlib.createInflate();\n const nodeStream = Readable.fromWeb(ctx.req.body as any);\n stream = Readable.toWeb(nodeStream.pipe(decompressor)) as unknown as ReadableStream;\n }\n }\n\n if (stream) {\n // Apply zipbomb protection\n const outputStream = stream.pipeThrough(createLimitStream(maxDecompressedSize));\n\n // Cache IP before swapping request, as requestIP might rely on the original native request identity\n const originalIp = ctx.ip;\n const originalReq = ctx.req;\n\n const newHeaders = new Headers(originalReq.headers);\n newHeaders.delete(\"content-encoding\");\n newHeaders.delete(\"content-length\");\n\n const newReq = new Proxy(originalReq, {\n get(target, prop, receiver) {\n if (prop === 'body') return outputStream;\n if (prop === 'headers') return newHeaders;\n if (prop === 'json') return async () => JSON.parse(await new Response(outputStream).text());\n if (prop === 'text') return async () => await new Response(outputStream).text();\n if (prop === 'arrayBuffer') return async () => await new Response(outputStream).arrayBuffer();\n if (prop === 'blob') return async () => await new Response(outputStream).blob();\n if (prop === 'formData') return async () => await new Response(outputStream).formData();\n\n // Use target as receiver to ensure native getters work (they check 'this')\n return Reflect.get(target, prop, target);\n }\n });\n\n // Force update request on context\n (ctx as any).request = newReq;\n\n // Restore IP via property override\n if (originalIp) {\n Object.defineProperty(ctx, 'ip', {\n configurable: true,\n get: () => originalIp\n });\n }\n }\n }\n\n // --- Response Compression Logic ---\n\n const acceptEncoding = ctx.headers.get(\"accept-encoding\") || \"\";\n\n // Check if compression is supported\n let method: 'br' | 'gzip' | 'zstd' | 'deflate' | null = null;\n if (acceptEncoding.includes(\"br\")) method = \"br\";\n else if (acceptEncoding.includes(\"zstd\")) {\n // Validate zstd is only used in Bun runtime\n if (typeof Bun === 'undefined') {\n throw new Error(\"zstd compression is only available in Bun runtime. Client requested zstd but server is running on Node.js.\");\n }\n method = \"zstd\";\n }\n else if (acceptEncoding.includes(\"gzip\")) method = \"gzip\";\n else if (acceptEncoding.includes(\"deflate\")) method = \"deflate\";\n\n if (!method) return next();\n\n if (!allowedAlgorithms.has(method)) {\n return next();\n }\n\n let response = await next();\n\n // Check for implicit return stored in context\n if (!(response instanceof Response) && ctx[$finalResponse] instanceof Response) {\n response = ctx[$finalResponse];\n }\n\n if (response instanceof Response) {\n // Don't compress if already compressed\n if (response.headers.has(\"Content-Encoding\")) return response;\n\n // Optimized path: use raw body from context if available\n // Optimized path: use raw body from context if available\n let body: ArrayBuffer | Uint8Array;\n let bodySize: number;\n\n if (ctx[$rawBody] !== undefined) {\n // Fast path: we have the raw body from ctx.json() or ctx.text()\n if (typeof ctx[$rawBody] === \"string\") {\n const encoded = new TextEncoder().encode(ctx[$rawBody]);\n body = encoded;\n bodySize = encoded.byteLength;\n } else if (ctx[$rawBody] instanceof Uint8Array) {\n body = ctx[$rawBody];\n bodySize = ctx[$rawBody].byteLength;\n } else {\n body = ctx[$rawBody] as ArrayBuffer;\n bodySize = body.byteLength;\n }\n } else {\n // Fallback: read from response (slower)\n body = await response.arrayBuffer();\n bodySize = body.byteLength;\n }\n\n if (bodySize < threshold) {\n // Don't compress, but we consumed the body so recreate the response\n return new Response(body as any, {\n status: response.status,\n statusText: response.statusText,\n headers: new Headers(response.headers)\n });\n }\n\n let compressed: Uint8Array;\n\n switch (method) {\n case \"br\":\n compressed = await new Promise((res, rej) => zlib.brotliCompress(body, {\n params: {\n [zlib.constants.BROTLI_PARAM_QUALITY]: 4,\n }\n }, (err, data) => {\n if (err) return rej(err);\n res(data);\n }));\n break;\n case \"gzip\":\n compressed = await new Promise((res, rej) => zlib.gzip(body, (err, data) => {\n if (err) return rej(err);\n res(data);\n }));\n break;\n case \"zstd\":\n // Note: Runtime check happens earlier in method selection\n compressed = await Bun.zstdCompress(body);\n break;\n default: // deflate\n compressed = await new Promise((res, rej) => zlib.deflate(body, (err, data) => {\n if (err) return rej(err);\n res(data);\n }));\n break;\n }\n\n const headers = new Headers(response.headers);\n headers.set(\"Content-Encoding\", method);\n headers.set(\"Content-Length\", String(compressed.length));\n\n return new Response(compressed as any, {\n status: response.status,\n statusText: response.statusText,\n headers\n });\n }\n\n return response;\n };\n\n compressionMiddleware.isBuiltin = true;\n compressionMiddleware.pluginName = 'Compression';\n return compressionMiddleware;\n};\n","import type { ShokupanContext } from \"../../context\";\nimport type { Middleware, NextFn } from \"../../util/types\";\n\nexport interface CorsOptions {\n /**\n * Origin to allow. Can be a string, array of strings, or function that returns a string.\n */\n origin?: string | string[] | ((ctx: ShokupanContext) => string | undefined | null | boolean);\n /**\n * HTTP methods to allow.\n */\n methods?: string | string[];\n /**\n * HTTP headers to allow.\n */\n allowedHeaders?: string | string[];\n /**\n * HTTP headers to expose.\n */\n exposedHeaders?: string | string[];\n /**\n * Whether to allow credentials.\n */\n credentials?: boolean;\n /**\n * Maximum age of preflight request.\n */\n maxAge?: number;\n}\n\n/**\n * CORS middleware.\n * @param options CORS options\n * @returns Middleware function\n */\nexport function Cors(options: CorsOptions = {}): Middleware {\n const defaults: CorsOptions = {\n origin: \"*\",\n methods: \"GET,HEAD,PUT,PATCH,POST,DELETE\",\n preflightContinue: false,\n optionsSuccessStatus: 204\n } as any;\n\n const opts = { ...defaults, ...options };\n\n const corsMiddleware: Middleware = async function CorsMiddleware(ctx: ShokupanContext, next: NextFn) {\n const headers: Record<string, string> = {};\n const origin = ctx.headers.get(\"origin\");\n\n const set = (k: string, v: string) => headers[k] = v;\n const append = (k: string, v: string) => {\n const current = headers[k];\n headers[k] = current ? current + ',' + v : v;\n };\n\n // Security: Reject null origin by default (can be used in attacks)\n if (origin === 'null' && opts.origin !== 'null') {\n // Null origin is not allowed unless explicitly set\n return next();\n }\n\n // Set Access-Control-Allow-Origin\n if (opts.origin === \"*\") {\n set(\"Access-Control-Allow-Origin\", \"*\");\n } else if (typeof opts.origin === \"string\") {\n set(\"Access-Control-Allow-Origin\", opts.origin);\n } else if (Array.isArray(opts.origin)) {\n if (origin) {\n // Security: Normalize origins for case-insensitive comparison\n const normalizedOrigin = origin.toLowerCase();\n const normalizedAllowed = opts.origin.map(o => o.toLowerCase());\n\n if (normalizedAllowed.includes(normalizedOrigin)) {\n // Use the original (non-normalized) origin in the response\n set(\"Access-Control-Allow-Origin\", origin);\n append(\"Vary\", \"Origin\");\n }\n }\n } else if (typeof opts.origin === \"function\") {\n const allowed = opts.origin(ctx);\n if (allowed === true && origin) {\n set(\"Access-Control-Allow-Origin\", origin);\n append(\"Vary\", \"Origin\");\n } else if (typeof allowed === 'string') {\n set(\"Access-Control-Allow-Origin\", allowed);\n append(\"Vary\", \"Origin\");\n }\n }\n\n // Access-Control-Allow-Credentials\n if (opts.credentials) {\n set(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n // Access-Control-Expose-Headers\n if (opts.exposedHeaders) {\n const exposed = Array.isArray(opts.exposedHeaders) ? opts.exposedHeaders.join(\",\") : opts.exposedHeaders;\n if (exposed) set(\"Access-Control-Expose-Headers\", exposed);\n }\n\n // Handle Preflight\n if (ctx.method === \"OPTIONS\") {\n // Access-Control-Allow-Methods\n if (opts.methods) {\n const methods = Array.isArray(opts.methods) ? opts.methods.join(\",\") : opts.methods;\n set(\"Access-Control-Allow-Methods\", methods);\n }\n\n // Access-Control-Allow-Headers\n if (opts.allowedHeaders) {\n const h = Array.isArray(opts.allowedHeaders) ? opts.allowedHeaders.join(\",\") : opts.allowedHeaders;\n set(\"Access-Control-Allow-Headers\", h);\n } else {\n // Reflect request headers if not specified\n const reqHeaders = ctx.headers.get(\"access-control-request-headers\");\n if (reqHeaders) {\n set(\"Access-Control-Allow-Headers\", reqHeaders);\n append(\"Vary\", \"Access-Control-Request-Headers\");\n }\n }\n\n // Access-Control-Max-Age\n if (opts.maxAge) {\n set(\"Access-Control-Max-Age\", String(opts.maxAge));\n }\n\n return new Response(null, {\n status: (opts as any).optionsSuccessStatus || 204,\n headers\n });\n }\n\n const response = await next();\n\n if (response instanceof Response) {\n const keys = Object.keys(headers);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n response.headers.set(key, headers[key]);\n }\n }\n\n return response;\n };\n corsMiddleware.isBuiltin = true;\n corsMiddleware.pluginName = 'Cors';\n\n return corsMiddleware;\n}\n","import type { Middleware } from '../../util/types';\n\n/**\n * Adapter to use legacy Express middleware.\n * NOTE: This provides a PARTIAL mock of req/res.\n */\nexport function useExpress(expressMiddleware: any): Middleware {\n return async (ctx, next) => {\n return new Promise((resolve, reject) => {\n // Mock Request\n // Express middleware often mutates req, but Request is readonly.\n // We use a Proxy to intercept writes and store them locally.\n const reqStore: any = {\n method: ctx.method,\n url: ctx.url.pathname + ctx.url.search,\n path: ctx.url.pathname,\n query: ctx.query,\n headers: ctx.headers,\n get: (name: string) => ctx.headers.get(name)\n };\n\n const req = new Proxy(ctx.request, {\n get(target, prop) {\n if (prop in reqStore) return reqStore[prop];\n const val = (target as any)[prop];\n if (typeof val === 'function') return val.bind(target);\n return val;\n },\n set(target, prop, value) {\n reqStore[prop] = value;\n ctx.state[prop as string] = value;\n return true;\n }\n });\n\n // Mock Response (res)\n const res: any = {\n locals: {},\n statusCode: 200,\n setHeader: (name: string, value: string) => {\n ctx.response.headers.set(name, value);\n },\n set: (name: string, value: string) => {\n ctx.response.headers.set(name, value);\n },\n end: (chunk: any) => {\n resolve(new Response(chunk, { status: res.statusCode }));\n },\n status: (code: number) => {\n res.statusCode = code;\n return res;\n },\n send: (body: any) => {\n let content = body;\n if (typeof body === 'object') content = JSON.stringify(body);\n resolve(new Response(content, { status: res.statusCode }));\n },\n json: (body: any) => {\n resolve(Response.json(body, { status: res.statusCode }));\n }\n };\n\n // Execute\n try {\n expressMiddleware(req, res, (err: any) => {\n if (err) return reject(err);\n resolve(next());\n });\n } catch (err) {\n reject(err);\n }\n });\n };\n}","// Lazy-loaded dependencies\nlet plainToInstance: any;\nlet validateOrReject: any;\nimport { ShokupanContext } from \"../../context\";\nimport type { Middleware } from \"../../util/types\";\n\nexport interface ValidationConfig {\n body?: any;\n query?: any;\n params?: any;\n headers?: any;\n}\n\nexport class ValidationError extends Error {\n public status = 400;\n constructor(public errors: any[]) {\n super(\"Validation Error\");\n }\n}\n\n// --- Adapters ---\n\nfunction isZod(schema: any): boolean {\n return typeof schema?.safeParse === 'function';\n}\n\nasync function validateZod(schema: any, data: any) {\n const result = await schema.safeParseAsync(data);\n if (!result.success) {\n throw new ValidationError(result.error.errors);\n }\n return result.data;\n}\n\nfunction isTypeBox(schema: any): boolean {\n return typeof schema?.Check === 'function' && typeof schema?.Errors === 'function';\n}\n\nfunction validateTypeBox(schema: any, data: any) {\n if (!schema.Check(data)) {\n throw new ValidationError([...schema.Errors(data)]);\n }\n return data;\n}\n\nfunction isAjv(schema: any): boolean {\n return typeof schema === 'function' && 'errors' in schema;\n}\n\nfunction validateAjv(schema: any, data: any) {\n const valid = schema(data);\n if (!valid) {\n throw new ValidationError(schema.errors);\n }\n return data;\n}\n\nexport const valibot = (schema: any, parser: Function) => {\n return {\n _valibot: true,\n schema,\n parser\n };\n};\n\nfunction isValibotWrapper(schema: any): boolean {\n return schema?._valibot === true;\n}\n\nasync function validateValibotWrapper(wrapper: any, data: any) {\n const result = await wrapper.parser(wrapper.schema, data);\n if (!result.success) {\n throw new ValidationError(result.issues);\n }\n return result.output;\n}\n\nfunction isClass(schema: any): boolean {\n // Check if it's a constructor for a class\n // Usually classes have names and are functions, but plain functions are also functions.\n // A robust check for a class constructor (especially with decorators) is tricky but checking for prototype \n // and if it looks like a constructor is a start.\n // However, for class-validator/transformer usages, compiling consumers typically pass the class Constructor.\n try {\n if (typeof schema === 'function' && /^\\s*class\\s+/.test(schema.toString())) {\n return true;\n }\n // Fallback for some complied outputs or if it just has a name and prototype\n // But we want to avoid treating `z.string()` (which might yield a function?) \n // actually Zod schemas are objects. Custom validation functions are functions.\n // We can assume if the user passes a class constructor it intends for class-validator.\n return typeof schema === 'function' && schema.prototype && schema.name;\n } catch {\n return false;\n }\n}\n\nasync function validateClassValidator(schema: any, data: any) {\n // Lazy load dependencies\n if (!plainToInstance || !validateOrReject) {\n try {\n const ct = await import('class-transformer');\n const cv = await import('class-validator');\n plainToInstance = ct.plainToInstance;\n validateOrReject = cv.validateOrReject;\n } catch (e) {\n throw new Error(\n 'class-transformer and class-validator are required for class-based validation. ' +\n 'Install them with: bun add class-transformer class-validator reflect-metadata'\n );\n }\n }\n\n // Transform plain object to class instance\n const object = plainToInstance(schema, data);\n try {\n await validateOrReject(object as any);\n return object;\n } catch (errors: any) {\n // Flatten errors or just return them\n // class-validator returns Array<ValidationError>\n // We'll wrap in our ValidationError\n const formattedErrors = Array.isArray(errors)\n ? errors.map((err: any) => ({\n property: err.property,\n constraints: err.constraints,\n children: err.children\n }))\n : errors;\n\n throw new ValidationError(formattedErrors);\n }\n}\n\n\n// --- Body Helper ---\n\nconst safelyGetBody = async (ctx: ShokupanContext) => {\n // Use context's built-in body caching mechanism\n try {\n return await ctx.body();\n } catch (e) {\n return {}; // Return empty object if parsing fails (flexible)\n }\n};\n\n\n// --- Main Middleware ---\n\n// --- Main Middleware ---\n\nfunction getValidator(schema: any): (data: any) => Promise<any> | any {\n if (isZod(schema)) {\n return (data) => validateZod(schema, data);\n }\n if (isTypeBox(schema)) {\n return (data) => validateTypeBox(schema, data);\n }\n if (isAjv(schema)) {\n return (data) => validateAjv(schema, data);\n }\n if (isValibotWrapper(schema)) {\n return (data) => validateValibotWrapper(schema, data);\n }\n if (isClass(schema)) {\n return (data) => validateClassValidator(schema, data);\n }\n if (typeof schema === 'function') {\n return schema;\n }\n throw new Error(\"Unknown validator type provided. Please use a supported library (Zod, Ajv, TypeBox) or a custom function.\");\n}\n\n/**\n * Validation middleware.\n * @param config Validation configuration\n * @returns Middleware function\n */\nexport function validate(config: ValidationConfig): Middleware {\n // Pre-compilation: Resolve validators for each part\n const validators: {\n params?: (data: any) => any;\n query?: (data: any) => any;\n headers?: (data: any) => any;\n body?: (data: any) => any;\n } = {};\n\n if (config.params) validators.params = getValidator(config.params);\n if (config.query) validators.query = getValidator(config.query);\n if (config.headers) validators.headers = getValidator(config.headers);\n if (config.body) validators.body = getValidator(config.body);\n\n return async (ctx: ShokupanContext, next) => {\n // Prepare data for beforeValidate hook\n const dataToValidate: any = {};\n if (config.params) dataToValidate.params = ctx.params;\n let queryObj: Record<string, string> | undefined;\n if (config.query) {\n const url = new URL(ctx.req.url);\n queryObj = Object.fromEntries(url.searchParams.entries());\n dataToValidate.query = queryObj;\n }\n if (config.headers) dataToValidate.headers = Object.fromEntries(ctx.req.headers.entries());\n\n let body: any;\n if (config.body) {\n body = await safelyGetBody(ctx);\n dataToValidate.body = body;\n }\n\n // Call beforeValidate Hook\n await ctx.app.runHooks('beforeValidate', ctx, dataToValidate);\n\n // Validate Params\n if (validators.params) {\n ctx.params = await validators.params(ctx.params);\n }\n\n // Validate Query\n let validQuery: any;\n if (validators.query && queryObj) {\n validQuery = await validators.query(queryObj);\n }\n\n // Validate Headers\n if (validators.headers) {\n const headersObj = Object.fromEntries(ctx.req.headers.entries());\n await validators.headers(headersObj);\n }\n\n // Validate Body\n let validBody: any;\n if (validators.body) {\n // Re-use body accessed above or get again (it's cached)\n const b = body ?? await safelyGetBody(ctx);\n validBody = await validators.body(b);\n\n // Update context's cached body with validated/transformed version\n (ctx as any)._cachedBody = validBody;\n\n // Monkey-patch req.json() to return the validated body\n // This ensures handlers can call ctx.req.json() and get the validated data\n const req = ctx.req as any;\n Object.defineProperty(req, 'json', {\n value: async () => validBody,\n writable: true,\n configurable: true\n });\n\n (ctx as any).body = validBody; // Legacy/Convenience\n }\n\n // Call afterValidate Hook\n const validatedData: any = { ...dataToValidate };\n if (config.params) validatedData.params = ctx.params;\n if (config.query) validatedData.query = validQuery;\n if (config.body) validatedData.body = validBody;\n\n await ctx.app.runHooks('afterValidate', ctx, validatedData);\n\n return next();\n };\n}\n","import Ajv from \"ajv\";\nimport addFormats from \"ajv-formats\";\nimport type { Middleware } from \"../../util/types\";\nimport { ValidationError } from \"./validation\";\n\nconst ajv = new Ajv({ coerceTypes: true, allErrors: true });\naddFormats(ajv);\n\ntype ValidatorCache = Map<string, {\n [method: string]: {\n body?: import(\"ajv\").ValidateFunction;\n query?: import(\"ajv\").ValidateFunction;\n params?: import(\"ajv\").ValidateFunction;\n headers?: import(\"ajv\").ValidateFunction;\n };\n}>;\n\nconst compiledValidators = new WeakMap<any, {\n paths: Map<string, {\n regex: RegExp;\n paramNames: string[];\n }>;\n validators: ValidatorCache;\n}>();\n\nexport function openApiValidator(): Middleware {\n return async (ctx, next) => {\n const app = ctx.app;\n if (!app || !app.openApiSpec) {\n return next();\n }\n\n let cache = compiledValidators.get(app);\n if (!cache) {\n cache = compileValidators(app.openApiSpec);\n compiledValidators.set(app, cache);\n }\n\n let matchPath: string | undefined;\n let matchParams: Record<string, string> = {};\n\n // Try exact match first\n if (cache.validators.has(ctx.path)) {\n matchPath = ctx.path;\n } else {\n // Regex match\n const pathEntries = Array.from(cache.paths.entries());\n for (let i = 0; i < pathEntries.length; i++) {\n const [path, { regex, paramNames }] = pathEntries[i];\n const match = regex.exec(ctx.path);\n if (match) {\n matchPath = path;\n // Extract params\n paramNames.forEach((name, i) => {\n matchParams[name] = match[i + 1];\n });\n break;\n }\n }\n }\n\n if (!matchPath) {\n return next();\n }\n\n const method = ctx.req.method.toLowerCase();\n const validators = cache.validators.get(matchPath)?.[method];\n if (!validators) {\n return next();\n }\n\n const errors: any[] = [];\n\n if (validators.body) {\n let body: any;\n try {\n // Use context's body parser which caches the result\n body = await ctx.body();\n } catch {\n body = {};\n }\n const valid = validators.body(body);\n if (!valid && validators.body.errors) {\n errors.push(...validators.body.errors.map(e => ({ ...e, location: 'body' })));\n }\n }\n\n // Validate Query\n if (validators.query) {\n const query = Object.fromEntries(new URL(ctx.req.url).searchParams.entries());\n const valid = validators.query(query);\n if (!valid && validators.query.errors) {\n errors.push(...validators.query.errors.map(e => ({ ...e, location: 'query' })));\n }\n }\n\n // Validate Params\n if (validators.params) {\n // Merge extracted params with context params (if any)\n // Prioritize context params if router already parsed them, otherwise use matchParams\n const params = { ...matchParams, ...ctx.params };\n\n const valid = validators.params(params);\n if (!valid && validators.params.errors) {\n errors.push(...validators.params.errors.map(e => ({ ...e, location: 'path' })));\n }\n }\n\n // Validate Headers\n if (validators.headers) {\n const headers = Object.fromEntries(ctx.req.headers.entries());\n // Headers in OpenAPI are case-insensitive usually, but schema keys are sensitive?\n // Typically headers schema property names are lowercased.\n const valid = validators.headers(headers);\n if (!valid && validators.headers.errors) {\n errors.push(...validators.headers.errors.map(e => ({ ...e, location: 'header' })));\n }\n }\n\n if (errors.length > 0) {\n throw new ValidationError(errors);\n }\n\n return next();\n };\n}\n\nexport function compileValidators(spec: any): { paths: Map<string, { regex: RegExp, paramNames: string[]; }>, validators: ValidatorCache; } {\n const validators: ValidatorCache = new Map();\n const paths = new Map<string, { regex: RegExp, paramNames: string[]; }>();\n\n const pathEntries = Object.entries(spec.paths || {});\n for (let i = 0; i < pathEntries.length; i++) {\n const [path, pathItem] = pathEntries[i];\n // Compile Path Regex\n if (path.includes('{')) {\n const paramNames: string[] = [];\n const regexStr = \"^\" + path.replace(/{([^}]+)}/g, (_, name) => {\n paramNames.push(name);\n return \"([^/]+)\";\n }) + \"$\";\n paths.set(path, {\n regex: new RegExp(regexStr),\n paramNames\n });\n }\n\n const pathValidators: any = {};\n\n const methodEntries = Object.entries(pathItem as any);\n for (let k = 0; k < methodEntries.length; k++) {\n const [method, operation] = methodEntries[k];\n if (method === 'parameters' || method === 'summary' || method === 'description') continue;\n\n const oper = operation as any;\n const opValidators: any = {};\n\n // 1. Compile Request Body\n if (oper.requestBody?.content?.['application/json']?.schema) {\n opValidators.body = ajv.compile(oper.requestBody.content['application/json'].schema);\n }\n\n // 2. Compile Parameters (Query, Path, Header)\n const parameters = [...(oper.parameters || []), ...(pathItem as any).parameters || []];\n\n const queryProps: any = {};\n const pathProps: any = {};\n const headerProps: any = {};\n const queryRequired: string[] = [];\n const pathRequired: string[] = [];\n const headerRequired: string[] = [];\n\n for (let j = 0; j < parameters.length; j++) {\n const param = parameters[j];\n if (param.in === 'query') {\n queryProps[param.name] = param.schema || {};\n if (param.required) queryRequired.push(param.name);\n } else if (param.in === 'path') {\n pathProps[param.name] = param.schema || {};\n pathRequired.push(param.name);\n } else if (param.in === 'header') {\n headerProps[param.name] = param.schema || {};\n if (param.required) headerRequired.push(param.name);\n }\n }\n\n if (Object.keys(queryProps).length > 0) {\n opValidators.query = ajv.compile({\n type: 'object',\n properties: queryProps,\n required: queryRequired.length > 0 ? queryRequired : undefined\n });\n }\n\n if (Object.keys(pathProps).length > 0) {\n opValidators.params = ajv.compile({\n type: 'object',\n properties: pathProps,\n required: pathRequired.length > 0 ? pathRequired : undefined\n });\n }\n\n if (Object.keys(headerProps).length > 0) {\n opValidators.headers = ajv.compile({\n type: 'object',\n properties: headerProps,\n required: headerRequired.length > 0 ? headerRequired : undefined\n });\n }\n\n pathValidators[method] = opValidators;\n }\n\n validators.set(path, pathValidators);\n }\n\n return { paths, validators };\n}\n\n/**\n * Pre-compiles validators for the application using the provided spec.\n * Should be called when the spec is available.\n */\nexport function precompileValidators(app: any, spec: any) {\n const cache = compileValidators(spec);\n compiledValidators.set(app, cache);\n}\n\n/**\n * Enables OpenAPI validation for the application.\n * This registers the middleware and the hook to pre-compile validators when the spec is generated.\n * \n * @param app The Shokupan application instance\n */\nexport function enableOpenApiValidation(app: import(\"../../shokupan\").Shokupan) {\n app.use(openApiValidator());\n app.onSpecAvailable((spec) => {\n precompileValidators(app, spec);\n });\n}\n","import type { ServerWebSocket } from \"bun\";\nimport type { ShokupanContext } from \"../../context\";\nimport type { Middleware, NextFn } from \"../../util/types\";\n\nexport interface ProxyOptions {\n /**\n * Target URL to proxy requests to.\n */\n target: string;\n /**\n * Function to rewrite the path of the request.\n */\n pathRewrite?: (path: string) => string;\n /**\n * Whether to change the origin of the request.\n */\n changeOrigin?: boolean;\n /**\n * Whether to proxy WebSocket connections.\n */\n ws?: boolean;\n /**\n * Additional headers to send with the request.\n */\n headers?: Record<string, string>;\n /**\n * Whitelist of allowed target hosts.\n */\n allowedHosts?: string[];\n /**\n * Whether to allow private IPs (disabled by default).\n */\n allowPrivateIPs?: boolean;\n}\n\n\n/**\n * Security: Validate if an IP address is in a private range\n */\nfunction isPrivateIP(ip: string): boolean {\n // IPv4 private ranges\n const ipv4Patterns = [\n /^10\\./, // 10.0.0.0/8\n /^172\\.(1[6-9]|2[0-9]|3[01])\\./, // 172.16.0.0/12\n /^192\\.168\\./, // 192.168.0.0/16\n /^127\\./, // 127.0.0.0/8 (loopback)\n /^169\\.254\\./, // 169.254.0.0/16 (link-local)\n /^0\\.0\\.0\\.0$/, // 0.0.0.0\n ];\n\n // IPv6 private ranges (simplified)\n const ipv6Patterns = [\n /^::1$/, // loopback\n /^fe80:/, // link-local\n /^fc00:/, // unique local\n /^fd00:/, // unique local\n ];\n\n for (const pattern of ipv4Patterns) {\n if (pattern.test(ip)) return true;\n }\n\n for (const pattern of ipv6Patterns) {\n if (pattern.test(ip.toLowerCase())) return true;\n }\n\n return false;\n}\n\n/**\n * Proxy middleware. This will proxy requests that match the path to the target URL.\n * @param options Proxy options\n * @returns Middleware function\n */\nexport function Proxy(options: ProxyOptions): Middleware {\n const targetUrl = new URL(options.target);\n\n // Security: Validate target URL\n if (!['http:', 'https:'].includes(targetUrl.protocol)) {\n throw new Error('Invalid proxy target protocol. Only http and https are allowed.');\n }\n\n // Security: Validate hostname is in allowlist (if provided)\n if (options.allowedHosts && options.allowedHosts.length > 0) {\n if (!options.allowedHosts.includes(targetUrl.hostname)) {\n throw new Error(`Target hostname ${targetUrl.hostname} is not in the allowed hosts list.`);\n }\n }\n\n // Security: Check if target is private IP (unless explicitly allowed)\n if (!options.allowPrivateIPs && isPrivateIP(targetUrl.hostname)) {\n throw new Error('Proxying to private IP addresses is not allowed.');\n }\n\n return async (ctx: ShokupanContext, next: NextFn) => {\n const req = ctx.request;\n\n // WebSocket Upgrade Handling\n if (options.ws && req.headers.get(\"upgrade\")?.toLowerCase() === \"websocket\") {\n const success = ctx.upgrade({\n data: {\n handler: {\n open: (ws: ServerWebSocket) => handleWSOpen(ws, ctx, options, targetUrl),\n message: (ws: ServerWebSocket, message: any) => handleWSMessage(ws, message),\n close: (ws: ServerWebSocket, code: number, reason: string) => handleWSClose(ws, code, reason),\n drain: (ws: ServerWebSocket) => handleWSDrain(ws)\n }\n }\n });\n\n if (success) {\n // Return undefined to stop the middleware chain, as the connection is upgraded\n return undefined;\n }\n }\n\n // HTTP Proxy Handling\n let path = ctx.url.pathname;\n if (options.pathRewrite) {\n path = options.pathRewrite(path);\n }\n\n const url = new URL(path + ctx.url.search, targetUrl);\n\n // Security: Validate the final URL doesn't bypass restrictions\n if (!['http:', 'https:'].includes(url.protocol)) {\n return ctx.text('Invalid protocol in proxied URL', 400);\n }\n\n const headers = new Headers(req.headers);\n if (options.changeOrigin) {\n headers.set(\"host\", targetUrl.host);\n }\n if (options.headers) {\n Object.entries(options.headers).forEach(([key, value]) => headers.set(key, value));\n }\n\n // Remove hop-by-hop headers\n headers.delete(\"connection\");\n headers.delete(\"keep-alive\");\n headers.delete(\"proxy-authenticate\");\n headers.delete(\"proxy-authorization\");\n headers.delete(\"te\");\n headers.delete(\"trailer\");\n headers.delete(\"transfer-encoding\");\n headers.delete(\"upgrade\");\n\n\n const proxyReq = new Request(url.toString(), {\n method: req.method,\n headers: headers,\n body: req.body,\n // @ts-ignore - duplex is needed for some node/bun versions for streaming bodies\n duplex: \"half\"\n });\n\n const res = await fetch(proxyReq);\n\n return new Response(res.body, {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers\n });\n };\n}\n\n// WebSocket Proxy Logic\nconst wsMap = new WeakMap<ServerWebSocket, WebSocket>();\n\nfunction handleWSOpen(ws: ServerWebSocket, ctx: ShokupanContext, options: ProxyOptions, targetUrl: URL) {\n let path = ctx.url.pathname;\n if (options.pathRewrite) {\n path = options.pathRewrite(path);\n }\n const url = new URL(path + ctx.url.search, targetUrl);\n url.protocol = targetUrl.protocol.replace('http', 'ws');\n\n const headers: Record<string, string> = {};\n if (options.changeOrigin) {\n headers['Host'] = targetUrl.host;\n }\n // Copy headers from client request\n ctx.request.headers.forEach((v, k) => {\n if (!['upgrade', 'connection', 'sec-websocket-key', 'sec-websocket-version', 'sec-websocket-extensions'].includes(k.toLowerCase())) {\n headers[k] = v;\n }\n });\n\n // TODO: Is this the correct WebSocket constructor?\n const upstream = new WebSocket(url.toString());\n\n wsMap.set(ws, upstream);\n\n const pendingMessages: any[] = [];\n let isConnected = false;\n\n upstream.onopen = () => {\n isConnected = true;\n // Float pending messages\n while (pendingMessages.length > 0) {\n const msg = pendingMessages.shift();\n upstream.send(msg);\n }\n };\n\n upstream.onmessage = (event) => {\n ws.send(event.data);\n };\n\n upstream.onclose = (event) => {\n ws.close(event.code, event.reason);\n };\n\n upstream.onerror = (err) => {\n console.error(\"Upstream WebSocket error:\", err);\n ws.close(1011, \"Internal Error\");\n };\n\n // Store pending buffer on the upstream socket object temporarily or closure? \n // Closure is fine since we have one upstream per ws.\n // Wait, we need to handle if `ws` sends message before `upstream` is open.\n (upstream as any)._pendingRequestMessages = pendingMessages;\n (upstream as any)._isConnected = () => isConnected;\n}\n\nfunction handleWSMessage(ws: ServerWebSocket, message: any) {\n const upstream = wsMap.get(ws);\n if (!upstream) return;\n\n if ((upstream as any)._isConnected && (upstream as any)._isConnected()) {\n upstream.send(message);\n } else {\n (upstream as any)._pendingRequestMessages.push(message);\n }\n}\n\nfunction handleWSClose(ws: ServerWebSocket, code: number, reason: string) {\n const upstream = wsMap.get(ws);\n if (upstream) {\n if (upstream.readyState === WebSocket.OPEN) {\n upstream.close(code, reason);\n }\n wsMap.delete(ws);\n }\n}\n\nfunction handleWSDrain(ws: ServerWebSocket) {\n // Optional: Handle backpressure\n}\n","import type { ShokupanContext } from \"../../context\";\nimport type { Middleware, NextFn } from \"../../util/types\";\n\nexport interface SecurityHeadersOptions {\n /**\n * Content Security Policy\n */\n contentSecurityPolicy?: boolean | Record<string, any>;\n /**\n * Cross-Origin Embedder Policy\n */\n crossOriginEmbedderPolicy?: boolean;\n /**\n * Cross-Origin Opener Policy\n */\n crossOriginOpenerPolicy?: boolean;\n /**\n * Cross-Origin Resource Policy\n */\n crossOriginResourcePolicy?: boolean;\n /**\n * DNS Prefetch Control\n */\n dnsPrefetchControl?: boolean | { allow: boolean; };\n /**\n * Expect CT\n */\n expectCt?: boolean | { maxAge?: number, enforce?: boolean, reportUri?: string; };\n /**\n * Frameguard\n */\n frameguard?: boolean | { action: 'deny' | 'sameorigin' | 'allow-from', domain?: string; };\n /**\n * Hide Powered By\n */\n hidePoweredBy?: boolean;\n /**\n * HTTP Strict Transport Security\n */\n hsts?: boolean | { maxAge?: number, includeSubDomains?: boolean, preload?: boolean; };\n /**\n * IE No Open\n */\n ieNoOpen?: boolean;\n /**\n * No Sniff\n */\n noSniff?: boolean;\n /**\n * Origin Agent Cluster\n */\n originAgentCluster?: boolean;\n /**\n * Permitted Cross Domain Policies\n */\n permittedCrossDomainPolicies?: boolean | { permittedPolicies: 'none' | 'master-only' | 'by-content-type' | 'all'; };\n /**\n * Referrer Policy\n */\n referrerPolicy?: boolean | { policy: string | string[]; };\n /**\n * X-XSS-Protection\n */\n xssFilter?: boolean;\n}\n\n/**\n * Security headers middleware.\n * @param options Security headers options\n * @returns Middleware function\n */\nexport function SecurityHeaders(options: SecurityHeadersOptions = {}): Middleware {\n const securityHeadersMiddleware: Middleware = async function SecurityHeadersMiddleware(ctx: ShokupanContext, next: NextFn) {\n // Helper to set header on the context response immediately\n const set = (k: string, v: string) => ctx.response.set(k, v);\n\n // X-DNS-Prefetch-Control\n if (options.dnsPrefetchControl !== false) {\n const allow = (options.dnsPrefetchControl as any)?.allow;\n set(\"X-DNS-Prefetch-Control\", allow ? \"on\" : \"off\");\n }\n\n // X-Frame-Options\n if (options.frameguard !== false) {\n const opt = options.frameguard as any || {};\n const action = opt.action || 'sameorigin';\n if (action === 'sameorigin') set('X-Frame-Options', 'SAMEORIGIN');\n else if (action === 'deny') set('X-Frame-Options', 'DENY');\n // 'allow-from' is deprecated/obsolete in modern browsers, but we can support it if needed.\n }\n\n // Strict-Transport-Security\n if (options.hsts !== false) {\n const opt = options.hsts as any || {};\n const maxAge = opt.maxAge || 15552000; // 180 days\n let header = `max-age=${maxAge}`;\n if (opt.includeSubDomains !== false) header += '; includeSubDomains';\n if (opt.preload) header += '; preload';\n set('Strict-Transport-Security', header);\n }\n\n // X-Download-Options\n if (options.ieNoOpen !== false) {\n set('X-Download-Options', 'noopen');\n }\n\n // X-Content-Type-Options\n if (options.noSniff !== false) {\n set('X-Content-Type-Options', 'nosniff');\n }\n\n // X-XSS-Protection (Legacy, but still sometimes used)\n if (options.xssFilter !== false) {\n set('X-XSS-Protection', '0'); // Modern recommendation is to disable it as it can introduce vulns\n }\n\n // Referrer-Policy\n if (options.referrerPolicy !== false) {\n const opt = options.referrerPolicy as any || {};\n const policy = opt.policy || 'no-referrer';\n set('Referrer-Policy', Array.isArray(policy) ? policy.join(',') : policy);\n }\n\n // Content-Security-Policy\n if (options.contentSecurityPolicy !== false) {\n // Basic default CSP if true, or use object\n const opt = options.contentSecurityPolicy;\n if (opt === undefined || opt === true) {\n set('Content-Security-Policy', \"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests\");\n } else if (typeof opt === 'object') {\n // Construct CSP string from object (simplified)\n // Assuming user passes raw string or we'd need a directive builder.\n // For now, let's assume they pass directives map.\n const parts = [];\n const optEntries = Object.entries(opt);\n for (let i = 0; i < optEntries.length; i++) {\n const [key, val] = optEntries[i];\n // directives, etc.\n // This is complex to implement fully without a library like 'helmet' itself.\n // We will support a simple string or custom logic later if requested.\n // For now, skip complex object parsing to keep it simple as per \"standard middleware\" MVP.\n }\n }\n }\n\n if (options.hidePoweredBy !== false) {\n // Note: Shokupan doesn't set X-Powered-By by default, so we usually don't need to remove it.\n // But we can ensure it's not there.\n // We can't delete from response easily before it's created, but we can try to suppress it if we had a hook.\n // Here we might just do nothing as we don't add it.\n }\n\n // Apply headers to context response\n // We need to apply these to the response *after* it's generated, or *before* if we use `ctx.headers` mutation?\n // `ctx.headers` is currently read-only wrapper around `req.headers` in `ShokupanContext`?\n // Wait, `ctx.headers` in `ShokupanContext` getter is `this.request.headers`.\n // We cannot set response headers on the request object.\n // We need to intercept the response.\n\n const response = await next();\n return response;\n };\n securityHeadersMiddleware.isBuiltin = true;\n securityHeadersMiddleware.pluginName = 'SecurityHeaders';\n return securityHeadersMiddleware;\n}\n","import { createHmac, randomUUID } from \"crypto\";\nimport { EventEmitter } from \"events\";\nimport { ShokupanContext } from \"../../context\";\nimport type { Middleware } from \"../../util/types\";\n\n// --- Types ---\n\nexport interface SessionData {\n cookie: Cookie;\n [key: string]: any;\n}\n\nexport interface SessionCookieOptions {\n /**\n * Maximum age of the session cookie in milliseconds.\n */\n maxAge?: number;\n /**\n * Whether the session cookie should be signed.\n */\n signed?: boolean;\n /**\n * Expiration date of the session cookie.\n */\n expires?: Date;\n /**\n * Whether the session cookie should be HTTP-only.\n */\n httpOnly?: boolean;\n /**\n * Path of the session cookie.\n */\n path?: string;\n /**\n * Domain of the session cookie.\n */\n domain?: string;\n /**\n * Whether the session cookie should be secure.\n */\n secure?: boolean | 'auto';\n /**\n * SameSite attribute of the session cookie.\n */\n sameSite?: boolean | 'lax' | 'strict' | 'none';\n /**\n * Priority of the session cookie.\n */\n priority?: 'low' | 'medium' | 'high';\n}\n\nexport interface SessionOptions {\n /**\n * Secret used to sign the session cookie.\n */\n secret: string | string[];\n /**\n * Name of the session cookie.\n */\n name?: string;\n /**\n * Store to use for session data.\n */\n store?: Store;\n /**\n * Options for the session cookie.\n */\n cookie?: SessionCookieOptions;\n /**\n * Function to generate a session ID.\n */\n genid?: (ctx: ShokupanContext) => string;\n /**\n * Whether to force a session identifier cookie to be set on every response.\n */\n resave?: boolean;\n /**\n * Whether to save the session on every request.\n */\n saveUninitialized?: boolean;\n /**\n * Whether to update the session cookie on every request.\n */\n rolling?: boolean;\n /**\n * Whether to destroy or keep the session on logout.\n */\n unset?: 'destroy' | 'keep';\n}\n\nexport interface Store extends EventEmitter {\n /**\n * Retrieves a session by ID.\n */\n get(sid: string, callback: (err: any, session?: SessionData | null) => void): void;\n /**\n * Stores a session.\n */\n set(sid: string, session: SessionData, callback?: (err?: any) => void): void;\n /**\n * Destroys a session.\n */\n destroy(sid: string, callback?: (err?: any) => void): void;\n /**\n * Touches a session.\n */\n touch?(sid: string, session: SessionData, callback?: (err?: any) => void): void;\n /**\n * Retrieves all sessions.\n */\n all?(callback: (err: any, obj?: { [sid: string]: SessionData; } | null) => void): void;\n /**\n * Retrieves the number of sessions.\n */\n length?(callback: (err: any, length?: number) => void): void;\n /**\n * Clears all sessions.\n */\n clear?(callback?: (err?: any) => void): void;\n /**\n * Loads a session.\n */\n load?(sid: string, fn: (err: any, session?: SessionData | null) => void): void;\n /**\n * Creates a session.\n */\n createSession?(req: any, session: SessionData): SessionData;\n}\n\n// --- Cookie Helper ---\n\nclass Cookie implements SessionCookieOptions {\n maxAge?: number;\n signed?: boolean;\n expires?: Date;\n httpOnly?: boolean;\n path?: string;\n domain?: string;\n secure?: boolean | 'auto';\n sameSite?: boolean | 'lax' | 'strict' | 'none';\n originalMaxAge: number | undefined;\n\n constructor(options: SessionCookieOptions = {}) {\n this.path = options.path || '/';\n this.httpOnly = options.httpOnly !== undefined ? options.httpOnly : true;\n this.secure = options.secure;\n this.maxAge = options.maxAge;\n this.sameSite = options.sameSite;\n this.domain = options.domain;\n this.expires = options.expires;\n\n if (this.maxAge !== undefined) {\n this.originalMaxAge = this.maxAge;\n this.expires = new Date(Date.now() + this.maxAge);\n }\n }\n\n serialize(name: string, val: string) {\n let str = `${name}=${encodeURIComponent(val)}`;\n\n if (this.maxAge) {\n const expires = new Date(Date.now() + this.maxAge);\n str += `; Expires=${expires.toUTCString()}`;\n // Also add Max-Age?\n str += `; Max-Age=${Math.floor(this.maxAge / 1000)}`;\n } else if (this.expires) {\n str += `; Expires=${this.expires.toUTCString()}`;\n }\n\n if (this.domain) str += `; Domain=${this.domain}`;\n if (this.path) str += `; Path=${this.path}`;\n if (this.httpOnly) str += `; HttpOnly`;\n if (this.secure) str += `; Secure`;\n if (this.sameSite) {\n const sameSite = typeof this.sameSite === 'string' ?\n this.sameSite.charAt(0).toUpperCase() + this.sameSite.slice(1) : 'Strict';\n str += `; SameSite=${sameSite}`;\n }\n\n return str;\n }\n}\n\n// --- Memory Store ---\n\n\nexport class MemoryStore extends EventEmitter implements Store {\n private sessions: Record<string, string> = {};\n\n get(sid: string, cb: (err: any, session?: SessionData | null) => void) {\n const sess = this.sessions[sid];\n if (!sess) return cb(null, null);\n try {\n const data = JSON.parse(sess);\n // Re-hydrate dates?\n if (data.cookie && data.cookie.expires) {\n data.cookie.expires = new Date(data.cookie.expires);\n }\n cb(null, data);\n } catch (e) {\n cb(e);\n }\n }\n\n set(sid: string, sess: SessionData, cb?: (err?: any) => void) {\n this.sessions[sid] = JSON.stringify(sess);\n cb?.();\n }\n\n destroy(sid: string, cb?: (err?: any) => void) {\n delete this.sessions[sid];\n cb?.();\n }\n\n touch(sid: string, sess: SessionData, cb?: (err?: any) => void) {\n const current = this.sessions[sid];\n if (current) {\n // Update the cookie expiry if needed without changing the whole object if we want to be efficient\n // But for MemoryStore, just set is fine\n this.sessions[sid] = JSON.stringify(sess);\n }\n cb?.();\n }\n\n all(cb: (err: any, obj?: { [sid: string]: SessionData; } | null) => void) {\n const result: Record<string, SessionData> = {};\n const sessionKeys = Object.keys(this.sessions);\n for (let i = 0; i < sessionKeys.length; i++) {\n const sid = sessionKeys[i];\n try {\n result[sid] = JSON.parse(this.sessions[sid]);\n } catch { }\n }\n cb(null, result);\n }\n\n clear(cb?: (err?: any) => void) {\n this.sessions = {};\n cb?.();\n }\n}\n\n// --- Crypto Helpers ---\n\nfunction sign(val: string, secret: string) {\n if (typeof val !== 'string') throw new TypeError(\"Cookie value must be provided as a string.\");\n if (typeof secret !== 'string') throw new TypeError(\"Secret string must be provided.\");\n return val + '.' + createHmac('sha256', secret).update(val).digest('base64').replace(/\\=+$/, '');\n}\n\nfunction unsign(input: string, secret: string) {\n if (typeof input !== 'string') throw new TypeError(\"Signed cookie string must be provided.\");\n if (typeof secret !== 'string') throw new TypeError(\"Secret string must be provided.\");\n const tentValue = input.slice(0, input.lastIndexOf('.'));\n const expectedInput = sign(tentValue, secret);\n\n // Security: Use constant-time comparison with padding to prevent timing attacks\n // Pad both buffers to the same length to avoid length-based timing leaks\n const maxLength = Math.max(expectedInput.length, input.length);\n const paddedExpected = Buffer.alloc(maxLength);\n const paddedInput = Buffer.alloc(maxLength);\n\n Buffer.from(expectedInput).copy(paddedExpected);\n Buffer.from(input).copy(paddedInput);\n\n // Use crypto.timingSafeEqual for constant-time comparison\n try {\n const valid = require('crypto').timingSafeEqual(paddedExpected, paddedInput);\n return valid ? tentValue : false;\n } catch {\n // Buffers are different lengths (shouldn't happen with padding, but handle gracefully)\n return false;\n }\n}\n\n// --- Middleware ---\n\nexport interface SessionContext {\n session: SessionData & {\n id: string;\n regenerate(): Promise<void>;\n destroy(): Promise<void>;\n reload(): Promise<void>;\n save(): Promise<void>;\n touch(): void;\n };\n sessionID: string;\n sessionStore: Store;\n}\n\n// Merge into ShokupanContext? TODO: Review.\ndeclare module \"../../context\" {\n interface ShokupanContext {\n session: SessionContext['session'];\n sessionID: string;\n sessionStore: Store;\n }\n}\n\n/**\n * Session middleware.\n * @param options Session options\n * @returns Middleware function\n */\nexport function Session(options: SessionOptions): Middleware {\n const store = options.store || new MemoryStore();\n const name = options.name || 'connect.sid';\n const secrets = Array.isArray(options.secret) ? options.secret : [options.secret];\n\n // Validate store\n // (Could add check for .get .set .destroy)\n\n const generateId = options.genid || (() => randomUUID());\n\n const resave = options.resave === undefined ? true : options.resave;\n const saveUninitialized = options.saveUninitialized === undefined ? true : options.saveUninitialized;\n const rolling = options.rolling || false;\n\n const sessionMiddleware: Middleware = async function SessionMiddleware(ctx: ShokupanContext, next) {\n // 1. Get Session ID from Cookie\n let reqSessionId: string | null = null;\n let isSigned = false;\n\n // Simple cookie parser\n const cookieHeader = ctx.req.headers.get(\"cookie\");\n const cookies: Record<string, string> = {};\n if (cookieHeader) {\n cookieHeader.split(';').forEach(c => {\n const [k, v] = c.split('=').map(s => s.trim());\n if (k && v) cookies[k] = decodeURIComponent(v);\n });\n }\n\n const rawCookie = cookies[name];\n\n if (rawCookie) {\n if (rawCookie.substr(0, 2) === 's:') {\n // Signed cookie\n const val = unsign(rawCookie.slice(2), secrets[0]);\n if (val) {\n reqSessionId = val as string;\n isSigned = true;\n }\n } else {\n reqSessionId = rawCookie;\n }\n }\n\n // 2. Generate new ID if none\n let sessionID = reqSessionId;\n let isNew = false;\n if (!sessionID) {\n sessionID = generateId(ctx);\n isNew = true;\n }\n\n // 3. Helper to wrap session object\n const createSessionObject = (data: SessionData | null): SessionContext['session'] => {\n const existing = data || { cookie: new Cookie(options.cookie) };\n if (!existing.cookie) existing.cookie = new Cookie(options.cookie);\n else {\n // re-hydrate cookie options methods\n const c = new Cookie(options.cookie); // defaults\n Object.assign(c, existing.cookie);\n // ensure expiry is date\n if (c.expires && typeof c.expires === 'string') c.expires = new Date(c.expires);\n existing.cookie = c;\n }\n\n const sessObj = existing as any;\n\n // Methods\n Object.defineProperty(sessObj, 'id', { value: sessionID, configurable: true });\n\n sessObj.save = () => {\n return new Promise<void>((resolve, reject) => {\n store.set(sessObj.id, sessObj, (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n };\n\n sessObj.destroy = () => {\n return new Promise<void>((resolve, reject) => {\n store.destroy(sessObj.id, (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n };\n\n sessObj.regenerate = () => {\n return new Promise<void>((resolve, reject) => {\n store.destroy(sessObj.id, (err) => {\n if (err) return reject(err);\n sessionID = generateId(ctx);\n // Create new session object\n // We actually need to replace the whole ctx.session object, which is tricky inside a method of that object.\n // Typically middleware attaches a proxy or the consumer does this.\n // But here we can reset properties.\n const keys = Object.keys(sessObj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (key !== 'cookie' && key !== 'id' && typeof sessObj[key] !== 'function') {\n delete sessObj[key];\n }\n }\n Object.defineProperty(sessObj, 'id', { value: sessionID, configurable: true });\n resolve();\n });\n });\n };\n\n sessObj.undefined = () => { }; // Helper? no\n sessObj.reload = () => {\n return new Promise<void>((resolve, reject) => {\n store.get(sessObj.id, (err, sess) => {\n if (err) return reject(err);\n if (!sess) return reject(new Error(\"Session not found\"));\n // Populate\n const keys = Object.keys(sessObj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (key !== 'cookie' && key !== 'id' && typeof sessObj[key] !== 'function') {\n delete sessObj[key];\n }\n }\n Object.assign(sessObj, sess);\n resolve();\n });\n });\n };\n\n sessObj.touch = () => {\n // Reset maxAge\n sessObj.cookie.expires = new Date(Date.now() + (sessObj.cookie.maxAge || 0));\n if (store.touch) store.touch(sessObj.id, sessObj);\n };\n\n return sessObj;\n };\n\n // 4. Load Session from Store\n let sessionData: SessionData | null = null;\n\n if (!isNew && sessionID) {\n await new Promise<void>((resolve) => {\n store.get(sessionID!, (err, sess) => {\n if (err) {\n // if error, treat as new? or error?\n // express-session logs and creates new\n sessionID = generateId(ctx);\n isNew = true;\n } else if (!sess) {\n // Session expired or invalid\n sessionID = generateId(ctx);\n isNew = true;\n } else {\n sessionData = sess;\n }\n resolve();\n });\n });\n }\n\n const sess = createSessionObject(sessionData);\n\n ctx.session = sess;\n ctx.sessionID = sessionID!;\n ctx.sessionStore = store;\n\n // Hash original sessionStr to detect changes\n const originalHash = JSON.stringify(sess);\n\n // 5. Run next\n const result = await next();\n\n // 6. Save Logic\n const currentHash = JSON.stringify(sess);\n const isModified = originalHash !== currentHash;\n\n if (!sessionID) return result; // Destroyed?\n\n let shouldSave = false;\n\n if (isModified) {\n shouldSave = true;\n } else if (isNew && saveUninitialized) {\n shouldSave = true;\n } else if (!isNew && resave) {\n shouldSave = true;\n }\n\n if (shouldSave) {\n await new Promise<void>((resolve, reject) => {\n store.set(sessionID!, sess, (err) => {\n if (err) console.error(\"Failed to save session\", err);\n resolve();\n });\n });\n }\n\n // 7. Set Cookie\n // Only set if new, or modified (rolling)\n // Express-session rules:\n // - if cookie.expires is set, it might need updating if rolling is true\n // - if isNew is true, definitely set cookie\n\n if (rolling && sess.cookie.maxAge) {\n sess.cookie.expires = new Date(Date.now() + sess.cookie.maxAge);\n }\n\n const shouldSetCookie = shouldSave || (!isNew && rolling);\n\n if (shouldSetCookie) {\n // value is just ID, or signed ID\n let val = sessionID;\n // We do simple signing s:id\n // Not enforcing secrets[0] yet\n if (secrets.length > 0) {\n val = 's:' + sign(val, secrets[0]);\n }\n\n const options = sess.cookie;\n // Serialize\n const str = options.serialize(name, val);\n ctx.set(\"Set-Cookie\", str);\n }\n\n return result;\n };\n sessionMiddleware.isBuiltin = true;\n sessionMiddleware.pluginName = 'Session';\n return sessionMiddleware;\n}\n"],"names":["resolve","callback","OpenAPIAnalyzer","file","Readable","RouteParamType","i","k","router","http","SecurityHeaders","generateAsyncApi","Container","RateLimitMiddleware","token","Headers","Sidebar","MainContent","readFile","join","os","require","URL","strategy","headers","resHeaders","html","Eta","defaults","Proxy","sess","options"],"mappings":"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"}
|