shokupan 0.4.4 → 0.5.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.
Files changed (44) hide show
  1. package/README.md +7 -8
  2. package/dist/analysis/openapi-analyzer.d.ts +0 -4
  3. package/dist/cli.cjs +1 -1
  4. package/dist/cli.js +1 -1
  5. package/dist/context.d.ts +3 -3
  6. package/dist/index.cjs +38 -39
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.js +38 -39
  9. package/dist/index.js.map +1 -1
  10. package/dist/{openapi-analyzer-BtIaHIfe.js → openapi-analyzer-D7y6Qa38.js} +31 -34
  11. package/dist/openapi-analyzer-D7y6Qa38.js.map +1 -0
  12. package/dist/{openapi-analyzer-D9YB3IkV.cjs → openapi-analyzer-z-7AoFRC.cjs} +31 -34
  13. package/dist/openapi-analyzer-z-7AoFRC.cjs.map +1 -0
  14. package/dist/plugins/scalar.d.ts +2 -2
  15. package/dist/server-adapter-BWrEJbKL.js.map +1 -1
  16. package/dist/server-adapter-fVKP60e0.cjs.map +1 -1
  17. package/dist/shokupan.d.ts +6 -5
  18. package/dist/types.d.ts +2 -1
  19. package/package.json +1 -1
  20. package/dist/benchmarking/advanced-cases/elysia.d.ts +0 -1
  21. package/dist/benchmarking/advanced-cases/express.d.ts +0 -1
  22. package/dist/benchmarking/advanced-cases/fastify.d.ts +0 -1
  23. package/dist/benchmarking/advanced-cases/hapi.d.ts +0 -1
  24. package/dist/benchmarking/advanced-cases/hono.d.ts +0 -1
  25. package/dist/benchmarking/advanced-cases/koa.d.ts +0 -1
  26. package/dist/benchmarking/advanced-cases/nest.d.ts +0 -1
  27. package/dist/benchmarking/advanced-cases/shokupan.d.ts +0 -1
  28. package/dist/benchmarking/advanced-data.d.ts +0 -33
  29. package/dist/benchmarking/advanced-runner.d.ts +0 -1
  30. package/dist/benchmarking/advanced-worker.d.ts +0 -0
  31. package/dist/benchmarking/cases/elysia.d.ts +0 -1
  32. package/dist/benchmarking/cases/express.d.ts +0 -1
  33. package/dist/benchmarking/cases/fastify.d.ts +0 -1
  34. package/dist/benchmarking/cases/hapi.d.ts +0 -1
  35. package/dist/benchmarking/cases/hono.d.ts +0 -1
  36. package/dist/benchmarking/cases/koa.d.ts +0 -1
  37. package/dist/benchmarking/cases/nest.d.ts +0 -1
  38. package/dist/benchmarking/cases/shokupan.d.ts +0 -1
  39. package/dist/benchmarking/data.d.ts +0 -15
  40. package/dist/benchmarking/quick_bench.d.ts +0 -1
  41. package/dist/benchmarking/runner.d.ts +0 -1
  42. package/dist/benchmarking/worker.d.ts +0 -0
  43. package/dist/openapi-analyzer-BtIaHIfe.js.map +0 -1
  44. package/dist/openapi-analyzer-D9YB3IkV.cjs.map +0 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/response.ts","../src/context.ts","../src/plugins/rate-limit.ts","../src/symbol.ts","../src/types.ts","../src/decorators.ts","../src/di.ts","../src/middleware.ts","../src/request.ts","../src/util/deep-merge.ts","../src/plugins/openapi.ts","../src/plugins/serve-static.ts","../src/router/trie.ts","../src/util/async-hooks.ts","../src/util/datastore.ts","../src/util/instrumentation.ts","../src/util/stack.ts","../src/router.ts","../src/util/cpu-monitor.ts","../src/shokupan.ts","../src/plugins/auth.ts","../src/plugins/compression.ts","../src/plugins/cors.ts","../src/plugins/express.ts","../src/plugins/validation.ts","../src/plugins/openapi-validator.ts","../src/plugins/scalar.ts","../src/plugins/security-headers.ts","../src/plugins/session.ts"],"sourcesContent":["\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","import type { BodyInit, Server } from 'bun';\nimport { readFile } from 'node:fs/promises';\nimport type { ShokupanRequest } from './request';\nimport { ShokupanResponse } from './response';\nimport type { Shokupan } from './shokupan';\nimport type { CookieOptions, JSXRenderer } from './types';\n\n// Shim for HeadersInit if not available globally in some envs\ntype HeadersInit = Headers | Record<string, string> | [string, string][];\n\n\nexport interface HandlerStackItem {\n name: string;\n file: string;\n line: number;\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\nexport class ShokupanContext<State extends Record<string, any> = Record<string, any>> {\n private _url: URL | undefined;\n public params: Record<string, string> = {}; // 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 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 ) {\n this.state = state || {} as State;\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 const q: Record<string, any> = {};\n for (const [key, value] of this.url.searchParams) {\n if (q[key] === undefined) {\n q[key] = value;\n } else if (Array.isArray(q[key])) {\n q[key].push(value);\n } else {\n q[key] = [q[key], value];\n }\n }\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() { return this.url.hostname; }\n\n /**\n * Request host (e.g. \"localhost:3000\")\n */\n get host() { return this.url.host; }\n\n /**\n * Request protocol (e.g. \"http:\", \"https:\")\n */\n get protocol() { return this.url.protocol; }\n\n /**\n * Whether request is secure (https)\n */\n get secure() { return this.url.protocol === 'https:'; }\n\n /**\n * Request origin (e.g. \"http://localhost:3000\")\n */\n get origin() { return this.url.origin; }\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 * 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 /**\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 // 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 * Send a response\n * @param body Response body\n * @param options Response options\n * @returns Response\n */\n public send(body?: BodyInit, options?: ResponseInit) {\n const headers = this.mergeHeaders(options?.headers as any);\n const status = options?.status ?? this.response.status;\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 this._finalResponse = new Response(body, { status, headers });\n return this._finalResponse;\n }\n\n /**\n * Read request body\n */\n async body<T = any>(): Promise<T> {\n const contentType = this.request.headers.get(\"content-type\") || \"\";\n\n if (contentType.includes(\"application/json\") || contentType.includes(\"+json\")) {\n return this.request.json() as any;\n }\n if (contentType.includes(\"multipart/form-data\") || contentType.includes(\"application/x-www-form-urlencoded\")) {\n return this.request.formData() as any;\n }\n return this.request.text() as any;\n }\n\n /**\n * Respond with a JSON object\n */\n json(data: any, status?: number, headers?: HeadersInit) {\n const finalStatus = status ?? this.response.status;\n const jsonString = JSON.stringify(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 text(data: string, status?: number, headers?: HeadersInit) {\n const finalStatus = status ?? this.response.status;\n\n // Store raw body for compression middleware\n this._rawBody = data;\n\n // Fast path: no custom headers and no response headers set\n if (!headers && !this.response.hasPopulatedHeaders) {\n this._finalResponse = new Response(data, {\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(data, { status: finalStatus, headers: finalHeaders });\n return this._finalResponse;\n }\n\n /**\n * Respond with HTML content\n */\n html(html: string, status?: number, headers?: HeadersInit) {\n const finalStatus = status ?? this.response.status;\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;\n\n this._finalResponse = new Response(html, { status: finalStatus, headers: finalHeaders });\n return this._finalResponse;\n }\n\n /**\n * Respond with a redirect\n */\n redirect(url: string, status = 302) {\n const headers = this.mergeHeaders();\n headers.set('Location', url);\n this._finalResponse = new Response(null, { status, headers });\n return this._finalResponse;\n }\n\n /**\n * Respond with a status code\n * DOES NOT CHAIN!\n */\n status(status: number) {\n const headers = this.mergeHeaders();\n this._finalResponse = new Response(null, { status, headers });\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 headers = this.mergeHeaders(responseOptions?.headers as any);\n const status = responseOptions?.status ?? this.response.status;\n\n if (typeof Bun !== \"undefined\") {\n this._finalResponse = new Response(Bun.file(path, fileOptions), { status, headers });\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 headers.set('content-type', fileOptions.type);\n }\n\n this._finalResponse = new Response(fileBuffer, { status, headers });\n return this._finalResponse;\n }\n }\n\n /**\n * JSX Rendering Function\n */\n public renderer?: JSXRenderer;\n\n /**\n * Render a JSX element\n * @param element JSX Element\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 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 type { Middleware, NextFn } from \"../types\";\n\nexport interface RateLimitOptions {\n windowMs?: number;\n max?: number;\n limit?: number; // Alias for max\n message?: string | object;\n statusCode?: number;\n headers?: boolean;\n keyGenerator?: (ctx: ShokupanContext) => string;\n skip?: (ctx: ShokupanContext) => boolean;\n mode?: 'user' | 'absolute';\n}\n\ninterface HitRecord {\n hits: number;\n resetTime: number;\n}\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\n const keyGenerator = options.keyGenerator || ((ctx) => {\n if (mode === 'absolute') {\n return 'global';\n }\n // Use IP if available\n return ctx.headers.get(\"x-forwarded-for\") || ctx.request.headers.get(\"x-forwarded-for\") || (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 for (const [key, record] of hits.entries()) {\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 // Dispatch 429\n const body = typeof message === 'object' ? JSON.stringify(message) : String(message);\n const res = typeof message === 'object' ? ctx.json(message, statusCode) : ctx.text(String(message), 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","export const $isApplication = Symbol.for(\"Shokupan.app\");\nexport const $appRoot = Symbol.for(\"Shokupan.app-root\");\nexport const $isMounted = Symbol(\"Shokupan.isMounted\");\nexport const $routeMethods = Symbol(\"Shokupan.routeMethods\");\nexport const $routeArgs = Symbol(\"Shokupan.routeArgs\");\nexport const $controllerPath = Symbol(\"Shokupan.controllerPath\");\nexport const $middleware = Symbol(\"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\");","import type { OpenAPI } from '@scalar/openapi-types';\nimport type { Server } from 'bun';\nimport type { ShokupanContext } from './context';\nimport { $isRouter } from \"./symbol\";\n\nexport type DeepPartial<T> = T extends Function ? T : T extends object ? {\n [P in keyof T]?: DeepPartial<T[P]>;\n} : T;\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\nexport interface ShokupanHooks<T = any> {\n onError?: (error: unknown, ctx: ShokupanContext<T>) => 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<T extends Record<string, any> = Record<string, any>> = (ctx: ShokupanContext<T>, next?: NextFn) => Promise<any> | any;\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>>;\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 */\n controllersOnly: boolean;\n\n /**\n * Whether to enable automatic backpressure based on system CPU load.\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;\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\nexport type ShokupanConfig<T extends Record<string, any> = Record<string, any>> = DeepPartial<{\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 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 * 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 * @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 * 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 */\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 */\n serverFactory: ServerFactory;\n\n /**\n * Lifecycle hooks.\n */\n hooks: ShokupanHooks<T> | ShokupanHooks<T>[];\n\n\n // Open for extension\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 * @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","import { RateLimitMiddleware, type RateLimitOptions } from \"./plugins/rate-limit\";\nimport { $controllerPath, $middleware, $routeArgs, $routeMethods, $routeSpec } from \"./symbol\";\nimport type { 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) {\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 });\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: Applies a rate limit to a class or method.\n */\nexport function RateLimit(options: RateLimitOptions) {\n return Use(RateLimitMiddleware(options));\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 type { ShokupanContext } from \"./context\";\nimport type { Middleware, NextFn } from './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","import type { Method } from './types';\n\nexport type ShokupanRequestProps = {\n method: Method;\n url: string;\n headers: Headers;\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","/**\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 for (const key in source) {\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","import type { ShokupanRouter } from '../router';\nimport { $childControllers, $childRouters, $mountPath, $routes } from '../symbol';\nimport type { OpenAPIOptions, ShokupanHandler } from '../types';\nimport { deepMerge } from '../util/deep-merge';\n\n/**\n * Analyze a handler function to infer request/response types\n */\nconst REGEX_QUERY_INT = /parseInt\\(ctx\\.query\\.(\\w+)\\)/g;\nconst REGEX_QUERY_FLOAT = /parseFloat\\(ctx\\.query\\.(\\w+)\\)/g;\nconst REGEX_QUERY_NUMBER = /Number\\(ctx\\.query\\.(\\w+)\\)/g;\nconst REGEX_QUERY_BOOL = /(?:Boolean\\(ctx\\.query\\.(\\w+)\\)|!+ctx\\.query\\.(\\w+))/g;\nconst REGEX_QUERY_GENERIC = /ctx\\.query\\.(\\w+)/g;\nconst REGEX_PARAM_INT = /parseInt\\(ctx\\.params\\.(\\w+)\\)/g;\nconst REGEX_PARAM_FLOAT = /parseFloat\\(ctx\\.params\\.(\\w+)\\)/g;\nconst REGEX_PARAM_GENERIC = /ctx\\.params\\.(\\w+)/;\nconst REGEX_HEADER_GET = /ctx\\.get\\(['\"](\\w+)['\"]\\)/g;\nconst REGEX_ERROR_STATUS = /ctx\\.(?:json|text|html)\\([^)]+,\\s*(\\d{3,})\\)/g;\n\n/**\n * Analyze a handler function to infer request/response types\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 // Query Integers\n for (const match of handlerSource.matchAll(REGEX_QUERY_INT)) {\n if (match[1]) queryParams.set(match[1], { type: 'integer', format: 'int32' });\n }\n\n // Query Floats\n for (const match of handlerSource.matchAll(REGEX_QUERY_FLOAT)) {\n if (match[1]) queryParams.set(match[1], { type: 'number', format: 'float' });\n }\n\n // Query Numbers\n for (const match of handlerSource.matchAll(REGEX_QUERY_NUMBER)) {\n if (match[1] && !queryParams.has(match[1])) {\n queryParams.set(match[1], { type: 'number' });\n }\n }\n\n // Query Booleans\n for (const match of handlerSource.matchAll(REGEX_QUERY_BOOL)) {\n const name = match[1] || match[2];\n if (name && !queryParams.has(name)) {\n queryParams.set(name, { type: 'boolean' });\n }\n }\n\n // Generic Query Strings\n for (const match of handlerSource.matchAll(REGEX_QUERY_GENERIC)) {\n const name = match[1];\n if (name && !queryParams.has(name)) {\n queryParams.set(name, { type: 'string' });\n }\n }\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\n // Path Integers\n for (const match of handlerSource.matchAll(REGEX_PARAM_INT)) {\n if (match[1]) pathParams.set(match[1], { type: 'integer', format: 'int32' });\n }\n\n // Path Floats\n for (const match of handlerSource.matchAll(REGEX_PARAM_FLOAT)) {\n if (match[1]) pathParams.set(match[1], { type: 'number', format: 'float' });\n }\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 for (const match of handlerSource.matchAll(REGEX_HEADER_GET)) {\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 response',\n content: { 'text/html': { schema: { type: 'string' } } }\n };\n }\n\n if (handlerSource.includes('ctx.text(')) {\n responses['200'] = {\n description: 'Successful 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 responses['302'] = { description: 'Redirect' };\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 for (const match of handlerSource.matchAll(REGEX_ERROR_STATUS)) {\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 * 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 // Step 4: Run AST Analysis if possible\n let astRoutes: any[] = [];\n try {\n // Dynamic import to avoid bundling issues if strictly runtime\n const { OpenAPIAnalyzer } = await import('../analysis/openapi-analyzer');\n const analyzer = new OpenAPIAnalyzer(process.cwd());\n const { applications } = await analyzer.analyze();\n\n // Create a map for easy lookup of apps by name/class\n const appMap = new Map<string, any>();\n applications.forEach(app => {\n appMap.set(app.name, app);\n // Also map by direct className if it's unique enough (heuristic)\n if (app.name !== app.className) {\n appMap.set(app.className, app);\n }\n });\n\n const getExpandedRoutes = (app: any, prefix: string = '', seen = new Set<string>()): any[] => {\n // Prevent infinite recursion in cyclic mounts\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 // Add app's own routes with accumulated prefix\n for (const route of app.routes) {\n const cleanPrefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;\n const cleanPath = route.path.startsWith('/') ? route.path : '/' + route.path;\n let joined = cleanPrefix + cleanPath;\n if (joined.length > 1 && joined.endsWith('/')) {\n joined = joined.slice(0, -1);\n }\n\n expanded.push({\n ...route,\n path: joined || '/'\n });\n }\n\n // Recurse into mounted apps\n if (app.mounted) {\n for (const mount of app.mounted) {\n const targetApp = appMap.get(mount.target);\n if (targetApp) {\n const cleanPrefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;\n const mountPrefix = mount.prefix.startsWith('/') ? mount.prefix : '/' + mount.prefix;\n expanded.push(...getExpandedRoutes(targetApp, cleanPrefix + mountPrefix, newSeen));\n }\n }\n }\n return expanded;\n };\n\n // Expand routes for all applications\n // This generates variants: e.g. UserController at '/' AND Main->UserController at '/api/user'\n applications.forEach(app => {\n astRoutes.push(...getExpandedRoutes(app));\n });\n\n // Deduplicate AST Routes with Scoring\n // Prioritize: 1. Has Response Schema, 2. Has Handler Source\n const dedupedRoutes = new Map<string, { route: any, score: number; }>();\n\n for (const route of astRoutes) {\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 // Prefer longer/specific paths? No, exact path matching handles that.\n\n if (!dedupedRoutes.has(key) || score > dedupedRoutes.get(key)!.score) {\n dedupedRoutes.set(key, { route, score });\n }\n }\n\n astRoutes = Array.from(dedupedRoutes.values()).map(v => v.route);\n\n } catch (e) {\n console.warn(\"OpenAPI AST analysis failed or skipped:\", e);\n }\n\n const collect = (router: ShokupanRouter<T>, prefix = \"\", currentGroup = defaultTagGroup, defaultTag = defaultTagName) => {\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 if (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 if (!tagGroups.has(group)) tagGroups.set(group, new Set());\n\n const routes = (router as any)[$routes] || [];\n // console.log(`[OpenAPI] Visiting router with ${routes.length} routes. Config:`, router.config, \"Prefix:\", prefix);\n // Debug symbols\n // console.log('[OpenAPI] Router keys:', Reflect.ownKeys(router).map(k => k.toString()));\n // console.log('[OpenAPI] Local $routes symbol:', $routes.toString());\n\n for (const route of routes) {\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 fullPath = fullPath.replace(/:([a-zA-Z0-9_]+)/g, \"{$1}\");\n\n // Normalize trailing slash\n if (fullPath.length > 1 && fullPath.endsWith('/')) {\n fullPath = fullPath.slice(0, -1);\n }\n\n if (!paths[fullPath]) paths[fullPath] = {};\n\n // Initialize operation structure\n const operation: any = {\n responses: { '200': { description: \"Successful response\" } },\n tags: [tag]\n };\n\n // Merge metadata from guards (if any)\n if (route.guards) {\n for (const guard of route.guards) {\n if (guard.spec) {\n // Merge security (deduplicated)\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 // Merge responses\n if (guard.spec.responses) {\n operation.responses = { ...operation.responses, ...guard.spec.responses };\n }\n }\n }\n }\n\n // --- Step 4: Base Data from AST ---\n\n // 1. Exact Match (Method + Path)\n let astMatch = astRoutes.find(r =>\n r.method.toUpperCase() === route.method.toUpperCase() &&\n r.path === fullPath\n );\n\n // 2. Fallback: Match by Handler Source (ignores Path mismatch due to mounting prefixes)\n if (!astMatch) {\n let runtimeSource = route.handler.toString();\n if ((route.handler as any).originalHandler) {\n runtimeSource = (route.handler as any).originalHandler.toString();\n }\n\n const runtimeHandlerSrc = runtimeSource.replace(/\\s+/g, ' ');\n\n // Filter all AST routes with same method\n const sameMethodRoutes = astRoutes.filter(r => r.method.toUpperCase() === route.method.toUpperCase());\n\n // Find one that matches source\n astMatch = sameMethodRoutes.find(r => {\n const astHandlerSrc = (r.handlerSource || r.handlerName || '').replace(/\\s+/g, ' ');\n if (!astHandlerSrc || astHandlerSrc.length < 20) return false;\n\n const match = runtimeHandlerSrc.includes(astHandlerSrc) ||\n astHandlerSrc.includes(runtimeHandlerSrc) ||\n (r.handlerSource && runtimeHandlerSrc.includes(r.handlerSource.substring(0, 50)));\n\n return match;\n });\n }\n\n\n // Disambiguate if multiple routes share the same path/method\n const potentialMatches = astRoutes.filter(r =>\n r.method.toUpperCase() === route.method.toUpperCase() &&\n r.path === fullPath\n );\n\n if (potentialMatches.length > 1) {\n const runtimeHandlerSrc = route.handler.toString().replace(/\\s+/g, ' ');\n\n // Try to find the best match by checking if AST handler snippet is in Runtime handler source\n const preciseMatch = potentialMatches.find(r => {\n const astHandlerSrc = (r.handlerSource || r.handlerName || '').replace(/\\s+/g, ' ');\n\n // Relaxed matching: check if ONE includes the other (source code containment)\n const match = runtimeHandlerSrc.includes(astHandlerSrc) || astHandlerSrc.includes(runtimeHandlerSrc) ||\n (r.handlerSource && runtimeHandlerSrc.includes(r.handlerSource.substring(0, 50)));\n\n return match;\n });\n\n if (preciseMatch) {\n astMatch = preciseMatch;\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 // Merge Request Body\n if (astMatch.requestTypes?.body) {\n operation.requestBody = {\n content: {\n 'application/json': { schema: astMatch.requestTypes.body }\n }\n };\n }\n\n // Merge Responses\n if (astMatch.responseSchema) {\n operation.responses['200'] = {\n description: 'Successful response',\n content: {\n 'application/json': { schema: astMatch.responseSchema }\n }\n };\n }\n else if (astMatch.responseType) {\n const contentType = astMatch.responseType === 'string' ? 'text/plain' : 'application/json';\n operation.responses['200'] = {\n description: 'Successful response',\n content: {\n [contentType]: { schema: { type: astMatch.responseType } }\n }\n };\n }\n\n // Merge Parameters (Query, Path, Header) from AST\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\n if (params.length > 0) {\n operation.parameters = params;\n }\n }\n\n // --- Step 5: Decorators / Path Patterns (Runtime) ---\n\n // Path Keys (e.g. /users/:id)\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 // Merge into existing parameters\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 (analyzeHandler)\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 // Merge metadata from runtime route definition (Manual override)\n if (route.handlerSpec) {\n const spec = route.handlerSpec;\n if (spec.summary) operation.summary = spec.summary;\n if (spec.description) operation.description = spec.description;\n if (spec.operationId) operation.operationId = spec.operationId;\n if (spec.tags) operation.tags = spec.tags;\n if (spec.security) operation.security = spec.security;\n\n // Merge responses\n if (spec.responses) {\n operation.responses = { ...operation.responses, ...spec.responses };\n }\n }\n\n // Apply tags\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 }\n else {\n paths[fullPath][methodLower] = operation;\n }\n };\n\n for (const controller of router[$childControllers]) {\n const controllerName = controller.constructor.name || \"UnknownController\";\n tagGroups.get(group)?.add(controllerName);\n }\n\n for (const child of router[$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 collect(child, nextPrefix, group, tag);\n }\n };\n\n collect(rootRouter);\n\n const xTagGroups: { name: string; tags: string[]; }[] = [];\n for (const [name, tags] of tagGroups) {\n xTagGroups.push({ name, tags: Array.from(tags).sort() });\n }\n\n return {\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 };\n}\n","import { Eta } from 'eta';\nimport { readdir, readFile, stat } from 'fs/promises';\nimport { basename, join, resolve } from 'path';\nimport type { ShokupanContext } from '../context';\nimport type { Middleware, StaticServeOptions } from '../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 // Decode URI components\n relative = decodeURIComponent(relative);\n\n // Security: Prevent directory traversal\n const requestPath = join(rootPath, relative);\n if (!requestPath.startsWith(rootPath)) {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n\n // check if path includes null byte\n if (requestPath.includes('\\0')) {\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 (const pattern of config.exclude) {\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 (const ext of config.extensions) {\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 (const idx of indexes) {\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);\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","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 (const segment of segments) {\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","\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport const asyncContext = new AsyncLocalStorage<Map<string, any>>();\n\nexport function runInContext<T>(callback: () => T, initialStore = new Map<string, any>()): T {\n return asyncContext.run(initialStore, callback);\n}\n","import { createNodeEngines } from '@surrealdb/node';\nimport { RecordId, Surreal } from 'surrealdb';\n\nconst engine = process.env['SHOKUPAN_DB_ENGINE'] === 'memory' ? 'mem://' : 'rocksdb://database';\n\nconst db = new Surreal({\n engines: createNodeEngines(),\n});\n\nconst ready = db.connect(engine, { namespace: \"vendor\", database: \"shokupan\" }).then(() => {\n // Define the tables with bare minimum schema\n return 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 `);\n});\n\nexport const datastore = {\n get<T extends Record<string, any>>(store: string, key: string) {\n return db.select<T>(new RecordId(store, key));\n },\n set(store: string, key: string, value: any) {\n return db.create(new RecordId(store, key)).content(value);\n },\n async query(query: string, vars?: Record<string, unknown>) {\n try {\n // console.error(\"DS QUERY:\", query);\n const r = await db.query(query, vars).collect<any>();\n // console.error(\"DS RESULT:\", JSON.stringify(r));\n return r;\n } catch (e) {\n console.error(\"DS ERROR:\", e);\n throw e;\n }\n },\n ready\n};\n\nprocess.on(\"exit\", async () => {\n await db.close();\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 // Index 0: Error\n // Index 1: getCallerInfo (this function)\n // Index 2: caller (or whatever calls this)\n\n // So we scan starting from a reasonable offset\n\n // However, stack trace format depends on many things. \n // A more robust way is to just look for the first line that ISN'T internal.\n\n // Filter out this file itself if possible, but identifying \"this file\" is tricky without context.\n // So we rely on skipFrames OR we filter known internal files.\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('src/util/stack.ts')) continue; // Ignore self\n if (l.includes('src/router.ts')) continue; // Ignore router internals\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 { ShokupanContext } from './context';\nimport { Container } from './di';\nimport { compose } from './middleware';\nimport { generateOpenApi } from './plugins/openapi';\nimport { serveStatic } from './plugins/serve-static';\nimport { ShokupanRequest } from './request';\nimport { RouterTrie } from './router/trie';\nimport type { Shokupan } from './shokupan';\nimport { $appRoot, $childControllers, $childRouters, $controllerPath, $dispatch, $isApplication, $isMounted, $isRouter, $middleware, $mountPath, $parent, $routeArgs, $routeMethods, $routes, $routeSpec } from './symbol';\n\nimport { type GuardAPISpec, HTTPMethods, type JSXRenderer, type Method, type MethodAPISpec, type Middleware, type OpenAPIOptions, type ProcessResult, type RequestOptions, type RouteMetadata, RouteParamType, type ShokupanController, type ShokupanHandler, type ShokupanHooks, type ShokupanRoute, type ShokupanRouteConfig, type StaticServeOptions } from './types';\nimport { asyncContext } from './util/async-hooks';\nimport { datastore } from './util/datastore';\nimport { traceHandler } from './util/instrumentation';\nimport { getCallerInfo } from './util/stack';\n\n\n// Shim for HeadersInit if not available globally\ntype HeadersInit = Headers | Record<string, string> | [string, string][];\n\n\nexport const RouterRegistry = new Map<string, ShokupanRouter<any>>();\n\nexport const ShokupanApplicationTree = {};\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 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\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 } {\n // Separation logic: Group routes by controller instance\n const controllerRoutesMap = new Map<any, any[]>();\n const localRoutes: any[] = [];\n\n for (const r of this[$routes]) {\n const entry = {\n type: 'route' as 'route',\n 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],\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 return {\n metadata: this.metadata,\n middleware,\n routes: localRoutes,\n routers,\n controllers\n };\n }\n\n constructor(\n public readonly config?: ShokupanRouteConfig\n ) {\n if (config?.requestTimeout) {\n this.requestTimeout = config.requestTimeout;\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 * 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 if (controller[$isMounted]) {\n throw new Error(\"Router is already mounted\");\n }\n\n controller[$mountPath] = prefix;\n\n // Capture mount location if not already present (create new router usually has it? no)\n if (!controller.metadata) {\n const info = getCallerInfo();\n controller.metadata = {\n file: info.file,\n line: info.line,\n name: 'MountedRouter'\n };\n }\n this[$childRouters].push(controller);\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 controller[$parent] = this;\n\n const setRouterContext = (router: ShokupanRouter<T>) => {\n router[$appRoot] = this.root;\n router[$childRouters].forEach((child) => setRouterContext(child));\n };\n setRouterContext(controller);\n\n\n // If the controller is the root router\n if (this[$appRoot]) {\n // TODO:\n }\n controller[$appRoot] = this.root;\n controller[$isMounted] = true;\n }\n // Controller is an arbitrary class\n else {\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) {\n // Combine mount prefix + controller path\n // mount('/api', Ctrl) + @Controller('/users') -> /api/users\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) {\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 this[$childControllers].push(instance as any);\n\n // Get Middleware for Controller\n // It could be on the Constructor (if passed as class) or Instance (if passed as object and manually set?)\n // Usually decorators set it on Constructor.\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 && 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\n let routesAttached = 0;\n for (const name of Array.from(methods)) {\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 if (decoratedRoutes && decoratedRoutes.has(name)) {\n const config = decoratedRoutes.get(name);\n method = config.method;\n subPath = config.path;\n }\n // 2. Fallback to Convention\n else {\n // Simple convention matching\n // Check if name starts with HTTP verb\n for (const m of HTTPMethods) {\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 // Existing parsing logic...\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 // Revised simple loop\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 if (method) {\n routesAttached++;\n // Remove trailing slash from prefix if needed, combine with subPath\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\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]; // Default to just context if no decorators\n\n if (routeArgs?.length > 0) {\n args = [];\n // Sort by index\n const sortedArgs = [...routeArgs].sort((a, b) => a.index - b.index);\n\n // Fill args array\n for (const arg of sortedArgs) {\n switch (arg.type) {\n case RouteParamType.BODY:\n try {\n if (ctx.req.headers.get(\"content-type\")?.includes(\"application/json\")) {\n args[arg.index] = await ctx.req.json();\n } else {\n // Fallback or empty if not JSON? \n // If @Body is used, valid JSON is expected.\n // If empty body, json() throws.\n const text = await ctx.req.text();\n if (!text) {\n args[arg.index] = {};\n } else {\n args[arg.index] = JSON.parse(text);\n }\n }\n } catch (e) {\n const err: any = new Error(\"Invalid JSON body\");\n err.status = 400;\n throw err;\n }\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 for (const key of url.searchParams.keys()) {\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 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 // Expose original handler for OpenAPI analysis\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 this.add({ method, path: normalizedPath, handler: finalHandler, spec, controller: instance });\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 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 (const child of this[$childRouters]) {\n const childRoutes = child.getRoutes();\n for (const route of childRoutes) {\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 a sub request to this router.\n * This is useful for triggering other methods or route handlers. \n * @param options The request options.\n * @returns The response.\n */\n public async subRequest(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 const store = asyncContext.getStore();\n const originalReq = store?.get(\"req\") as ShokupanRequest<T>;\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 directly.\n */\n public async processRequest(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 for (const [k, v] of Object.entries(options.query)) {\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 = 200;\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 = err.status || err.statusCode || 500;\n result = { error: err.message || \"Internal Server Error\" };\n if (err.errors) result.errors = err.errors;\n }\n }\n else {\n status = 404;\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 applyRouterHooks(match: { handler: ShokupanHandler<T>; params: Record<string, string>; }) {\n if (!this.config?.hooks) return match;\n const hooks = this.config.hooks;\n // Re-use static helper or method to avoid code duplication with add()\n return {\n ...match,\n handler: this.wrapWithHooks(match.handler, hooks)\n };\n }\n\n private wrapWithHooks(handler: ShokupanHandler<T>, hooks: ShokupanHooks | ShokupanHooks[]) {\n const hookList = Array.isArray(hooks) ? hooks : [hooks];\n\n // Optimize: Check if any relevant hooks are actually defined\n const hasStart = hookList.some(h => !!h.onRequestStart);\n const hasEnd = hookList.some(h => !!h.onRequestEnd);\n const hasError = hookList.some(h => !!h.onError);\n\n if (!hasStart && !hasEnd && !hasError) return handler;\n\n const originalHandler = handler;\n\n const wrapped = async (ctx: ShokupanContext<T>) => {\n if (hasStart) {\n for (let i = 0; i < hookList.length; i++) {\n const h = hookList[i];\n if (typeof h.onRequestStart === 'function') await h.onRequestStart(ctx);\n }\n }\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 for (let i = 0; i < hookList.length; i++) {\n const h = hookList[i];\n if (typeof h.onRequestEnd === 'function') await h.onRequestEnd(ctx);\n }\n return res;\n } catch (err) {\n debug?.trackStep(debugId, 'handler', performance.now() - start, 'error', err);\n\n for (let i = 0; i < hookList.length; i++) {\n const h = hookList[i];\n if (typeof h.onError === 'function') await h.onError(err, ctx);\n }\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 /**\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 (const child of this[$childRouters]) {\n const prefix = child[$mountPath];\n // console.log(` -> Checking child prefix ${prefix}`);\n\n if (path === prefix || path.startsWith(prefix + \"/\")) {\n const subPath = path.slice(prefix.length) || \"/\";\n const match = child.find(method, subPath);\n if (match) return this.applyRouterHooks(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 this.applyRouterHooks(match);\n }\n }\n }\n\n return null; // Not found\n }\n\n private parsePath(path: string): { regex: RegExp; keys: string[]; } {\n const keys: string[] = [];\n const pattern = path\n .replace(/:([a-zA-Z0-9_]+)/g, (_, key) => {\n keys.push(key);\n return \"([^/]+)\";\n })\n .replace(/\\*\\*/g, \".*\") // Recursive wildcard\n .replace(/\\*/g, \"[^/]+\"); // Single segment wildcard\n\n return {\n regex: new RegExp(`^${pattern}$`),\n keys\n };\n }\n\n // --- Functional Routing ---\n\n public requestTimeout?: number;\n\n /**\n * Adds a route to the router.\n * \n * @param method - HTTP method\n * @param path - URL path\n * @param spec - OpenAPI specification for the route\n * @param handler - Route handler function\n * @param requestTimeout - Timeout for this route in milliseconds\n */\n public add({ method, path, spec, handler, regex: customRegex, group, requestTimeout, renderer, controller }: {\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 }) {\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 (const guard of this.currentGuards) {\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 = 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 (const guard of routeGuards) {\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.renderer = effectiveRenderer;\n return innerHandler(ctx);\n };\n }\n\n // --- Middleware Tracking Logic ---\n const { file, line } = getCallerInfo();\n\n const trackingHandler = wrappedHandler;\n wrappedHandler = async (ctx: ShokupanContext<T>) => {\n // Optimization: Skip all tracking overhead if disabled\n if (!ctx.app?.applicationConfig.enableMiddlewareTracking) {\n return trackingHandler(ctx);\n }\n\n const startTime = performance.now();\n let error: any = undefined;\n\n try {\n if (ctx.app?.applicationConfig.enableMiddlewareTracking) {\n ctx.handlerStack.push({\n name: handler.name || 'anonymous',\n file,\n line\n });\n }\n return await trackingHandler(ctx);\n } catch (e) {\n error = e;\n throw e; // Bubble up to error hook\n } finally {\n // Store in datastore after execution\n if (ctx.app?.applicationConfig.enableMiddlewareTracking) {\n const duration = performance.now() - startTime;\n const config = ctx.app.applicationConfig;\n\n // Store middleware execution in datastore\n try {\n const timestamp = Date.now();\n const key = `${timestamp}-${handler.name || 'anonymous'}-${Math.random().toString(36).substring(7)}`;\n\n await datastore.set('middleware_tracking', key, {\n name: handler.name || 'anonymous',\n path: ctx.path,\n timestamp,\n duration,\n file,\n line,\n error: error ? String(error) : undefined,\n metadata: {\n isBuiltin: (handler as any).isBuiltin,\n pluginName: (handler as any).pluginName\n }\n });\n\n // Cleanup old entries based on TTL and capacity\n const ttl = config.middlewareTrackingTTL ?? 86400000; // 1 day default\n const maxCapacity = config.middlewareTrackingMaxCapacity ?? 10000;\n const cutoff = Date.now() - ttl;\n\n // Delete entries older than TTL\n await datastore.query(`DELETE middleware_tracking WHERE timestamp < ${cutoff}`);\n\n // Enforce capacity limit\n const results = await datastore.query('SELECT count() FROM middleware_tracking GROUP ALL');\n if (results && results[0] && results[0].count > maxCapacity) {\n const toDelete = results[0].count - maxCapacity;\n await datastore.query(`DELETE middleware_tracking ORDER BY timestamp ASC LIMIT ${toDelete}`);\n }\n } catch (datastoreError) {\n // Silently fail datastore operations to not break request flow\n console.error('Failed to store middleware tracking:', datastoreError);\n }\n }\n }\n };\n (wrappedHandler as any).originalHandler = (trackingHandler as any).originalHandler || trackingHandler;\n\n // Bake in Hooks if present (Optimization)\n let bakedHandler = wrappedHandler;\n if (this.config?.hooks) {\n bakedHandler = this.wrapWithHooks(wrappedHandler, this.config.hooks);\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 });\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 handler - Route handler function \n */\n public get(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 handler - Route handler function \n */\n public post(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 handler - Route handler function \n */\n public put(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 handler - Route handler function \n */\n public delete(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 handler - Route handler function \n */\n public patch(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 handler - Route handler function \n */\n public options(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 handler - Route handler function \n */\n public head(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 const match = callerLine.match(/\\((.*):(\\d+):(\\d+)\\)/) || callerLine.match(/at (.*):(\\d+):(\\d+)/);\n if (match) {\n file = match[1];\n line = parseInt(match[2], 10);\n }\n }\n } catch (e) { }\n\n const trackedGuard = async (ctx: ShokupanContext<T>, next?: any) => {\n if (ctx.app?.applicationConfig.enableMiddlewareTracking) {\n ctx.handlerStack.push({\n name: guardHandler.name || 'guard',\n file,\n line\n });\n }\n return guardHandler(ctx, next);\n };\n (trackedGuard as any).originalHandler = (guardHandler as any).originalHandler || guardHandler;\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]; // Last handler is the main handler?\n // Wait, compose logic: \n // If we have [m1, m2, h], we want m1 -> m2 -> h.\n // compose([m1, m2, h]) does exactly that.\n // However, middleware returns `Promise<any>`.\n // If `handlers.length > 1`, we wrap them.\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 // if (spec) {\n // console.log(`[Router] attachVerb ${method} ${path} has spec:`, spec);\n // } \n // else {\n // console.log(`[Router] attachVerb ${method} ${path} NO SPEC`);\n // }\n\n this.add({\n method,\n path,\n spec,\n handler: finalHandler\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 = {}): any {\n return generateOpenApi(this, options);\n }\n}\n","import * as os from 'node:os';\n\nexport class SystemCpuMonitor {\n private interval: Timer | null = null;\n private lastCpus: os.CpuInfo[] = [];\n private currentUsage: number = 0;\n\n constructor(private readonly intervalMs: number = 1000) { }\n\n public start() {\n if (this.interval) return;\n this.lastCpus = os.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 const cpus = os.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 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 \"./util/instrumentation\";\n\nimport { context, trace } from '@opentelemetry/api';\nimport { ShokupanContext } from \"./context\";\nimport { compose } from \"./middleware\";\nimport { generateOpenApi } from \"./plugins/openapi\";\nimport { ShokupanRequest } from './request';\nimport { ShokupanRouter } from \"./router\";\nimport { $appRoot, $dispatch, $isApplication } from './symbol';\nimport type { Method, Middleware, ProcessResult, RequestOptions, ShokupanConfig, ShokupanHooks } from './types';\nimport { asyncContext } from \"./util/async-hooks\";\n\n\nimport { SystemCpuMonitor } from \"./util/cpu-monitor\";\nimport { getCallerInfo } from './util/stack';\n\n\nconst defaults: ShokupanConfig = {\n port: 3000,\n hostname: \"localhost\",\n development: process.env.NODE_ENV !== \"production\",\n enableAsyncLocalStorage: false,\n reusePort: false,\n};\nconst tracer = trace.getTracer(\"shokupan.application\");\n\n\nexport class Shokupan<T = any> extends ShokupanRouter<T> {\n readonly applicationConfig: ShokupanConfig = {};\n public openApiSpec?: any;\n private composedMiddleware?: Middleware;\n private cpuMonitor?: SystemCpuMonitor;\n\n private hookCache = new Map<keyof ShokupanHooks, Function[]>();\n private hooksInitialized = false;\n\n get logger() {\n return this.applicationConfig.logger;\n }\n\n constructor(\n applicationConfig: ShokupanConfig = {}\n ) {\n const config = Object.assign({}, defaults, applicationConfig);\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);\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\n /**\n * Adds middleware to the application.\n */\n public use(middleware: Middleware) {\n let trackedMiddleware = middleware;\n\n // --- Middleware Tracking Logic ---\n const { file, line } = getCallerInfo();\n\n // Store metadata on the original middleware function if possible\n if (!(middleware as any).metadata) {\n (middleware as any).metadata = {\n file,\n line,\n name: middleware.name || 'middleware',\n isBuiltin: (middleware as any).isBuiltin,\n pluginName: (middleware as any).pluginName\n };\n }\n\n // Create wrapper but preserve metadata for registry\n trackedMiddleware = async (ctx, next) => {\n // Cast to any to access handlerStack if types are strict, but ShokupanContext should have it.\n const c = ctx as any;\n if (c.handlerStack && c.app?.applicationConfig.enableMiddlewareTracking) {\n const metadata = (middleware as any).metadata || {};\n const start = performance.now();\n const item = {\n name: metadata.pluginName ? `${metadata.pluginName} (${metadata.name})` : metadata.name || middleware.name || 'middleware',\n file: metadata.file || file,\n line: metadata.line || line,\n isBuiltin: metadata.isBuiltin,\n startTime: start,\n duration: -1\n };\n c.handlerStack.push(item);\n\n try {\n return await middleware(ctx, next);\n } finally {\n item.duration = performance.now() - start;\n }\n }\n return middleware(ctx, next);\n };\n (trackedMiddleware as any).metadata = (middleware as any).metadata;\n Object.defineProperty(trackedMiddleware, 'name', { value: (middleware as any).name || 'middleware' });\n\n (trackedMiddleware as any).order = this.middleware.length;\n this.middleware.push(trackedMiddleware);\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) {\n throw new Error(\"Invalid port number\");\n }\n\n // Run startup hooks\n for (const hook of this.startupHooks) {\n await hook();\n }\n\n if (this.applicationConfig.enableOpenApiGen) {\n this.openApiSpec = await generateOpenApi(this);\n // Run spec available hooks\n for (const hook of this.specAvailableHooks) {\n await hook(this.openApiSpec);\n }\n }\n\n if (port === 0 && process.platform === \"linux\") {\n\n }\n\n\n if (this.applicationConfig.autoBackpressureFeedback) {\n this.cpuMonitor = new SystemCpuMonitor();\n this.cpuMonitor.start();\n }\n\n const serveOptions = {\n\n port: finalPort,\n hostname: this.applicationConfig.hostname,\n development: this.applicationConfig.development,\n fetch: this.fetch.bind(this),\n reusePort: this.applicationConfig.reusePort,\n idleTimeout: this.applicationConfig.readTimeout ? this.applicationConfig.readTimeout / 1000 : undefined,\n websocket: {\n open(ws) {\n ws.data?.handler?.open?.(ws);\n },\n message(ws, message) {\n ws.data?.handler?.message?.(ws, message);\n },\n drain(ws) {\n ws.data?.handler?.drain?.(ws);\n },\n close(ws, code, reason) {\n ws.data?.handler?.close?.(ws, code, reason);\n },\n }\n };\n\n\n\n let factory = this.applicationConfig.serverFactory;\n\n // Detect if we are not running on Bun\n // @ts-ignore\n if (!factory && typeof Bun === \"undefined\") {\n const { createHttpServer } = await import(\"./plugins/server-adapter\");\n factory = createHttpServer();\n }\n\n const server = factory\n ? await factory(serveOptions)\n : Bun.serve(serveOptions);\n\n console.log(`Shokupan server listening on http://${server.hostname}:${server.port}`);\n return server;\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 processRequest(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 for (const [k, v] of Object.entries(options.query)) {\n u.searchParams.set(k, v);\n }\n url = u.toString();\n }\n\n // Create Request to pass to fetch\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 }) 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?: import(\"bun\").Server<any>): Promise<Response> {\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?.get(\"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 ctxMap = new Map();\n ctxMap.set(\"span\", span);\n ctxMap.set(\"request\", req);\n\n return asyncContext.run(ctxMap, () => 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 ctxMap = new Map();\n ctxMap.set(\"request\", req);\n return asyncContext.run(ctxMap, () => this.handleRequest(req, server));\n }\n\n return this.handleRequest(req, server);\n }\n\n private async handleRequest(req: Request, server?: import(\"bun\").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 await this.executeHook('onResponseEnd', ctx, res);\n return res;\n }\n\n try {\n // Request Start Hook\n if (this.hasHook('onRequestStart')) {\n await this.executeHook('onRequestStart', ctx);\n }\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 const match = this.find(req.method, ctx.path);\n // TODO: Execute router-level hooks from match?\n // For now, only app-level hooks are fully supported here.\n if (match) {\n ctx.params = match.params;\n return match.handler(ctx);\n }\n return null;\n });\n\n let response: 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 // 1. Check if response was explicitly set via helper (e.g. ctx.text())\n if (ctx._finalResponse instanceof Response) {\n response = ctx._finalResponse;\n }\n // 2. Check if user manipulated ctx.response state manually (status/headers)\n // If status is NOT 200 (default), or headers are set, maybe we should construct a response?\n // But usually returning nothing implies 404 in this framework unless explicit.\n // However, if one sets `ctx.response.status = 201`, they expect 201?\n // Currently `ShokupanResponse` doesn't automatically generate a body.\n // So we'd send empty body with that status.\n else if (ctx.response.status !== 200 || ctx.response.hasPopulatedHeaders) {\n // Construct response from context state\n response = ctx.send(null, { status: ctx.response.status, headers: ctx.response.headers });\n }\n // 3. Fallback: Not Found\n else {\n response = ctx.text(\"Not Found\", 404);\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.hasHook('onRequestEnd')) {\n await this.executeHook('onRequestEnd', ctx);\n }\n\n // Response Start Hook - About to send response\n if (this.hasHook('onResponseStart')) {\n await this.executeHook('onResponseStart', ctx, response);\n }\n\n return response;\n\n }\n catch (err: any) {\n console.error(err);\n const span = asyncContext.getStore()?.get(\"span\");\n if (span) span.setStatus({ code: 2 }); // Error\n\n const status = err.status || err.statusCode || 500;\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.hasHook('onError')) {\n await this.executeHook('onError', err, ctx);\n }\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 if (this.hasHook('onRequestTimeout')) {\n await this.executeHook('onRequestTimeout', ctx);\n }\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\", 408);\n }\n console.error(\"Unexpected error in request execution:\", err);\n return ctx.text(\"Internal Server Error\", 500);\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 if (this.hasHook('onResponseEnd')) {\n await this.executeHook('onResponseEnd', ctx, res);\n }\n return res;\n });\n }\n\n private ensureHooksInitialized() {\n\n const hooks = this.applicationConfig.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 (const type of hookTypes) {\n const fns: Function[] = [];\n for (const h of hookList) {\n if (h[type]) fns.push(h[type]!);\n }\n if (fns.length > 0) {\n this.hookCache.set(type, fns);\n }\n }\n }\n this.hooksInitialized = true;\n }\n\n private async executeHook(name: keyof ShokupanHooks, ...args: any[]) {\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 for (const fn of fns) {\n // @ts-ignore\n await fn(...args);\n }\n }\n\n private hasHook(name: keyof ShokupanHooks) {\n if (!this.hooksInitialized) {\n this.ensureHooksInitialized();\n }\n return this.hookCache.has(name);\n }\n}\n","\nimport {\n Apple, Auth0,\n GitHub, Google, MicrosoftEntraId,\n OAuth2Client,\n Okta,\n generateCodeVerifier,\n generateState\n} from \"arctic\";\nimport * as jose from \"jose\";\nimport { ShokupanContext } from \"../context\";\nimport { ShokupanRouter } from \"../router\";\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 clientId: string;\n clientSecret: string;\n redirectUri: string; // Must be absolute\n scopes?: string[];\n tenantId?: string; // For MS\n domain?: string; // For Auth0, Okta\n teamId?: string; // For Apple\n keyId?: string; // For Apple\n authUrl?: string; // For generic OAuth2\n tokenUrl?: string; // For generic OAuth2\n userInfoUrl?: string; // For generic OAuth2\n}\n\nexport interface AuthConfig {\n jwtSecret: string | Uint8Array;\n jwtExpiration?: string; // e.g. \"2h\"\n cookieOptions?: {\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n path?: string;\n maxAge?: number;\n };\n onSuccess?: (user: AuthUser, ctx: ShokupanContext) => Promise<any> | any;\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\nexport class AuthPlugin extends ShokupanRouter<any> {\n private secret: Uint8Array;\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 this.init();\n }\n\n private getProviderInstance(name: string, p: ProviderConfig) {\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 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 for (const [providerName, providerConfig] of Object.entries(this.authConfig.providers)) {\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 ctx.res.headers.set(\"Set-Cookie\", `oauth_state=${state}; Path=/; HttpOnly; Max-Age=600`);\n if (codeVerifier) {\n ctx.res.headers.append(\"Set-Cookie\", `oauth_verifier=${codeVerifier}; Path=/; HttpOnly; 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 console.error(\"Auth Error\", e);\n return ctx.text(\"Authentication failed: \" + e.message + \"\\n\" + e.stack, 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 = 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 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 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 * as zlib from \"node:zlib\"; // TODO: When bun compression support supercedes node, remove this\nimport type { ShokupanContext } from \"../context\";\nimport type { Middleware, NextFn } from \"../types\";\n\nexport interface CompressionOptions {\n threshold?: number; // Minimum byte size to compress\n}\n\nexport function Compression(options: CompressionOptions = {}): Middleware {\n const threshold = options.threshold ?? 512; // 512 bytes default\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 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, {\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, {\n status: response.status,\n statusText: response.statusText,\n headers\n });\n }\n\n return response;\n };\n compressionMiddleware.isBuiltin = true;\n compressionMiddleware.pluginName = 'Compression';\n return compressionMiddleware;\n};\n","import type { ShokupanContext } from \"../context\";\nimport type { Middleware, NextFn } from \"../types\";\n\nexport interface CorsOptions {\n origin?: string | string[] | ((ctx: ShokupanContext) => string | undefined | null | boolean);\n methods?: string | string[];\n allowedHeaders?: string | string[];\n exposedHeaders?: string | string[];\n credentials?: boolean;\n maxAge?: number;\n}\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 = new Headers();\n const origin = ctx.headers.get(\"origin\");\n\n const set = (k: string, v: string) => headers.set(k, v);\n const append = (k: string, v: string) => headers.append(k, v);\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 && opts.origin.includes(origin)) {\n set(\"Access-Control-Allow-Origin\", origin);\n append(\"Vary\", \"Origin\");\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 for (const [key, value] of headers.entries()) {\n response.headers.set(key, value);\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 '../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}","import { plainToInstance } from \"class-transformer\";\nimport { validateOrReject } from \"class-validator\";\nimport { ShokupanContext } from \"../context\";\nimport type { Middleware } from \"../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 // 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 const req = ctx.req as any;\n\n // Check if already parsed\n if (req._bodyParsed) {\n return req._bodyValue;\n }\n\n try {\n let data: any;\n // Standard Request consumes stream\n // ShokupanRequest (internal) has properties\n if (typeof req.json === 'function') {\n data = await req.json();\n }\n else {\n // Fallback if req is plain object with body property (internal usage)\n data = req.body;\n if (typeof data === 'string') {\n try { data = JSON.parse(data); } catch { }\n }\n }\n\n // Cache it\n req._bodyParsed = true;\n req._bodyValue = data;\n\n // Monkey patch json() to return cached data\n // This ensures subsequent calls (e.g. in handlers) get the same data\n // and don't fail due to stream locked\n Object.defineProperty(req, 'json', {\n value: async () => req._bodyValue,\n configurable: true\n });\n\n return data;\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\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 if (ctx.app?.applicationConfig.hooks?.beforeValidate) {\n await ctx.app.applicationConfig.hooks.beforeValidate(ctx, dataToValidate);\n }\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 cached body with validated/sanitized version\n const req = ctx.req as any;\n req._bodyValue = validBody;\n\n // Ensure json() returns the validated body\n Object.defineProperty(req, 'json', {\n value: async () => validBody,\n configurable: true\n });\n\n (ctx as any).body = validBody; // Legacy/Convenience\n }\n\n // Call afterValidate Hook\n if (ctx.app?.applicationConfig.hooks?.afterValidate) {\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.applicationConfig.hooks.afterValidate(ctx, validatedData);\n }\n\n return next();\n };\n}\n","import Ajv from \"ajv\";\nimport addFormats from \"ajv-formats\";\nimport type { Middleware } from \"../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 for (const [path, { regex, paramNames }] of cache.paths) {\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 for (const [path, pathItem] of Object.entries(spec.paths || {})) {\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 for (const [method, operation] of Object.entries(pathItem as any)) {\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 (const param of parameters) {\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 { ApiReferenceConfiguration } from '@scalar/api-reference';\nimport type { OpenAPI } from '@scalar/openapi-types';\nimport { Eta } from 'eta';\nimport { OpenAPIAnalyzer } from '../analysis/openapi-analyzer';\nimport { ShokupanRouter } from '../router';\nimport type { DeepPartial } from '../types';\nimport { deepMerge } from '../util/deep-merge';\n\nconst eta = new Eta();\n\nexport type ScalarPluginOptions = {\n baseDocument?: DeepPartial<OpenAPI.Document>;\n config: Partial<ApiReferenceConfiguration>;\n enableStaticAnalysis?: boolean;\n};\n\nexport class ScalarPlugin extends ShokupanRouter<any> {\n constructor(\n private readonly pluginOptions: ScalarPluginOptions\n ) {\n super();\n this.init();\n }\n\n init() {\n this.get(\"/\", ctx => {\n let path = ctx.url.toString();\n if (!path.endsWith(\"/\")) path += \"/\";\n\n return ctx.html(eta.renderString(`<!doctype html>\n <html>\n <head>\n <title>API Reference</title>\n <meta charset = \"utf-8\" />\n <meta name=\"viewport\" content = \"width=device-width, initial-scale=1\" />\n </head>\n\n <body>\n <div id=\"app\"></div>\n\n <script src=\"<%= it.path %>scalar.js\"></script>\n <script>\n Scalar.createApiReference('#app', [{ ...<%~ JSON.stringify(it.config.baseDocument) %>,\n url: \"<%= it.path %>openapi.json\",\n }\n ])\n </script>\n </body>\n\n </html>`, { path, config: this.pluginOptions }));\n });\n\n this.get(\"/scalar.js\", (ctx) => {\n return ctx.file(__dirname + \"/../../node_modules/@scalar/api-reference/dist/browser/standalone.js\");\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 { ShokupanContext } from \"../context\";\nimport type { Middleware, NextFn } from \"../types\";\n\nexport interface SecurityHeadersOptions {\n contentSecurityPolicy?: boolean | Record<string, any>;\n crossOriginEmbedderPolicy?: boolean;\n crossOriginOpenerPolicy?: boolean;\n crossOriginResourcePolicy?: boolean;\n dnsPrefetchControl?: boolean | { allow: boolean; };\n expectCt?: boolean | { maxAge?: number, enforce?: boolean, reportUri?: string; };\n frameguard?: boolean | { action: 'deny' | 'sameorigin' | 'allow-from', domain?: string; };\n hidePoweredBy?: boolean;\n hsts?: boolean | { maxAge?: number, includeSubDomains?: boolean, preload?: boolean; };\n ieNoOpen?: boolean;\n noSniff?: boolean;\n originAgentCluster?: boolean;\n permittedCrossDomainPolicies?: boolean | { permittedPolicies: 'none' | 'master-only' | 'by-content-type' | 'all'; };\n referrerPolicy?: boolean | { policy: string | string[]; };\n xssFilter?: boolean;\n}\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 for (const [key, val] of Object.entries(opt)) {\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 for (const [k, v] of Object.entries(headers)) {\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 \"../types\";\n\n// --- Types ---\n\nexport interface SessionData {\n cookie: Cookie;\n [key: string]: any;\n}\n\nexport interface 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 priority?: 'low' | 'medium' | 'high';\n}\n\nexport interface SessionOptions {\n secret: string | string[];\n name?: string;\n store?: Store;\n cookie?: SessionCookieOptions;\n genid?: (ctx: ShokupanContext) => string;\n resave?: boolean;\n saveUninitialized?: boolean;\n rolling?: boolean;\n unset?: 'destroy' | 'keep';\n}\n\nexport interface Store extends EventEmitter {\n get(sid: string, callback: (err: any, session?: SessionData | null) => void): void;\n set(sid: string, session: SessionData, callback?: (err?: any) => void): void;\n destroy(sid: string, callback?: (err?: any) => void): void;\n touch?(sid: string, session: SessionData, callback?: (err?: any) => void): void;\n all?(callback: (err: any, obj?: { [sid: string]: SessionData; } | null) => void): void;\n length?(callback: (err: any, length?: number) => void): void;\n clear?(callback?: (err?: any) => void): void;\n load?(sid: string, fn: (err: any, session?: SessionData | null) => void): void;\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 && cb();\n }\n\n destroy(sid: string, cb?: (err?: any) => void) {\n delete this.sessions[sid];\n cb && 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 && cb();\n }\n\n all(cb: (err: any, obj?: { [sid: string]: SessionData; } | null) => void) {\n const result: Record<string, SessionData> = {};\n for (const sid in this.sessions) {\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 && 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 const expectedBuffer = Buffer.from(expectedInput);\n const inputBuffer = Buffer.from(input);\n if (expectedBuffer.length !== inputBuffer.length) return false;\n // timingSafeEqual\n // crypto.timingSafeEqual is available in node/bun\n const valid = require('crypto').timingSafeEqual(expectedBuffer, inputBuffer);\n return valid ? tentValue : false;\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\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 for (const key in sessObj) {\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 for (const key in sessObj) {\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":["RateLimitMiddleware","RouteParamType","Headers","context","OpenAPIAnalyzer","eta","readFile","tracer","defaults","resolve","sess","options"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/response.ts","../src/context.ts","../src/plugins/rate-limit.ts","../src/symbol.ts","../src/types.ts","../src/decorators.ts","../src/di.ts","../src/middleware.ts","../src/request.ts","../src/util/deep-merge.ts","../src/plugins/openapi.ts","../src/plugins/serve-static.ts","../src/router/trie.ts","../src/util/async-hooks.ts","../src/util/datastore.ts","../src/util/instrumentation.ts","../src/util/stack.ts","../src/router.ts","../src/util/cpu-monitor.ts","../src/shokupan.ts","../src/plugins/auth.ts","../src/plugins/compression.ts","../src/plugins/cors.ts","../src/plugins/express.ts","../src/plugins/validation.ts","../src/plugins/openapi-validator.ts","../src/plugins/scalar.ts","../src/plugins/security-headers.ts","../src/plugins/session.ts"],"sourcesContent":["\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","import type { BodyInit, Server } from 'bun';\nimport { readFile } from 'node:fs/promises';\nimport type { ShokupanRequest } from './request';\nimport { ShokupanResponse } from './response';\nimport type { Shokupan } from './shokupan';\nimport type { CookieOptions, JSXRenderer } from './types';\n\n// Shim for HeadersInit if not available globally in some envs\ntype HeadersInit = Headers | Record<string, string> | [string, string][];\n\n\nexport interface HandlerStackItem {\n name: string;\n file: string;\n line: number;\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\nexport class ShokupanContext<State extends Record<string, any> = Record<string, any>> {\n private _url: URL | undefined;\n public params: Record<string, string> = {}; // 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 constructor(\n public readonly request: ShokupanRequest<any>,\n public readonly server?: Server,\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 ) {\n this.state = state || {} as State;\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 const q: Record<string, any> = {};\n for (const [key, value] of this.url.searchParams) {\n if (q[key] === undefined) {\n q[key] = value;\n } else if (Array.isArray(q[key])) {\n q[key].push(value);\n } else {\n q[key] = [q[key], value];\n }\n }\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() { return this.url.hostname; }\n\n /**\n * Request host (e.g. \"localhost:3000\")\n */\n get host() { return this.url.host; }\n\n /**\n * Request protocol (e.g. \"http:\", \"https:\")\n */\n get protocol() { return this.url.protocol; }\n\n /**\n * Whether request is secure (https)\n */\n get secure() { return this.url.protocol === 'https:'; }\n\n /**\n * Request origin (e.g. \"http://localhost:3000\")\n */\n get origin() { return this.url.origin; }\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 * 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 /**\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 // 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 * Send a response\n * @param body Response body\n * @param options Response options\n * @returns Response\n */\n public send(body?: BodyInit, options?: ResponseInit) {\n const headers = this.mergeHeaders(options?.headers as any);\n const status = options?.status ?? this.response.status;\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 this._finalResponse = new Response(body, { status, headers });\n return this._finalResponse;\n }\n\n /**\n * Read request body\n */\n async body<T = any>(): Promise<T> {\n const contentType = this.request.headers.get(\"content-type\") || \"\";\n\n if (contentType.includes(\"application/json\") || contentType.includes(\"+json\")) {\n return this.request.json() as any;\n }\n if (contentType.includes(\"multipart/form-data\") || contentType.includes(\"application/x-www-form-urlencoded\")) {\n return this.request.formData() as any;\n }\n return this.request.text() as any;\n }\n\n /**\n * Respond with a JSON object\n */\n json(data: any, status?: number, headers?: HeadersInit) {\n const finalStatus = status ?? this.response.status;\n const jsonString = JSON.stringify(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 text(data: string, status?: number, headers?: HeadersInit) {\n const finalStatus = status ?? this.response.status;\n\n // Store raw body for compression middleware\n this._rawBody = data;\n\n // Fast path: no custom headers and no response headers set\n if (!headers && !this.response.hasPopulatedHeaders) {\n this._finalResponse = new Response(data, {\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(data, { status: finalStatus, headers: finalHeaders });\n return this._finalResponse;\n }\n\n /**\n * Respond with HTML content\n */\n html(html: string, status?: number, headers?: HeadersInit) {\n const finalStatus = status ?? this.response.status;\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;\n\n this._finalResponse = new Response(html, { status: finalStatus, headers: finalHeaders });\n return this._finalResponse;\n }\n\n /**\n * Respond with a redirect\n */\n redirect(url: string, status = 302) {\n const headers = this.mergeHeaders();\n headers.set('Location', url);\n this._finalResponse = new Response(null, { status, headers });\n return this._finalResponse;\n }\n\n /**\n * Respond with a status code\n * DOES NOT CHAIN!\n */\n status(status: number) {\n const headers = this.mergeHeaders();\n this._finalResponse = new Response(null, { status, headers });\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 headers = this.mergeHeaders(responseOptions?.headers as any);\n const status = responseOptions?.status ?? this.response.status;\n\n if (typeof Bun !== \"undefined\") {\n this._finalResponse = new Response(Bun.file(path, fileOptions), { status, headers });\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 headers.set('content-type', fileOptions.type);\n }\n\n this._finalResponse = new Response(fileBuffer, { status, headers });\n return this._finalResponse;\n }\n }\n\n /**\n * JSX Rendering Function\n */\n public renderer?: JSXRenderer;\n\n /**\n * Render a JSX element\n * @param element JSX Element\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 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 type { Middleware, NextFn } from \"../types\";\n\nexport interface RateLimitOptions {\n windowMs?: number;\n max?: number;\n limit?: number; // Alias for max\n message?: string | object;\n statusCode?: number;\n headers?: boolean;\n keyGenerator?: (ctx: ShokupanContext) => string;\n skip?: (ctx: ShokupanContext) => boolean;\n mode?: 'user' | 'absolute';\n}\n\ninterface HitRecord {\n hits: number;\n resetTime: number;\n}\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\n const keyGenerator = options.keyGenerator || ((ctx) => {\n if (mode === 'absolute') {\n return 'global';\n }\n // Use IP if available\n return ctx.headers.get(\"x-forwarded-for\") || ctx.request.headers.get(\"x-forwarded-for\") || (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 for (const [key, record] of hits.entries()) {\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 // Dispatch 429\n const body = typeof message === 'object' ? JSON.stringify(message) : String(message);\n const res = typeof message === 'object' ? ctx.json(message, statusCode) : ctx.text(String(message), 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","export const $isApplication = Symbol.for(\"Shokupan.app\");\nexport const $appRoot = Symbol.for(\"Shokupan.app-root\");\nexport const $isMounted = Symbol(\"Shokupan.isMounted\");\nexport const $routeMethods = Symbol(\"Shokupan.routeMethods\");\nexport const $routeArgs = Symbol(\"Shokupan.routeArgs\");\nexport const $controllerPath = Symbol(\"Shokupan.controllerPath\");\nexport const $middleware = Symbol(\"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\");","import type { OpenAPI } from '@scalar/openapi-types';\nimport type { Server } from 'bun';\nimport type { Server as NodeServer } from 'node:http';\nimport type { ShokupanContext } from './context';\nimport { $isRouter } from \"./symbol\";\n\nexport type DeepPartial<T> = T extends Function ? T : T extends object ? {\n [P in keyof T]?: DeepPartial<T[P]>;\n} : T;\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\nexport interface ShokupanHooks<T = any> {\n onError?: (error: unknown, ctx: ShokupanContext<T>) => 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<T extends Record<string, any> = Record<string, any>> = (ctx: ShokupanContext<T>, next?: NextFn) => Promise<any> | any;\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 | Promise<Server> | 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 */\n controllersOnly: boolean;\n\n /**\n * Whether to enable automatic backpressure based on system CPU load.\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;\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\nexport type ShokupanConfig<T extends Record<string, any> = Record<string, any>> = DeepPartial<{\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 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 * 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 * @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 * 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 */\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 */\n serverFactory: ServerFactory;\n\n /**\n * Lifecycle hooks.\n */\n hooks: ShokupanHooks<T> | ShokupanHooks<T>[];\n\n\n // Open for extension\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 * @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","import { RateLimitMiddleware, type RateLimitOptions } from \"./plugins/rate-limit\";\nimport { $controllerPath, $middleware, $routeArgs, $routeMethods, $routeSpec } from \"./symbol\";\nimport type { 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) {\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 });\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: Applies a rate limit to a class or method.\n */\nexport function RateLimit(options: RateLimitOptions) {\n return Use(RateLimitMiddleware(options));\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 type { ShokupanContext } from \"./context\";\nimport type { Middleware, NextFn } from './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","import type { Method } from './types';\n\nexport type ShokupanRequestProps = {\n method: Method;\n url: string;\n headers: Headers;\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","/**\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 for (const key in source) {\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","import type { ShokupanRouter } from '../router';\nimport { $childControllers, $childRouters, $mountPath, $routes } from '../symbol';\nimport type { OpenAPIOptions, ShokupanHandler } from '../types';\nimport { deepMerge } from '../util/deep-merge';\n\n/**\n * Analyze a handler function to infer request/response types\n */\nconst REGEX_QUERY_INT = /parseInt\\(ctx\\.query\\.(\\w+)\\)/g;\nconst REGEX_QUERY_FLOAT = /parseFloat\\(ctx\\.query\\.(\\w+)\\)/g;\nconst REGEX_QUERY_NUMBER = /Number\\(ctx\\.query\\.(\\w+)\\)/g;\nconst REGEX_QUERY_BOOL = /(?:Boolean\\(ctx\\.query\\.(\\w+)\\)|!+ctx\\.query\\.(\\w+))/g;\nconst REGEX_QUERY_GENERIC = /ctx\\.query\\.(\\w+)/g;\nconst REGEX_PARAM_INT = /parseInt\\(ctx\\.params\\.(\\w+)\\)/g;\nconst REGEX_PARAM_FLOAT = /parseFloat\\(ctx\\.params\\.(\\w+)\\)/g;\nconst REGEX_PARAM_GENERIC = /ctx\\.params\\.(\\w+)/;\nconst REGEX_HEADER_GET = /ctx\\.get\\(['\"](\\w+)['\"]\\)/g;\nconst REGEX_ERROR_STATUS = /ctx\\.(?:json|text|html)\\([^)]+,\\s*(\\d{3,})\\)/g;\n\n/**\n * Analyze a handler function to infer request/response types\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 // Query Integers\n for (const match of handlerSource.matchAll(REGEX_QUERY_INT)) {\n if (match[1]) queryParams.set(match[1], { type: 'integer', format: 'int32' });\n }\n\n // Query Floats\n for (const match of handlerSource.matchAll(REGEX_QUERY_FLOAT)) {\n if (match[1]) queryParams.set(match[1], { type: 'number', format: 'float' });\n }\n\n // Query Numbers\n for (const match of handlerSource.matchAll(REGEX_QUERY_NUMBER)) {\n if (match[1] && !queryParams.has(match[1])) {\n queryParams.set(match[1], { type: 'number' });\n }\n }\n\n // Query Booleans\n for (const match of handlerSource.matchAll(REGEX_QUERY_BOOL)) {\n const name = match[1] || match[2];\n if (name && !queryParams.has(name)) {\n queryParams.set(name, { type: 'boolean' });\n }\n }\n\n // Generic Query Strings\n for (const match of handlerSource.matchAll(REGEX_QUERY_GENERIC)) {\n const name = match[1];\n if (name && !queryParams.has(name)) {\n queryParams.set(name, { type: 'string' });\n }\n }\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\n // Path Integers\n for (const match of handlerSource.matchAll(REGEX_PARAM_INT)) {\n if (match[1]) pathParams.set(match[1], { type: 'integer', format: 'int32' });\n }\n\n // Path Floats\n for (const match of handlerSource.matchAll(REGEX_PARAM_FLOAT)) {\n if (match[1]) pathParams.set(match[1], { type: 'number', format: 'float' });\n }\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 for (const match of handlerSource.matchAll(REGEX_HEADER_GET)) {\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 response',\n content: { 'text/html': { schema: { type: 'string' } } }\n };\n }\n\n if (handlerSource.includes('ctx.text(')) {\n responses['200'] = {\n description: 'Successful 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 responses['302'] = { description: 'Redirect' };\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 for (const match of handlerSource.matchAll(REGEX_ERROR_STATUS)) {\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 * 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 // Step 4: Run AST Analysis if possible\n let astRoutes: any[] = [];\n try {\n // Dynamic import to avoid bundling issues if strictly runtime\n const { OpenAPIAnalyzer } = await import('../analysis/openapi-analyzer');\n const analyzer = new OpenAPIAnalyzer(process.cwd());\n const { applications } = await analyzer.analyze();\n\n // Create a map for easy lookup of apps by name/class\n const appMap = new Map<string, any>();\n applications.forEach(app => {\n appMap.set(app.name, app);\n // Also map by direct className if it's unique enough (heuristic)\n if (app.name !== app.className) {\n appMap.set(app.className, app);\n }\n });\n\n const getExpandedRoutes = (app: any, prefix: string = '', seen = new Set<string>()): any[] => {\n // Prevent infinite recursion in cyclic mounts\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 // Add app's own routes with accumulated prefix\n for (const route of app.routes) {\n const cleanPrefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;\n const cleanPath = route.path.startsWith('/') ? route.path : '/' + route.path;\n let joined = cleanPrefix + cleanPath;\n if (joined.length > 1 && joined.endsWith('/')) {\n joined = joined.slice(0, -1);\n }\n\n expanded.push({\n ...route,\n path: joined || '/'\n });\n }\n\n // Recurse into mounted apps\n if (app.mounted) {\n for (const mount of app.mounted) {\n const targetApp = appMap.get(mount.target);\n if (targetApp) {\n const cleanPrefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;\n const mountPrefix = mount.prefix.startsWith('/') ? mount.prefix : '/' + mount.prefix;\n expanded.push(...getExpandedRoutes(targetApp, cleanPrefix + mountPrefix, newSeen));\n }\n }\n }\n return expanded;\n };\n\n // Expand routes for all applications\n // This generates variants: e.g. UserController at '/' AND Main->UserController at '/api/user'\n applications.forEach(app => {\n astRoutes.push(...getExpandedRoutes(app));\n });\n\n // Deduplicate AST Routes with Scoring\n // Prioritize: 1. Has Response Schema, 2. Has Handler Source\n const dedupedRoutes = new Map<string, { route: any, score: number; }>();\n\n for (const route of astRoutes) {\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 // Prefer longer/specific paths? No, exact path matching handles that.\n\n if (!dedupedRoutes.has(key) || score > dedupedRoutes.get(key)!.score) {\n dedupedRoutes.set(key, { route, score });\n }\n }\n\n astRoutes = Array.from(dedupedRoutes.values()).map(v => v.route);\n\n } catch (e) {\n console.warn(\"OpenAPI AST analysis failed or skipped:\", e);\n }\n\n const collect = (router: ShokupanRouter<T>, prefix = \"\", currentGroup = defaultTagGroup, defaultTag = defaultTagName) => {\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 if (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 if (!tagGroups.has(group)) tagGroups.set(group, new Set());\n\n const routes = (router as any)[$routes] || [];\n // console.log(`[OpenAPI] Visiting router with ${routes.length} routes. Config:`, router.config, \"Prefix:\", prefix);\n // Debug symbols\n // console.log('[OpenAPI] Router keys:', Reflect.ownKeys(router).map(k => k.toString()));\n // console.log('[OpenAPI] Local $routes symbol:', $routes.toString());\n\n for (const route of routes) {\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 fullPath = fullPath.replace(/:([a-zA-Z0-9_]+)/g, \"{$1}\");\n\n // Normalize trailing slash\n if (fullPath.length > 1 && fullPath.endsWith('/')) {\n fullPath = fullPath.slice(0, -1);\n }\n\n if (!paths[fullPath]) paths[fullPath] = {};\n\n // Initialize operation structure\n const operation: any = {\n responses: { '200': { description: \"Successful response\" } },\n tags: [tag]\n };\n\n // Merge metadata from guards (if any)\n if (route.guards) {\n for (const guard of route.guards) {\n if (guard.spec) {\n // Merge security (deduplicated)\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 // Merge responses\n if (guard.spec.responses) {\n operation.responses = { ...operation.responses, ...guard.spec.responses };\n }\n }\n }\n }\n\n // --- Step 4: Base Data from AST ---\n\n // 1. Exact Match (Method + Path)\n let astMatch = astRoutes.find(r =>\n r.method.toUpperCase() === route.method.toUpperCase() &&\n r.path === fullPath\n );\n\n // 2. Fallback: Match by Handler Source (ignores Path mismatch due to mounting prefixes)\n if (!astMatch) {\n let runtimeSource = route.handler.toString();\n if ((route.handler as any).originalHandler) {\n runtimeSource = (route.handler as any).originalHandler.toString();\n }\n\n const runtimeHandlerSrc = runtimeSource.replace(/\\s+/g, ' ');\n\n // Filter all AST routes with same method\n const sameMethodRoutes = astRoutes.filter(r => r.method.toUpperCase() === route.method.toUpperCase());\n\n // Find one that matches source\n astMatch = sameMethodRoutes.find(r => {\n const astHandlerSrc = (r.handlerSource || r.handlerName || '').replace(/\\s+/g, ' ');\n if (!astHandlerSrc || astHandlerSrc.length < 20) return false;\n\n const match = runtimeHandlerSrc.includes(astHandlerSrc) ||\n astHandlerSrc.includes(runtimeHandlerSrc) ||\n (r.handlerSource && runtimeHandlerSrc.includes(r.handlerSource.substring(0, 50)));\n\n return match;\n });\n }\n\n\n // Disambiguate if multiple routes share the same path/method\n const potentialMatches = astRoutes.filter(r =>\n r.method.toUpperCase() === route.method.toUpperCase() &&\n r.path === fullPath\n );\n\n if (potentialMatches.length > 1) {\n const runtimeHandlerSrc = route.handler.toString().replace(/\\s+/g, ' ');\n\n // Try to find the best match by checking if AST handler snippet is in Runtime handler source\n const preciseMatch = potentialMatches.find(r => {\n const astHandlerSrc = (r.handlerSource || r.handlerName || '').replace(/\\s+/g, ' ');\n\n // Relaxed matching: check if ONE includes the other (source code containment)\n const match = runtimeHandlerSrc.includes(astHandlerSrc) || astHandlerSrc.includes(runtimeHandlerSrc) ||\n (r.handlerSource && runtimeHandlerSrc.includes(r.handlerSource.substring(0, 50)));\n\n return match;\n });\n\n if (preciseMatch) {\n astMatch = preciseMatch;\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 // Merge Request Body\n if (astMatch.requestTypes?.body) {\n operation.requestBody = {\n content: {\n 'application/json': { schema: astMatch.requestTypes.body }\n }\n };\n }\n\n // Merge Responses\n if (astMatch.responseSchema) {\n operation.responses['200'] = {\n description: 'Successful response',\n content: {\n 'application/json': { schema: astMatch.responseSchema }\n }\n };\n }\n else if (astMatch.responseType) {\n const contentType = astMatch.responseType === 'string' ? 'text/plain' : 'application/json';\n operation.responses['200'] = {\n description: 'Successful response',\n content: {\n [contentType]: { schema: { type: astMatch.responseType } }\n }\n };\n }\n\n // Merge Parameters (Query, Path, Header) from AST\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\n if (params.length > 0) {\n operation.parameters = params;\n }\n }\n\n // --- Step 5: Decorators / Path Patterns (Runtime) ---\n\n // Path Keys (e.g. /users/:id)\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 // Merge into existing parameters\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 (analyzeHandler)\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 // Merge metadata from runtime route definition (Manual override)\n if (route.handlerSpec) {\n const spec = route.handlerSpec;\n if (spec.summary) operation.summary = spec.summary;\n if (spec.description) operation.description = spec.description;\n if (spec.operationId) operation.operationId = spec.operationId;\n if (spec.tags) operation.tags = spec.tags;\n if (spec.security) operation.security = spec.security;\n\n // Merge responses\n if (spec.responses) {\n operation.responses = { ...operation.responses, ...spec.responses };\n }\n }\n\n // Apply tags\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 }\n else {\n paths[fullPath][methodLower] = operation;\n }\n };\n\n for (const controller of router[$childControllers]) {\n const controllerName = controller.constructor.name || \"UnknownController\";\n tagGroups.get(group)?.add(controllerName);\n }\n\n for (const child of router[$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 collect(child, nextPrefix, group, tag);\n }\n };\n\n collect(rootRouter);\n\n const xTagGroups: { name: string; tags: string[]; }[] = [];\n for (const [name, tags] of tagGroups) {\n xTagGroups.push({ name, tags: Array.from(tags).sort() });\n }\n\n return {\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 };\n}\n","import { Eta } from 'eta';\nimport { readdir, readFile, stat } from 'fs/promises';\nimport { basename, join, resolve } from 'path';\nimport type { ShokupanContext } from '../context';\nimport type { Middleware, StaticServeOptions } from '../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 // Decode URI components\n relative = decodeURIComponent(relative);\n\n // Security: Prevent directory traversal\n const requestPath = join(rootPath, relative);\n if (!requestPath.startsWith(rootPath)) {\n return ctx.json({ error: 'Forbidden' }, 403);\n }\n\n // check if path includes null byte\n if (requestPath.includes('\\0')) {\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 (const pattern of config.exclude) {\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 (const ext of config.extensions) {\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 (const idx of indexes) {\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);\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","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 (const segment of segments) {\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","\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport const asyncContext = new AsyncLocalStorage<Map<string, any>>();\n\nexport function runInContext<T>(callback: () => T, initialStore = new Map<string, any>()): T {\n return asyncContext.run(initialStore, callback);\n}\n","import { createNodeEngines } from '@surrealdb/node';\nimport { RecordId, Surreal } from 'surrealdb';\n\nconst engine = process.env['SHOKUPAN_DB_ENGINE'] === 'memory' ? 'mem://' : 'rocksdb://database';\n\nconst db = new Surreal({\n engines: createNodeEngines(),\n});\n\nconst ready = db.connect(engine, { namespace: \"vendor\", database: \"shokupan\" }).then(() => {\n // Define the tables with bare minimum schema\n return 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 `);\n});\n\nexport const datastore = {\n get<T extends Record<string, any>>(store: string, key: string) {\n return db.select<T>(new RecordId(store, key));\n },\n set(store: string, key: string, value: any) {\n return db.create(new RecordId(store, key)).content(value);\n },\n async query(query: string, vars?: Record<string, unknown>) {\n try {\n // console.error(\"DS QUERY:\", query);\n const r = await db.query(query, vars).collect<any>();\n // console.error(\"DS RESULT:\", JSON.stringify(r));\n return r;\n } catch (e) {\n console.error(\"DS ERROR:\", e);\n throw e;\n }\n },\n ready\n};\n\nprocess.on(\"exit\", async () => {\n await db.close();\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 // Index 0: Error\n // Index 1: getCallerInfo (this function)\n // Index 2: caller (or whatever calls this)\n\n // So we scan starting from a reasonable offset\n\n // However, stack trace format depends on many things. \n // A more robust way is to just look for the first line that ISN'T internal.\n\n // Filter out this file itself if possible, but identifying \"this file\" is tricky without context.\n // So we rely on skipFrames OR we filter known internal files.\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('src/util/stack.ts')) continue; // Ignore self\n if (l.includes('src/router.ts')) continue; // Ignore router internals\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 { ShokupanContext } from './context';\nimport { Container } from './di';\nimport { compose } from './middleware';\nimport { generateOpenApi } from './plugins/openapi';\nimport { serveStatic } from './plugins/serve-static';\nimport { ShokupanRequest } from './request';\nimport { RouterTrie } from './router/trie';\nimport type { Shokupan } from './shokupan';\nimport { $appRoot, $childControllers, $childRouters, $controllerPath, $dispatch, $isApplication, $isMounted, $isRouter, $middleware, $mountPath, $parent, $routeArgs, $routeMethods, $routes, $routeSpec } from './symbol';\n\nimport { type GuardAPISpec, HTTPMethods, type JSXRenderer, type Method, type MethodAPISpec, type Middleware, type OpenAPIOptions, type ProcessResult, type RequestOptions, type RouteMetadata, RouteParamType, type ShokupanController, type ShokupanHandler, type ShokupanHooks, type ShokupanRoute, type ShokupanRouteConfig, type StaticServeOptions } from './types';\nimport { asyncContext } from './util/async-hooks';\nimport { datastore } from './util/datastore';\nimport { traceHandler } from './util/instrumentation';\nimport { getCallerInfo } from './util/stack';\n\n\n// Shim for HeadersInit if not available globally\ntype HeadersInit = Headers | Record<string, string> | [string, string][];\n\n\nexport const RouterRegistry = new Map<string, ShokupanRouter<any>>();\n\nexport const ShokupanApplicationTree = {};\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 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\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 } {\n // Separation logic: Group routes by controller instance\n const controllerRoutesMap = new Map<any, any[]>();\n const localRoutes: any[] = [];\n\n for (const r of this[$routes]) {\n const entry = {\n type: 'route' as 'route',\n 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],\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 return {\n metadata: this.metadata,\n middleware,\n routes: localRoutes,\n routers,\n controllers\n };\n }\n\n constructor(\n public readonly config?: ShokupanRouteConfig\n ) {\n if (config?.requestTimeout) {\n this.requestTimeout = config.requestTimeout;\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 * 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 if (controller[$isMounted]) {\n throw new Error(\"Router is already mounted\");\n }\n\n controller[$mountPath] = prefix;\n\n // Capture mount location if not already present (create new router usually has it? no)\n if (!controller.metadata) {\n const info = getCallerInfo();\n controller.metadata = {\n file: info.file,\n line: info.line,\n name: 'MountedRouter'\n };\n }\n this[$childRouters].push(controller);\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 controller[$parent] = this;\n\n const setRouterContext = (router: ShokupanRouter<T>) => {\n router[$appRoot] = this.root;\n router[$childRouters].forEach((child) => setRouterContext(child));\n };\n setRouterContext(controller);\n\n\n // If the controller is the root router\n if (this[$appRoot]) {\n // TODO:\n }\n controller[$appRoot] = this.root;\n controller[$isMounted] = true;\n }\n // Controller is an arbitrary class\n else {\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) {\n // Combine mount prefix + controller path\n // mount('/api', Ctrl) + @Controller('/users') -> /api/users\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) {\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 this[$childControllers].push(instance as any);\n\n // Get Middleware for Controller\n // It could be on the Constructor (if passed as class) or Instance (if passed as object and manually set?)\n // Usually decorators set it on Constructor.\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 && 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\n let routesAttached = 0;\n for (const name of Array.from(methods)) {\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 if (decoratedRoutes && decoratedRoutes.has(name)) {\n const config = decoratedRoutes.get(name);\n method = config.method;\n subPath = config.path;\n }\n // 2. Fallback to Convention\n else {\n // Simple convention matching\n // Check if name starts with HTTP verb\n for (const m of HTTPMethods) {\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 // Existing parsing logic...\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 // Revised simple loop\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 if (method) {\n routesAttached++;\n // Remove trailing slash from prefix if needed, combine with subPath\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\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]; // Default to just context if no decorators\n\n if (routeArgs?.length > 0) {\n args = [];\n // Sort by index\n const sortedArgs = [...routeArgs].sort((a, b) => a.index - b.index);\n\n // Fill args array\n for (const arg of sortedArgs) {\n switch (arg.type) {\n case RouteParamType.BODY:\n try {\n if (ctx.req.headers.get(\"content-type\")?.includes(\"application/json\")) {\n args[arg.index] = await ctx.req.json();\n } else {\n // Fallback or empty if not JSON? \n // If @Body is used, valid JSON is expected.\n // If empty body, json() throws.\n const text = await ctx.req.text();\n if (!text) {\n args[arg.index] = {};\n } else {\n args[arg.index] = JSON.parse(text);\n }\n }\n } catch (e) {\n const err: any = new Error(\"Invalid JSON body\");\n err.status = 400;\n throw err;\n }\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 for (const key of url.searchParams.keys()) {\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 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 // Expose original handler for OpenAPI analysis\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 this.add({ method, path: normalizedPath, handler: finalHandler, spec, controller: instance });\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 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 (const child of this[$childRouters]) {\n const childRoutes = child.getRoutes();\n for (const route of childRoutes) {\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 a sub request to this router.\n * This is useful for triggering other methods or route handlers. \n * @param options The request options.\n * @returns The response.\n */\n public async subRequest(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 const store = asyncContext.getStore();\n const originalReq = store?.get(\"req\") as ShokupanRequest<T>;\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 directly.\n */\n public async processRequest(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 for (const [k, v] of Object.entries(options.query)) {\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 = 200;\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 = err.status || err.statusCode || 500;\n result = { error: err.message || \"Internal Server Error\" };\n if (err.errors) result.errors = err.errors;\n }\n }\n else {\n status = 404;\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 applyRouterHooks(match: { handler: ShokupanHandler<T>; params: Record<string, string>; }) {\n if (!this.config?.hooks) return match;\n const hooks = this.config.hooks;\n // Re-use static helper or method to avoid code duplication with add()\n return {\n ...match,\n handler: this.wrapWithHooks(match.handler, hooks)\n };\n }\n\n private wrapWithHooks(handler: ShokupanHandler<T>, hooks: ShokupanHooks | ShokupanHooks[]) {\n const hookList = Array.isArray(hooks) ? hooks : [hooks];\n\n // Optimize: Check if any relevant hooks are actually defined\n const hasStart = hookList.some(h => !!h.onRequestStart);\n const hasEnd = hookList.some(h => !!h.onRequestEnd);\n const hasError = hookList.some(h => !!h.onError);\n\n if (!hasStart && !hasEnd && !hasError) return handler;\n\n const originalHandler = handler;\n\n const wrapped = async (ctx: ShokupanContext<T>) => {\n if (hasStart) {\n for (let i = 0; i < hookList.length; i++) {\n const h = hookList[i];\n if (typeof h.onRequestStart === 'function') await h.onRequestStart(ctx);\n }\n }\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 for (let i = 0; i < hookList.length; i++) {\n const h = hookList[i];\n if (typeof h.onRequestEnd === 'function') await h.onRequestEnd(ctx);\n }\n return res;\n } catch (err) {\n debug?.trackStep(debugId, 'handler', performance.now() - start, 'error', err);\n\n for (let i = 0; i < hookList.length; i++) {\n const h = hookList[i];\n if (typeof h.onError === 'function') await h.onError(err, ctx);\n }\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 /**\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 (const child of this[$childRouters]) {\n const prefix = child[$mountPath];\n // console.log(` -> Checking child prefix ${prefix}`);\n\n if (path === prefix || path.startsWith(prefix + \"/\")) {\n const subPath = path.slice(prefix.length) || \"/\";\n const match = child.find(method, subPath);\n if (match) return this.applyRouterHooks(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 this.applyRouterHooks(match);\n }\n }\n }\n\n return null; // Not found\n }\n\n private parsePath(path: string): { regex: RegExp; keys: string[]; } {\n const keys: string[] = [];\n const pattern = path\n .replace(/:([a-zA-Z0-9_]+)/g, (_, key) => {\n keys.push(key);\n return \"([^/]+)\";\n })\n .replace(/\\*\\*/g, \".*\") // Recursive wildcard\n .replace(/\\*/g, \"[^/]+\"); // Single segment wildcard\n\n return {\n regex: new RegExp(`^${pattern}$`),\n keys\n };\n }\n\n // --- Functional Routing ---\n\n public requestTimeout?: number;\n\n /**\n * Adds a route to the router.\n * \n * @param method - HTTP method\n * @param path - URL path\n * @param spec - OpenAPI specification for the route\n * @param handler - Route handler function\n * @param requestTimeout - Timeout for this route in milliseconds\n */\n public add({ method, path, spec, handler, regex: customRegex, group, requestTimeout, renderer, controller }: {\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 }) {\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 (const guard of this.currentGuards) {\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 = 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 (const guard of routeGuards) {\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.renderer = effectiveRenderer;\n return innerHandler(ctx);\n };\n }\n\n // --- Middleware Tracking Logic ---\n const { file, line } = getCallerInfo();\n\n const trackingHandler = wrappedHandler;\n wrappedHandler = async (ctx: ShokupanContext<T>) => {\n // Optimization: Skip all tracking overhead if disabled\n if (!ctx.app?.applicationConfig.enableMiddlewareTracking) {\n return trackingHandler(ctx);\n }\n\n const startTime = performance.now();\n let error: any = undefined;\n\n try {\n if (ctx.app?.applicationConfig.enableMiddlewareTracking) {\n ctx.handlerStack.push({\n name: handler.name || 'anonymous',\n file,\n line\n });\n }\n return await trackingHandler(ctx);\n } catch (e) {\n error = e;\n throw e; // Bubble up to error hook\n } finally {\n // Store in datastore after execution (non-blocking)\n if (ctx.app?.applicationConfig.enableMiddlewareTracking) {\n const duration = performance.now() - startTime;\n const config = ctx.app.applicationConfig;\n\n // Execute datastore operations in background without blocking response\n Promise.resolve().then(async () => {\n try {\n const timestamp = Date.now();\n const key = `${timestamp}-${handler.name || 'anonymous'}-${Math.random().toString(36).substring(7)}`;\n\n await datastore.set('middleware_tracking', key, {\n name: handler.name || 'anonymous',\n path: ctx.path,\n timestamp,\n duration,\n file,\n line,\n error: error ? String(error) : undefined,\n metadata: {\n isBuiltin: (handler as any).isBuiltin,\n pluginName: (handler as any).pluginName\n }\n });\n\n // Cleanup old entries based on TTL and capacity\n const ttl = config.middlewareTrackingTTL ?? 86400000; // 1 day default\n const maxCapacity = config.middlewareTrackingMaxCapacity ?? 10000;\n const cutoff = Date.now() - ttl;\n\n // Delete entries older than TTL\n await datastore.query(`DELETE middleware_tracking WHERE timestamp < ${cutoff}`);\n\n // Enforce capacity limit\n const results = await datastore.query('SELECT count() FROM middleware_tracking GROUP ALL');\n if (results && results[0] && results[0].count > maxCapacity) {\n const toDelete = results[0].count - maxCapacity;\n await datastore.query(`DELETE middleware_tracking ORDER BY timestamp ASC LIMIT ${toDelete}`);\n }\n } catch (datastoreError) {\n // Silently fail datastore operations to not break request flow\n console.error('Failed to store middleware tracking:', datastoreError);\n }\n });\n }\n }\n };\n (wrappedHandler as any).originalHandler = (trackingHandler as any).originalHandler || trackingHandler;\n\n // Bake in Hooks if present (Optimization)\n let bakedHandler = wrappedHandler;\n if (this.config?.hooks) {\n bakedHandler = this.wrapWithHooks(wrappedHandler, this.config.hooks);\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 });\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 handler - Route handler function \n */\n public get(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 handler - Route handler function \n */\n public post(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 handler - Route handler function \n */\n public put(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 handler - Route handler function \n */\n public delete(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 handler - Route handler function \n */\n public patch(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 handler - Route handler function \n */\n public options(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 handler - Route handler function \n */\n public head(path: string, ...handlers: ShokupanHandler<T>[]);\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: string, spec: MethodAPISpec, ...handlers: ShokupanHandler<T>[]);\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 const match = callerLine.match(/\\((.*):(\\d+):(\\d+)\\)/) || callerLine.match(/at (.*):(\\d+):(\\d+)/);\n if (match) {\n file = match[1];\n line = parseInt(match[2], 10);\n }\n }\n } catch (e) { }\n\n const trackedGuard = async (ctx: ShokupanContext<T>, next?: any) => {\n if (ctx.app?.applicationConfig.enableMiddlewareTracking) {\n ctx.handlerStack.push({\n name: guardHandler.name || 'guard',\n file,\n line\n });\n }\n return guardHandler(ctx, next);\n };\n (trackedGuard as any).originalHandler = (guardHandler as any).originalHandler || guardHandler;\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]; // Last handler is the main handler?\n // Wait, compose logic: \n // If we have [m1, m2, h], we want m1 -> m2 -> h.\n // compose([m1, m2, h]) does exactly that.\n // However, middleware returns `Promise<any>`.\n // If `handlers.length > 1`, we wrap them.\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 // if (spec) {\n // console.log(`[Router] attachVerb ${method} ${path} has spec:`, spec);\n // } \n // else {\n // console.log(`[Router] attachVerb ${method} ${path} NO SPEC`);\n // }\n\n this.add({\n method,\n path,\n spec,\n handler: finalHandler\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 = {}): any {\n return generateOpenApi(this, options);\n }\n}\n","import * as os from 'node:os';\n\nexport class SystemCpuMonitor {\n private interval: Timer | null = null;\n private lastCpus: os.CpuInfo[] = [];\n private currentUsage: number = 0;\n\n constructor(private readonly intervalMs: number = 1000) { }\n\n public start() {\n if (this.interval) return;\n this.lastCpus = os.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 const cpus = os.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 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 \"./util/instrumentation\";\n\nimport { context, trace } from '@opentelemetry/api';\nimport { ShokupanContext } from \"./context\";\nimport { compose } from \"./middleware\";\nimport { generateOpenApi } from \"./plugins/openapi\";\nimport { ShokupanRequest } from './request';\nimport { ShokupanRouter } from \"./router\";\nimport { $appRoot, $dispatch, $isApplication } from './symbol';\nimport type { Method, Middleware, ProcessResult, RequestOptions, ShokupanConfig, ShokupanHooks } from './types';\nimport { asyncContext } from \"./util/async-hooks\";\n\n\nimport type { Server } from 'bun';\nimport { SystemCpuMonitor } from \"./util/cpu-monitor\";\nimport { getCallerInfo } from './util/stack';\n\n\nconst defaults: ShokupanConfig = {\n port: 3000,\n hostname: \"localhost\",\n development: process.env.NODE_ENV !== \"production\",\n enableAsyncLocalStorage: false,\n reusePort: false,\n};\nconst tracer = trace.getTracer(\"shokupan.application\");\n\n\nexport class Shokupan<T = any> extends ShokupanRouter<T> {\n readonly applicationConfig: ShokupanConfig = {};\n public openApiSpec?: any;\n private composedMiddleware?: Middleware;\n private cpuMonitor?: SystemCpuMonitor;\n\n private hookCache = new Map<keyof ShokupanHooks, Function[]>();\n private hooksInitialized = false;\n\n get logger() {\n return this.applicationConfig.logger;\n }\n\n constructor(\n applicationConfig: ShokupanConfig = {}\n ) {\n const config = Object.assign({}, defaults, applicationConfig);\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);\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\n /**\n * Adds middleware to the application.\n */\n public use(middleware: Middleware) {\n let trackedMiddleware = middleware;\n\n // --- Middleware Tracking Logic ---\n const { file, line } = getCallerInfo();\n\n // Store metadata on the original middleware function if possible\n if (!(middleware as any).metadata) {\n (middleware as any).metadata = {\n file,\n line,\n name: middleware.name || 'middleware',\n isBuiltin: (middleware as any).isBuiltin,\n pluginName: (middleware as any).pluginName\n };\n }\n\n // Create wrapper but preserve metadata for registry\n trackedMiddleware = async (ctx, next) => {\n // Cast to any to access handlerStack if types are strict, but ShokupanContext should have it.\n const c = ctx as any;\n if (c.handlerStack && c.app?.applicationConfig.enableMiddlewareTracking) {\n const metadata = (middleware as any).metadata || {};\n const start = performance.now();\n const item = {\n name: metadata.pluginName ? `${metadata.pluginName} (${metadata.name})` : metadata.name || middleware.name || 'middleware',\n file: metadata.file || file,\n line: metadata.line || line,\n isBuiltin: metadata.isBuiltin,\n startTime: start,\n duration: -1\n };\n c.handlerStack.push(item);\n\n try {\n return await middleware(ctx, next);\n } finally {\n item.duration = performance.now() - start;\n }\n }\n return middleware(ctx, next);\n };\n (trackedMiddleware as any).metadata = (middleware as any).metadata;\n Object.defineProperty(trackedMiddleware, 'name', { value: (middleware as any).name || 'middleware' });\n\n (trackedMiddleware as any).order = this.middleware.length;\n this.middleware.push(trackedMiddleware);\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) {\n throw new Error(\"Invalid port number\");\n }\n\n // Run startup hooks\n for (const hook of this.startupHooks) {\n await hook();\n }\n\n if (this.applicationConfig.enableOpenApiGen) {\n this.openApiSpec = await generateOpenApi(this);\n // Run spec available hooks\n for (const hook of this.specAvailableHooks) {\n await hook(this.openApiSpec);\n }\n }\n\n if (port === 0 && process.platform === \"linux\") {\n\n }\n\n\n if (this.applicationConfig.autoBackpressureFeedback) {\n this.cpuMonitor = new SystemCpuMonitor();\n this.cpuMonitor.start();\n }\n\n const serveOptions = {\n\n port: finalPort,\n hostname: this.applicationConfig.hostname,\n development: this.applicationConfig.development,\n fetch: this.fetch.bind(this),\n reusePort: this.applicationConfig.reusePort,\n idleTimeout: this.applicationConfig.readTimeout ? this.applicationConfig.readTimeout / 1000 : undefined,\n websocket: {\n open(ws) {\n ws.data?.handler?.open?.(ws);\n },\n message(ws, message) {\n ws.data?.handler?.message?.(ws, message);\n },\n drain(ws) {\n ws.data?.handler?.drain?.(ws);\n },\n close(ws, code, reason) {\n ws.data?.handler?.close?.(ws, code, reason);\n },\n }\n };\n\n\n\n let factory = this.applicationConfig.serverFactory;\n\n // Detect if we are not running on Bun\n // @ts-ignore\n if (!factory && typeof Bun === \"undefined\") {\n const { createHttpServer } = await import(\"./plugins/server-adapter\");\n factory = createHttpServer();\n }\n\n const server = factory\n ? await factory(serveOptions)\n : Bun.serve(serveOptions);\n\n console.log(`Shokupan server listening on http://${serveOptions.hostname}:${serveOptions.port}`);\n return server;\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 processRequest(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 for (const [k, v] of Object.entries(options.query)) {\n u.searchParams.set(k, v);\n }\n url = u.toString();\n }\n\n // Create Request to pass to fetch\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 }) 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): Promise<Response> {\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?.get(\"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 ctxMap = new Map();\n ctxMap.set(\"span\", span);\n ctxMap.set(\"request\", req);\n\n return asyncContext.run(ctxMap, () => 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 ctxMap = new Map();\n ctxMap.set(\"request\", req);\n return asyncContext.run(ctxMap, () => this.handleRequest(req, server));\n }\n\n return this.handleRequest(req, server);\n }\n\n private async handleRequest(req: Request, server?: Server): 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 await this.executeHook('onResponseEnd', ctx, res);\n return res;\n }\n\n try {\n // Request Start Hook\n if (this.hasHook('onRequestStart')) {\n await this.executeHook('onRequestStart', ctx);\n }\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 const match = this.find(req.method, ctx.path);\n // TODO: Execute router-level hooks from match?\n // For now, only app-level hooks are fully supported here.\n if (match) {\n ctx.params = match.params;\n return match.handler(ctx);\n }\n return null;\n });\n\n let response: 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 // 1. Check if response was explicitly set via helper (e.g. ctx.text())\n if (ctx._finalResponse instanceof Response) {\n response = ctx._finalResponse;\n }\n // 2. Check if user manipulated ctx.response state manually (status/headers)\n // If status is NOT 200 (default), or headers are set, maybe we should construct a response?\n // But usually returning nothing implies 404 in this framework unless explicit.\n // However, if one sets `ctx.response.status = 201`, they expect 201?\n // Currently `ShokupanResponse` doesn't automatically generate a body.\n // So we'd send empty body with that status.\n else if (ctx.response.status !== 200 || ctx.response.hasPopulatedHeaders) {\n // Construct response from context state\n response = ctx.send(null, { status: ctx.response.status, headers: ctx.response.headers });\n }\n // 3. Fallback: Not Found\n else {\n response = ctx.text(\"Not Found\", 404);\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.hasHook('onRequestEnd')) {\n await this.executeHook('onRequestEnd', ctx);\n }\n\n // Response Start Hook - About to send response\n if (this.hasHook('onResponseStart')) {\n await this.executeHook('onResponseStart', ctx, response);\n }\n\n return response;\n\n }\n catch (err: any) {\n console.error(err);\n const span = asyncContext.getStore()?.get(\"span\");\n if (span) span.setStatus({ code: 2 }); // Error\n\n const status = err.status || err.statusCode || 500;\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.hasHook('onError')) {\n await this.executeHook('onError', err, ctx);\n }\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 if (this.hasHook('onRequestTimeout')) {\n await this.executeHook('onRequestTimeout', ctx);\n }\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\", 408);\n }\n console.error(\"Unexpected error in request execution:\", err);\n return ctx.text(\"Internal Server Error\", 500);\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 if (this.hasHook('onResponseEnd')) {\n await this.executeHook('onResponseEnd', ctx, res);\n }\n return res;\n });\n }\n\n private ensureHooksInitialized() {\n\n const hooks = this.applicationConfig.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 (const type of hookTypes) {\n const fns: Function[] = [];\n for (const h of hookList) {\n if (h[type]) fns.push(h[type]!);\n }\n if (fns.length > 0) {\n this.hookCache.set(type, fns);\n }\n }\n }\n this.hooksInitialized = true;\n }\n\n public async executeHook(name: keyof ShokupanHooks, ...args: any[]) {\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 for (const fn of fns) {\n await fn(...args);\n }\n }\n\n public hasHook(name: keyof ShokupanHooks) {\n if (!this.hooksInitialized) {\n this.ensureHooksInitialized();\n }\n return this.hookCache.has(name);\n }\n}\n","\nimport {\n Apple, Auth0,\n GitHub, Google, MicrosoftEntraId,\n OAuth2Client,\n Okta,\n generateCodeVerifier,\n generateState\n} from \"arctic\";\nimport * as jose from \"jose\";\nimport { ShokupanContext } from \"../context\";\nimport { ShokupanRouter } from \"../router\";\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 clientId: string;\n clientSecret: string;\n redirectUri: string; // Must be absolute\n scopes?: string[];\n tenantId?: string; // For MS\n domain?: string; // For Auth0, Okta\n teamId?: string; // For Apple\n keyId?: string; // For Apple\n authUrl?: string; // For generic OAuth2\n tokenUrl?: string; // For generic OAuth2\n userInfoUrl?: string; // For generic OAuth2\n}\n\nexport interface AuthConfig {\n jwtSecret: string | Uint8Array;\n jwtExpiration?: string; // e.g. \"2h\"\n cookieOptions?: {\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n path?: string;\n maxAge?: number;\n };\n onSuccess?: (user: AuthUser, ctx: ShokupanContext) => Promise<any> | any;\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\nexport class AuthPlugin extends ShokupanRouter<any> {\n private secret: Uint8Array;\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 this.init();\n }\n\n private getProviderInstance(name: string, p: ProviderConfig) {\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 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 for (const [providerName, providerConfig] of Object.entries(this.authConfig.providers)) {\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 ctx.res.headers.set(\"Set-Cookie\", `oauth_state=${state}; Path=/; HttpOnly; Max-Age=600`);\n if (codeVerifier) {\n ctx.res.headers.append(\"Set-Cookie\", `oauth_verifier=${codeVerifier}; Path=/; HttpOnly; 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 console.error(\"Auth Error\", e);\n return ctx.text(\"Authentication failed: \" + e.message + \"\\n\" + e.stack, 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 = 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 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 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 * as zlib from \"node:zlib\"; // TODO: When bun compression support supercedes node, remove this\nimport type { ShokupanContext } from \"../context\";\nimport type { Middleware, NextFn } from \"../types\";\n\nexport interface CompressionOptions {\n threshold?: number; // Minimum byte size to compress\n}\n\nexport function Compression(options: CompressionOptions = {}): Middleware {\n const threshold = options.threshold ?? 512; // 512 bytes default\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 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, {\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, {\n status: response.status,\n statusText: response.statusText,\n headers\n });\n }\n\n return response;\n };\n compressionMiddleware.isBuiltin = true;\n compressionMiddleware.pluginName = 'Compression';\n return compressionMiddleware;\n};\n","import type { ShokupanContext } from \"../context\";\nimport type { Middleware, NextFn } from \"../types\";\n\nexport interface CorsOptions {\n origin?: string | string[] | ((ctx: ShokupanContext) => string | undefined | null | boolean);\n methods?: string | string[];\n allowedHeaders?: string | string[];\n exposedHeaders?: string | string[];\n credentials?: boolean;\n maxAge?: number;\n}\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 = new Headers();\n const origin = ctx.headers.get(\"origin\");\n\n const set = (k: string, v: string) => headers.set(k, v);\n const append = (k: string, v: string) => headers.append(k, v);\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 && opts.origin.includes(origin)) {\n set(\"Access-Control-Allow-Origin\", origin);\n append(\"Vary\", \"Origin\");\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 for (const [key, value] of headers.entries()) {\n response.headers.set(key, value);\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 '../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}","import { plainToInstance } from \"class-transformer\";\nimport { validateOrReject } from \"class-validator\";\nimport { ShokupanContext } from \"../context\";\nimport type { Middleware } from \"../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 // 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 const req = ctx.req as any;\n\n // Check if already parsed\n if (req._bodyParsed) {\n return req._bodyValue;\n }\n\n try {\n let data: any;\n // Standard Request consumes stream\n // ShokupanRequest (internal) has properties\n if (typeof req.json === 'function') {\n data = await req.json();\n }\n else {\n // Fallback if req is plain object with body property (internal usage)\n data = req.body;\n if (typeof data === 'string') {\n try { data = JSON.parse(data); } catch { }\n }\n }\n\n // Cache it\n req._bodyParsed = true;\n req._bodyValue = data;\n\n // Monkey patch json() to return cached data\n // This ensures subsequent calls (e.g. in handlers) get the same data\n // and don't fail due to stream locked\n Object.defineProperty(req, 'json', {\n value: async () => req._bodyValue,\n configurable: true\n });\n\n return data;\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\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 if (ctx.app?.hasHook('beforeValidate')) {\n await ctx.app.executeHook('beforeValidate', ctx, dataToValidate);\n }\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 cached body with validated/sanitized version\n const req = ctx.req as any;\n req._bodyValue = validBody;\n\n // Ensure json() returns the validated body\n Object.defineProperty(req, 'json', {\n value: async () => validBody,\n configurable: true\n });\n\n (ctx as any).body = validBody; // Legacy/Convenience\n }\n\n // Call afterValidate Hook\n if (ctx.app?.hasHook('afterValidate')) {\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?.executeHook('afterValidate', ctx, validatedData);\n }\n\n return next();\n };\n}\n","import Ajv from \"ajv\";\nimport addFormats from \"ajv-formats\";\nimport type { Middleware } from \"../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 for (const [path, { regex, paramNames }] of cache.paths) {\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 for (const [path, pathItem] of Object.entries(spec.paths || {})) {\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 for (const [method, operation] of Object.entries(pathItem as any)) {\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 (const param of parameters) {\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 { ApiReferenceConfiguration } from '@scalar/api-reference';\nimport type { OpenAPI } from '@scalar/openapi-types';\nimport { Eta } from 'eta';\nimport { OpenAPIAnalyzer } from '../analysis/openapi-analyzer';\nimport { ShokupanRouter } from '../router';\nimport type { DeepPartial } from '../types';\nimport { deepMerge } from '../util/deep-merge';\n\nconst eta = new Eta();\n\nexport type ScalarPluginOptions = {\n baseDocument?: DeepPartial<OpenAPI.Document>;\n config?: Partial<ApiReferenceConfiguration>;\n enableStaticAnalysis?: boolean;\n};\n\nexport class ScalarPlugin extends ShokupanRouter<any> {\n constructor(\n private readonly pluginOptions: ScalarPluginOptions = {}\n ) {\n pluginOptions.config ??= {};\n super();\n this.init();\n }\n\n init() {\n this.get(\"/\", ctx => {\n let path = ctx.url.toString();\n if (!path.endsWith(\"/\")) path += \"/\";\n\n return ctx.html(eta.renderString(`<!doctype html>\n <html>\n <head>\n <title>API Reference</title>\n <meta charset = \"utf-8\" />\n <meta name=\"viewport\" content = \"width=device-width, initial-scale=1\" />\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 </body>\n\n </html>`, { path, config: this.pluginOptions }));\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 { ShokupanContext } from \"../context\";\nimport type { Middleware, NextFn } from \"../types\";\n\nexport interface SecurityHeadersOptions {\n contentSecurityPolicy?: boolean | Record<string, any>;\n crossOriginEmbedderPolicy?: boolean;\n crossOriginOpenerPolicy?: boolean;\n crossOriginResourcePolicy?: boolean;\n dnsPrefetchControl?: boolean | { allow: boolean; };\n expectCt?: boolean | { maxAge?: number, enforce?: boolean, reportUri?: string; };\n frameguard?: boolean | { action: 'deny' | 'sameorigin' | 'allow-from', domain?: string; };\n hidePoweredBy?: boolean;\n hsts?: boolean | { maxAge?: number, includeSubDomains?: boolean, preload?: boolean; };\n ieNoOpen?: boolean;\n noSniff?: boolean;\n originAgentCluster?: boolean;\n permittedCrossDomainPolicies?: boolean | { permittedPolicies: 'none' | 'master-only' | 'by-content-type' | 'all'; };\n referrerPolicy?: boolean | { policy: string | string[]; };\n xssFilter?: boolean;\n}\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 for (const [key, val] of Object.entries(opt)) {\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 for (const [k, v] of Object.entries(headers)) {\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 \"../types\";\n\n// --- Types ---\n\nexport interface SessionData {\n cookie: Cookie;\n [key: string]: any;\n}\n\nexport interface 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 priority?: 'low' | 'medium' | 'high';\n}\n\nexport interface SessionOptions {\n secret: string | string[];\n name?: string;\n store?: Store;\n cookie?: SessionCookieOptions;\n genid?: (ctx: ShokupanContext) => string;\n resave?: boolean;\n saveUninitialized?: boolean;\n rolling?: boolean;\n unset?: 'destroy' | 'keep';\n}\n\nexport interface Store extends EventEmitter {\n get(sid: string, callback: (err: any, session?: SessionData | null) => void): void;\n set(sid: string, session: SessionData, callback?: (err?: any) => void): void;\n destroy(sid: string, callback?: (err?: any) => void): void;\n touch?(sid: string, session: SessionData, callback?: (err?: any) => void): void;\n all?(callback: (err: any, obj?: { [sid: string]: SessionData; } | null) => void): void;\n length?(callback: (err: any, length?: number) => void): void;\n clear?(callback?: (err?: any) => void): void;\n load?(sid: string, fn: (err: any, session?: SessionData | null) => void): void;\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 && cb();\n }\n\n destroy(sid: string, cb?: (err?: any) => void) {\n delete this.sessions[sid];\n cb && 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 && cb();\n }\n\n all(cb: (err: any, obj?: { [sid: string]: SessionData; } | null) => void) {\n const result: Record<string, SessionData> = {};\n for (const sid in this.sessions) {\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 && 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 const expectedBuffer = Buffer.from(expectedInput);\n const inputBuffer = Buffer.from(input);\n if (expectedBuffer.length !== inputBuffer.length) return false;\n // timingSafeEqual\n // crypto.timingSafeEqual is available in node/bun\n const valid = require('crypto').timingSafeEqual(expectedBuffer, inputBuffer);\n return valid ? tentValue : false;\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\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 for (const key in sessObj) {\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 for (const key in sessObj) {\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":["RateLimitMiddleware","RouteParamType","Headers","context","OpenAPIAnalyzer","eta","readFile","tracer","defaults","resolve","sess","options"],"mappings":"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"}