{"version":3,"sources":["../src/core-exports.ts","../src/app.ts","../src/container.ts","../src/sse.ts","../src/context.ts","../src/decorators/inject.ts","../src/decorators/injectable.ts","../src/decorators.ts","../src/helpers/async-handler.ts","../src/logger.ts","../src/ffi/fallback.ts","../src/ffi/index.ts","../src/router/node.ts","../src/router/index.ts","../src/base-controller.ts","../src/base-service.ts","../src/emitter.ts","../src/helpers/async.ts","../src/helpers/cookie.ts","../src/helpers/crypto.ts","../src/helpers/date.ts","../src/helpers/timezone.ts","../src/helpers/id.ts","../src/helpers/network.ts","../src/helpers/number.ts","../src/helpers/object.ts","../src/helpers/password.ts","../src/helpers/string.ts","../src/middlewares/audit-log.ts","../src/middlewares/compress.ts","../src/middlewares/cors.ts","../src/middlewares/health-check.ts","../src/middlewares/helmet.ts","../src/middlewares/rate-limiter.ts","../src/middlewares/request-id.ts","../src/middlewares/response-time.ts","../src/middlewares/timeout.ts","../src/middlewares/rbac.ts","../src/middlewares/validator.ts","../src/upload.ts"],"sourcesContent":["// Core\nexport { z } from \"zod\";\nexport type {\n\tErrorHandler,\n\tExtractParams,\n\tHandler,\n\tMiddleware,\n\tNotFoundHandler,\n\tRouteContext,\n\tWSData,\n\tWSHandler,\n\tZodCtx,\n} from \"./app\";\nexport { App } from \"./app\";\n// Base classes\nexport { BaseController } from \"./base-controller\";\nexport { BaseService } from \"./base-service\";\nexport {\n\ttype ClassProvider,\n\tContainer,\n\ttype FactoryProvider,\n\ttype Provider,\n\ttype Scope,\n\ttype ValueProvider,\n} from \"./container\";\nexport { Context } from \"./context\";\nexport type { ControllerMeta, RouteMeta } from \"./decorators\";\n// Emitter\nexport { emitter, EventEmitter } from \"./emitter\";\nexport type { AppEvents } from \"./emitter\";\n// Decorators\nexport {\n\tAll,\n\tController,\n\tDelete,\n\tGet,\n\ttype GuardFn,\n\tHead,\n\tInject,\n\tInjectable,\n\tOptions,\n\tPatch,\n\tPost,\n\tPut,\n\tQuery,\n\tUse,\n\tUseGuard,\n} from \"./decorators\";\nexport type { RetryOptions } from \"./helpers/async\";\n// Async helpers\nexport { delay, retry } from \"./helpers/async\";\n// Error helpers\nexport {\n\tasyncHandler,\n\tBadRequestError,\n\tConflictError,\n\tForbiddenError,\n\tHttpError,\n\tInternalServerError,\n\tMethodNotAllowedError,\n\tNotFoundError,\n\tServiceUnavailableError,\n\tTooManyRequestsError,\n\tUnauthorizedError,\n\tUnprocessableEntityError,\n} from \"./helpers/async-handler\";\nexport type { CookieOptions } from \"./helpers/cookie\";\n// Cookie helpers\nexport {\n\tdeleteCookie,\n\tgetCookie,\n\tgetCookies,\n\tparseCookies,\n\tserializeCookie,\n\tsetCookie,\n} from \"./helpers/cookie\";\n// Crypto helpers\nexport {\n\tdecrypt,\n\tencrypt,\n\thash,\n\thashVerify,\n\thmac,\n\tmd5,\n\trandomAlphaNumeric,\n\trandomBytes,\n\trandomHex,\n\trandomToken,\n\tsha256,\n\tsha512,\n} from \"./helpers/crypto\";\n// Date helpers\nexport { formatDate, timeAgo } from \"./helpers/date\";\n// Timezone helpers\nexport {\n\tformatGroupLabel,\n\tformatInTimezone,\n\tgetGroupLabels,\n\tgetTimezoneOffset,\n\tgetTimezoneOffsetString,\n\tgroupByTimezone,\n\tisValidTimezone,\n\tnowInTimezone,\n\tparseTime,\n\ttoISOWithTimezone,\n\ttoTimezoneParts,\n} from \"./helpers/timezone\";\nexport type { GroupByKey, GroupByTimezoneOptions } from \"./helpers/timezone\";\n// ID helpers\nexport {\n\tgenerateCode,\n\tnanoid,\n\tresetCounter,\n\tulid,\n} from \"./helpers/id\";\n// Network helpers\nexport { getClientIP, isPrivateIP, parseUserAgent } from \"./helpers/network\";\n// Number helpers\nexport {\n\tclamp,\n\tformatBytes,\n\tformatCurrency,\n\tformatNumber,\n\trandom,\n\trandomFloat,\n} from \"./helpers/number\";\n// Object helpers\nexport {\n\tchunk,\n\tdeepMerge,\n\tflatten,\n\tflattenObject,\n\tgroupBy,\n\tomit,\n\tpick,\n\tuniq,\n} from \"./helpers/object\";\n// Password helpers\nexport { hashPassword, verifyPassword } from \"./helpers/password\";\n// String helpers\nexport {\n\tcamelCase,\n\tcapitalize,\n\tkebabCase,\n\tslugify,\n\tsnakeCase,\n\ttruncate,\n} from \"./helpers/string\";\n// Logger\nexport { Logger, LogLevel, logger } from \"./logger\";\n// Middlewares\nexport { auditLog, type AuditLogEntry, type AuditLogOptions } from \"./middlewares/audit-log\";\nexport type { CompressOptions } from \"./middlewares/compress\";\nexport { compress } from \"./middlewares/compress\";\nexport type { CorsOptions } from \"./middlewares/cors\";\nexport { cors } from \"./middlewares/cors\";\nexport type {\n\tHealthCheckOptions,\n\tHealthStatus,\n} from \"./middlewares/health-check\";\nexport {\n\tcreateDatabaseCheck,\n\tcreateHealthCheck,\n\thealthCheck,\n} from \"./middlewares/health-check\";\nexport type { HelmetOptions } from \"./middlewares/helmet\";\n// Helmet\nexport { helmet } from \"./middlewares/helmet\";\nexport type { RateLimiterOptions } from \"./middlewares/rate-limiter\";\nexport {\n\trateLimiter,\n\tslidingWindowRateLimiter,\n} from \"./middlewares/rate-limiter\";\nexport type { RequestIdOptions } from \"./middlewares/request-id\";\nexport { requestId, shortId, uuid } from \"./middlewares/request-id\";\nexport type { ResponseTimeOptions } from \"./middlewares/response-time\";\nexport { responseTime } from \"./middlewares/response-time\";\n// Timeout\nexport { TimeoutError, timeout } from \"./middlewares/timeout\";\n// RBAC\nexport { requirePermission, requireRole } from \"./middlewares/rbac\";\nexport type { RequirePermissionOptions, RequireRoleOptions } from \"./middlewares/rbac\";\nexport type {\n\tBodyContentType,\n\tValidationTarget,\n\tZValidatorOptions,\n} from \"./middlewares/validator\";\nexport {\n\tvalidate,\n\tvalidateBody,\n\tvalidateParams,\n\tzResponse,\n\tzValidator,\n} from \"./middlewares/validator\";\nexport { Router } from \"./router\";\n// SSE\nexport type { SSEMessage, SSEOptions } from \"./sse\";\nexport { createSSE, SSE } from \"./sse\";\n// Upload\nexport type {\n\tParseUploadResult,\n\tStorageDriver,\n\tUploadedFile,\n\tUploadFieldConfig,\n\tUploadOptions,\n} from \"./upload\";\nexport {\n\tdeleteUploadedFile,\n\tLocalDiskStorage,\n\tMemoryStorage,\n\tparseUploads,\n\tuploader,\n} from \"./upload\";\n","import { join, sep } from \"node:path\";\nimport type { Server, ServerWebSocket } from \"bun\";\nimport { z } from \"zod\";\nimport { Container } from \"./container\";\nimport { Context } from \"./context\";\nimport { getControllerMeta } from \"./decorators\";\nimport { HttpError } from \"./helpers/async-handler\";\nimport { logger } from \"./logger\";\nimport { Router } from \"./router\";\n\nexport interface WSData<DI = Record<string, unknown>> {\n\tctx: Context<DI>;\n\thandler: WSHandler<DI>;\n}\n\nexport interface WSHandler<DI = Record<string, unknown>> {\n\topen?: (ws: ServerWebSocket<WSData<DI>>) => void;\n\tmessage?: (ws: ServerWebSocket<WSData<DI>>, message: string | Buffer) => void;\n\tclose?: (\n\t\tws: ServerWebSocket<WSData<DI>>,\n\t\tcode: number,\n\t\treason: string,\n\t) => void;\n\tdrain?: (ws: ServerWebSocket<WSData<DI>>) => void;\n}\n\nexport type ExtractParams<Path extends string> =\n\tPath extends `${infer _Start}:${infer Param}/${infer Rest}`\n\t\t? { [K in Param]: string } & ExtractParams<`/${Rest}`>\n\t\t: Path extends `${infer _Start}:${infer Param}`\n\t\t\t? { [K in Param]: string }\n\t\t\t: Path extends `${infer _Start}*${infer Catchall}`\n\t\t\t\t? { [K in Catchall]: string } & { \"*\": string }\n\t\t\t\t: Record<string, never>;\n\n/**\n * @deprecated Use `ZodCtx<{ body: typeof schema; query: typeof schema }>` instead.\n * `RouteContext` has 5 generic parameters that are hard to remember.\n * `ZodCtx` only needs one and infers types automatically from your Zod schemas.\n */\nexport type RouteContext<\n\tPath extends string = string,\n\tBodyType = unknown,\n\tDI = Record<string, unknown>,\n\tQueryType = unknown,\n\tParamsType = ExtractParams<Path>,\n> = {\n\tbody(): Promise<BodyType>;\n\tvalid<T extends \"body\" | \"query\" | \"params\">(\n\t\ttarget: T,\n\t): T extends \"body\"\n\t\t? BodyType\n\t\t: T extends \"query\"\n\t\t\t? QueryType\n\t\t\t: T extends \"params\"\n\t\t\t\t? ParamsType\n\t\t\t\t: unknown;\n} & Context<DI, ParamsType>;\n\n/**\n * Helper to infer Context types from Zod schemas automatically.\n *\n * Just pass your Zod schemas — no need to remember generic parameter order.\n *\n * @example\n * const paginationSchema = z.object({ page: z.coerce.number(), limit: z.coerce.number() });\n *\n * @Controller(\"/users\")\n * export class UserController {\n *   @Get(\"/\")\n *   @Use(zValidator(\"query\", paginationSchema))\n *   async getAll(ctx: ZodCtx<{ query: typeof paginationSchema }>) {\n *     const { page, limit } = ctx.valid(\"query\"); // Fully typed!\n *   }\n * }\n */\nexport type ZodCtx<\n\t// biome-ignore lint/suspicious/noExplicitAny: Requires accessing Zod types\n\tT extends { query?: any; body?: any; params?: any },\n> = {\n\tbody(): Promise<T[\"body\"] extends { _type: infer U } ? U : T[\"body\"]>;\n\tvalid<Target extends \"body\" | \"query\" | \"params\">(\n\t\ttarget: Target,\n\t): Target extends \"body\"\n\t\t? T[\"body\"] extends { _type: infer U }\n\t\t\t? U\n\t\t\t: T[\"body\"]\n\t\t: Target extends \"query\"\n\t\t\t? T[\"query\"] extends { _type: infer U }\n\t\t\t\t? U\n\t\t\t\t: T[\"query\"]\n\t\t\t: Target extends \"params\"\n\t\t\t\t? T[\"params\"] extends { _type: infer U }\n\t\t\t\t\t? U\n\t\t\t\t\t: T[\"params\"]\n\t\t\t\t: unknown;\n} & Context<\n\tRecord<string, unknown>,\n\tT[\"params\"] extends { _type: infer U }\n\t\t? U\n\t\t: T[\"params\"] extends Record<string, string>\n\t\t\t? T[\"params\"]\n\t\t\t: Record<string, string>\n>;\n\nexport type Handler<\n\tDI = Record<string, unknown>,\n\tPath extends string = string,\n> = (ctx: Context<DI, ExtractParams<Path>>) => Response | Promise<Response>;\nexport type Middleware<\n\tDI = Record<string, unknown>,\n\tPath extends string = string,\n> = (\n\tctx: Context<DI, ExtractParams<Path>>,\n\tnext: () => Promise<Response> | Response,\n) => Response | Promise<Response>;\nexport type ErrorHandler<DI = Record<string, unknown>> = (\n\terr: Error,\n\t// biome-ignore lint/suspicious/noExplicitAny: generic\n\tctx: Context<DI, any>,\n) => Response | Promise<Response>;\nexport type NotFoundHandler<DI = Record<string, unknown>> = (\n\t// biome-ignore lint/suspicious/noExplicitAny: generic\n\tctx: Context<DI, any>,\n) => Response | Promise<Response>;\n\nexport class App<DI extends Record<string, unknown> = Record<string, unknown>> {\n\tprivate router: Router;\n\tprivate middlewares: Middleware<DI>[] = [];\n\tprivate compiledGlobalPipeline?: (\n\t\tctx: Context<DI>,\n\t\tfinalHandler: Handler<DI>,\n\t) => Response | Promise<Response>;\n\tprivate iconPath: string = \"./public/favicon.ico\";\n\tprivate isListening: boolean = false;\n\tpublic di = {} as DI;\n\tprivate wsRoutes: Map<string, WSHandler<DI>> = new Map();\n\tprivate poweredByHeaderEnabled: boolean = true;\n\tprivate _reusePort: boolean = false;\n\tprivate _skipLogResponse: boolean = false;\n\t// biome-ignore lint/suspicious/noExplicitAny: Required for internal OpenAPI registry\n\tpublic openApiDocs: any[] = [];\n\tprivate container: Container | null = null;\n\n\t/**\n\t * The underlying Bun Server instance. Only available after app.listen() is called.\n\t * Can be used for server.publish() to broadcast WebSocket messages.\n\t */\n\tpublic server?: Server<WSData<DI>>;\n\n\tprivate customErrorHandler: ErrorHandler<DI> = (err, ctx) => {\n\t\tlogger.error(\"Unhandled Exception\", {\n\t\t\terror: err.message,\n\t\t\tstack: err.stack,\n\t\t});\n\t\tconst status = err instanceof HttpError ? err.status : 500;\n\t\tconst errorName =\n\t\t\tstatus === 400\n\t\t\t\t? \"Bad Request\"\n\t\t\t\t: status === 401\n\t\t\t\t\t? \"Unauthorized\"\n\t\t\t\t\t: status === 403\n\t\t\t\t\t\t? \"Forbidden\"\n\t\t\t\t\t\t: status === 404\n\t\t\t\t\t\t\t? \"Not Found\"\n\t\t\t\t\t\t\t: status === 405\n\t\t\t\t\t\t\t\t? \"Method Not Allowed\"\n\t\t\t\t\t\t\t\t: status === 409\n\t\t\t\t\t\t\t\t\t? \"Conflict\"\n\t\t\t\t\t\t\t\t\t: status === 422\n\t\t\t\t\t\t\t\t\t\t? \"Unprocessable Entity\"\n\t\t\t\t\t\t\t\t\t\t: status === 429\n\t\t\t\t\t\t\t\t\t\t\t? \"Too Many Requests\"\n\t\t\t\t\t\t\t\t\t\t\t: status === 503\n\t\t\t\t\t\t\t\t\t\t\t\t? \"Service Unavailable\"\n\t\t\t\t\t\t\t\t\t\t\t\t: \"Internal Server Error\";\n\t\treturn ctx.json(\n\t\t\t{\n\t\t\t\tsuccess: false,\n\t\t\t\terror: errorName,\n\t\t\t\tmessage:\n\t\t\t\t\tprocess.env.NODE_ENV === \"production\"\n\t\t\t\t\t\t? \"Terjadi kesalahan pada server\"\n\t\t\t\t\t\t: err.message,\n\t\t\t},\n\t\t\tstatus,\n\t\t);\n\t};\n\n\tprivate customNotFoundHandler: NotFoundHandler<DI> = (ctx) => {\n\t\treturn ctx.json(\n\t\t\t{\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"Not Found\",\n\t\t\t\tpath: new URL(ctx.request.url).pathname,\n\t\t\t},\n\t\t\t404,\n\t\t);\n\t};\n\n\tconstructor() {\n\t\tthis.router = new Router();\n\t\tthis.registerFaviconRoute();\n\t}\n\n\tpublic use(middleware: Middleware<DI>): this {\n\t\tthis.middlewares.push(middleware);\n\t\treturn this;\n\t}\n\n\tpublic set<K extends keyof DI>(key: K, value: DI[K]): this {\n\t\tthis.di[key] = value;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Attach an IoC Container to the app. When set, `registerController()`\n\t * will auto-resolve `@Inject`-annotated properties from the container\n\t * before binding routes.\n\t */\n\tpublic setContainer(container: Container): this {\n\t\tthis.container = container;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Get the attached IoC Container, or create an empty one if none was set.\n\t */\n\tpublic getContainer(): Container {\n\t\tif (!this.container) {\n\t\t\tthis.container = new Container();\n\t\t}\n\t\treturn this.container;\n\t}\n\n\tpublic group(prefix: string): RouterGroup<DI> {\n\t\treturn new RouterGroup<DI>(prefix, this);\n\t}\n\n\t/**\n\t * Register a WebSocket endpoint at an exact path (no params/wildcards).\n\t * Backed directly by Bun's native WebSocket server — no polyfill or\n\t * extra abstraction layer between your handler and `Bun.serve`.\n\t *\n\t * ```ts\n\t * app.ws(\"/chat\", {\n\t *   open: (ws) => ws.subscribe(\"room\"),\n\t *   message: (ws, msg) => ws.publish(\"room\", msg),\n\t * });\n\t * ```\n\t */\n\tpublic ws(path: string, handler: WSHandler<DI>): this {\n\t\tthis.wsRoutes.set(path, handler);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Type-safe Environment Variables Validator.\n\t * Validates `process.env` against a Zod schema object and returns the typed result.\n\t * If validation fails, it prints a beautiful error to the console and exits the process (stops booting).\n\t */\n\tpublic validateEnv<T extends z.ZodRawShape>(\n\t\tschema: T,\n\t): z.infer<z.ZodObject<T>> {\n\t\tconst envSchema = z.object(schema);\n\t\tconst result = envSchema.safeParse(process.env);\n\n\t\tif (!result.success) {\n\t\t\tconsole.error(\"\\n\\x1b[41m\\x1b[37m 🚨 Buntok Environment Error \\x1b[0m\\n\");\n\t\t\tconsole.error(\n\t\t\t\t\"\\x1b[31mMissing or invalid environment variables:\\x1b[0m\\n\",\n\t\t\t);\n\n\t\t\tresult.error.issues.forEach((err) => {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`  \\x1b[33m❯\\x1b[0m \\x1b[36m${err.path.join(\".\")}\\x1b[0m: \\x1b[90m${err.message}\\x1b[0m`,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tconsole.error(\"\\n\\x1b[31mServer boot aborted.\\x1b[0m\\n\");\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\treturn result.data;\n\t}\n\n\t/**\n\t * Register all `@Get`/`@Post`/etc. routes declared on a `@Controller`\n\t * class. This is sugar over `registerRoute()` — it instantiates the\n\t * class once (at boot time, not per request) and wires each decorated\n\t * method up exactly like a manual `app.get(path, handler)` call would.\n\t *\n\t * When a Container is attached via `app.setContainer()`, `@Inject`-\n\t * annotated properties on the controller are automatically resolved\n\t * from the container before routes are bound.\n\t *\n\t * ```ts\n\t * app.registerController(UserController);\n\t * ```\n\t */\n\tpublic registerController<T extends object>(\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Constructor args are unknowable\n\t\ttarget: (new (...args: any[]) => T) | T,\n\t): this {\n\t\t// Detect if target is a class (constructor) or an instance\n\t\tconst isInstance =\n\t\t\ttypeof target === \"object\" &&\n\t\t\ttarget !== null &&\n\t\t\ttypeof target === \"object\";\n\n\t\tconst ControllerClass = isInstance\n\t\t\t? // biome-ignore lint/suspicious/noExplicitAny: dynamic type narrowing\n\t\t\t\t(target as any).constructor\n\t\t\t: // biome-ignore lint/suspicious/noExplicitAny: dynamic type narrowing\n\t\t\t\t(target as new (\n\t\t\t\t\t...args: any[]\n\t\t\t\t) => T);\n\n\t\tconst meta = getControllerMeta(ControllerClass);\n\t\tif (!meta) {\n\t\t\tthrow new Error(\n\t\t\t\t`${ControllerClass.name} is not decorated with @Controller — did you forget to add it?`,\n\t\t\t);\n\t\t}\n\n\t\tlet instance: T;\n\n\t\tif (isInstance) {\n\t\t\t// Use the provided instance directly\n\t\t\tinstance = target as T;\n\t\t} else if (this.container) {\n\t\t\tconst resolved = this.container.resolve<T>(ControllerClass);\n\t\t\tinstance = resolved;\n\t\t} else {\n\t\t\tinstance = new ControllerClass();\n\t\t}\n\n\t\tconst normalizedPrefix = meta.prefix.endsWith(\"/\")\n\t\t\t? meta.prefix.slice(0, -1)\n\t\t\t: meta.prefix;\n\n\t\tfor (const route of meta.routes) {\n\t\t\tconst cleanPath = route.path === \"/\" ? \"\" : route.path;\n\t\t\tconst fullPath = `${normalizedPrefix}${cleanPath}` || \"/\";\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: dynamic method dispatch by decorated property key\n\t\t\tconst handler = (instance as any)[route.propertyKey].bind(\n\t\t\t\tinstance,\n\t\t\t) as Handler<DI>;\n\n\t\t\tthis.registerRoute(route.method, fullPath, [\n\t\t\t\t...(route.middlewares as Middleware<DI>[]),\n\t\t\t\thandler,\n\t\t\t]);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tpublic onError(handler: ErrorHandler<DI>): this {\n\t\tthis.customErrorHandler = handler;\n\t\treturn this;\n\t}\n\n\tpublic notFound(handler: NotFoundHandler<DI>): this {\n\t\tthis.customNotFoundHandler = handler;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Disable a built-in feature. Currently only `\"x-powered-by\"` is\n\t * supported, which turns off the `X-Powered-By: buntok` response header.\n\t * The header's value itself is not configurable — this only controls\n\t * whether it's sent.\n\t */\n\tpublic disable(feature: \"x-powered-by\"): this {\n\t\tif (feature === \"x-powered-by\") {\n\t\t\tthis.poweredByHeaderEnabled = false;\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * Re-enable a feature previously turned off with `disable()`.\n\t */\n\tpublic enable(feature: \"x-powered-by\"): this {\n\t\tif (feature === \"x-powered-by\") {\n\t\t\tthis.poweredByHeaderEnabled = true;\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * Enable SO_REUSEPORT for multi-process load balancing (Linux only).\n\t * When enabled, multiple instances of the app can bind to the same port,\n\t * and incoming requests are load-balanced at the kernel level.\n\t */\n\tpublic enableReusePort(enabled = true): this {\n\t\tthis._reusePort = enabled;\n\t\treturn this;\n\t}\n\n\tpublic icon(path: string): this {\n\t\tthis.iconPath = path;\n\t\treturn this;\n\t}\n\n\tprivate registerFaviconRoute(): void {\n\t\tthis.get(\"/favicon.ico\", async (_ctx) => {\n\t\t\t// Try custom path first\n\t\t\tconst customFile = Bun.file(this.iconPath);\n\t\t\tif (await customFile.exists()) {\n\t\t\t\treturn new Response(customFile);\n\t\t\t}\n\t\t\t// Fallback to built-in icon\n\t\t\tconst builtInFile = Bun.file(this.getBuiltInIconPath());\n\t\t\tif (await builtInFile.exists()) {\n\t\t\t\treturn new Response(builtInFile);\n\t\t\t}\n\t\t\t// No favicon found\n\t\t\treturn new Response(null, { status: 404 });\n\t\t});\n\t}\n\n\tprivate getBuiltInIconPath(): string {\n\t\treturn join(__dirname, \"..\", \"public\", \"favicon.ico\");\n\t}\n\n\tpublic get<Path extends string>(path: Path, handler: Handler<DI, Path>): this;\n\tpublic get<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic get<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic get<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic get<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic get<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic get<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.registerRoute(\"GET\", path, handlers);\n\t\treturn this;\n\t}\n\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.registerRoute(\"POST\", path, handlers);\n\t\treturn this;\n\t}\n\n\tpublic put<Path extends string>(path: Path, handler: Handler<DI, Path>): this;\n\tpublic put<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic put<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic put<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic put<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic put<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic put<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.registerRoute(\"PUT\", path, handlers);\n\t\treturn this;\n\t}\n\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.registerRoute(\"DELETE\", path, handlers);\n\t\treturn this;\n\t}\n\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.registerRoute(\"OPTIONS\", path, handlers);\n\t\treturn this;\n\t}\n\n\tpublic query(path: string, handler: Handler<DI>): this;\n\tpublic query(\n\t\tpath: string,\n\t\tmiddleware: Middleware<DI>,\n\t\thandler: Handler<DI>,\n\t): this;\n\tpublic query(\n\t\tpath: string,\n\t\tm1: Middleware<DI>,\n\t\tm2: Middleware<DI>,\n\t\thandler: Handler<DI>,\n\t): this;\n\tpublic query(\n\t\tpath: string,\n\t\tm1: Middleware<DI>,\n\t\tm2: Middleware<DI>,\n\t\tm3: Middleware<DI>,\n\t\thandler: Handler<DI>,\n\t): this;\n\tpublic query(\n\t\tpath: string,\n\t\tm1: Middleware<DI>,\n\t\tm2: Middleware<DI>,\n\t\tm3: Middleware<DI>,\n\t\tm4: Middleware<DI>,\n\t\thandler: Handler<DI>,\n\t): this;\n\tpublic query(\n\t\tpath: string,\n\t\tm1: Middleware<DI>,\n\t\tm2: Middleware<DI>,\n\t\tm3: Middleware<DI>,\n\t\tm4: Middleware<DI>,\n\t\tm5: Middleware<DI>,\n\t\thandler: Handler<DI>,\n\t): this;\n\tpublic query(\n\t\tpath: string,\n\t\t...handlers: Array<Middleware<DI> | Handler<DI>>\n\t): this {\n\t\tthis.registerRoute(\"QUERY\", path, handlers);\n\t\treturn this;\n\t}\n\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.registerRoute(\"PATCH\", path, handlers);\n\t\treturn this;\n\t}\n\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.registerRoute(\"HEAD\", path, handlers);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Register a handler for all standard HTTP methods (GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS).\n\t */\n\tpublic all<Path extends string>(path: Path, handler: Handler<DI, Path>): this;\n\tpublic all<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic all<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic all<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic all<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic all<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic all<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tconst methods = [\n\t\t\t\"GET\",\n\t\t\t\"HEAD\",\n\t\t\t\"POST\",\n\t\t\t\"PUT\",\n\t\t\t\"PATCH\",\n\t\t\t\"DELETE\",\n\t\t\t\"OPTIONS\",\n\t\t];\n\t\tfor (const method of methods) {\n\t\t\tthis.registerRoute(method, path, handlers);\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * Serve static files from `directory` under `routePath`.\n\t *\n\t * Rejects any request whose resolved path escapes `directory` (e.g.\n\t * `/files/../../etc/passwd`) — without this check, static serving is a\n\t * directory-traversal vulnerability.\n\t *\n\t * Supports ETag-based conditional requests (If-None-Match → 304).\n\t * ETag is only computed when the client sends If-None-Match, keeping\n\t * the hot path (first request) free of metadata reads.\n\t */\n\tpublic static(routePath: string, directory: string): this {\n\t\tconst baseDir = join(process.cwd(), directory);\n\n\t\tconst handler: Handler<DI> = async (ctx) => {\n\t\t\tconst requestedPath = ctx.params[\"*\"] || \"\";\n\t\t\tconst absolutePath = join(baseDir, requestedPath);\n\n\t\t\tif (absolutePath !== baseDir && !absolutePath.startsWith(baseDir + sep)) {\n\t\t\t\treturn ctx.json({ error: \"Forbidden\" }, 403);\n\t\t\t}\n\n\t\t\tconst file = Bun.file(absolutePath);\n\n\t\t\tif (!(await file.exists())) {\n\t\t\t\treturn ctx.json({ error: \"File Not Found\" }, 404);\n\t\t\t}\n\n\t\t\t// Only compute ETag when client sends If-None-Match (conditional request)\n\t\t\tconst ifNoneMatch = ctx.request.headers.get(\"If-None-Match\");\n\t\t\tif (ifNoneMatch) {\n\t\t\t\tconst etag = `\"${file.size}-${file.lastModified}\"`;\n\t\t\t\tif (ifNoneMatch === etag) {\n\t\t\t\t\treturn new Response(null, {\n\t\t\t\t\t\tstatus: 304,\n\t\t\t\t\t\theaders: { ETag: etag },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new Response(file, {\n\t\t\t\theaders: {\n\t\t\t\t\t\"Cache-Control\": \"public, max-age=3600\",\n\t\t\t\t},\n\t\t\t});\n\t\t};\n\n\t\tconst wildcardPath = routePath.endsWith(\"/\")\n\t\t\t? `${routePath}*`\n\t\t\t: `${routePath}/*`;\n\t\tthis.get(wildcardPath, handler);\n\t\treturn this;\n\t}\n\n\tpublic registerRoute(\n\t\tmethod: string,\n\t\tpath: string,\n\t\thandlers: Array<Middleware<DI> | Handler<DI>>,\n\t): void {\n\t\tconst mainHandler = handlers[handlers.length - 1] as Handler<DI>;\n\t\tconst routeMiddlewares = handlers.slice(0, -1) as Middleware<DI>[];\n\n\t\t// Collect OpenAPI metadata\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Required for flexible schema representation\n\t\tconst openApiDoc: any = {\n\t\t\tmethod: method.toLowerCase(),\n\t\t\tpath,\n\t\t\trequest: { params: null, query: null, body: null },\n\t\t\tresponses: [],\n\t\t};\n\n\t\tfor (const handler of handlers) {\n\t\t\tconst h = handler as unknown as Record<string, unknown>;\n\t\t\tif (h._isBuntokValidator) {\n\t\t\t\tconst target = h._target as string;\n\t\t\t\tconst schema = h._schema;\n\t\t\t\topenApiDoc.request[target] = schema;\n\t\t\t\tif (target === \"body\") {\n\t\t\t\t\topenApiDoc.request.bodyContentType = h._contentType as string;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (h._isBuntokResponse) {\n\t\t\t\topenApiDoc.responses.push({\n\t\t\t\t\tstatus: h._status,\n\t\t\t\t\tschema: h._schema,\n\t\t\t\t\tdescription: h._description,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Always register the route in OpenAPI, even if it lacks explicit validation/responses\n\t\tthis.openApiDocs.push(openApiDoc);\n\n\t\t// AOT Compile route middlewares\n\t\tconst executionChain = this.compilePipeline(routeMiddlewares, mainHandler);\n\n\t\tthis.router.insert(method, path, executionChain);\n\t}\n\n\tprivate compilePipeline(\n\t\tmiddlewares: Middleware<DI>[],\n\t\tfinalHandler: Handler<DI>,\n\t): Handler<DI> {\n\t\tif (middlewares.length === 0) return finalHandler;\n\n\t\tconst fns = [...middlewares, finalHandler];\n\t\tlet code = `return fns[${fns.length - 1}](ctx);`;\n\t\tfor (let i = fns.length - 2; i >= 0; i--) {\n\t\t\tcode = `return fns[${i}](ctx, () => { ${code} });`;\n\t\t}\n\n\t\tconst factory = new Function(\"fns\", `return function(ctx) { ${code} }`);\n\t\treturn factory(fns) as Handler<DI>;\n\t}\n\n\tprivate compileGlobalPipeline(): void {\n\t\tif (this.middlewares.length === 0) {\n\t\t\tthis.compiledGlobalPipeline = (ctx, finalHandler) =>\n\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: compiled\n\t\t\t\tfinalHandler(ctx as any);\n\t\t\treturn;\n\t\t}\n\n\t\tconst fns = [...this.middlewares];\n\t\tlet code = `return finalHandler(ctx);`;\n\t\tfor (let i = fns.length - 1; i >= 0; i--) {\n\t\t\tcode = `return fns[${i}](ctx, () => { ${code} });`;\n\t\t}\n\n\t\tconst factory = new Function(\n\t\t\t\"fns\",\n\t\t\t`return function(ctx, finalHandler) { ${code} }`,\n\t\t);\n\t\tthis.compiledGlobalPipeline = factory(fns) as (\n\t\t\tctx: Context<DI>,\n\t\t\tfinalHandler: Handler<DI>,\n\t\t) => Response | Promise<Response>;\n\t}\n\n\tprivate compileAOTRouter(): (\n\t\trequest: Request,\n\t\tserver?: Server<WSData<DI>>,\n\t) => Response | Promise<Response> {\n\t\tlet code =\n\t\t\t\"return function(request, server) {\\n\" +\n\t\t\t\"  const url = request.url;\\n\" +\n\t\t\t\"  let start = url.indexOf('/', url.indexOf('//') + 2);\\n\" +\n\t\t\t\"  if (start === -1) start = url.length;\\n\" +\n\t\t\t\"  let end = url.indexOf('?', start);\\n\" +\n\t\t\t\"  if (end === -1) end = url.length;\\n\" +\n\t\t\t\"  const pathname = start === url.length ? '/' : url.substring(start, end);\\n\";\n\n\t\tif (this.wsRoutes.size > 0) {\n\t\t\tcode +=\n\t\t\t\t\"  if (server && wsRoutes.has(pathname)) {\\n\" +\n\t\t\t\t\"    const wsHandler = wsRoutes.get(pathname);\\n\" +\n\t\t\t\t\"    const ctx = new Context(request, EMPTY_PARAMS, di);\\n\" +\n\t\t\t\t\"    const data = { ctx, handler: wsHandler };\\n\" +\n\t\t\t\t\"    const upgraded = server.upgrade(request, { data });\\n\" +\n\t\t\t\t\"    if (upgraded) return undefined;\\n\" +\n\t\t\t\t\"    return new Response('Upgrade Required', { status: 426, headers: { Connection: 'Upgrade', Upgrade: 'websocket' } });\\n\" +\n\t\t\t\t\"  }\\n\";\n\t\t}\n\n\t\tcode += \"  const method = request.method;\\n\" + \"  switch(method) {\\n\";\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: generic\n\t\tconst handlersList: any[] = [];\n\t\t// biome-ignore lint/suspicious/noExplicitAny: generic\n\t\tconst handlersMap = new Map<any, string>();\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: generic\n\t\tfunction getHandlerIndex(handler: any) {\n\t\t\tif (handlersMap.has(handler)) return handlersMap.get(handler);\n\t\t\tconst idx = handlersList.length;\n\t\t\thandlersList.push(handler);\n\t\t\thandlersMap.set(handler, `handlers[${idx}]`);\n\t\t\treturn `handlers[${idx}]`;\n\t\t}\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: generic\n\t\tconst methodPaths = new Map<string, { path: string; handler: any }[]>();\n\t\tfor (const [path, methodMap] of this.router.staticRoutes.entries()) {\n\t\t\tfor (const [method, handler] of methodMap.entries()) {\n\t\t\t\tif (!methodPaths.has(method)) methodPaths.set(method, []);\n\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: guaranteed\n\t\t\t\tmethodPaths.get(method)!.push({ path, handler });\n\t\t\t}\n\t\t}\n\n\t\tfor (const [method, routes] of methodPaths.entries()) {\n\t\t\tcode += `case \"${method}\": {\\n`;\n\t\t\tcode += \"  switch(pathname) {\\n\";\n\t\t\tfor (const route of routes) {\n\t\t\t\tconst handlerRef = getHandlerIndex(route.handler);\n\t\t\t\tcode += `    case \"${route.path}\": {\\n`;\n\t\t\t\tcode += \"      const ctx = new Context(request, EMPTY_PARAMS, di);\\n\";\n\t\t\t\tcode += \"      try {\\n\";\n\t\t\t\tcode +=\n\t\t\t\t\t\"        const result = compiledGlobalPipeline(ctx, \" +\n\t\t\t\t\thandlerRef +\n\t\t\t\t\t\");\\n\";\n\t\t\t\tif (this._skipLogResponse) {\n\t\t\t\t\tcode += \"        if (result instanceof Promise) {\\n\";\n\t\t\t\t\tcode +=\n\t\t\t\t\t\t\"          return result.catch((e) => handleError(request, pathname, ctx, e));\\n\";\n\t\t\t\t\tcode += \"        }\\n\";\n\t\t\t\t\tcode += \"        return result;\\n\";\n\t\t\t\t} else {\n\t\t\t\t\tcode += \"        if (result instanceof Promise) {\\n\";\n\t\t\t\t\tcode +=\n\t\t\t\t\t\t\"          return result.then((r) => logResponse(request, pathname, r)).catch((e) => handleError(request, pathname, ctx, e));\\n\";\n\t\t\t\t\tcode += \"        }\\n\";\n\t\t\t\t\tcode += \"        return logResponse(request, pathname, result);\\n\";\n\t\t\t\t}\n\t\t\t\tcode += \"      } catch (err) {\\n\";\n\t\t\t\tcode += \"        return handleError(request, pathname, ctx, err);\\n\";\n\t\t\t\tcode += \"      }\\n\";\n\t\t\t\tcode += \"    }\\n\";\n\t\t\t}\n\t\t\tcode += \"  }\\n\";\n\t\t\tcode += \"  break;\\n\";\n\t\t\tcode += \"}\\n\";\n\t\t}\n\n\t\tcode += \"  }\\n\" + \"  return fallback(request, server);\\n\" + \"};\\n\";\n\n\t\tconst factory = new Function(\n\t\t\t\"Context\",\n\t\t\t\"EMPTY_PARAMS\",\n\t\t\t\"di\",\n\t\t\t\"handlers\",\n\t\t\t\"compiledGlobalPipeline\",\n\t\t\t\"logResponse\",\n\t\t\t\"handleError\",\n\t\t\t\"fallback\",\n\t\t\t\"wsRoutes\",\n\t\t\tcode,\n\t\t);\n\n\t\tconst EMPTY_PARAMS = Object.freeze({});\n\t\treturn factory(\n\t\t\tContext,\n\t\t\tEMPTY_PARAMS,\n\t\t\tthis.di,\n\t\t\thandlersList,\n\t\t\tthis.compiledGlobalPipeline,\n\t\t\tthis.logResponse,\n\t\t\tthis.handleError,\n\t\t\tthis.fallbackHandleRequest.bind(this),\n\t\t\tthis.wsRoutes,\n\t\t);\n\t}\n\n\tprivate extractPathname(url: string): string {\n\t\t// Skip protocol + authority (http://localhost:1212)\n\t\tconst start = url.indexOf(\"/\", url.indexOf(\"//\") + 2);\n\t\tif (start === -1) return \"/\";\n\t\tlet end = url.indexOf(\"?\", start);\n\t\tif (end === -1) end = url.length;\n\t\treturn url.substring(start, end);\n\t}\n\n\t// Bound once per App instance instead of allocating a new closure per request\n\tprivate readonly logResponse = (\n\t\trequest: Request,\n\t\tpathname: string,\n\t\tresponse: Response,\n\t): Response => {\n\t\t// Skip building the log string entirely when request logging is off\n\t\tif (logger.logRequests) {\n\t\t\tlogger.info(`${request.method} ${pathname}`, {\n\t\t\t\tstatus: response.status,\n\t\t\t});\n\t\t}\n\t\tif (this.poweredByHeaderEnabled) {\n\t\t\tresponse.headers.set(\"X-Powered-By\", \"buntok\");\n\t\t}\n\t\treturn response;\n\t};\n\n\tprivate readonly handleError = (\n\t\trequest: Request,\n\t\tpathname: string,\n\t\tctx: Context<DI>,\n\t\terr: unknown,\n\t): Response | Promise<Response> => {\n\t\tconst errorObj = err instanceof Error ? err : new Error(String(err));\n\t\tlogger.error(`${request.method} ${pathname}`, {\n\t\t\terror: errorObj.message,\n\t\t});\n\t\tconst result = this.customErrorHandler(errorObj, ctx);\n\t\tif (result instanceof Promise) {\n\t\t\treturn result.then((response) => {\n\t\t\t\tif (this.poweredByHeaderEnabled) {\n\t\t\t\t\tresponse.headers.set(\"X-Powered-By\", \"buntok\");\n\t\t\t\t}\n\t\t\t\treturn response;\n\t\t\t});\n\t\t}\n\t\tif (this.poweredByHeaderEnabled) {\n\t\t\tresult.headers.set(\"X-Powered-By\", \"buntok\");\n\t\t}\n\t\treturn result;\n\t};\n\n\t/**\n\t * Dispatch a request through the app without binding to a real port.\n\t * Meant for tests: `await app.request(\"/users/1\")` is much faster than\n\t * spinning up a server and making a real HTTP call.\n\t *\n\t * Accepts the same input as the global `fetch()` / `Request` constructor.\n\t */\n\tpublic async request(\n\t\tinput: string | Request | URL,\n\t\tinit?: RequestInit,\n\t): Promise<Response> {\n\t\tif (!this.compiledGlobalPipeline) this.compileGlobalPipeline();\n\t\tthis._compiledAOTRouter = this.compileAOTRouter();\n\t\tconst request =\n\t\t\tinput instanceof Request && !init\n\t\t\t\t? input\n\t\t\t\t: new Request(\n\t\t\t\t\t\ttypeof input === \"string\" && !/^https?:\\/\\//.test(input)\n\t\t\t\t\t\t\t? `http://localhost${input.startsWith(\"/\") ? \"\" : \"/\"}${input}`\n\t\t\t\t\t\t\t: // biome-ignore lint/suspicious/noExplicitAny: Standard fetch input overriding\n\t\t\t\t\t\t\t\t(input as any),\n\t\t\t\t\t\tinit,\n\t\t\t\t\t);\n\t\treturn this.handleRequest(request);\n\t}\n\n\tprivate _compiledAOTRouter: (\n\t\trequest: Request,\n\t\tserver?: Server<WSData<DI>>,\n\t) => Response | Promise<Response> = this.fallbackHandleRequest.bind(this);\n\n\tpublic handleRequest(\n\t\trequest: Request,\n\t\tserver?: Server<WSData<DI>>,\n\t): Response | Promise<Response> {\n\t\treturn this._compiledAOTRouter(request, server);\n\t}\n\n\tpublic fallbackHandleRequest(\n\t\trequest: Request,\n\t\tserver?: Server<WSData<DI>>,\n\t): Response | Promise<Response> {\n\t\tconst pathname = this.extractPathname(request.url);\n\n\t\tif (server && this.wsRoutes.size > 0) {\n\t\t\tconst wsHandler = this.wsRoutes.get(pathname);\n\t\t\tif (wsHandler) {\n\t\t\t\tconst ctx = new Context(request, {}, this.di) as Context<DI>;\n\t\t\t\tconst data: WSData<DI> = { ctx, handler: wsHandler };\n\t\t\t\tconst upgraded = server.upgrade(request, { data });\n\t\t\t\tif (upgraded) {\n\t\t\t\t\treturn undefined as unknown as Response;\n\t\t\t\t}\n\t\t\t\treturn new Response(\"Upgrade Required\", {\n\t\t\t\t\tstatus: 426,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tConnection: \"Upgrade\",\n\t\t\t\t\t\tUpgrade: \"websocket\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tconst route = this.router.find(request.method, pathname);\n\n\t\tconst ctx = new Context(request, route.params, this.di) as Context<DI>;\n\n\t\tlet finalHandler = route.handler as Handler<DI>;\n\t\tif (!finalHandler) {\n\t\t\tfinalHandler = this.customNotFoundHandler;\n\t\t}\n\n\t\ttry {\n\t\t\t// biome-ignore lint/style/noNonNullAssertion: Guaranteed by compileGlobalPipeline\n\t\t\tconst result = this.compiledGlobalPipeline!(ctx, finalHandler);\n\n\t\t\tif (result instanceof Promise) {\n\t\t\t\t// A closure is unavoidable here since .then/.catch need the\n\t\t\t\t// per-request context, but this only happens on the async path.\n\t\t\t\treturn result\n\t\t\t\t\t.then((response) => this.logResponse(request, pathname, response))\n\t\t\t\t\t.catch((err) => this.handleError(request, pathname, ctx, err));\n\t\t\t}\n\t\t\treturn this.logResponse(request, pathname, result);\n\t\t} catch (err) {\n\t\t\treturn this.handleError(request, pathname, ctx, err);\n\t\t}\n\t}\n\n\tpublic listen(port?: number, callback?: () => void): void {\n\t\t// Skip server startup when running under make:docs\n\t\tif (process.env.BUNTOK_DOCS_BUILD === \"1\") return;\n\t\tif (this.isListening) return;\n\t\tthis.isListening = true;\n\n\t\t// Pre-compute whether logResponse can be skipped entirely\n\t\tthis._skipLogResponse = !logger.logRequests && !this.poweredByHeaderEnabled;\n\n\t\t// Perform AOT compilation for global middlewares\n\t\tthis.compileGlobalPipeline();\n\t\tthis._compiledAOTRouter = this.compileAOTRouter();\n\n\t\tconst finalPort = port || Number(process.env.PORT) || 1212;\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Required for bun serve signature compatibility\n\t\tconst serveOptions: any = {\n\t\t\tport: finalPort,\n\t\t\tfetch: this._compiledAOTRouter,\n\t\t};\n\n\t\tif (this._reusePort) {\n\t\t\tserveOptions.reusePort = true;\n\t\t}\n\n\t\tif (this.wsRoutes.size > 0) {\n\t\t\tserveOptions.websocket = {\n\t\t\t\topen: (ws: ServerWebSocket<WSData<DI>>) => {\n\t\t\t\t\tws.data.handler.open?.(ws);\n\t\t\t\t},\n\t\t\t\tmessage: (\n\t\t\t\t\tws: ServerWebSocket<WSData<DI>>,\n\t\t\t\t\tmessage: string | Buffer,\n\t\t\t\t) => {\n\t\t\t\t\tws.data.handler.message?.(ws, message);\n\t\t\t\t},\n\t\t\t\tclose: (\n\t\t\t\t\tws: ServerWebSocket<WSData<DI>>,\n\t\t\t\t\tcode: number,\n\t\t\t\t\treason: string,\n\t\t\t\t) => {\n\t\t\t\t\tws.data.handler.close?.(ws, code, reason);\n\t\t\t\t},\n\t\t\t\tdrain: (ws: ServerWebSocket<WSData<DI>>) => {\n\t\t\t\t\tws.data.handler.drain?.(ws);\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tthis.server = Bun.serve<WSData<DI>>(serveOptions);\n\n\t\tlogger.info(`Server listening at http://localhost:${finalPort}`);\n\n\t\tif (callback) callback();\n\t}\n}\n\nexport class RouterGroup<\n\tDI extends Record<string, unknown> = Record<string, unknown>,\n> {\n\tprivate prefix: string;\n\tprivate app: App<DI>;\n\tprivate groupMiddlewares: Middleware<DI>[] = [];\n\n\tconstructor(prefix: string, app: App<DI>) {\n\t\tthis.prefix = prefix.endsWith(\"/\") ? prefix.slice(0, -1) : prefix;\n\t\tthis.app = app;\n\t}\n\n\tpublic use(middleware: Middleware<DI>): this {\n\t\tthis.groupMiddlewares.push(middleware);\n\t\treturn this;\n\t}\n\n\tpublic group(prefix: string): RouterGroup<DI> {\n\t\tconst newGroup = new RouterGroup<DI>(this.prefix + prefix, this.app);\n\t\tnewGroup.groupMiddlewares = [...this.groupMiddlewares];\n\t\treturn newGroup;\n\t}\n\n\tprivate normalizePath(path: string): string {\n\t\tconst cleanPath = path === \"/\" ? \"\" : path;\n\t\treturn `${this.prefix}${cleanPath}`;\n\t}\n\n\tpublic get<Path extends string>(path: Path, handler: Handler<DI, Path>): this;\n\tpublic get<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic get<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic get<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic get<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic get<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic get<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.app.registerRoute(\"GET\", this.normalizePath(path), [\n\t\t\t...this.groupMiddlewares,\n\t\t\t...handlers,\n\t\t]);\n\t\treturn this;\n\t}\n\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic post<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.app.registerRoute(\"POST\", this.normalizePath(path), [\n\t\t\t...this.groupMiddlewares,\n\t\t\t...handlers,\n\t\t]);\n\t\treturn this;\n\t}\n\n\tpublic put<Path extends string>(path: Path, handler: Handler<DI, Path>): this;\n\tpublic put<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic put<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic put<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic put<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic put<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic put<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.app.registerRoute(\"PUT\", this.normalizePath(path), [\n\t\t\t...this.groupMiddlewares,\n\t\t\t...handlers,\n\t\t]);\n\t\treturn this;\n\t}\n\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic delete<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.app.registerRoute(\"DELETE\", this.normalizePath(path), [\n\t\t\t...this.groupMiddlewares,\n\t\t\t...handlers,\n\t\t]);\n\t\treturn this;\n\t}\n\n\t// QUERY method - like GET but with body support\n\tpublic query(path: string, handler: Handler<DI>): this;\n\tpublic query(\n\t\tpath: string,\n\t\tmiddleware: Middleware<DI>,\n\t\thandler: Handler<DI>,\n\t): this;\n\tpublic query(\n\t\tpath: string,\n\t\tm1: Middleware<DI>,\n\t\tm2: Middleware<DI>,\n\t\thandler: Handler<DI>,\n\t): this;\n\tpublic query(\n\t\tpath: string,\n\t\tm1: Middleware<DI>,\n\t\tm2: Middleware<DI>,\n\t\tm3: Middleware<DI>,\n\t\thandler: Handler<DI>,\n\t): this;\n\tpublic query(\n\t\tpath: string,\n\t\tm1: Middleware<DI>,\n\t\tm2: Middleware<DI>,\n\t\tm3: Middleware<DI>,\n\t\tm4: Middleware<DI>,\n\t\thandler: Handler<DI>,\n\t): this;\n\tpublic query(\n\t\tpath: string,\n\t\tm1: Middleware<DI>,\n\t\tm2: Middleware<DI>,\n\t\tm3: Middleware<DI>,\n\t\tm4: Middleware<DI>,\n\t\tm5: Middleware<DI>,\n\t\thandler: Handler<DI>,\n\t): this;\n\tpublic query(\n\t\tpath: string,\n\t\t...handlers: Array<Middleware<DI> | Handler<DI>>\n\t): this {\n\t\tthis.app.registerRoute(\"QUERY\", this.normalizePath(path), [\n\t\t\t...this.groupMiddlewares,\n\t\t\t...handlers,\n\t\t]);\n\t\treturn this;\n\t}\n\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic options<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.app.registerRoute(\"OPTIONS\", this.normalizePath(path), [\n\t\t\t...this.groupMiddlewares,\n\t\t\t...handlers,\n\t\t]);\n\t\treturn this;\n\t}\n\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic patch<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.app.registerRoute(\"PATCH\", this.normalizePath(path), [\n\t\t\t...this.groupMiddlewares,\n\t\t\t...handlers,\n\t\t]);\n\t\treturn this;\n\t}\n\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic head<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tthis.app.registerRoute(\"HEAD\", this.normalizePath(path), [\n\t\t\t...this.groupMiddlewares,\n\t\t\t...handlers,\n\t\t]);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Register a handler for all standard HTTP methods (GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS).\n\t */\n\tpublic all<Path extends string>(path: Path, handler: Handler<DI, Path>): this;\n\tpublic all<Path extends string>(\n\t\tpath: Path,\n\t\tmiddleware: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic all<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic all<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic all<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic all<Path extends string>(\n\t\tpath: Path,\n\t\tm1: Middleware<DI, Path>,\n\t\tm2: Middleware<DI, Path>,\n\t\tm3: Middleware<DI, Path>,\n\t\tm4: Middleware<DI, Path>,\n\t\tm5: Middleware<DI, Path>,\n\t\thandler: Handler<DI, Path>,\n\t): this;\n\tpublic all<Path extends string>(\n\t\tpath: Path,\n\t\t...handlers: Array<Middleware<DI, Path> | Handler<DI, Path>>\n\t): this {\n\t\tconst methods = [\n\t\t\t\"GET\",\n\t\t\t\"HEAD\",\n\t\t\t\"POST\",\n\t\t\t\"PUT\",\n\t\t\t\"PATCH\",\n\t\t\t\"DELETE\",\n\t\t\t\"OPTIONS\",\n\t\t];\n\t\tfor (const method of methods) {\n\t\t\tthis.app.registerRoute(method, this.normalizePath(path), [\n\t\t\t\t...this.groupMiddlewares,\n\t\t\t\t...handlers,\n\t\t\t]);\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * Register a WebSocket endpoint within this group.\n\t * Path is prefixed with the group prefix.\n\t */\n\tpublic ws(path: string, handler: WSHandler<DI>): this {\n\t\tthis.app.ws(this.normalizePath(path), handler);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Serve static files within this group.\n\t * Route path is prefixed with the group prefix.\n\t */\n\tpublic static(routePath: string, directory: string): this {\n\t\tthis.app.static(this.normalizePath(routePath), directory);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Register a decorator-based controller within this group.\n\t * The controller's prefix is combined with the group prefix.\n\t *\n\t * @example\n\t * const api = app.group(\"/api/v1\");\n\t * api.registerController(UserController);\n\t * // → routes registered as /api/v1/users, /api/v1/users/:id, etc.\n\t */\n\tpublic registerController<T extends object>(\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Constructor args are unknowable\n\t\ttarget: (new (...args: any[]) => T) | T,\n\t): this {\n\t\tconst isInstance =\n\t\t\ttypeof target === \"object\" &&\n\t\t\ttarget !== null &&\n\t\t\ttypeof target === \"object\";\n\n\t\tconst ControllerClass = isInstance\n\t\t\t? // biome-ignore lint/suspicious/noExplicitAny: dynamic type narrowing\n\t\t\t\t(target as any).constructor\n\t\t\t: // biome-ignore lint/suspicious/noExplicitAny: dynamic type narrowing\n\t\t\t\t(target as new (\n\t\t\t\t\t...args: any[]\n\t\t\t\t) => T);\n\n\t\tconst meta = getControllerMeta(ControllerClass);\n\t\tif (!meta) {\n\t\t\tthrow new Error(\n\t\t\t\t`${ControllerClass.name} is not decorated with @Controller — did you forget to add it?`,\n\t\t\t);\n\t\t}\n\n\t\tlet instance: T;\n\n\t\tif (isInstance) {\n\t\t\tinstance = target as T;\n\t\t} else {\n\t\t\tconst container = this.app.getContainer();\n\t\t\tif (container) {\n\t\t\t\tinstance = container.resolve<T>(ControllerClass);\n\t\t\t} else {\n\t\t\t\tinstance = new ControllerClass();\n\t\t\t}\n\t\t}\n\n\t\tconst normalizedPrefix = meta.prefix.endsWith(\"/\")\n\t\t\t? meta.prefix.slice(0, -1)\n\t\t\t: meta.prefix;\n\n\t\tfor (const route of meta.routes) {\n\t\t\tconst cleanPath = route.path === \"/\" ? \"\" : route.path;\n\t\t\tconst fullPath =\n\t\t\t\t`${this.normalizePath(normalizedPrefix)}${cleanPath}` || \"/\";\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: dynamic method dispatch by decorated property key\n\t\t\tconst handler = (instance as any)[route.propertyKey].bind(\n\t\t\t\tinstance,\n\t\t\t) as Handler<DI>;\n\n\t\t\tthis.app.registerRoute(route.method, fullPath, [\n\t\t\t\t...(route.middlewares as Middleware<DI>[]),\n\t\t\t\t...this.groupMiddlewares,\n\t\t\t\thandler,\n\t\t\t]);\n\t\t}\n\n\t\treturn this;\n\t}\n}\n","export type Scope = \"singleton\" | \"transient\";\n\n// biome-ignore lint/complexity/noBannedTypes: Token can be string or class constructor\ntype Token = string | Function;\n\n// biome-ignore lint/suspicious/noExplicitAny: Generic provider defaults require any\nexport interface ClassProvider<T = any> {\n\tuseClass: new (\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Constructor args are unknowable\n\t\t...args: any[]\n\t) => T;\n\tscope?: Scope;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: Generic provider defaults require any\nexport interface ValueProvider<T = any> {\n\tuseValue: T;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: Generic provider defaults require any\nexport interface FactoryProvider<T = any> {\n\tuseFactory: (container: Container) => T;\n\tscope?: Scope;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: Generic provider defaults require any\nexport type Provider<T = any> =\n\t| ClassProvider<T>\n\t| ValueProvider<T>\n\t| FactoryProvider<T>;\n\nfunction isClassProvider(p: Provider): p is ClassProvider {\n\treturn \"useClass\" in p;\n}\n\nfunction isValueProvider(p: Provider): p is ValueProvider {\n\treturn \"useValue\" in p;\n}\n\nfunction isFactoryProvider(p: Provider): p is FactoryProvider {\n\treturn \"useFactory\" in p;\n}\n\nexport class Container {\n\t// biome-ignore lint/suspicious/noExplicitAny: Internal provider storage\n\tprivate providers = new Map<Token, Provider<any>>();\n\t// biome-ignore lint/suspicious/noExplicitAny: Cached singleton instances\n\tprivate singletons = new Map<Token, any>();\n\tprivate resolving = new Set<Token>();\n\n\t/**\n\t * Register a provider for a given token (class or string key).\n\t */\n\tregister<T>(token: Token, provider: Provider<T>): this {\n\t\tthis.providers.set(token, provider);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Auto-register a class provider by its own constructor as the token.\n\t */\n\tregisterClass<T>(\n\t\tcls: new (\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: Constructor args are unknowable\n\t\t\t...args: any[]\n\t\t) => T,\n\t\tscope: Scope = \"singleton\",\n\t): this {\n\t\tthis.providers.set(cls, { useClass: cls, scope });\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resolve a dependency by token. Returns cached instance for singletons.\n\t */\n\tresolve<T>(token: Token): T {\n\t\tconst cached = this.singletons.get(token);\n\t\tif (cached !== undefined) return cached as T;\n\n\t\tif (this.resolving.has(token)) {\n\t\t\tconst name = typeof token === \"function\" ? token.name : String(token);\n\t\t\tthrow new Error(`Circular dependency detected: ${name}`);\n\t\t}\n\n\t\tconst provider = this.providers.get(token);\n\t\tif (!provider) {\n\t\t\tconst name = typeof token === \"function\" ? token.name : String(token);\n\t\t\tthrow new Error(`No provider registered for: ${name}`);\n\t\t}\n\n\t\tthis.resolving.add(token);\n\t\t// biome-ignore lint/suspicious/noExplicitAny: Dynamic instantiation\n\t\tlet instance: any;\n\t\tlet scope: Scope = \"singleton\";\n\n\t\tif (isClassProvider(provider)) {\n\t\t\tscope = provider.scope ?? \"singleton\";\n\t\t\tconst meta = provider.useClass[Symbol.metadata] as\n\t\t\t\t| Record<string, unknown>\n\t\t\t\t| undefined;\n\t\t\tconst injections = meta?.__injections as Map<string, Token> | undefined;\n\n\t\t\tinstance = new provider.useClass();\n\n\t\t\tif (injections) {\n\t\t\t\tfor (const [prop, depToken] of injections) {\n\t\t\t\t\t(instance as Record<string, unknown>)[prop] = this.resolve(depToken);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (isValueProvider(provider)) {\n\t\t\tscope = \"singleton\";\n\t\t\tinstance = provider.useValue;\n\t\t} else if (isFactoryProvider(provider)) {\n\t\t\tscope = provider.scope ?? \"singleton\";\n\t\t\tinstance = provider.useFactory(this);\n\t\t}\n\n\t\tthis.resolving.delete(token);\n\n\t\tif (scope !== \"transient\") {\n\t\t\tthis.singletons.set(token, instance);\n\t\t}\n\n\t\treturn instance as T;\n\t}\n\n\t/**\n\t * Resolve and return an instance, or undefined if not registered.\n\t */\n\tget<T>(token: Token): T | undefined {\n\t\tif (this.singletons.has(token)) return this.singletons.get(token) as T;\n\t\tif (this.providers.has(token)) return this.resolve(token);\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Check whether a token has been registered.\n\t */\n\thas(token: Token): boolean {\n\t\treturn this.providers.has(token);\n\t}\n\n\t/**\n\t * Check whether a token has been resolved and cached.\n\t */\n\thasResolved(token: Token): boolean {\n\t\treturn this.singletons.has(token);\n\t}\n\n\t/**\n\t * Force-clear all providers and cached instances.\n\t * Useful in tests.\n\t */\n\tclear(): void {\n\t\tthis.providers.clear();\n\t\tthis.singletons.clear();\n\t\tthis.resolving.clear();\n\t}\n}\n","export interface SSEOptions {\n\t/** Send initial connection event */\n\tsendInitial?: boolean;\n\t/** Custom event name for initial connection */\n\tinitialEvent?: string;\n\t/** Retry timeout in milliseconds (client reconnection) */\n\tretry?: number;\n}\n\nexport interface SSEMessage {\n\t/** Event name */\n\tevent?: string;\n\t/** Message data */\n\tdata: string | object;\n\t/** Unique message ID for resumption */\n\tid?: string | number;\n}\n\nexport class SSE {\n\tprivate controller: ReadableStreamDefaultController | null = null;\n\tprivate encoder = new TextEncoder();\n\tprivate closed = false;\n\tprivate heartbeatInterval: ReturnType<typeof setInterval> | null = null;\n\n\tconstructor(\n\t\tprivate request: Request,\n\t\tprivate options: SSEOptions = {},\n\t) {}\n\n\t/**\n\t * Create SSE response with ReadableStream\n\t */\n\tconnect(): Response {\n\t\tconst stream = new ReadableStream({\n\t\t\tstart: (controller) => {\n\t\t\t\tthis.controller = controller;\n\n\t\t\t\t// Send initial connection event\n\t\t\t\tif (this.options.sendInitial !== false) {\n\t\t\t\t\tconst eventName = this.options.initialEvent || \"connected\";\n\t\t\t\t\tthis.sendMessage({ event: eventName, data: \"connected\" });\n\t\t\t\t}\n\n\t\t\t\t// Send retry timeout\n\t\t\t\tif (this.options.retry) {\n\t\t\t\t\tthis.sendRaw(`retry: ${this.options.retry}\\n\\n`);\n\t\t\t\t}\n\n\t\t\t\t// Start heartbeat to keep connection alive\n\t\t\t\tthis.startHeartbeat();\n\n\t\t\t\t// Handle client disconnect\n\t\t\t\tthis.request.signal.addEventListener(\"abort\", () => {\n\t\t\t\t\tthis.close();\n\t\t\t\t});\n\t\t\t},\n\t\t\tcancel: () => {\n\t\t\t\tthis.close();\n\t\t\t},\n\t\t});\n\n\t\treturn new Response(stream, {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\t\"Cache-Control\": \"no-cache\",\n\t\t\t\tConnection: \"keep-alive\",\n\t\t\t\t\"X-Accel-Buffering\": \"no\", // Disable nginx buffering\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * Send a message to the client\n\t */\n\tsend(message: SSEMessage): void {\n\t\tif (this.closed) return;\n\t\tthis.sendMessage(message);\n\t}\n\n\t/**\n\t * Send a simple data message\n\t */\n\tsendData(data: string | object): void {\n\t\tthis.send({ data });\n\t}\n\n\t/**\n\t * Send a named event\n\t */\n\tsendEvent(event: string, data: string | object): void {\n\t\tthis.send({ event, data });\n\t}\n\n\t/**\n\t * Send a message with ID (for resumption)\n\t */\n\tsendWithId(id: string | number, data: string | object): void {\n\t\tthis.send({ id, data });\n\t}\n\n\tprivate disconnectCallbacks: Array<() => void> = [];\n\n\t/**\n\t * Register a callback to be called when the connection closes\n\t */\n\tonClose(callback: () => void): void {\n\t\tthis.disconnectCallbacks.push(callback);\n\t}\n\n\t/**\n\t * Send raw string to the stream\n\t */\n\tprivate sendRaw(raw: string): void {\n\t\tif (this.closed || !this.controller) return;\n\t\ttry {\n\t\t\tthis.controller.enqueue(this.encoder.encode(raw));\n\t\t} catch (_error) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/**\n\t * Format and send SSE message\n\t */\n\tprivate sendMessage(message: SSEMessage): void {\n\t\tlet raw = \"\";\n\n\t\tif (message.id !== undefined) {\n\t\t\traw += `id: ${message.id}\\n`;\n\t\t}\n\t\tif (message.event) {\n\t\t\traw += `event: ${message.event}\\n`;\n\t\t}\n\n\t\tconst data =\n\t\t\ttypeof message.data === \"object\"\n\t\t\t\t? JSON.stringify(message.data)\n\t\t\t\t: message.data;\n\n\t\t// SSE spec: data cannot contain \\n, split into multiple data lines\n\t\tconst dataLines = data.split(\"\\n\");\n\t\tfor (const line of dataLines) {\n\t\t\traw += `data: ${line}\\n`;\n\t\t}\n\n\t\traw += \"\\n\";\n\t\tthis.sendRaw(raw);\n\t}\n\n\t/**\n\t * Start heartbeat to keep connection alive\n\t */\n\tprivate startHeartbeat(): void {\n\t\t// Send comment every 30 seconds to keep connection alive\n\t\tthis.heartbeatInterval = setInterval(() => {\n\t\t\tthis.sendRaw(\": heartbeat\\n\\n\");\n\t\t}, 30000);\n\t}\n\n\t/**\n\t * Close the SSE connection\n\t */\n\tclose(): void {\n\t\tif (this.closed) return;\n\t\tthis.closed = true;\n\n\t\tfor (const cb of this.disconnectCallbacks) {\n\t\t\ttry {\n\t\t\t\tcb();\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error(\"SSE onClose error:\", e);\n\t\t\t}\n\t\t}\n\t\tthis.disconnectCallbacks = [];\n\n\t\tif (this.heartbeatInterval) {\n\t\t\tclearInterval(this.heartbeatInterval);\n\t\t\tthis.heartbeatInterval = null;\n\t\t}\n\n\t\tif (this.controller) {\n\t\t\ttry {\n\t\t\t\tthis.controller.close();\n\t\t\t} catch (_e) {}\n\t\t\tthis.controller = null;\n\t\t}\n\t}\n\n\t/**\n\t * Check if connection is still open\n\t */\n\tget isConnected(): boolean {\n\t\treturn !this.closed;\n\t}\n}\n\n/**\n * Create SSE helper from Buntok context\n */\nexport function createSSE(request: Request, options?: SSEOptions): SSE {\n\treturn new SSE(request, options);\n}\n","import { createSSE, type SSE, type SSEOptions } from \"./sse\";\n\nexport class Context<\n\tDI = Record<string, unknown>,\n\tParams = Record<string, string>,\n> {\n\tpublic request: Request;\n\tpublic params: Params & Record<string, string>;\n\n\tprivate _store: Record<string, unknown> | undefined;\n\tprivate _cookies: Record<string, string> | undefined;\n\tprivate _query: Record<string, string> | undefined;\n\tprivate _validated: Record<string, unknown> | undefined;\n\tpublic readonly di: DI;\n\tpublic _afterHooks?: Array<(res: Response) => Response | undefined>;\n\n\tconstructor(request: Request, params: Record<string, string>, di: DI) {\n\t\tthis.request = request;\n\t\tthis.params = params as unknown as Params & Record<string, string>;\n\t\tthis.di = di;\n\t}\n\n\tpublic get store(): Record<string, unknown> {\n\t\tif (!this._store) {\n\t\t\tthis._store = {};\n\t\t}\n\t\treturn this._store;\n\t}\n\n\tpublic set store(value: Record<string, unknown>) {\n\t\tthis._store = value;\n\t}\n\n\tpublic get ip(): string {\n\t\tconst forwardedFor = this.request.headers.get(\"x-forwarded-for\");\n\t\tif (forwardedFor) {\n\t\t\treturn forwardedFor.split(\",\")[0]?.trim() ?? \"\";\n\t\t}\n\t\treturn \"127.0.0.1\";\n\t}\n\n\tprivate parseCookies(): Record<string, string> {\n\t\tif (this._cookies) return this._cookies;\n\n\t\tconst nativeCookies = (this.request as { cookies?: unknown }).cookies;\n\t\tif (nativeCookies && typeof nativeCookies === \"object\") {\n\t\t\tconst map = nativeCookies as Iterable<[string, string]>;\n\t\t\tconst result: Record<string, string> = {};\n\t\t\tfor (const [key, value] of map) {\n\t\t\t\tresult[key] = value;\n\t\t\t}\n\t\t\tthis._cookies = result;\n\t\t\treturn this._cookies;\n\t\t}\n\n\t\tconst cookieHeader = this.request.headers.get(\"Cookie\");\n\t\tif (!cookieHeader) {\n\t\t\tthis._cookies = {};\n\t\t\treturn this._cookies;\n\t\t}\n\n\t\tconst result: Record<string, string> = {};\n\t\tlet start = 0;\n\t\twhile (start < cookieHeader.length) {\n\t\t\tlet end = cookieHeader.indexOf(\";\", start);\n\t\t\tif (end === -1) end = cookieHeader.length;\n\n\t\t\tconst eqIdx = cookieHeader.indexOf(\"=\", start);\n\t\t\tif (eqIdx !== -1 && eqIdx < end) {\n\t\t\t\tlet keyStart = start;\n\t\t\t\twhile (keyStart < eqIdx && cookieHeader[keyStart] === \" \") keyStart++;\n\n\t\t\t\tlet valStart = eqIdx + 1;\n\t\t\t\twhile (valStart < end && cookieHeader[valStart] === \" \") valStart++;\n\n\t\t\t\tconst key = cookieHeader.substring(keyStart, eqIdx);\n\t\t\t\tconst val = cookieHeader.substring(valStart, end);\n\t\t\t\tif (key && val) result[key] = decodeURIComponent(val);\n\t\t\t}\n\t\t\tstart = end + 1;\n\t\t}\n\n\t\tthis._cookies = result;\n\t\treturn this._cookies;\n\t}\n\n\t/**\n\t * Get a cookie value from request\n\t */\n\tpublic getCookie(name: string): string | undefined {\n\t\tconst nativeCookies = (this.request as { cookies?: unknown }).cookies;\n\t\tif (\n\t\t\t!this._cookies &&\n\t\t\tnativeCookies &&\n\t\t\ttypeof (nativeCookies as { get?: unknown }).get === \"function\"\n\t\t) {\n\t\t\treturn (\n\t\t\t\t(nativeCookies as { get: (name: string) => string | null }).get(name) ??\n\t\t\t\tundefined\n\t\t\t);\n\t\t}\n\t\treturn this.parseCookies()[name];\n\t}\n\n\t/**\n\t * Get all cookies from request\n\t */\n\tpublic getCookies(): Record<string, string> {\n\t\treturn this.parseCookies();\n\t}\n\n\t/**\n\t * Parsed query string parameters — accessed as a plain property.\n\t * Parsed lazily and cached after first access.\n\t *\n\t * @example\n\t * // GET /search?q=buntok&limit=10\n\t * const { q, limit } = ctx.query;\n\t */\n\tpublic get query(): Record<string, string> {\n\t\tif (this._query) return this._query;\n\n\t\tthis._query = {};\n\t\tconst url = this.request.url;\n\t\tconst queryIdx = url.indexOf(\"?\");\n\t\tif (queryIdx !== -1) {\n\t\t\tconst queryStr = url.substring(queryIdx + 1);\n\t\t\tif (queryStr) {\n\t\t\t\tconst pairs = queryStr.split(\"&\");\n\t\t\t\tfor (let i = 0; i < pairs.length; i++) {\n\t\t\t\t\tconst pair = pairs[i] as string;\n\t\t\t\t\tif (!pair) continue;\n\t\t\t\t\tconst eqIdx = pair.indexOf(\"=\");\n\t\t\t\t\tif (eqIdx !== -1) {\n\t\t\t\t\t\tconst key = decodeURIComponent(\n\t\t\t\t\t\t\tpair.substring(0, eqIdx).replace(/\\+/g, \" \"),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst value = decodeURIComponent(\n\t\t\t\t\t\t\tpair.substring(eqIdx + 1).replace(/\\+/g, \" \"),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis._query[key] = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst key = decodeURIComponent(pair.replace(/\\+/g, \" \"));\n\t\t\t\t\t\tthis._query[key] = \"\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this._query;\n\t}\n\n\t/**\n\t * Internal: used by validator middleware to stash parsed/validated data.\n\t * Not intended to be called directly from route handlers.\n\t */\n\tpublic setValidated(\n\t\ttarget: \"body\" | \"query\" | \"params\",\n\t\tdata: unknown,\n\t): void {\n\t\tif (!this._validated) this._validated = {};\n\t\tthis._validated[target] = data;\n\t}\n\n\t/**\n\t * Read data previously validated by `zValidator()` for the given target,\n\t * typed as `T`. Throws if no validator ran for that target, so a typo'd\n\t * target (or forgetting to add the middleware) fails loudly instead of\n\t * silently returning `undefined`.\n\t */\n\tpublic valid<T>(target: \"body\" | \"query\" | \"params\"): T {\n\t\tif (!this._validated || !(target in this._validated)) {\n\t\t\tthrow new Error(\n\t\t\t\t`ctx.valid(\"${target}\") called but no zValidator(\"${target}\", ...) middleware ran for this route`,\n\t\t\t);\n\t\t}\n\t\treturn this._validated[target] as T;\n\t}\n\n\tprivate _body: unknown | undefined;\n\n\tpublic async body<T>(): Promise<T> {\n\t\tif (this._body !== undefined) {\n\t\t\treturn this._body as T;\n\t\t}\n\t\tthis._body = await this.request.json();\n\t\treturn this._body as T;\n\t}\n\n\t// biome-ignore lint/suspicious/noExplicitAny: Undici types conflict with lib.dom FormData\n\tprivate _formData: any | undefined;\n\n\t/**\n\t * Parse and cache the multipart/form-data body.\n\t * Safe to call multiple times — the parsed FormData is cached after the first read,\n\t * so `zValidator(\"form\", ...)` and `uploader()` can both be used in the same route\n\t * without conflicting over the body stream.\n\t */\n\t// biome-ignore lint/suspicious/noExplicitAny: Undici types conflict with lib.dom FormData\n\tpublic async formData(): Promise<any> {\n\t\tif (this._formData !== undefined) {\n\t\t\treturn this._formData;\n\t\t}\n\t\tthis._formData = await this.request.formData();\n\t\treturn this._formData;\n\t}\n\n\tpublic json(data: unknown, status = 200): Response {\n\t\tif (status === 200) {\n\t\t\treturn Response.json(data);\n\t\t}\n\t\treturn Response.json(data, { status });\n\t}\n\n\tpublic success(data?: unknown, message = \"Success\", status = 200): Response {\n\t\treturn this.json({ success: true, message, data }, status);\n\t}\n\n\t/**\n\t * Standardize an offset-based pagination response.\n\t */\n\tpublic paginate<T>(\n\t\tdata: T[],\n\t\ttotal: number,\n\t\tpage: number,\n\t\tlimit: number,\n\t\tmessage = \"Success\",\n\t\tstatus = 200,\n\t): Response {\n\t\treturn this.json(\n\t\t\t{\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage,\n\t\t\t\tdata,\n\t\t\t\tmeta: {\n\t\t\t\t\tcurrentPage: page,\n\t\t\t\t\tperPage: limit,\n\t\t\t\t\ttotal,\n\t\t\t\t\tlastPage: Math.ceil(total / limit),\n\t\t\t\t\thasMore: page * limit < total,\n\t\t\t\t},\n\t\t\t},\n\t\t\tstatus,\n\t\t);\n\t}\n\n\t/**\n\t * Standardize a cursor-based pagination response (infinite scroll).\n\t */\n\tpublic cursorPaginate<T>(\n\t\tdata: T[],\n\t\tnextCursor: string | number | null,\n\t\tmessage = \"Success\",\n\t\tstatus = 200,\n\t): Response {\n\t\treturn this.json(\n\t\t\t{\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage,\n\t\t\t\tdata,\n\t\t\t\tmeta: {\n\t\t\t\t\tnextCursor,\n\t\t\t\t\thasMore: nextCursor !== null,\n\t\t\t\t},\n\t\t\t},\n\t\t\tstatus,\n\t\t);\n\t}\n\n\tpublic error(message: string, status = 400, details?: unknown): Response {\n\t\treturn this.json({ success: false, message, details }, status);\n\t}\n\n\tprivate static readonly TEXT_HEADERS = {\n\t\t\"Content-Type\": \"text/plain; charset=utf-8\",\n\t};\n\n\tpublic text(text: string, status = 200): Response {\n\t\tif (status === 200) {\n\t\t\treturn new Response(text);\n\t\t}\n\t\treturn new Response(text, {\n\t\t\tstatus,\n\t\t\theaders: Context.TEXT_HEADERS,\n\t\t});\n\t}\n\n\tprivate static readonly HTML_HEADERS = { \"Content-Type\": \"text/html\" };\n\t/**\n\t * Return HTML response\n\t */\n\tpublic html(html: string, status = 200): Response {\n\t\treturn new Response(html, {\n\t\t\tstatus,\n\t\t\theaders: Context.HTML_HEADERS,\n\t\t});\n\t}\n\n\tpublic onAfterResponse(hook: (res: Response) => Response | undefined): void {\n\t\tif (!this._afterHooks) this._afterHooks = [];\n\t\tthis._afterHooks.push(hook);\n\t}\n\n\t/**\n\t * Redirect to URL\n\t */\n\tpublic redirect(\n\t\turl: string,\n\t\tstatus: 301 | 302 | 303 | 307 | 308 = 302,\n\t): Response {\n\t\treturn new Response(null, {\n\t\t\tstatus,\n\t\t\theaders: { Location: url },\n\t\t});\n\t}\n\n\t/**\n\t * Return empty response with status code\n\t */\n\tpublic status(code: number): Response {\n\t\treturn new Response(null, { status: code });\n\t}\n\n\t/**\n\t * Start a Server-Sent Events (SSE) stream\n\t */\n\tpublic sse(\n\t\tcallback: (stream: SSE) => void | Promise<void>,\n\t\toptions?: SSEOptions,\n\t): Response {\n\t\tconst stream = createSSE(this.request, options);\n\n\t\t// Run the callback asynchronously so we can return the response immediately\n\t\tsetTimeout(async () => {\n\t\t\ttry {\n\t\t\t\tawait callback(stream);\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[SSE Error]\", err);\n\t\t\t\tstream.close();\n\t\t\t}\n\t\t}, 0);\n\n\t\treturn stream.connect();\n\t}\n}\n","// biome-ignore lint/complexity/noBannedTypes: Token can be string or class constructor\ntype Token = string | Function;\n\ninterface InjectableMetadata extends Record<string, unknown> {\n\t__injections?: Map<string, Token>;\n}\n\n/**\n * Property decorator that tells the IoC Container to resolve and inject\n * a dependency by its token when the owning class is instantiated.\n *\n * ```ts\n * @Injectable()\n * class UserController {\n *   @Inject(UserService) private service: UserService;\n *   @Inject(\"config\") private config: AppConfig;\n * }\n * ```\n */\nexport function Inject(token: Token) {\n\treturn (_value: undefined, context: ClassFieldDecoratorContext): void => {\n\t\tif (context.kind !== \"field\") {\n\t\t\tthrow new Error(\"@Inject can only decorate fields\");\n\t\t}\n\t\tconst meta = context.metadata as unknown as InjectableMetadata;\n\t\tif (!meta.__injections) {\n\t\t\tmeta.__injections = new Map();\n\t\t}\n\t\tmeta.__injections.set(String(context.name), token);\n\t};\n}\n","import type { Scope } from \"../container\";\n\n// biome-ignore lint/suspicious/noExplicitAny: Symbol.metadata is not typed in TS\ninterface InjectableMetadata extends Record<string, any> {\n\t__injectable: boolean;\n\t__scope: Scope;\n}\n\n/**\n * Marks a class as managed by the IoC Container.\n * When the container resolves this class, it will instantiate it and\n * resolve any `@Inject`-annotated properties automatically.\n *\n * ```ts\n * @Injectable()\n * class UserService {\n *   @Inject(UserRepository) private repo: UserRepository;\n * }\n * ```\n */\nexport function Injectable(options?: { scope?: Scope }) {\n\treturn (\n\t\t// biome-ignore lint/complexity/noBannedTypes: Native Decorator API uses Function\n\t\t_target: Function,\n\t\tcontext: ClassDecoratorContext,\n\t): void => {\n\t\tif (context.kind !== \"class\") {\n\t\t\tthrow new Error(\"@Injectable can only decorate classes\");\n\t\t}\n\t\tconst meta = context.metadata as unknown as InjectableMetadata;\n\t\tmeta.__injectable = true;\n\t\tmeta.__scope = options?.scope ?? \"singleton\";\n\t};\n}\n","import type { Middleware } from \"./app\";\nimport type { Context } from \"./context\";\n\n/**\n * Decorator-based controller routing, built on Stage 3 (TC39) decorators —\n * the same kind natively supported by Bun/TypeScript 5+ without setting\n * `experimentalDecorators`.\n *\n * This is a thin layer on top of the existing functional API: decorators\n * only run once at class-definition/bootstrap time, and end up calling the\n * exact same `app.registerRoute()` used by `app.get()`/`app.post()`. There\n * is zero per-request overhead — the router has no idea (and doesn't care)\n * whether a route came from a decorator or a direct `.get()` call.\n *\n * ```ts\n * @Controller(\"/users\")\n * class UserController {\n *   @Get(\"/:id\")\n *   getUser(ctx: Context) {\n *     return ctx.json({ id: ctx.params.id });\n *   }\n *\n *   @Post(\"/\")\n *   @Use(zValidator(\"body\", createUserSchema))\n *   createUser(ctx: Context) {\n *     const data = ctx.valid<{ name: string }>(\"body\");\n *     return ctx.json(data, 201);\n *   }\n * }\n *\n * app.registerController(UserController);\n * ```\n */\n\nexport interface RouteMeta {\n\tmethod: string;\n\tpath: string;\n\tpropertyKey: string;\n\tmiddlewares: Middleware[];\n}\n\nexport interface ControllerMeta {\n\tprefix: string;\n\troutes: RouteMeta[];\n}\n\nlet pendingRoutes: RouteMeta[] = [];\n\n// biome-ignore lint/complexity/noBannedTypes: Native Decorator API uses Function\nconst controllerRegistry = new WeakMap<Function, ControllerMeta>();\n\ntype MethodDecoratorFn = (\n\t// biome-ignore lint/suspicious/noExplicitAny: Required for TS method decorator contravariance\n\toriginalMethod: (...args: any[]) => any,\n\tcontext: ClassMethodDecoratorContext,\n) => void;\n\nfunction createRouteDecorator(method: string) {\n\treturn (path: string): MethodDecoratorFn => {\n\t\treturn (_originalMethod, context) => {\n\t\t\tif (context.kind !== \"method\") {\n\t\t\t\tthrow new Error(`@${method} can only decorate methods`);\n\t\t\t}\n\t\t\tconst propertyKey = String(context.name);\n\t\t\tconst entry = pendingRoutes.find((r) => r.propertyKey === propertyKey);\n\t\t\tif (entry) {\n\t\t\t\tentry.method = method;\n\t\t\t\tentry.path = path;\n\t\t\t} else {\n\t\t\t\tpendingRoutes.push({\n\t\t\t\t\tmethod,\n\t\t\t\t\tpath,\n\t\t\t\t\tpropertyKey,\n\t\t\t\t\tmiddlewares: [],\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\t};\n}\n\nexport const Get = createRouteDecorator(\"GET\");\nexport const Post = createRouteDecorator(\"POST\");\nexport const Put = createRouteDecorator(\"PUT\");\nexport const Patch = createRouteDecorator(\"PATCH\");\nexport const Delete = createRouteDecorator(\"DELETE\");\nexport const Options = createRouteDecorator(\"OPTIONS\");\nexport const Head = createRouteDecorator(\"HEAD\");\nexport const Query = createRouteDecorator(\"QUERY\");\n\n/**\n * Matches ALL HTTP methods. Useful for catch-all handlers or proxies.\n * Note: more specific method decorators (@Get, @Post, etc.) registered on the\n * same path will take precedence in the AOT-compiled router.\n */\nexport const All = createRouteDecorator(\"ALL\");\n\n/**\n * Attach middleware to a single decorated route. Stack multiple `@Use()`\n * calls to chain several — they run in the order listed, same as passing\n * multiple middleware args to `app.get(path, mw1, mw2, handler)`.\n */\n// biome-ignore lint/suspicious/noExplicitAny: Flexible middleware signature for decorators\nexport function Use(\n\tmiddleware: (ctx: any, next: any) => any,\n): MethodDecoratorFn {\n\treturn (_originalMethod, context) => {\n\t\tif (context.kind !== \"method\") {\n\t\t\tthrow new Error(\"@Use can only decorate methods\");\n\t\t}\n\t\tconst propertyKey = String(context.name);\n\t\tlet entry = pendingRoutes.find((r) => r.propertyKey === propertyKey);\n\t\tif (!entry) {\n\t\t\tentry = { method: \"\", path: \"\", propertyKey, middlewares: [] };\n\t\t\tpendingRoutes.push(entry);\n\t\t}\n\t\tentry.middlewares.unshift(middleware as Middleware);\n\t};\n}\n\nexport type GuardFn<DI = Record<string, unknown>> = (\n\tctx: Context<DI>,\n) => boolean | Promise<boolean>;\n\n/**\n * Apply one or more guards to a controller method.\n * A guard is a function that returns a boolean. If it returns false,\n * the request is rejected with a 403 Forbidden.\n */\nexport function UseGuard<DI = Record<string, unknown>>(\n\t...guards: GuardFn<DI>[]\n) {\n\t// biome-ignore lint/suspicious/noExplicitAny: Required for internal Context bypass\n\treturn Use(async (ctx: any, next: any) => {\n\t\tfor (const guard of guards) {\n\t\t\tconst passed = await guard(ctx);\n\t\t\tif (!passed) {\n\t\t\t\treturn ctx.error(\"Forbidden resource\", 403);\n\t\t\t}\n\t\t}\n\t\treturn next();\n\t});\n}\n\n/**\n * Marks a class as a controller and registers its accumulated `@Get`/\n * `@Post`/etc. routes under `prefix`. Must be the outermost (topmost)\n * decorator on the class so it runs after all method decorators have\n * populated the pending route list.\n */\nexport function Controller(prefix = \"\") {\n\t// biome-ignore lint/complexity/noBannedTypes: Native Decorator API uses Function\n\treturn (target: Function, context: ClassDecoratorContext): void => {\n\t\tif (context.kind !== \"class\") {\n\t\t\tthrow new Error(\"@Controller can only decorate classes\");\n\t\t}\n\t\tconst routes = pendingRoutes.filter((r) => r.method !== \"\");\n\t\tpendingRoutes = [];\n\t\tcontrollerRegistry.set(target, { prefix, routes });\n\t};\n}\n\n/**\n * Reads the routes registered on a `@Controller`-decorated class. Used\n * internally by `App.registerController()`. Walks the prototype chain\n * to merge parent class routes with child class routes.\n */\nexport function getControllerMeta(\n\t// biome-ignore lint/complexity/noBannedTypes: Native Decorator API uses Function\n\tControllerClass: Function,\n): ControllerMeta | undefined {\n\tconst meta = controllerRegistry.get(ControllerClass);\n\n\t// Walk prototype chain to get parent routes\n\tconst parentProto = Object.getPrototypeOf(ControllerClass.prototype);\n\tconst ParentClass = parentProto?.constructor;\n\n\tif (\n\t\tParentClass &&\n\t\tParentClass !== Function.prototype &&\n\t\tParentClass !== Object\n\t) {\n\t\tconst parentMeta = getControllerMeta(ParentClass);\n\t\tif (parentMeta) {\n\t\t\t// Merge: parent routes + child routes (child overrides parent on same propertyKey)\n\t\t\tconst childRoutes = meta?.routes ?? [];\n\t\t\tconst parentRoutes = parentMeta.routes;\n\n\t\t\t// Child routes override parent routes with same propertyKey\n\t\t\tconst mergedRoutes = [...parentRoutes];\n\t\t\tfor (const childRoute of childRoutes) {\n\t\t\t\tconst existingIndex = mergedRoutes.findIndex(\n\t\t\t\t\t(r) => r.propertyKey === childRoute.propertyKey,\n\t\t\t\t);\n\t\t\t\tif (existingIndex >= 0) {\n\t\t\t\t\tmergedRoutes[existingIndex] = childRoute;\n\t\t\t\t} else {\n\t\t\t\t\tmergedRoutes.push(childRoute);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tprefix: meta?.prefix ?? parentMeta.prefix,\n\t\t\t\troutes: mergedRoutes,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn meta;\n}\n\n// Re-export DI decorators\nexport { Inject } from \"./decorators/inject\";\nexport { Injectable } from \"./decorators/injectable\";\n","import type { Context } from \"../context\";\n\ntype RouteHandler<DI = Record<string, unknown>> = (\n\tctx: Context<DI>,\n) => Promise<Response>;\n\nexport function asyncHandler<DI = Record<string, unknown>>(\n\thandler: (ctx: Context<DI>) => Promise<Response | undefined>,\n): RouteHandler<DI> {\n\treturn async (ctx: Context<DI>): Promise<Response> => {\n\t\ttry {\n\t\t\tconst result = await handler(ctx);\n\t\t\treturn result ?? new Response(null, { status: 204 });\n\t\t} catch (error: unknown) {\n\t\t\tconst message =\n\t\t\t\terror instanceof Error ? error.message : \"Internal Server Error\";\n\t\t\tconst status = error instanceof HttpError ? error.status : 500;\n\n\t\t\tconst errorName =\n\t\t\t\tstatus === 400\n\t\t\t\t\t? \"Bad Request\"\n\t\t\t\t\t: status === 401\n\t\t\t\t\t\t? \"Unauthorized\"\n\t\t\t\t\t\t: status === 403\n\t\t\t\t\t\t\t? \"Forbidden\"\n\t\t\t\t\t\t\t: status === 404\n\t\t\t\t\t\t\t\t? \"Not Found\"\n\t\t\t\t\t\t\t\t: status === 405\n\t\t\t\t\t\t\t\t\t? \"Method Not Allowed\"\n\t\t\t\t\t\t\t\t\t: status === 409\n\t\t\t\t\t\t\t\t\t\t? \"Conflict\"\n\t\t\t\t\t\t\t\t\t\t: status === 422\n\t\t\t\t\t\t\t\t\t\t\t? \"Unprocessable Entity\"\n\t\t\t\t\t\t\t\t\t\t\t: status === 429\n\t\t\t\t\t\t\t\t\t\t\t\t? \"Too Many Requests\"\n\t\t\t\t\t\t\t\t\t\t\t\t: status === 503\n\t\t\t\t\t\t\t\t\t\t\t\t\t? \"Service Unavailable\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t: \"Internal Server Error\";\n\n\t\t\treturn ctx.json({ success: false, error: errorName, message }, status);\n\t\t}\n\t};\n}\n\nexport class HttpError extends Error {\n\tstatus: number;\n\n\tconstructor(status: number, message: string) {\n\t\tsuper(message);\n\t\tthis.status = status;\n\t\tthis.name = \"HttpError\";\n\t}\n}\n\nexport class NotFoundError extends HttpError {\n\tconstructor(message = \"Not Found\") {\n\t\tsuper(404, message);\n\t\tthis.name = \"NotFoundError\";\n\t}\n}\n\nexport class BadRequestError extends HttpError {\n\tconstructor(message = \"Bad Request\") {\n\t\tsuper(400, message);\n\t\tthis.name = \"BadRequestError\";\n\t}\n}\n\nexport class UnauthorizedError extends HttpError {\n\tconstructor(message = \"Unauthorized\") {\n\t\tsuper(401, message);\n\t\tthis.name = \"UnauthorizedError\";\n\t}\n}\n\nexport class ForbiddenError extends HttpError {\n\tconstructor(message = \"Forbidden\") {\n\t\tsuper(403, message);\n\t\tthis.name = \"ForbiddenError\";\n\t}\n}\n\nexport class MethodNotAllowedError extends HttpError {\n\tconstructor(message = \"Method Not Allowed\") {\n\t\tsuper(405, message);\n\t\tthis.name = \"MethodNotAllowedError\";\n\t}\n}\n\nexport class ConflictError extends HttpError {\n\tconstructor(message = \"Conflict\") {\n\t\tsuper(409, message);\n\t\tthis.name = \"ConflictError\";\n\t}\n}\n\nexport class UnprocessableEntityError extends HttpError {\n\tconstructor(message = \"Unprocessable Entity\") {\n\t\tsuper(422, message);\n\t\tthis.name = \"UnprocessableEntityError\";\n\t}\n}\n\nexport class TooManyRequestsError extends HttpError {\n\tconstructor(message = \"Too Many Requests\") {\n\t\tsuper(429, message);\n\t\tthis.name = \"TooManyRequestsError\";\n\t}\n}\n\nexport class InternalServerError extends HttpError {\n\tconstructor(message = \"Internal Server Error\") {\n\t\tsuper(500, message);\n\t\tthis.name = \"InternalServerError\";\n\t}\n}\n\nexport class ServiceUnavailableError extends HttpError {\n\tconstructor(message = \"Service Unavailable\") {\n\t\tsuper(503, message);\n\t\tthis.name = \"ServiceUnavailableError\";\n\t}\n}\n","import { appendFile, existsSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport enum LogLevel {\n\tDEBUG = 0,\n\tINFO = 1,\n\tWARN = 2,\n\tERROR = 3,\n}\n\ninterface LoggerOptions {\n\tlevel?: LogLevel;\n\tformat?: \"text\" | \"json\";\n\t// Disable request logging (useful for benchmarks)\n\tlogRequests?: boolean;\n}\n\n// Pre-computed ANSI colors for each log level\nconst COLORS: Record<number, string> = {\n\t[LogLevel.DEBUG]: \"\\x1b[34m\", // Blue\n\t[LogLevel.INFO]: \"\\x1b[32m\", // Green\n\t[LogLevel.WARN]: \"\\x1b[33m\", // Yellow\n\t[LogLevel.ERROR]: \"\\x1b[31m\", // Red\n};\nconst RESET = \"\\x1b[0m\";\nconst GRAY = \"\\x1b[90m\";\n\nexport class Logger {\n\tprivate level: LogLevel;\n\tprivate format: \"text\" | \"json\";\n\tprivate logDir: string | undefined;\n\tprivate isProd: boolean;\n\tprivate _logRequests: boolean;\n\tprivate flushScheduled = false;\n\tprivate stdoutBuffer: string[] = [];\n\tprivate stderrBuffer: string[] = [];\n\n\tconstructor(options?: LoggerOptions) {\n\t\tthis.isProd = process.env.NODE_ENV === \"production\";\n\t\tthis.level =\n\t\t\toptions?.level ?? (this.isProd ? LogLevel.WARN : LogLevel.INFO);\n\t\tthis.format = options?.format ?? (this.isProd ? \"json\" : \"text\");\n\t\tthis._logRequests = options?.logRequests ?? true;\n\n\t\tthis.logDir = process.env.LOG_DIR;\n\t\tif (this.logDir && !existsSync(this.logDir)) {\n\t\t\tmkdirSync(this.logDir, { recursive: true });\n\t\t}\n\t}\n\n\tprivate flush() {\n\t\tif (this.stdoutBuffer.length > 0) {\n\t\t\tprocess.stdout.write(this.stdoutBuffer.join(\"\"));\n\t\t\tthis.stdoutBuffer.length = 0;\n\t\t}\n\t\tif (this.stderrBuffer.length > 0) {\n\t\t\tprocess.stderr.write(this.stderrBuffer.join(\"\"));\n\t\t\tthis.stderrBuffer.length = 0;\n\t\t}\n\t\tthis.flushScheduled = false;\n\t}\n\n\tprivate scheduleFlush() {\n\t\tif (this.flushScheduled) return;\n\t\tthis.flushScheduled = true;\n\t\tqueueMicrotask(() => this.flush());\n\t}\n\n\tprivate print(\n\t\tlevel: LogLevel,\n\t\tlevelName: string,\n\t\tmessage: string,\n\t\tmeta?: Record<string, unknown>,\n\t) {\n\t\tif (level < this.level) return;\n\n\t\tconst isStderr = level === LogLevel.ERROR;\n\n\t\tif (this.format === \"json\") {\n\t\t\tconst timestamp = new Date().toISOString();\n\t\t\tconst logEntryObj = { timestamp, level: levelName, message, ...meta };\n\t\t\tconst jsonString = JSON.stringify(logEntryObj);\n\t\t\tconst line = `${jsonString}\\n`;\n\n\t\t\t// Non-blocking: buffer and schedule flush\n\t\t\tif (isStderr) {\n\t\t\t\tthis.stderrBuffer.push(line);\n\t\t\t} else {\n\t\t\t\tthis.stdoutBuffer.push(line);\n\t\t\t}\n\t\t\tthis.scheduleFlush();\n\n\t\t\t// File logging (already async with appendFile)\n\t\t\tif (this.logDir) {\n\t\t\t\tconst dateStr = timestamp.split(\"T\")[0];\n\t\t\t\tconst filePath = join(this.logDir, `app-${dateStr}.log`);\n\t\t\t\tappendFile(filePath, line, () => {});\n\t\t\t}\n\t\t} else {\n\t\t\tconst now = Date.now();\n\t\t\tconst color = COLORS[level] ?? COLORS[LogLevel.INFO];\n\n\t\t\tlet logString = `[${now}] ${color}[${levelName}]${RESET} ${message}`;\n\n\t\t\tif (meta) {\n\t\t\t\tconst keys = Object.keys(meta);\n\t\t\t\tif (keys.length > 0) {\n\t\t\t\t\tif (keys.length === 1) {\n\t\t\t\t\t\tconst val = meta[keys[0] || 0];\n\t\t\t\t\t\tlogString += ` ${GRAY}{${JSON.stringify(keys[0])}:${JSON.stringify(val)}}${RESET}`;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogString += ` ${GRAY}${JSON.stringify(meta)}${RESET}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Non-blocking: buffer and schedule flush\n\t\t\tif (isStderr) {\n\t\t\t\tthis.stderrBuffer.push(`${logString}\\n`);\n\t\t\t} else {\n\t\t\t\tthis.stdoutBuffer.push(`${logString}\\n`);\n\t\t\t}\n\t\t\tthis.scheduleFlush();\n\t\t}\n\t}\n\n\tpublic debug(message: string, meta?: Record<string, unknown>) {\n\t\tthis.print(LogLevel.DEBUG, \"DEBUG\", message, meta);\n\t}\n\n\tpublic info(message: string, meta?: Record<string, unknown>) {\n\t\tthis.print(LogLevel.INFO, \"INFO\", message, meta);\n\t}\n\n\tpublic warn(message: string, meta?: Record<string, unknown>) {\n\t\tthis.print(LogLevel.WARN, \"WARN\", message, meta);\n\t}\n\n\tpublic error(message: string, meta?: Record<string, unknown>) {\n\t\tthis.print(LogLevel.ERROR, \"ERROR\", message, meta);\n\t}\n\n\tpublic get logRequests(): boolean {\n\t\treturn this._logRequests;\n\t}\n\n\t// Flush remaining logs (useful for graceful shutdown)\n\tpublic flushSync() {\n\t\tif (this.stdoutBuffer.length > 0) {\n\t\t\tprocess.stdout.write(this.stdoutBuffer.join(\"\"));\n\t\t\tthis.stdoutBuffer.length = 0;\n\t\t}\n\t\tif (this.stderrBuffer.length > 0) {\n\t\t\tprocess.stderr.write(this.stderrBuffer.join(\"\"));\n\t\t\tthis.stderrBuffer.length = 0;\n\t\t}\n\t}\n}\n\n// Create logger with env-based configuration\nexport const logger = new Logger({\n\tlogRequests: process.env.LOG_REQUESTS !== \"false\",\n});\n","// ─── JS Fallback: Route Trie ──────────────────────────────────────────────────\n\ntype NodeType = \"static\" | \"param\" | \"catchall\";\n\ninterface TrieNode {\n\tchildren: Map<string, TrieNode>;\n\tparamChild: TrieNode | null;\n\tcatchAllChild: TrieNode | null;\n\thandlerId: number;\n\tparamName: string | null;\n\tnodeType: NodeType;\n}\n\nfunction createNode(nodeType: NodeType = \"static\"): TrieNode {\n\treturn {\n\t\tchildren: new Map(),\n\t\tparamChild: null,\n\t\tcatchAllChild: null,\n\t\thandlerId: -1,\n\t\tparamName: null,\n\t\tnodeType,\n\t};\n}\n\nfunction splitPath(path: string): string[] {\n\tconst segments: string[] = [];\n\tlet start = path[0] === \"/\" ? 1 : 0;\n\tfor (let i = start; i < path.length; i++) {\n\t\tif (path[i] === \"/\") {\n\t\t\tif (i > start) {\n\t\t\t\tsegments.push(path.substring(start, i));\n\t\t\t}\n\t\t\tstart = i + 1;\n\t\t}\n\t}\n\tif (start < path.length) {\n\t\tsegments.push(path.substring(start));\n\t}\n\treturn segments;\n}\n\n// ─── JS Fallback: Trie Implementation ────────────────────────────────────────\n\nexport class JSTrie {\n\tprivate root: TrieNode;\n\tprivate nodeCount: number = 0;\n\n\tconstructor() {\n\t\tthis.root = createNode();\n\t}\n\n\tinsert(path: string, handlerId: number): void {\n\t\tconst segments = splitPath(path);\n\t\tlet current = this.root;\n\n\t\tfor (const segment of segments) {\n\t\t\tif (segment.length === 0) continue;\n\n\t\t\tlet nodeType: NodeType = \"static\";\n\t\t\tlet cleanSegment = segment;\n\t\t\tlet paramName: string | null = null;\n\n\t\t\tif (segment[0] === \":\") {\n\t\t\t\tnodeType = \"param\";\n\t\t\t\tparamName = segment.slice(1);\n\t\t\t\tcleanSegment = \":\";\n\t\t\t} else if (segment[0] === \"*\") {\n\t\t\t\tnodeType = \"catchall\";\n\t\t\t\tparamName = segment.slice(1);\n\t\t\t\tcleanSegment = \"*\";\n\t\t\t}\n\n\t\t\tlet nextNode: TrieNode | null = null;\n\n\t\t\tif (nodeType === \"static\") {\n\t\t\t\tnextNode = current.children.get(cleanSegment) ?? null;\n\t\t\t} else if (nodeType === \"param\") {\n\t\t\t\tnextNode = current.paramChild;\n\t\t\t} else {\n\t\t\t\tnextNode = current.catchAllChild;\n\t\t\t}\n\n\t\t\tif (!nextNode) {\n\t\t\t\tnextNode = createNode(nodeType);\n\t\t\t\tnextNode.paramName = paramName;\n\n\t\t\t\tif (nodeType === \"static\") {\n\t\t\t\t\tcurrent.children.set(cleanSegment, nextNode);\n\t\t\t\t} else if (nodeType === \"param\") {\n\t\t\t\t\tcurrent.paramChild = nextNode;\n\t\t\t\t} else {\n\t\t\t\t\tcurrent.catchAllChild = nextNode;\n\t\t\t\t}\n\t\t\t\tthis.nodeCount++;\n\t\t\t}\n\n\t\t\tcurrent = nextNode;\n\n\t\t\tif (nodeType === \"catchall\") break;\n\t\t}\n\n\t\tcurrent.handlerId = handlerId;\n\t}\n\n\tfind(path: string): { handlerId: number; params: Record<string, string> } {\n\t\tlet current = this.root;\n\t\tconst params: Record<string, string> = {};\n\t\tlet start = path[0] === \"/\" ? 1 : 0;\n\n\t\tif (start >= path.length) {\n\t\t\treturn { handlerId: current.handlerId, params };\n\t\t}\n\n\t\twhile (start < path.length) {\n\t\t\tlet end = path.indexOf(\"/\", start);\n\t\t\tif (end === -1) end = path.length;\n\n\t\t\tif (end > start) {\n\t\t\t\tconst segment = path.substring(start, end);\n\t\t\t\tlet nextNode = current.children.get(segment);\n\n\t\t\t\tif (!nextNode) {\n\t\t\t\t\tif (current.paramChild) {\n\t\t\t\t\t\tnextNode = current.paramChild;\n\t\t\t\t\t\tif (nextNode.paramName) {\n\t\t\t\t\t\t\tparams[nextNode.paramName] = segment;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (current.catchAllChild) {\n\t\t\t\t\t\tnextNode = current.catchAllChild;\n\t\t\t\t\t\tparams[\"*\"] = path.substring(start);\n\t\t\t\t\t\tcurrent = nextNode;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn { handlerId: -1, params };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcurrent = nextNode;\n\t\t\t}\n\t\t\tstart = end + 1;\n\t\t}\n\n\t\treturn { handlerId: current.handlerId, params };\n\t}\n\n\tgetNodeCount(): number {\n\t\treturn this.nodeCount;\n\t}\n}\n\n// ─── JS Fallback: JSON Escape ────────────────────────────────────────────────\n\nexport function jsEscapeString(str: string): string {\n\treturn JSON.stringify(str);\n}\n\n// ─── JS Fallback: Query Parser ───────────────────────────────────────────────\n\nexport function jsParseQuery(query: string): Record<string, string> {\n\tif (!query) return {};\n\n\tconst params: Record<string, string> = {};\n\tconst pairs = query.split(\"&\");\n\n\tfor (const pair of pairs) {\n\t\tif (!pair) continue;\n\t\tconst eqIdx = pair.indexOf(\"=\");\n\t\tlet key: string;\n\t\tlet value: string;\n\n\t\tif (eqIdx === -1) {\n\t\t\tkey = pair;\n\t\t\tvalue = \"\";\n\t\t} else {\n\t\t\tkey = pair.substring(0, eqIdx);\n\t\t\tvalue = pair.substring(eqIdx + 1);\n\t\t}\n\n\t\tparams[decodeURIComponent(key)] = decodeURIComponent(value);\n\t}\n\n\treturn params;\n}\n\n// ─── JS Fallback: Cookie Parser ──────────────────────────────────────────────\n\nexport function jsParseCookies(cookieHeader: string): Record<string, string> {\n\tif (!cookieHeader) return {};\n\n\tconst cookies: Record<string, string> = {};\n\tconst pairs = cookieHeader.split(\";\");\n\n\tfor (const pair of pairs) {\n\t\tconst trimmed = pair.trim();\n\t\tif (!trimmed) continue;\n\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tlet name: string;\n\t\tlet value: string;\n\n\t\tif (eqIdx === -1) {\n\t\t\tname = trimmed;\n\t\t\tvalue = \"\";\n\t\t} else {\n\t\t\tname = trimmed.substring(0, eqIdx);\n\t\t\tvalue = trimmed.substring(eqIdx + 1);\n\t\t}\n\n\t\tcookies[name] = value;\n\t}\n\n\treturn cookies;\n}\n","import {\n\tJSTrie,\n\tjsEscapeString,\n\tjsParseCookies,\n\tjsParseQuery,\n} from \"./fallback\";\n\n// ─── Lazy Native Loading ─────────────────────────────────────────────────────\n\nlet _nativeAvailable: boolean | undefined;\n// biome-ignore lint/suspicious/noExplicitAny: FFI libs are dynamic\nlet _nativeJsonLib: any;\n// biome-ignore lint/suspicious/noExplicitAny: FFI ptr cache\nlet _ffi: any;\n\nfunction tryLoadNative(): void {\n\tif (_nativeAvailable !== undefined) return;\n\ttry {\n\t\t// biome-ignore lint: dynamic require for optional FFI\n\t\t_ffi = require(\"bun:ffi\");\n\t\t// biome-ignore lint: dynamic require\n\t\tconst fs = require(\"node:fs\");\n\t\t// biome-ignore lint: dynamic require\n\t\tconst path = require(\"node:path\");\n\n\t\tconst ext =\n\t\t\tprocess.platform === \"win32\"\n\t\t\t\t? \".dll\"\n\t\t\t\t: process.platform === \"darwin\"\n\t\t\t\t\t? \".dylib\"\n\t\t\t\t\t: \".so\";\n\t\tconst prefix = process.platform === \"win32\" ? \"\" : \"lib\";\n\n\t\tfunction findLib(name: string): string {\n\t\t\tconst candidates = [\n\t\t\t\tpath.join(\n\t\t\t\t\tprocess.cwd(),\n\t\t\t\t\t\"node_modules\",\n\t\t\t\t\t\".buntok-native\",\n\t\t\t\t\t`${prefix}${name}${ext}`,\n\t\t\t\t),\n\t\t\t\tpath.join(process.cwd(), \"dist\", \"native\", `${prefix}${name}${ext}`),\n\t\t\t\tpath.join(process.cwd(), \"zig-out\", \"lib\", `${prefix}${name}${ext}`),\n\t\t\t];\n\t\t\tfor (const p of candidates) {\n\t\t\t\tif (fs.existsSync(p)) return p;\n\t\t\t}\n\t\t\treturn \"\";\n\t\t}\n\n\t\tconst FFIType = _ffi.FFIType;\n\t\tconst jsonPath = findLib(\"buntok_json\");\n\n\t\tif (jsonPath) {\n\t\t\t_nativeJsonLib = _ffi.dlopen(jsonPath, {\n\t\t\t\tjson_init: { args: [], returns: FFIType.void },\n\t\t\t\tjson_deinit: { args: [], returns: FFIType.void },\n\t\t\t\tjson_escape_string: {\n\t\t\t\t\targs: [FFIType.ptr, FFIType.u32, FFIType.ptr, FFIType.ptr],\n\t\t\t\t\treturns: FFIType.i32,\n\t\t\t\t},\n\t\t\t});\n\t\t\t_nativeJsonLib.symbols.json_init();\n\t\t}\n\n\t\t_nativeAvailable = true;\n\t} catch {\n\t\t_nativeAvailable = false;\n\t}\n}\n\n// ─── Trie ────────────────────────────────────────────────────────────────────\n\n// Native trie removed — JS trie is faster when not doing double-walk.\n// Benchmark: native+JS was 38% SLOWER than JS-only due to syncing overhead.\n// JS engines optimize Map.get/set in native C++, so pure JS is optimal.\n\nexport class Trie {\n\tprivate jsImpl: JSTrie;\n\n\tconstructor() {\n\t\tthis.jsImpl = new JSTrie();\n\t}\n\n\tinsert(path: string, handlerId: number): void {\n\t\tthis.jsImpl.insert(path, handlerId);\n\t}\n\n\tfind(path: string): { handlerId: number; params: Record<string, string> } {\n\t\treturn this.jsImpl.find(path);\n\t}\n\n\tgetNodeCount(): number {\n\t\treturn this.jsImpl.getNodeCount();\n\t}\n}\n\n// ─── JSON Escape ─────────────────────────────────────────────────────────────\n\nexport function escapeString(str: string): string {\n\tif (_nativeAvailable && _nativeJsonLib) {\n\t\ttry {\n\t\t\tconst inputBuf = Buffer.from(str, \"utf-8\");\n\t\t\tconst outputPtrBuf = Buffer.alloc(8);\n\t\t\tconst outputLenBuf = Buffer.alloc(4);\n\n\t\t\tconst result = _nativeJsonLib.symbols.json_escape_string(\n\t\t\t\t_ffi.ptr(inputBuf),\n\t\t\t\tinputBuf.length,\n\t\t\t\t_ffi.ptr(outputPtrBuf),\n\t\t\t\t_ffi.ptr(outputLenBuf),\n\t\t\t);\n\n\t\t\tif (result === 0) {\n\t\t\t\tconst outLen = outputLenBuf.readUint32LE(0);\n\t\t\t\tconst outPtr = outputPtrBuf.readBigUInt64LE(0);\n\t\t\t\t// biome-ignore lint: reading native memory via FFI\n\t\t\t\tconst mem = new ArrayBuffer(Number(outPtr) + outLen);\n\t\t\t\tconst outBuf = Buffer.from(new Uint8Array(mem, Number(outPtr), outLen));\n\t\t\t\treturn outBuf.toString(\"utf-8\");\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to JS\n\t\t}\n\t}\n\treturn jsEscapeString(str);\n}\n\n// ─── Query Parser ────────────────────────────────────────────────────────────\n\nexport function parseQuery(query: string): Record<string, string> {\n\treturn jsParseQuery(query);\n}\n\n// ─── Cookie Parser ───────────────────────────────────────────────────────────\n\nexport function parseCookies(cookieHeader: string): Record<string, string> {\n\treturn jsParseCookies(cookieHeader);\n}\n\n// ─── Status ──────────────────────────────────────────────────────────────────\n\nexport function isNativeAvailable(): boolean {\n\ttryLoadNative();\n\treturn _nativeAvailable === true;\n}\n\nexport function getBackend(): \"native\" | \"js\" {\n\treturn isNativeAvailable() ? \"native\" : \"js\";\n}\n","export enum NodeType {\n\tSTATIC = 0,\n\tPARAM = 1,\n\tCATCHALL = 2,\n}\n\nexport interface RouteHandler {\n\tmethod: string;\n\t// biome-ignore lint/suspicious/noExplicitAny: generic router handler\n\thandler: (...args: any[]) => any;\n}\n\nexport class RouterNode {\n\tpath: string = \"\";\n\ttype: NodeType = NodeType.STATIC;\n\tstaticChildren: Map<string, RouterNode> = new Map();\n\tparamChild: RouterNode | null = null;\n\tcatchAllChild: RouterNode | null = null;\n\t// biome-ignore lint/suspicious/noExplicitAny: generic router handler\n\thandlers: Map<string, (...args: any[]) => any> = new Map();\n\tparamName: string | null = null;\n\n\tconstructor(path: string = \"\", type: NodeType = NodeType.STATIC) {\n\t\tthis.path = path;\n\t\tthis.type = type;\n\t}\n}\n","import { Trie as NativeTrie } from \"../ffi\";\nimport { NodeType, RouterNode } from \"./node\";\n\nexport interface LookupResult {\n\t// biome-ignore lint/suspicious/noExplicitAny: generic router handler\n\thandler: ((...args: any[]) => any) | null;\n\tparams: Record<string, string>;\n}\n\nconst EMPTY_PARAMS: Record<string, string> = Object.freeze({});\n\n// Simple fixed-size LRU cache for trie lookup results on dynamic routes.\n// Avoids re-walking the trie for the same (method, pathname) pair —\n// common in real apps where the same resource is hit repeatedly.\nconst CACHE_MAX = 2048;\n\nclass LookupCache {\n\tprivate map = new Map<string, Map<string, LookupResult>>();\n\tprivate queue: Array<{ method: string; path: string }> = [];\n\n\tget(method: string, path: string): LookupResult | undefined {\n\t\tconst methodMap = this.map.get(method);\n\t\tif (!methodMap) return undefined;\n\t\treturn methodMap.get(path);\n\t}\n\n\tset(method: string, path: string, val: LookupResult): void {\n\t\tlet methodMap = this.map.get(method);\n\t\tif (!methodMap) {\n\t\t\tmethodMap = new Map();\n\t\t\tthis.map.set(method, methodMap);\n\t\t}\n\n\t\tif (methodMap.has(path)) {\n\t\t\tmethodMap.set(path, val);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.queue.length >= CACHE_MAX) {\n\t\t\t// Evict the oldest entry\n\t\t\tconst oldest = this.queue.shift();\n\t\t\tif (oldest) {\n\t\t\t\tconst oldMethodMap = this.map.get(oldest.method);\n\t\t\t\tif (oldMethodMap) oldMethodMap.delete(oldest.path);\n\t\t\t}\n\t\t}\n\n\t\tmethodMap.set(path, val);\n\t\tthis.queue.push({ method, path });\n\t}\n}\n\nexport class Router {\n\tprivate root: RouterNode = new RouterNode(\"/\", NodeType.STATIC);\n\t// biome-ignore lint/suspicious/noExplicitAny: generic router handler\n\tpublic staticRoutes: Map<string, Map<string, (...args: any[]) => any>> =\n\t\tnew Map();\n\n\t// LRU cache for dynamic (param/catchall) route lookups\n\tprivate readonly lookupCache = new LookupCache();\n\n\t// Trie for dynamic route lookup\n\tprivate nativeTrie: NativeTrie;\n\t// biome-ignore lint/suspicious/noExplicitAny: generic router handler\n\tprivate handlerRegistry: Map<number, (...args: any[]) => any> = new Map();\n\tprivate nextHandlerId = 0;\n\n\tconstructor() {\n\t\tthis.nativeTrie = new NativeTrie();\n\t}\n\n\tprivate static splitPath(path: string): string[] {\n\t\tconst segments: string[] = [];\n\t\tlet start = 0;\n\t\tif (path[0] === \"/\") start = 1;\n\t\tfor (let i = start; i < path.length; i++) {\n\t\t\tif (path[i] === \"/\") {\n\t\t\t\tif (i > start) {\n\t\t\t\t\tsegments.push(path.substring(start, i));\n\t\t\t\t}\n\t\t\t\tstart = i + 1;\n\t\t\t}\n\t\t}\n\t\tif (start < path.length) {\n\t\t\tsegments.push(path.substring(start));\n\t\t}\n\t\treturn segments;\n\t}\n\n\tpublic insert(\n\t\tmethod: string,\n\t\tpath: string,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: generic router handler\n\t\thandler: (...args: any[]) => any,\n\t): void {\n\t\tif (path === \"\") return;\n\n\t\tconst upperMethod = method.toUpperCase();\n\t\tconst segments = Router.splitPath(path);\n\t\tconst hasParams = segments.some((s) => s[0] === \":\" || s[0] === \"*\");\n\n\t\t// Fast path: store static routes in flat map\n\t\tif (!hasParams) {\n\t\t\tlet methodMap = this.staticRoutes.get(path);\n\t\t\tif (!methodMap) {\n\t\t\t\tmethodMap = new Map();\n\t\t\t\tthis.staticRoutes.set(path, methodMap);\n\t\t\t}\n\t\t\tmethodMap.set(upperMethod, handler);\n\t\t}\n\n\t\t// Register in trie for dynamic routes\n\t\tif (hasParams) {\n\t\t\tconst handlerId = this.nextHandlerId++;\n\t\t\tthis.handlerRegistry.set(handlerId, handler);\n\t\t\t// Use composite key: \"METHOD:/path/:param\"\n\t\t\tconst compositeKey = `${upperMethod}:${path}`;\n\t\t\tthis.nativeTrie.insert(compositeKey, handlerId);\n\t\t}\n\n\t\t// Also insert into JS trie for fallback / non-native\n\t\tlet currentNode = this.root;\n\n\t\tif (segments.length === 0) {\n\t\t\tthis.root.handlers.set(upperMethod, handler);\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const segment of segments) {\n\t\t\tlet nodeType = NodeType.STATIC;\n\t\t\tlet paramName: string | null = null;\n\t\t\tlet cleanSegment = segment;\n\n\t\t\tif (segment.startsWith(\":\")) {\n\t\t\t\tnodeType = NodeType.PARAM;\n\t\t\t\tparamName = segment.slice(1);\n\t\t\t\tcleanSegment = \":\";\n\t\t\t} else if (segment.startsWith(\"*\")) {\n\t\t\t\tnodeType = NodeType.CATCHALL;\n\t\t\t\tparamName = segment.slice(1);\n\t\t\t\tcleanSegment = \"*\";\n\t\t\t} else {\n\t\t\t\tnodeType = NodeType.STATIC;\n\t\t\t\tcleanSegment = segment;\n\t\t\t}\n\n\t\t\tlet childNode: RouterNode | undefined;\n\n\t\t\tif (nodeType === NodeType.STATIC) {\n\t\t\t\tchildNode = currentNode.staticChildren.get(cleanSegment);\n\t\t\t} else if (nodeType === NodeType.PARAM) {\n\t\t\t\tchildNode = currentNode.paramChild ?? undefined;\n\t\t\t} else {\n\t\t\t\tchildNode = currentNode.catchAllChild ?? undefined;\n\t\t\t}\n\n\t\t\tif (!childNode) {\n\t\t\t\tchildNode = new RouterNode(cleanSegment, nodeType);\n\n\t\t\t\tif (nodeType === NodeType.PARAM) {\n\t\t\t\t\tchildNode.paramName = paramName;\n\t\t\t\t\tcurrentNode.paramChild = childNode;\n\t\t\t\t} else if (nodeType === NodeType.CATCHALL) {\n\t\t\t\t\tchildNode.paramName = paramName;\n\t\t\t\t\tcurrentNode.catchAllChild = childNode;\n\t\t\t\t} else {\n\t\t\t\t\tcurrentNode.staticChildren.set(cleanSegment, childNode);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcurrentNode = childNode;\n\n\t\t\tif (nodeType === NodeType.CATCHALL) break;\n\t\t}\n\n\t\tcurrentNode.handlers.set(upperMethod, handler);\n\t}\n\n\tpublic find(method: string, path: string): LookupResult {\n\t\t// Fast path: try flat static route cache first (O(1))\n\t\tconst methodMap = this.staticRoutes.get(path);\n\t\tif (methodMap) {\n\t\t\tconst handler = methodMap.get(method); // method is already uppercase\n\t\t\tif (handler) {\n\t\t\t\treturn { handler, params: EMPTY_PARAMS };\n\t\t\t}\n\t\t}\n\n\t\t// LRU cache for dynamic routes — avoids re-walking the trie for\n\t\t// repeated (method, pathname) pairs (e.g. same user ID hit often)\n\t\tconst cached = this.lookupCache.get(method, path);\n\t\tif (cached) return cached;\n\n\t\t// Trie lookup for dynamic routes\n\t\t{\n\t\t\tconst compositeKey = `${method}:${path}`;\n\t\t\tconst nativeResult = this.nativeTrie.find(compositeKey);\n\n\t\t\tif (nativeResult.handlerId !== -1) {\n\t\t\t\tconst handler = this.handlerRegistry.get(nativeResult.handlerId);\n\t\t\t\tif (handler) {\n\t\t\t\t\tconst result: LookupResult = {\n\t\t\t\t\t\thandler,\n\t\t\t\t\t\tparams: nativeResult.params,\n\t\t\t\t\t};\n\t\t\t\t\tthis.lookupCache.set(method, path, result);\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Slow path: JS trie traversal for param/catchall routes\n\t\tconst result: LookupResult = {\n\t\t\thandler: null,\n\t\t\tparams: null as unknown as Record<string, string>,\n\t\t};\n\t\tlet currentNode = this.root;\n\n\t\tlet start = path[0] === \"/\" ? 1 : 0;\n\t\tif (start >= path.length) {\n\t\t\tresult.handler = this.root.handlers.get(method) || null;\n\t\t\tif (result.handler) result.params = EMPTY_PARAMS;\n\t\t\telse result.params = EMPTY_PARAMS;\n\t\t\treturn result;\n\t\t}\n\n\t\twhile (start < path.length) {\n\t\t\tlet end = path.indexOf(\"/\", start);\n\t\t\tif (end === -1) end = path.length;\n\n\t\t\tif (end > start) {\n\t\t\t\tconst segment = path.substring(start, end);\n\t\t\t\tlet nextNode = currentNode.staticChildren.get(segment);\n\n\t\t\t\tif (!nextNode) {\n\t\t\t\t\tif (currentNode.paramChild) {\n\t\t\t\t\t\tnextNode = currentNode.paramChild;\n\t\t\t\t\t\tif (!result.params) result.params = {};\n\t\t\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: Known to exist due to node structure\n\t\t\t\t\t\tresult.params[nextNode.paramName!] = segment;\n\t\t\t\t\t} else if (currentNode.catchAllChild) {\n\t\t\t\t\t\tnextNode = currentNode.catchAllChild;\n\t\t\t\t\t\tif (!result.params) result.params = {};\n\t\t\t\t\t\tresult.params[\"*\"] = path.substring(start);\n\t\t\t\t\t\tcurrentNode = nextNode;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn { handler: null, params: EMPTY_PARAMS };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcurrentNode = nextNode;\n\t\t\t}\n\t\t\tstart = end + 1;\n\t\t}\n\n\t\tresult.handler = currentNode.handlers.get(method) || null;\n\t\tif (!result.params) result.params = EMPTY_PARAMS;\n\n\t\t// Cache the result for future identical lookups\n\t\tif (result.handler) {\n\t\t\tthis.lookupCache.set(method, path, result);\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import type { Context } from \"./context\";\nimport { Controller, Delete, Get, Post, Put } from \"./decorators\";\n\n/**\n * Abstract base controller with built-in CRUD routes using decorators.\n *\n * Extend this class and provide a route prefix via @Controller decorator.\n * The CRUD methods are pre-decorated with @Get, @Post, @Put, @Delete.\n *\n * @example\n * ```ts\n * import { Controller, BaseController, Context } from \"@buntok/core\";\n *\n * // Simple usage (no input types needed)\n * @Controller(\"/users\")\n * class UserController extends BaseController<User> {\n *   constructor(private userService: UserService) {\n *     super(userService);\n *   }\n * }\n *\n * // With typed inputs (optional)\n * @Controller(\"/users\")\n * class UserController extends BaseController<User, CreateUserInput, UpdateUserInput> {\n *   constructor(private userService: UserService) {\n *     super(userService);\n *   }\n * }\n *\n * // Routes automatically registered:\n * // GET    /users\n * // GET    /users/:id\n * // POST   /users\n * // PUT    /users/:id\n * // DELETE /users/:id\n * ```\n */\n@Controller(\"\")\nexport abstract class BaseController<T, CreateInput = any, UpdateInput = any> {\n\tconstructor(\n\t\tprotected service: {\n\t\t\tgetAll: () => Promise<T[]>;\n\t\t\tgetById: (id: string | number) => Promise<T>;\n\t\t\tcreate: (data: CreateInput) => Promise<T>;\n\t\t\tupdate: (id: string | number, data: UpdateInput) => Promise<T>;\n\t\t\tdelete: (id: string | number) => Promise<T>;\n\t\t},\n\t) {}\n\n\t/**\n\t * Parse URL param id to the correct type.\n\t * Default: tries to convert to number, falls back to string.\n\t * Override this if you need custom id parsing (e.g., UUID).\n\t */\n\tprotected parseId(id: string): string | number {\n\t\tif (id === \"\") return id;\n\t\tconst num = Number(id);\n\t\treturn Number.isNaN(num) ? id : num;\n\t}\n\n\t@Get(\"/\")\n\tasync getAll(ctx: Context) {\n\t\tconst data = await this.service.getAll();\n\t\treturn ctx.success(data);\n\t}\n\n\t@Get(\"/:id\")\n\tasync getById(ctx: Context) {\n\t\tconst id = this.parseId(ctx.params.id ?? \"\");\n\t\tconst data = await this.service.getById(id);\n\t\treturn ctx.success(data);\n\t}\n\n\t@Post(\"/\")\n\tasync create(ctx: Context) {\n\t\tconst body = await ctx.body();\n\t\tconst data = await this.service.create(body as CreateInput);\n\t\treturn ctx.success(data, `Created successfully!.`, 201);\n\t}\n\n\t@Put(\"/:id\")\n\tasync update(ctx: Context) {\n\t\tconst id = this.parseId(ctx.params.id ?? \"\");\n\t\tconst body = await ctx.body();\n\t\tconst data = await this.service.update(id, body as UpdateInput);\n\t\treturn ctx.success(data);\n\t}\n\n\t@Delete(\"/:id\")\n\tasync delete(ctx: Context) {\n\t\tconst id = this.parseId(ctx.params.id ?? \"\");\n\t\tawait this.service.delete(id);\n\t\treturn ctx.status(204);\n\t}\n}\n","import { NotFoundError } from \"./helpers/async-handler\";\n\nexport abstract class BaseService<T, CreateInput = any, UpdateInput = any> {\n\tconstructor(\n\t\tprotected repository: {\n\t\t\tfindAll: () => Promise<T[]>;\n\t\t\tfindById: (id: string | number) => Promise<T | null>;\n\t\t\tcreate: (data: CreateInput) => Promise<T>;\n\t\t\tupdate: (id: string | number, data: UpdateInput) => Promise<T>;\n\t\t\tdelete: (id: string | number) => Promise<T>;\n\t\t\tcount: () => Promise<number>;\n\t\t},\n\t) {}\n\n\tasync getAll(): Promise<T[]> {\n\t\treturn this.repository.findAll();\n\t}\n\n\tasync getById(id: string | number): Promise<T> {\n\t\tconst item = await this.repository.findById(id);\n\t\tif (!item) throw new NotFoundError(`Data dengan id ${id} tidak ditemukan`);\n\t\treturn item;\n\t}\n\n\tasync create(data: CreateInput): Promise<T> {\n\t\treturn this.repository.create(data);\n\t}\n\n\tasync update(id: string | number, data: UpdateInput): Promise<T> {\n\t\tawait this.getById(id);\n\t\treturn this.repository.update(id, data);\n\t}\n\n\tasync delete(id: string | number): Promise<T> {\n\t\tawait this.getById(id);\n\t\treturn this.repository.delete(id);\n\t}\n\n\tasync count(): Promise<number> {\n\t\treturn this.repository.count();\n\t}\n}\n","/**\n * Lightweight event emitter for loose coupling between modules.\n *\n * @example\n * ```ts\n * import { emitter } from \"buntok\";\n *\n * // Subscribe to events\n * emitter.on(\"user:created\", async ({ user, ctx }) => {\n *   await sendWelcomeEmail(user.email);\n * });\n *\n * // Emit events\n * emitter.emit(\"user:created\", { user, ctx });\n *\n * // One-time listener\n * emitter.once(\"app:ready\", () => {\n *   console.log(\"App is ready!\");\n * });\n * ```\n */\n\ntype EventMap = Record<string, any>;\n\ntype Listener<T> = (data: T) => Promise<void> | void;\n\nexport class EventEmitter<TEvents extends EventMap = EventMap> {\n\tprivate listeners = new Map<keyof TEvents, Set<Listener<any>>>();\n\n\t/**\n\t * Subscribe to an event.\n\t * @returns Unsubscribe function\n\t */\n\ton<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): () => void {\n\t\tif (!this.listeners.has(event)) {\n\t\t\tthis.listeners.set(event, new Set());\n\t\t}\n\t\tthis.listeners.get(event)!.add(listener);\n\n\t\t// Return unsubscribe function\n\t\treturn () => {\n\t\t\tthis.listeners.get(event)?.delete(listener);\n\t\t};\n\t}\n\n\t/**\n\t * Subscribe to an event, but only fire once.\n\t * @returns Unsubscribe function\n\t */\n\tonce<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): () => void {\n\t\tconst wrapper: Listener<TEvents[K]> = async (data) => {\n\t\t\tunsub();\n\t\t\tawait listener(data);\n\t\t};\n\t\tconst unsub = this.on(event, wrapper);\n\t\treturn unsub;\n\t}\n\n\t/**\n\t * Emit an event with data.\n\t * Returns a promise that resolves when all listeners have finished.\n\t */\n\tasync emit<K extends keyof TEvents>(event: K, data: TEvents[K]): Promise<void> {\n\t\tconst listeners = this.listeners.get(event);\n\t\tif (!listeners || listeners.size === 0) return;\n\n\t\tconst promises: Promise<void>[] = [];\n\t\tfor (const listener of listeners) {\n\t\t\tpromises.push(Promise.resolve(listener(data)));\n\t\t}\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * Remove all listeners for an event, or all listeners entirely.\n\t */\n\toff<K extends keyof TEvents>(event?: K): void {\n\t\tif (event) {\n\t\t\tthis.listeners.delete(event);\n\t\t} else {\n\t\t\tthis.listeners.clear();\n\t\t}\n\t}\n\n\t/**\n\t * Get the number of listeners for an event.\n\t */\n\tlistenerCount<K extends keyof TEvents>(event: K): number {\n\t\treturn this.listeners.get(event)?.size ?? 0;\n\t}\n}\n\n/**\n * Default emitter instance with common application events.\n *\n * @example\n * ```ts\n * import { emitter } from \"buntok\";\n *\n * emitter.on(\"user:created\", ({ user }) => {\n *   console.log(\"New user:\", user.name);\n * });\n * ```\n */\nexport interface AppEvents {\n\t// Auth events\n\t\"user:created\": { user: any; ctx?: any };\n\t\"user:updated\": { user: any; ctx?: any };\n\t\"user:deleted\": { userId: string | number; ctx?: any };\n\t\"user:logged_in\": { user: any; ctx?: any };\n\t\"user:logged_out\": { user: any; ctx?: any };\n\n\t// Request events\n\t\"request:start\": { method: string; path: string; ctx?: any };\n\t\"request:end\": { method: string; path: string; status: number; duration: number; ctx?: any };\n\t\"request:error\": { method: string; path: string; error: Error; ctx?: any };\n\n\t// App events\n\t\"app:ready\": void;\n\t\"app:shutdown\": void;\n\n\t// Custom events (extensible)\n\t[key: string]: any;\n}\n\nexport const emitter = new EventEmitter<AppEvents>();\n","/**\n * Async sleep — returns a promise that resolves after `ms` milliseconds.\n *\n * @example\n * await delay(1000); // wait 1 second\n */\nexport function delay(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport interface RetryOptions {\n\t/** Maximum number of retries (default: 3) */\n\tretries?: number;\n\t/** Delay between retries in ms (default: 1000) */\n\tdelay?: number;\n\t/** Backoff strategy: \"fixed\" or \"exponential\" (default: \"exponential\") */\n\tbackoff?: \"fixed\" | \"exponential\";\n\t/** Function to decide if the error is retryable. Default: always retry. */\n\tonError?: (error: unknown, attempt: number) => boolean;\n}\n\n/**\n * Retry an async function with configurable backoff.\n *\n * @example\n * const data = await retry(\n *   () => fetch(\"https://api.example.com/data\").then(r => r.json()),\n *   { retries: 3, delay: 1000, backoff: \"exponential\" }\n * );\n */\nexport async function retry<T>(\n\tfn: () => Promise<T>,\n\toptions?: RetryOptions,\n): Promise<T> {\n\tconst {\n\t\tretries = 3,\n\t\tdelay: baseDelay = 1000,\n\t\tbackoff = \"exponential\",\n\t\tonError,\n\t} = options ?? {};\n\n\tlet lastError: unknown;\n\n\tfor (let attempt = 0; attempt <= retries; attempt++) {\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} catch (err) {\n\t\t\tlastError = err;\n\n\t\t\tif (onError && !onError(err, attempt)) {\n\t\t\t\tthrow err;\n\t\t\t}\n\n\t\t\tif (attempt < retries) {\n\t\t\t\tconst waitTime =\n\t\t\t\t\tbackoff === \"exponential\" ? baseDelay * 2 ** attempt : baseDelay;\n\t\t\t\tawait delay(waitTime);\n\t\t\t}\n\t\t}\n\t}\n\n\tthrow lastError;\n}\n","export interface CookieOptions {\n\t/** Domain to set the cookie on */\n\tdomain?: string;\n\t/** Expiration time in seconds */\n\tmaxAge?: number;\n\t/** Absolute expiration date */\n\texpires?: Date;\n\t/** Cookie path (default: /) */\n\tpath?: string;\n\t/** Secure flag (HTTPS only) */\n\tsecure?: boolean;\n\t/** HttpOnly flag (not accessible via JavaScript) */\n\thttpOnly?: boolean;\n\t/** SameSite policy */\n\tsameSite?: \"strict\" | \"lax\" | \"none\";\n\t/** Cookie partition key (for partitioned cookies) */\n\tpartitioned?: boolean;\n}\n\n/**\n * Parse cookies from Cookie header string\n */\nexport function parseCookies(cookieHeader: string): Record<string, string> {\n\tconst cookies: Record<string, string> = {};\n\n\tif (!cookieHeader) return cookies;\n\n\tconst pairs = cookieHeader.split(\";\");\n\n\tfor (const pair of pairs) {\n\t\tconst [name, ...valueParts] = pair.split(\"=\");\n\t\tif (name === undefined) continue;\n\t\tconst trimmedName = name.trim();\n\t\tconst value = valueParts.join(\"=\").trim();\n\n\t\tif (trimmedName) {\n\t\t\tcookies[trimmedName] = decodeURIComponent(value);\n\t\t}\n\t}\n\n\treturn cookies;\n}\n\n/**\n * Serialize a cookie to a string\n */\nexport function serializeCookie(\n\tname: string,\n\tvalue: string,\n\toptions: CookieOptions = {},\n): string {\n\tlet cookie = `${name}=${encodeURIComponent(value)}`;\n\n\tif (options.domain) {\n\t\tcookie += `; Domain=${options.domain}`;\n\t}\n\n\tif (options.maxAge !== undefined) {\n\t\tcookie += `; Max-Age=${options.maxAge}`;\n\t}\n\n\tif (options.expires) {\n\t\tcookie += `; Expires=${options.expires.toUTCString()}`;\n\t}\n\n\tcookie += `; Path=${options.path || \"/\"}`;\n\n\tif (options.secure) {\n\t\tcookie += \"; Secure\";\n\t}\n\n\tif (options.httpOnly) {\n\t\tcookie += \"; HttpOnly\";\n\t}\n\n\tif (options.sameSite) {\n\t\tcookie += `; SameSite=${options.sameSite.charAt(0).toUpperCase() + options.sameSite.slice(1)}`;\n\t}\n\n\tif (options.partitioned) {\n\t\tcookie += \"; Partitioned\";\n\t}\n\n\treturn cookie;\n}\n\n/**\n * Get a cookie value from request\n */\nexport function getCookie(request: Request, name: string): string | undefined {\n\tconst cookieHeader = request.headers.get(\"Cookie\");\n\tif (!cookieHeader) return undefined;\n\n\tconst cookies = parseCookies(cookieHeader);\n\treturn cookies[name];\n}\n\n/**\n * Get all cookies from request\n */\nexport function getCookies(request: Request): Record<string, string> {\n\tconst cookieHeader = request.headers.get(\"Cookie\");\n\treturn parseCookies(cookieHeader || \"\");\n}\n\n/**\n * Set a cookie on Response\n */\nexport function setCookie(\n\tresponse: Response,\n\tname: string,\n\tvalue: string,\n\toptions: CookieOptions = {},\n): Response {\n\tconst cookie = serializeCookie(name, value, options);\n\n\t// Clone response and add Set-Cookie header\n\tconst newResponse = new Response(response.body, {\n\t\tstatus: response.status,\n\t\tstatusText: response.statusText,\n\t\theaders: response.headers,\n\t});\n\n\tnewResponse.headers.append(\"Set-Cookie\", cookie);\n\treturn newResponse;\n}\n\n/**\n * Delete a cookie (set expired)\n */\nexport function deleteCookie(\n\tresponse: Response,\n\tname: string,\n\toptions: Omit<CookieOptions, \"maxAge\" | \"expires\"> = {},\n): Response {\n\treturn setCookie(response, name, \"\", {\n\t\t...options,\n\t\tmaxAge: 0,\n\t\texpires: new Date(0),\n\t});\n}\n","const ENCODER = new TextEncoder();\nconst DECODER = new TextDecoder();\n\nfunction toBuffer(\n\tdata: string | ArrayBuffer | Uint8Array,\n): Uint8Array<ArrayBuffer> {\n\tif (typeof data === \"string\") return ENCODER.encode(data);\n\tif (data instanceof ArrayBuffer) return new Uint8Array(data);\n\treturn new Uint8Array(\n\t\tdata.buffer as ArrayBuffer,\n\t\tdata.byteOffset,\n\t\tdata.byteLength,\n\t);\n}\n\nfunction toHex(buffer: Uint8Array): string {\n\treturn [...buffer].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n// ── Hash ─────────────────────────────────────────────────────────────\n\nexport async function hash(\n\tdata: string | ArrayBuffer | Uint8Array,\n\talgorithm: \"SHA-1\" | \"SHA-256\" | \"SHA-384\" | \"SHA-512\" = \"SHA-256\",\n): Promise<string> {\n\tconst digest = await crypto.subtle.digest(algorithm, toBuffer(data));\n\treturn toHex(new Uint8Array(digest));\n}\n\nexport async function sha256(\n\tdata: string | ArrayBuffer | Uint8Array,\n): Promise<string> {\n\treturn hash(data, \"SHA-256\");\n}\n\nexport async function sha512(\n\tdata: string | ArrayBuffer | Uint8Array,\n): Promise<string> {\n\treturn hash(data, \"SHA-512\");\n}\n\n/**\n * MD5 hash — uses a pure JS implementation since WebCrypto doesn't support MD5.\n * Intended for legacy compatibility and cache keys, NOT for security.\n */\nexport async function md5(\n\tdata: string | ArrayBuffer | Uint8Array,\n): Promise<string> {\n\tconst buf = toBuffer(data);\n\tconst T = [\n\t\t0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a,\n\t\t0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,\n\t\t0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340,\n\t\t0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,\n\t\t0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8,\n\t\t0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,\n\t\t0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa,\n\t\t0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,\n\t\t0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92,\n\t\t0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,\n\t\t0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,\n\t];\n\tconst S = [\n\t\t7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5,\n\t\t9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11,\n\t\t16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10,\n\t\t15, 21,\n\t];\n\n\tconst msg = new Uint8Array((((buf.length + 8) >>> 6) + 1) << 6);\n\tmsg.set(buf);\n\tmsg[buf.length] = 0x80;\n\tconst msgBuffer = msg.buffer as ArrayBuffer;\n\tconst view = new DataView(msgBuffer);\n\tview.setUint32(msg.length - 8, buf.length * 8, true);\n\tview.setUint32(msg.length - 4, 0, true);\n\n\tlet [a0, b0, c0, d0] = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476];\n\n\tfor (let i = 0; i < msg.length; i += 64) {\n\t\tconst M = new Array<number>(16).fill(0);\n\t\tfor (let j = 0; j < 16; j++) M[j] = view.getUint32(i + j * 4, true);\n\n\t\tlet [A, B, C, D] = [a0, b0, c0, d0];\n\t\tlet g = 0;\n\n\t\tfor (let j = 0; j < 64; j++) {\n\t\t\tlet F: number;\n\t\t\tif (j < 16) {\n\t\t\t\tF = (B & C) | (~B & D);\n\t\t\t\tg = j;\n\t\t\t} else if (j < 32) {\n\t\t\t\tF = (D & B) | (~D & C);\n\t\t\t\tg = (5 * j + 1) % 16;\n\t\t\t} else if (j < 48) {\n\t\t\t\tF = B ^ C ^ D;\n\t\t\t\tg = (3 * j + 5) % 16;\n\t\t\t} else {\n\t\t\t\tF = C ^ (B | ~D);\n\t\t\t\tg = (7 * j) % 16;\n\t\t\t}\n\t\t\tF = (F + A + T[j]! + M[g]!) | 0;\n\t\t\tA = D;\n\t\t\tD = C;\n\t\t\tC = B;\n\t\t\tB = (B + ((F << S[j]!) | (F >>> (32 - S[j]!)))) | 0;\n\t\t}\n\n\t\ta0 = (a0 + A) | 0;\n\t\tb0 = (b0 + B) | 0;\n\t\tc0 = (c0 + C) | 0;\n\t\td0 = (d0 + D) | 0;\n\t}\n\n\tconst result = new Uint8Array(16);\n\tconst rView = new DataView(result.buffer as ArrayBuffer);\n\trView.setUint32(0, a0, true);\n\trView.setUint32(4, b0, true);\n\trView.setUint32(8, c0, true);\n\trView.setUint32(12, d0, true);\n\treturn toHex(result);\n}\n\n// ── HMAC ─────────────────────────────────────────────────────────────\n\nexport async function hmac(\n\tdata: string | ArrayBuffer | Uint8Array,\n\tkey: string | ArrayBuffer | Uint8Array,\n\talgorithm: \"SHA-1\" | \"SHA-256\" | \"SHA-384\" | \"SHA-512\" = \"SHA-256\",\n): Promise<string> {\n\tconst cryptoKey = await crypto.subtle.importKey(\n\t\t\"raw\",\n\t\ttoBuffer(key),\n\t\t{ name: \"HMAC\", hash: algorithm },\n\t\tfalse,\n\t\t[\"sign\"],\n\t);\n\tconst signature = await crypto.subtle.sign(\"HMAC\", cryptoKey, toBuffer(data));\n\treturn toHex(new Uint8Array(signature));\n}\n\nexport async function hashVerify(\n\tdata: string | ArrayBuffer | Uint8Array,\n\texpected: string,\n\talgorithm: \"SHA-1\" | \"SHA-256\" | \"SHA-384\" | \"SHA-512\" = \"SHA-256\",\n): Promise<boolean> {\n\tconst actual = await hash(data, algorithm);\n\tif (actual.length !== expected.length) return false;\n\tlet result = 0;\n\tfor (let i = 0; i < actual.length; i++) {\n\t\tresult |= actual.charCodeAt(i) ^ expected.charCodeAt(i);\n\t}\n\treturn result === 0;\n}\n\n// ── Random ───────────────────────────────────────────────────────────\n\nexport function randomBytes(length: number): Uint8Array {\n\treturn crypto.getRandomValues(new Uint8Array(length));\n}\n\nexport function randomHex(length: number): string {\n\treturn toHex(randomBytes(Math.ceil(length / 2))).slice(0, length);\n}\n\nconst ALPHA_NUM =\n\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\nexport function randomAlphaNumeric(length: number): string {\n\tconst bytes = randomBytes(length);\n\treturn Array.from(bytes, (b) => ALPHA_NUM[b % ALPHA_NUM.length]).join(\"\");\n}\n\nexport function randomToken(length = 32): string {\n\tconst bytes = randomBytes(length);\n\treturn btoa(String.fromCharCode(...bytes))\n\t\t.replace(/\\+/g, \"-\")\n\t\t.replace(/\\//g, \"_\")\n\t\t.replace(/=+$/, \"\");\n}\n\n// ── Encrypt / Decrypt (AES-256-GCM) ─────────────────────────────────\n\nasync function importAesKey(\n\tkey: string | ArrayBuffer | Uint8Array,\n): Promise<CryptoKey> {\n\tconst keyData = typeof key === \"string\" ? ENCODER.encode(key) : toBuffer(key);\n\tconst rawKey =\n\t\tkeyData.length === 32\n\t\t\t? keyData\n\t\t\t: new Uint8Array(await crypto.subtle.digest(\"SHA-256\", keyData));\n\treturn crypto.subtle.importKey(\"raw\", rawKey, \"AES-GCM\", false, [\n\t\t\"encrypt\",\n\t\t\"decrypt\",\n\t]);\n}\n\nexport async function encrypt(\n\tdata: string | ArrayBuffer | Uint8Array,\n\tkey: string | ArrayBuffer | Uint8Array,\n\tiv?: Uint8Array,\n): Promise<{ ciphertext: string; iv: string }> {\n\tconst cryptoKey = await importAesKey(key);\n\tconst ivBytes = (iv ??\n\t\tcrypto.getRandomValues(new Uint8Array(12))) as Uint8Array<ArrayBuffer>;\n\tconst encrypted = await crypto.subtle.encrypt(\n\t\t{ name: \"AES-GCM\", iv: ivBytes },\n\t\tcryptoKey,\n\t\ttoBuffer(data),\n\t);\n\treturn {\n\t\tciphertext: toHex(new Uint8Array(encrypted)),\n\t\tiv: toHex(ivBytes),\n\t};\n}\n\nexport async function decrypt(\n\tciphertext: string,\n\tkey: string | ArrayBuffer | Uint8Array,\n\tiv: string,\n): Promise<string> {\n\tconst cryptoKey = await importAesKey(key);\n\tconst ivBytes = new Uint8Array(\n\t\tiv.match(/.{1,2}/g)?.map((h) => Number.parseInt(h, 16)) ?? [],\n\t);\n\tconst data = new Uint8Array(\n\t\tciphertext.match(/.{1,2}/g)?.map((h) => Number.parseInt(h, 16)) ?? [],\n\t);\n\tconst decrypted = await crypto.subtle.decrypt(\n\t\t{ name: \"AES-GCM\", iv: ivBytes },\n\t\tcryptoKey,\n\t\tdata,\n\t);\n\treturn DECODER.decode(decrypted);\n}\n","const UNITS: [string, number][] = [\n\t[\"year\", 31536000],\n\t[\"month\", 2628000],\n\t[\"week\", 604800],\n\t[\"day\", 86400],\n\t[\"hour\", 3600],\n\t[\"minute\", 60],\n\t[\"second\", 1],\n];\n\nfunction pluralize(unit: string, value: number): string {\n\treturn value === 1 ? unit : `${unit}s`;\n}\n\n/**\n * Format a Date to ISO string or custom format.\n *\n * @example\n * formatDate(new Date()); // \"2024-01-15T10:30:00.000Z\"\n */\nexport function formatDate(date: Date | string | number): string {\n\tconst d = date instanceof Date ? date : new Date(date);\n\treturn d.toISOString();\n}\n\n/**\n * Get human-readable relative time (\"3 minutes ago\", \"2 hours ago\").\n *\n * @example\n * timeAgo(new Date(Date.now() - 180000)); // \"3 minutes ago\"\n * timeAgo(new Date(Date.now() - 7200000)); // \"2 hours ago\"\n */\nexport function timeAgo(date: Date | string | number): string {\n\tconst d = date instanceof Date ? date : new Date(date);\n\tconst seconds = Math.floor((Date.now() - d.getTime()) / 1000);\n\n\tfor (const [unit, secs] of UNITS) {\n\t\tconst value = Math.floor(seconds / secs);\n\t\tif (value >= 1) {\n\t\t\treturn `${value} ${pluralize(unit, value)} ago`;\n\t\t}\n\t}\n\n\treturn \"just now\";\n}\n","/**\n * Timezone helper utilities for handling time conversions between server and client.\n *\n * Common use case:\n * - Server stores times in ISO +7 (Asia/Jakarta)\n * - Dashboard needs to display/group data by client's local timezone\n */\n\nfunction toDate(date: Date | string | number): Date {\n\treturn date instanceof Date ? date : new Date(date);\n}\n\n/**\n * Get the timezone offset in minutes for a given IANA timezone.\n *\n * @example\n * getTimezoneOffset(\"Asia/Jakarta\"); // -420 (UTC+7)\n * getTimezoneOffset(\"America/New_York\"); // varies (DST aware)\n */\nexport function getTimezoneOffset(timezone: string, date?: Date): number {\n\tconst d = date ?? new Date();\n\tconst utcStr = d.toLocaleString(\"en-US\", { timeZone: \"UTC\" });\n\tconst tzStr = d.toLocaleString(\"en-US\", { timeZone: timezone });\n\tconst utc = new Date(utcStr);\n\tconst tz = new Date(tzStr);\n\treturn (utc.getTime() - tz.getTime()) / 60000;\n}\n\n/**\n * Parse a time string and interpret it in a specific timezone.\n *\n * If the string has no timezone info (no Z, no +07:00), it will be\n * interpreted as being in the specified timezone.\n *\n * @example\n * // Server receives \"2026-08-24 05:00\" from client in UTC+7\n * const date = parseTime(\"2026-08-24 05:00\", \"Asia/Jakarta\");\n * date.toISOString(); // \"2026-08-23T22:00:00.000Z\" (correct UTC)\n */\nexport function parseTime(timeStr: string, timezone: string): Date {\n\t// If already has timezone info (Z or ±HH:MM), use native parsing\n\tif (/[Zz]$|[+-]\\d{2}:\\d{2}$/.test(timeStr.trim())) {\n\t\treturn new Date(timeStr);\n\t}\n\n\t// Parse as local time in target timezone\n\tconst d = new Date(timeStr);\n\tif (Number.isNaN(d.getTime())) {\n\t\tthrow new Error(`Invalid date string: \"${timeStr}\"`);\n\t}\n\n\t// Get what this date looks like in the target timezone\n\tconst offset = getTimezoneOffset(timezone, d);\n\tconst utcOffset = d.getTimezoneOffset(); // local offset in minutes (negative for east)\n\n\t// Adjust: move from local interpretation to target timezone\n\tconst adjusted = new Date(d.getTime() + (utcOffset + offset) * 60000);\n\treturn adjusted;\n}\n\n/**\n * Convert a Date to a specific timezone and return parts.\n *\n * @example\n * const parts = toTimezoneParts(new Date(\"2026-08-23T22:00:00Z\"), \"Asia/Jakarta\");\n * // { year: 2026, month: 8, day: 24, hour: 5, minute: 0, second: 0 }\n */\nexport function toTimezoneParts(date: Date, timezone: string) {\n\tconst d = toDate(date);\n\tconst parts = new Intl.DateTimeFormat(\"en-US\", {\n\t\ttimeZone: timezone,\n\t\tyear: \"numeric\",\n\t\tmonth: \"2-digit\",\n\t\tday: \"2-digit\",\n\t\thour: \"2-digit\",\n\t\tminute: \"2-digit\",\n\t\tsecond: \"2-digit\",\n\t\thour12: false,\n\t}).formatToParts(d);\n\n\tconst get = (type: string) => Number(parts.find((p) => p.type === type)?.value ?? 0);\n\n\treturn {\n\t\tyear: get(\"year\"),\n\t\tmonth: get(\"month\"),\n\t\tday: get(\"day\"),\n\t\thour: get(\"hour\"),\n\t\tminute: get(\"minute\"),\n\t\tsecond: get(\"second\"),\n\t};\n}\n\n/**\n * Format a Date in a specific timezone.\n *\n * @example\n * const date = new Date(\"2026-08-23T22:00:00Z\");\n * formatInTimezone(date, \"Asia/Jakarta\"); // \"2026-08-24 05:00:00\"\n * formatInTimezone(date, \"Asia/Jakarta\", \"short\"); // \"2026-08-24 05:00\"\n * formatInTimezone(date, \"Asia/Jakarta\", \"full\"); // \"2026-08-24 05:00:00.000\"\n */\nexport function formatInTimezone(\n\tdate: Date | string | number,\n\ttimezone: string,\n\tformat: \"short\" | \"default\" | \"full\" = \"default\",\n): string {\n\tconst d = toDate(date);\n\tconst parts = toTimezoneParts(d, timezone);\n\n\tconst pad = (n: number) => String(n).padStart(2, \"0\");\n\tconst y = parts.year;\n\tconst m = pad(parts.month);\n\tconst day = pad(parts.day);\n\tconst h = pad(parts.hour);\n\tconst min = pad(parts.minute);\n\tconst sec = pad(parts.second);\n\n\tswitch (format) {\n\t\tcase \"short\":\n\t\t\treturn `${y}-${m}-${day} ${h}:${min}`;\n\t\tcase \"full\":\n\t\t\treturn `${y}-${m}-${day} ${h}:${min}:${sec}.000`;\n\t\tdefault:\n\t\t\treturn `${y}-${m}-${day} ${h}:${min}:${sec}`;\n\t}\n}\n\n/**\n * Get current time in a specific timezone.\n *\n * @example\n * const now = nowInTimezone(\"Asia/Jakarta\");\n * // Date object representing current time, displayable in Jakarta timezone\n */\nexport function nowInTimezone(timezone: string): Date {\n\tconst now = new Date();\n\tconst parts = toTimezoneParts(now, timezone);\n\tconst reconstructed = new Date(\n\t\tDate.UTC(parts.year, parts.month - 1, parts.day, parts.hour, parts.minute, parts.second),\n\t);\n\tconst tzOffset = getTimezoneOffset(timezone, now);\n\treturn new Date(reconstructed.getTime() + tzOffset * 60000);\n}\n\n/**\n * Get the timezone offset string (e.g., \"+07:00\", \"-05:00\") for a timezone.\n *\n * @example\n * getTimezoneOffsetString(\"Asia/Jakarta\"); // \"+07:00\"\n * getTimezoneOffsetString(\"America/New_York\"); // \"-04:00\" or \"-05:00\" (DST)\n */\nexport function getTimezoneOffsetString(timezone: string, date?: Date): string {\n\tconst offset = getTimezoneOffset(timezone, date);\n\tconst sign = offset <= 0 ? \"+\" : \"-\";\n\tconst absOffset = Math.abs(offset);\n\tconst hours = Math.floor(absOffset / 60);\n\tconst minutes = absOffset % 60;\n\treturn `${sign}${String(hours).padStart(2, \"0\")}:${String(minutes).padStart(2, \"0\")}`;\n}\n\n/**\n * Convert a Date to ISO string with a specific timezone offset.\n *\n * @example\n * const date = new Date(\"2026-08-23T22:00:00Z\");\n * toISOWithTimezone(date, \"Asia/Jakarta\");\n * // \"2026-08-24T05:00:00+07:00\"\n */\nexport function toISOWithTimezone(date: Date | string | number, timezone: string): string {\n\tconst d = toDate(date);\n\tconst parts = toTimezoneParts(d, timezone);\n\tconst offset = getTimezoneOffsetString(timezone, d);\n\n\tconst pad = (n: number) => String(n).padStart(2, \"0\");\n\treturn `${parts.year}-${pad(parts.month)}-${pad(parts.day)}T${pad(parts.hour)}:${pad(parts.minute)}:${pad(parts.second)}${offset}`;\n}\n\nexport type GroupByKey = \"hour\" | \"day\" | \"month\" | \"year\";\n\nexport interface GroupByTimezoneOptions {\n\tlocale?: string;\n\tlabelFormatter?: (key: string, groupBy: GroupByKey) => string;\n}\n\nfunction defaultLabelFormatter(key: string, groupBy: GroupByKey, locale: string): string {\n\t// If key looks like a date (YYYY-MM-DD)\n\tif (/^\\d{4}-\\d{2}-\\d{2}$/.test(key)) {\n\t\tconst [y, m, d] = key.split(\"-\").map(Number) as [number, number, number];\n\t\tconst date = new Date(y, m - 1, d);\n\t\treturn new Intl.DateTimeFormat(locale, {\n\t\t\tweekday: \"long\",\n\t\t\tyear: \"numeric\",\n\t\t\tmonth: \"long\",\n\t\t\tday: \"numeric\",\n\t\t}).format(date);\n\t}\n\n\t// If key looks like YYYY-MM\n\tif (/^\\d{4}-\\d{2}$/.test(key)) {\n\t\tconst [y, m] = key.split(\"-\").map(Number) as [number, number];\n\t\tconst date = new Date(y, m - 1, 1);\n\t\treturn new Intl.DateTimeFormat(locale, {\n\t\t\tyear: \"numeric\",\n\t\t\tmonth: \"long\",\n\t\t}).format(date);\n\t}\n\n\t// If key is just a year\n\tif (/^\\d{4}$/.test(key)) {\n\t\treturn key;\n\t}\n\n\t// If key is hour (00-23)\n\tif (/^\\d{2}$/.test(key)) {\n\t\tconst hour = Number(key);\n\t\tconst date = new Date(2000, 0, 1, hour);\n\t\treturn new Intl.DateTimeFormat(locale, {\n\t\t\thour: \"numeric\",\n\t\t\thour12: false,\n\t\t}).format(date);\n\t}\n\n\treturn key;\n}\n\n/**\n * Format a group key into a human-readable label.\n *\n * @example\n * formatGroupLabel(\"2026-08-24\", \"day\", \"id\");\n * // \"Rabu, 24 Agustus 2026\"\n *\n * formatGroupLabel(\"2026-08-24\", \"day\", \"en\");\n * // \"Wednesday, August 24, 2026\"\n *\n * formatGroupLabel(\"05\", \"hour\", \"id\");\n * // \"05.00\"\n */\nexport function formatGroupLabel(\n\tkey: string,\n\tgroupBy: GroupByKey,\n\tlocale = \"en-US\",\n): string {\n\treturn defaultLabelFormatter(key, groupBy, locale);\n}\n\n/**\n * Group items by their date value in a specific timezone.\n *\n * @example\n * const transactions = [\n *   { id: 1, createdAt: \"2026-08-24T05:00:00+07:00\", amount: 100 },\n *   { id: 2, createdAt: \"2026-08-24T08:30:00+07:00\", amount: 200 },\n *   { id: 3, createdAt: \"2026-08-24T14:00:00+07:00\", amount: 150 },\n * ];\n *\n * // Group by hour in Jakarta timezone\n * const hourly = groupByTimezone(transactions, \"createdAt\", \"Asia/Jakarta\", \"hour\");\n * // Map {\n * //   \"05\" => [{ id: 1, ... }],\n * //   \"08\" => [{ id: 2, ... }],\n * //   \"14\" => [{ id: 3, ... }],\n * // }\n *\n * // Group by day\n * const daily = groupByTimezone(transactions, \"createdAt\", \"Asia/Jakarta\", \"day\");\n * // Map {\n * //   \"2026-08-24\" => [all 3 transactions],\n * // }\n *\n * // With human-readable labels\n * const dailyWithLabels = groupByTimezone(\n *   transactions, \"createdAt\", \"Asia/Jakarta\", \"day\",\n *   { locale: \"id\" }\n * );\n * // Labels: \"Rabu, 24 Agustus 2026\"\n */\nexport function groupByTimezone<T>(\n\titems: T[],\n\tdateField: keyof T,\n\ttimezone: string,\n\tgroupBy: GroupByKey = \"day\",\n\toptions?: GroupByTimezoneOptions,\n): Map<string, T[]> {\n\tconst groups = new Map<string, T[]>();\n\tconst locale = options?.locale ?? \"en-US\";\n\n\tfor (const item of items) {\n\t\tconst dateVal = item[dateField];\n\t\tif (!dateVal) continue;\n\n\t\tconst d = toDate(dateVal as Date | string | number);\n\t\tconst parts = toTimezoneParts(d, timezone);\n\t\tconst pad = (n: number) => String(n).padStart(2, \"0\");\n\n\t\tlet key: string;\n\t\tswitch (groupBy) {\n\t\t\tcase \"hour\":\n\t\t\t\tkey = `${pad(parts.hour)}`;\n\t\t\t\tbreak;\n\t\t\tcase \"month\":\n\t\t\t\tkey = `${parts.year}-${pad(parts.month)}`;\n\t\t\t\tbreak;\n\t\t\tcase \"year\":\n\t\t\t\tkey = `${parts.year}`;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tkey = `${parts.year}-${pad(parts.month)}-${pad(parts.day)}`;\n\t\t}\n\n\t\tconst group = groups.get(key) ?? [];\n\t\tgroup.push(item);\n\t\tgroups.set(key, group);\n\t}\n\n\treturn groups;\n}\n\n/**\n * Get labels for groupByTimezone keys.\n *\n * @example\n * const hourly = groupByTimezone(transactions, \"createdAt\", \"Asia/Jakarta\", \"hour\");\n * const labels = getGroupLabels(hourly, \"hour\", \"id\");\n * // Map { \"05\" => \"05.00\", \"08\" => \"08.00\", ... }\n *\n * const daily = groupByTimezone(transactions, \"createdAt\", \"Asia/Jakarta\", \"day\");\n * const labels = getGroupLabels(daily, \"day\", \"id\");\n * // Map { \"2026-08-24\" => \"Rabu, 24 Agustus 2026\", ... }\n */\nexport function getGroupLabels(\n\tgroups: Map<string, unknown[]>,\n\tgroupBy: GroupByKey,\n\tlocale = \"en-US\",\n): Map<string, string> {\n\tconst labels = new Map<string, string>();\n\tfor (const key of groups.keys()) {\n\t\tlabels.set(key, formatGroupLabel(key, groupBy, locale));\n\t}\n\treturn labels;\n}\n\n/**\n * Check if a timezone string is valid.\n *\n * @example\n * isValidTimezone(\"Asia/Jakarta\"); // true\n * isValidTimezone(\"Invalid/Zone\"); // false\n */\nexport function isValidTimezone(timezone: string): boolean {\n\ttry {\n\t\tnew Intl.DateTimeFormat(\"en-US\", { timeZone: timezone });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n","const _ALPHANUMERIC =\n\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\nconst urlAlphabet =\n\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n/**\n * Generate a sequential code with prefix and auto-incrementing counter.\n *\n * @example\n * generateCode(\"T\");      // \"T0001\"\n * generateCode(\"T\");      // \"T0002\"\n * generateCode(\"INV\");    // \"INV0001\"\n * generateCode(\"ORD\", 42); // \"ORD0042\"\n */\nexport function generateCode(prefix: string, counter?: number): string {\n\tif (counter === undefined) {\n\t\t// Use module-level counter per prefix\n\t\tconst current = counters.get(prefix) ?? 0;\n\t\tcounter = current + 1;\n\t\tcounters.set(prefix, counter);\n\t}\n\treturn `${prefix}${counter.toString().padStart(4, \"0\")}`;\n}\n\nconst counters = new Map<string, number>();\n\n/**\n * Reset the auto-increment counter for a prefix.\n *\n * @example\n * resetCounter(\"T\"); // next generateCode(\"T\") will be \"T0001\"\n */\nexport function resetCounter(prefix: string): void {\n\tcounters.delete(prefix);\n}\n\n/**\n * Generate a URL-safe unique ID (nanoid-style).\n *\n * @example\n * nanoid();     // \"V1StGXR8_Z5jdHi6B-myT\"  (21 chars)\n * nanoid(10);   // \"V1StGXR8_Z5\"             (10 chars)\n */\nexport function nanoid(size = 21): string {\n\tconst bytes = crypto.getRandomValues(new Uint8Array(size));\n\treturn Array.from(bytes, (b) => urlAlphabet[b % 64]).join(\"\");\n}\n\n/**\n * Generate a ULID (Time-Ordered Unique Identifier).\n * Format: 26 chars, sortable by creation time.\n *\n * @example\n * ulid(); // \"01ARZ3NDEKTSV4RRFFQ69G5FAV\"\n */\nexport function ulid(): string {\n\tconst time = Date.now();\n\tconst timeStr = encodeTime(time, 10);\n\tconst randomStr = encodeRandom(16);\n\treturn timeStr + randomStr;\n}\n\nconst ENCODING = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\n\nfunction encodeTime(time: number, length: number): string {\n\tlet result = \"\";\n\tfor (let i = length - 1; i >= 0; i--) {\n\t\tresult = ENCODING[time % 32] + result;\n\t\ttime = Math.floor(time / 32);\n\t}\n\treturn result;\n}\n\nfunction encodeRandom(length: number): string {\n\tconst bytes = crypto.getRandomValues(new Uint8Array(length));\n\treturn Array.from(bytes, (b) => ENCODING[b % 32]).join(\"\");\n}\n","const PRIVATE_IP_REGEX =\n\t/^(10\\.|172\\.(1[6-9]|2\\d|3[01])\\.|192\\.168\\.|127\\.|0\\.|localhost|::1|fc|fd)/i;\n\n/**\n * Get the client IP address from a Request.\n * Checks X-Forwarded-For, X-Real-IP, then falls back to request.remoteAddress.\n */\nexport function getClientIP(request: Request): string {\n\tconst xff = request.headers.get(\"x-forwarded-for\");\n\tif (xff) {\n\t\tconst first = xff.split(\",\")[0]?.trim();\n\t\tif (first) return first;\n\t}\n\n\tconst xri = request.headers.get(\"x-real-ip\");\n\tif (xri) return xri;\n\n\t// Bun exposes remoteAddress on the request\n\t// biome-ignore lint/suspicious/noExplicitAny: Bun-specific property\n\tconst remote = (request as any).remoteAddress;\n\tif (remote) return remote;\n\n\treturn \"unknown\";\n}\n\n/**\n * Check if an IP address is a private/reserved address.\n */\nexport function isPrivateIP(ip: string): boolean {\n\treturn PRIVATE_IP_REGEX.test(ip);\n}\n\ninterface UserAgentInfo {\n\tbrowser: string;\n\tos: string;\n\tdevice: string;\n}\n\nconst BROWSER_PATTERNS: [RegExp, string][] = [\n\t[/opr\\//i, \"Opera\"],\n\t[/edg/i, \"Edge\"],\n\t[/chrome/i, \"Chrome\"],\n\t[/firefox/i, \"Firefox\"],\n\t[/safari/i, \"Safari\"],\n\t[/msie|trident/i, \"IE\"],\n];\n\nconst OS_PATTERNS: [RegExp, string][] = [\n\t[/windows/i, \"Windows\"],\n\t[/mac os/i, \"macOS\"],\n\t[/linux/i, \"Linux\"],\n\t[/android/i, \"Android\"],\n\t[/iphone|ipad|ipod/i, \"iOS\"],\n\t[/cros/i, \"Chrome OS\"],\n\t[/winphone/i, \"Windows Phone\"],\n];\n\nconst DEVICE_PATTERNS: [RegExp, string][] = [\n\t[/mobile|android.*mobile|iphone/i, \"Mobile\"],\n\t[/ipad|tablet|android(?!.*mobile)/i, \"Tablet\"],\n];\n\n/**\n * Parse the User-Agent header into a simple `{ browser, os, device }` object.\n */\nexport function parseUserAgent(request: Request): UserAgentInfo {\n\tconst ua = request.headers.get(\"user-agent\") ?? \"\";\n\n\tlet browser = \"Other\";\n\tfor (const [pattern, name] of BROWSER_PATTERNS) {\n\t\tif (pattern.test(ua)) {\n\t\t\tbrowser = name;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tlet os = \"Other\";\n\tfor (const [pattern, name] of OS_PATTERNS) {\n\t\tif (pattern.test(ua)) {\n\t\t\tos = name;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tlet device = \"Desktop\";\n\tfor (const [pattern, name] of DEVICE_PATTERNS) {\n\t\tif (pattern.test(ua)) {\n\t\t\tdevice = name;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn { browser, os, device };\n}\n","/**\n * Clamp a number between min and max (inclusive).\n *\n * @example\n * clamp(15, 0, 10);  // 10\n * clamp(-5, 0, 10);  // 0\n * clamp(5, 0, 10);   // 5\n */\nexport function clamp(value: number, min: number, max: number): number {\n\treturn Math.min(Math.max(value, min), max);\n}\n\n/**\n * Random integer between min and max (inclusive).\n *\n * @example\n * random(1, 100); // 42\n */\nexport function random(min: number, max: number): number {\n\treturn Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\n/**\n * Random float between min and max.\n *\n * @example\n * randomFloat(1.5, 3.5); // 2.731\n */\nexport function randomFloat(min: number, max: number): number {\n\treturn Math.random() * (max - min) + min;\n}\n\n/**\n * Format a number with locale-aware separators.\n *\n * @example\n * formatNumber(1000000);       // \"1,000,000\"\n * formatNumber(1000000, \"de\"); // \"1.000.000\"\n */\nexport function formatNumber(n: number, locale = \"en-US\"): string {\n\treturn n.toLocaleString(locale);\n}\n\n/**\n * Format bytes to human-readable string.\n *\n * @example\n * formatBytes(0);          // \"0 B\"\n * formatBytes(1024);       // \"1 KB\"\n * formatBytes(1536);       // \"1.5 KB\"\n * formatBytes(1048576);    // \"1 MB\"\n */\nexport function formatBytes(bytes: number): string {\n\tif (bytes === 0) return \"0 B\";\n\tconst units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\"];\n\tconst i = Math.floor(Math.log(bytes) / Math.log(1024));\n\tconst size = bytes / 1024 ** i;\n\treturn `${size === 0 ? \"0\" : size.toFixed(size >= 100 ? 0 : size >= 10 ? 1 : 2)} ${units[i]}`;\n}\n\n/**\n * Format a number as currency.\n *\n * @example\n * formatCurrency(1000);          // \"$1,000.00\"\n * formatCurrency(1000, \"EUR\");   // \"€1,000.00\"\n * formatCurrency(1000, \"IDR\", \"id-ID\"); // \"Rp1.000\"\n */\nexport function formatCurrency(\n\tamount: number,\n\tcurrency = \"USD\",\n\tlocale = \"en-US\",\n): string {\n\treturn amount.toLocaleString(locale, {\n\t\tstyle: \"currency\",\n\t\tcurrency,\n\t});\n}\n","/**\n * Pick specified keys from an object.\n * `pick({ a: 1, b: 2, c: 3 }, [\"a\", \"c\"])` → `{ a: 1, c: 3 }`\n */\nexport function pick<T extends Record<string, unknown>, K extends keyof T>(\n\tobj: T,\n\tkeys: K[],\n): Pick<T, K> {\n\tconst result = {} as Pick<T, K>;\n\tfor (const key of keys) {\n\t\tif (key in obj) result[key] = obj[key];\n\t}\n\treturn result;\n}\n\n/**\n * Omit specified keys from an object.\n * `omit({ a: 1, b: 2, c: 3 }, [\"b\"])` → `{ a: 1, c: 3 }`\n */\nexport function omit<T extends Record<string, unknown>, K extends keyof T>(\n\tobj: T,\n\tkeys: K[],\n): Omit<T, K> {\n\tconst result = { ...obj };\n\tfor (const key of keys) {\n\t\tdelete result[key];\n\t}\n\treturn result as Omit<T, K>;\n}\n\n/**\n * Group an array of objects by a key or field function.\n * `groupBy([{ type: \"a\" }, { type: \"b\" }, { type: \"a\" }], \"type\")`\n * → `{ a: [{ type: \"a\" }, { type: \"a\" }], b: [{ type: \"b\" }] }`\n */\nexport function groupBy<T>(\n\tarr: T[],\n\tkey: keyof T | ((item: T) => string),\n): Record<string, T[]> {\n\tconst result: Record<string, T[]> = {};\n\tfor (const item of arr) {\n\t\tconst k = typeof key === \"function\" ? key(item) : String(item[key]);\n\t\tif (!result[k]) {\n\t\t\tresult[k] = [];\n\t\t}\n\t\tresult[k].push(item);\n\t}\n\treturn result;\n}\n\n/**\n * Return unique values from an array.\n * `uniq([1, 2, 2, 3])` → `[1, 2, 3]`\n */\nexport function uniq<T>(arr: T[]): T[] {\n\treturn [...new Set(arr)];\n}\n\n/**\n * Flatten a nested array.\n * `flatten([[1, 2], [3, [4, 5]]])` → `[1, 2, 3, 4, 5]`\n */\nexport function flatten<T>(arr: unknown[], depth = Infinity): T[] {\n\treturn arr.flat(depth) as T[];\n}\n\n/**\n * Split an array into chunks of a given size.\n * `chunk([1, 2, 3, 4, 5], 2)` → `[[1, 2], [3, 4], [5]]`\n */\nexport function chunk<T>(arr: T[], size: number): T[][] {\n\tif (size <= 0) throw new Error(\"chunk size must be > 0\");\n\tconst chunks: T[][] = [];\n\tfor (let i = 0; i < arr.length; i += size) {\n\t\tchunks.push(arr.slice(i, i + size));\n\t}\n\treturn chunks;\n}\n\n/**\n * Deep merge two objects. Arrays are replaced, not merged.\n *\n * @example\n * deepMerge({ a: 1, b: { c: 2 } }, { b: { d: 3 } });\n * // => { a: 1, b: { c: 2, d: 3 } }\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n\ttarget: T,\n\t...sources: Partial<T>[]\n): T {\n\tconst result = { ...target };\n\tfor (const source of sources) {\n\t\tfor (const key of Object.keys(source) as (keyof T)[]) {\n\t\t\tconst targetVal = result[key];\n\t\t\tconst sourceVal = source[key];\n\t\t\tif (isPlainObject(targetVal) && isPlainObject(sourceVal)) {\n\t\t\t\t(result[key] as Record<string, unknown>) = deepMerge(\n\t\t\t\t\ttargetVal as Record<string, unknown>,\n\t\t\t\t\tsourceVal as Record<string, unknown>,\n\t\t\t\t);\n\t\t\t} else if (sourceVal !== undefined) {\n\t\t\t\tresult[key] = sourceVal as T[typeof key];\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction isPlainObject(val: unknown): val is Record<string, unknown> {\n\treturn typeof val === \"object\" && val !== null && !Array.isArray(val);\n}\n\n/**\n * Flatten a nested object into a single-depth object with dot-notation keys.\n *\n * @example\n * flattenObject({ a: { b: { c: 1 } } });\n * // => { \"a.b.c\": 1 }\n *\n * flattenObject({ a: { b: 1 }, c: 2 }, \"-\");\n * // => { \"a-b\": 1, c: 2 }\n */\nexport function flattenObject(\n\tobj: Record<string, unknown>,\n\tsep = \".\",\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = {};\n\n\tfunction recurse(current: Record<string, unknown>, prefix: string) {\n\t\tfor (const key of Object.keys(current)) {\n\t\t\tconst value = current[key];\n\t\t\tconst newKey = prefix ? `${prefix}${sep}${key}` : key;\n\n\t\t\tif (isPlainObject(value)) {\n\t\t\t\trecurse(value as Record<string, unknown>, newKey);\n\t\t\t} else {\n\t\t\t\tresult[newKey] = value;\n\t\t\t}\n\t\t}\n\t}\n\n\trecurse(obj, \"\");\n\treturn result;\n}\n","const ITERATIONS = 100_000;\nconst KEY_LENGTH = 64;\nconst DIGEST = \"SHA-256\";\n\nfunction toHex(buffer: Uint8Array): string {\n\treturn [...buffer].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nfunction fromHex(hex: string): Uint8Array {\n\treturn new Uint8Array(\n\t\thex.match(/.{1,2}/g)?.map((h) => Number.parseInt(h, 16)) ?? [],\n\t);\n}\n\n/**\n * Hash a password using PBKDF2-SHA-256.\n * Returns a string in the format `iterations:salt:hash` (all hex-encoded).\n */\nexport async function hashPassword(password: string): Promise<string> {\n\tconst salt = crypto.getRandomValues(new Uint8Array(32));\n\tconst key = await crypto.subtle.importKey(\n\t\t\"raw\",\n\t\tnew TextEncoder().encode(password),\n\t\t\"PBKDF2\",\n\t\tfalse,\n\t\t[\"deriveBits\"],\n\t);\n\tconst derived = await crypto.subtle.deriveBits(\n\t\t{ name: \"PBKDF2\", salt, iterations: ITERATIONS, hash: DIGEST },\n\t\tkey,\n\t\tKEY_LENGTH * 8,\n\t);\n\treturn `${ITERATIONS}:${toHex(salt)}:${toHex(new Uint8Array(derived))}`;\n}\n\n/**\n * Verify a password against a stored hash string (`iterations:salt:hash`).\n * Uses timing-safe comparison.\n */\nexport async function verifyPassword(\n\tpassword: string,\n\tstored: string,\n): Promise<boolean> {\n\tconst parts = stored.split(\":\");\n\tif (parts.length < 3) return false;\n\n\tconst iterations = Number(parts[0]);\n\tconst saltHex = parts[1] as string;\n\tconst expectedHash = parts[2] as string;\n\tconst salt = fromHex(saltHex) as Uint8Array<ArrayBuffer>;\n\n\tconst key = await crypto.subtle.importKey(\n\t\t\"raw\",\n\t\tnew TextEncoder().encode(password),\n\t\t\"PBKDF2\",\n\t\tfalse,\n\t\t[\"deriveBits\"],\n\t);\n\tconst derived = await crypto.subtle.deriveBits(\n\t\t{ name: \"PBKDF2\", salt, iterations, hash: DIGEST },\n\t\tkey,\n\t\tKEY_LENGTH * 8,\n\t);\n\tconst actual = toHex(new Uint8Array(derived));\n\n\tif (actual.length !== expectedHash.length) return false;\n\tlet result = 0;\n\tfor (let i = 0; i < actual.length; i++) {\n\t\tresult |= actual.charCodeAt(i) ^ expectedHash.charCodeAt(i);\n\t}\n\treturn result === 0;\n}\n","/**\n * Convert a string to a URL-friendly slug.\n * `\"Hello World!\"` → `\"hello-world\"`\n */\nexport function slugify(str: string): string {\n\treturn str\n\t\t.toLowerCase()\n\t\t.trim()\n\t\t.replace(/[^\\w\\s-]/g, \"\")\n\t\t.replace(/[\\s_]+/g, \"-\")\n\t\t.replace(/-+/g, \"-\")\n\t\t.replace(/^-|-$/g, \"\");\n}\n\n/**\n * Truncate a string to a maximum length with an ellipsis suffix.\n * `\"Lorem ipsum dolor sit\"` → `\"Lorem ipsum...\"` (max=13)\n */\nexport function truncate(str: string, max = 100, suffix = \"...\"): string {\n\tif (str.length <= max) return str;\n\treturn str.slice(0, max - suffix.length) + suffix;\n}\n\n/**\n * Capitalize the first letter of a string.\n * `\"hello\"` → `\"Hello\"`\n */\nexport function capitalize(str: string): string {\n\treturn str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n/**\n * Convert a string to camelCase.\n * `\"hello-world\"` → `\"helloWorld\"`\n * `\"hello_world\"` → `\"helloWorld\"`\n */\nexport function camelCase(str: string): string {\n\treturn str\n\t\t.replace(/[-_\\s]+(.)/g, (_, c: string) => c.toUpperCase())\n\t\t.replace(/^(.)/, (_, c: string) => c.toLowerCase());\n}\n\n/**\n * Convert a string to snake_case.\n * `\"helloWorld\"` → `\"hello_world\"`\n * `\"hello-world\"` → `\"hello_world\"`\n */\nexport function snakeCase(str: string): string {\n\treturn str\n\t\t.replace(/([A-Z])/g, \"_$1\")\n\t\t.replace(/[-\\s]+/g, \"_\")\n\t\t.toLowerCase()\n\t\t.replace(/^_/, \"\")\n\t\t.replace(/_+/g, \"_\");\n}\n\n/**\n * Convert a string to kebab-case.\n * `\"helloWorld\"` → `\"hello-world\"`\n * `\"hello_world\"` → `\"hello-world\"`\n */\nexport function kebabCase(str: string): string {\n\treturn snakeCase(str).replace(/_/g, \"-\");\n}\n","/**\n * Audit logging middleware for tracking user actions.\n *\n * @example\n * ```ts\n * import { auditLog } from \"buntok\";\n *\n * // Log all requests\n * app.use(auditLog());\n *\n * // Log with custom storage\n * app.use(auditLog({\n *   storage: async (entry) => {\n *     await db.auditLog.create({ data: entry });\n *   },\n *   excludePaths: [\"/health\", \"/docs\"],\n *   excludeMethods: [\"OPTIONS\"],\n * }));\n * ```\n */\n\nexport interface AuditLogEntry {\n\ttimestamp: string;\n\tmethod: string;\n\tpath: string;\n\tstatus: number;\n\tduration: number;\n\tip?: string;\n\tuserId?: string | number;\n\tuserAgent?: string;\n\tbody?: any;\n\tquery?: Record<string, any>;\n\terror?: string;\n}\n\nexport interface AuditLogOptions {\n\t/** Custom storage function. If not provided, logs to console. */\n\tstorage?: (entry: AuditLogEntry) => Promise<void> | void;\n\n\t/** Paths to exclude from logging */\n\texcludePaths?: string[];\n\n\t/** Methods to exclude from logging */\n\texcludeMethods?: string[];\n\n\t/** Whether to log request body (default: false) */\n\tlogBody?: boolean;\n\n\t/** Whether to log query params (default: true) */\n\tlogQuery?: boolean;\n\n\t/** Max body size to log in bytes (default: 1024) */\n\tmaxBodySize?: number;\n}\n\nfunction shouldLog(\n\tpath: string,\n\tmethod: string,\n\toptions: AuditLogOptions,\n): boolean {\n\tif (options.excludePaths?.some((p) => path.startsWith(p))) return false;\n\tif (options.excludeMethods?.includes(method)) return false;\n\treturn true;\n}\n\nfunction truncate(str: string, max: number): string {\n\tif (str.length <= max) return str;\n\treturn `${str.slice(0, max)}...[truncated]`;\n}\n\n/**\n * Audit logging middleware.\n * Logs all requests with timing, user info, and optional body/query.\n */\nexport function auditLog(options: AuditLogOptions = {}) {\n\tconst {\n\t\tlogBody = false,\n\t\tlogQuery = true,\n\t\tmaxBodySize = 1024,\n\t} = options;\n\n\treturn async (ctx: any, next: () => Promise<void>) => {\n\t\tconst { method, path } = ctx.req;\n\t\tconst start = performance.now();\n\n\t\tif (!shouldLog(path, method, options)) {\n\t\t\tawait next();\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait next();\n\t\t} finally {\n\t\t\tconst duration = performance.now() - start;\n\t\t\tconst status = ctx.res?.status ?? 200;\n\n\t\t\tconst entry: AuditLogEntry = {\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\tmethod,\n\t\t\t\tpath,\n\t\t\t\tstatus,\n\t\t\t\tduration: Math.round(duration * 100) / 100,\n\t\t\t\tip: ctx.req.headers?.[\"x-forwarded-for\"] ?? ctx.req.remoteAddress,\n\t\t\t\tuserId: ctx.user?.id,\n\t\t\t\tuserAgent: ctx.req.headers?.[\"user-agent\"],\n\t\t\t};\n\n\t\t\tif (logBody && ctx.req.body) {\n\t\t\t\tconst bodyStr = JSON.stringify(ctx.req.body);\n\t\t\t\tentry.body = truncate(bodyStr, maxBodySize);\n\t\t\t}\n\n\t\t\tif (logQuery) {\n\t\t\t\tconst url = new URL(ctx.req.url, `http://${ctx.req.headers.host}`);\n\t\t\t\tconst query = Object.fromEntries(url.searchParams);\n\t\t\t\tif (Object.keys(query).length > 0) {\n\t\t\t\t\tentry.query = query;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (status >= 400) {\n\t\t\t\tentry.error = ctx._error?.message;\n\t\t\t}\n\n\t\t\t// Custom storage or console\n\t\t\tif (options.storage) {\n\t\t\t\tawait options.storage(entry);\n\t\t\t} else {\n\t\t\t\tconst logFn = status >= 500\n\t\t\t\t\t? console.error\n\t\t\t\t\t: status >= 400\n\t\t\t\t\t\t? console.warn\n\t\t\t\t\t\t: console.log;\n\t\t\t\tlogFn(`[audit] ${method} ${path} ${status} ${entry.duration}ms`);\n\t\t\t}\n\t\t}\n\t};\n}\n","import type { Middleware } from \"../app\";\n\nexport interface CompressOptions {\n\t/**\n\t * Minimum response body size (bytes) before compressing. Compressing\n\t * tiny payloads wastes CPU for zero/negative gain, so this defaults to\n\t * 1024 rather than compressing everything unconditionally.\n\t */\n\tthreshold?: number;\n\t/** Content-Type prefixes eligible for compression. */\n\ttypes?: string[];\n\t/** Brotli compression level (1-11). Default 4 gives ~85% of max compression\n\t * at 3-5x the speed of level 11. Set to 11 for maximum ratio. */\n\tbrotliLevel?: number;\n}\n\nconst DEFAULT_TYPES = [\n\t\"text/\",\n\t\"application/json\",\n\t\"application/javascript\",\n\t\"application/xml\",\n\t\"image/svg+xml\",\n];\n\nconst DEFAULT_OPTIONS: Required<CompressOptions> = {\n\tthreshold: 1024,\n\ttypes: DEFAULT_TYPES,\n\tbrotliLevel: 4,\n};\n\n/**\n * Compress response bodies with gzip or brotli, negotiated from the\n * request's `Accept-Encoding` header. Opt-in via `app.use(compress())` —\n * compression is real CPU work, so routes that don't need it (or that\n * already stream pre-compressed/binary content) shouldn't pay for it.\n *\n * Uses Bun's native `Bun.gzipSync` (Zig, not a JS gzip implementation) and\n * falls back to `node:zlib`'s brotli when the client prefers `br`.\n *\n * Brotli defaults to level 4 for a good speed/ratio tradeoff — roughly\n * 3-5x faster than level 11 with only ~15% larger output.\n */\nexport function compress(options: CompressOptions = {}): Middleware {\n\tconst opts = { ...DEFAULT_OPTIONS, ...options };\n\n\treturn async (ctx, next) => {\n\t\tconst result = await next();\n\t\tif (!(result instanceof Response) || !result.body) return result;\n\n\t\tif (result.headers.get(\"Content-Encoding\")) return result;\n\n\t\tconst contentType = result.headers.get(\"Content-Type\") || \"\";\n\t\tconst eligible = opts.types.some((t) => contentType.startsWith(t));\n\t\tif (!eligible) return result;\n\n\t\tconst acceptEncoding = ctx.request.headers.get(\"Accept-Encoding\") || \"\";\n\t\tconst supportsBrotli = acceptEncoding.includes(\"br\");\n\t\tconst supportsGzip = acceptEncoding.includes(\"gzip\");\n\t\tif (!supportsBrotli && !supportsGzip) return result;\n\n\t\t// Fast path: use Content-Length header to skip buffering for small responses\n\t\tconst contentLength = result.headers.get(\"Content-Length\");\n\t\tif (contentLength && Number(contentLength) < opts.threshold) {\n\t\t\treturn result;\n\t\t}\n\n\t\t// If no Content-Length, we must buffer to check size — but only compress\n\t\t// if above threshold. For small responses without Content-Length, skip\n\t\t// compression entirely to avoid unnecessary buffering + new Response.\n\t\tif (!contentLength) return result;\n\n\t\tconst buffer = new Uint8Array(await result.arrayBuffer());\n\t\tif (buffer.byteLength < opts.threshold) {\n\t\t\treturn result;\n\t\t}\n\n\t\tlet compressed: Uint8Array;\n\t\tlet encoding: string;\n\n\t\tif (supportsBrotli) {\n\t\t\tconst zlib = await import(\"node:zlib\");\n\t\t\tcompressed = zlib.brotliCompressSync(buffer, {\n\t\t\t\tparams: {\n\t\t\t\t\t[zlib.constants.BROTLI_PARAM_QUALITY]: opts.brotliLevel,\n\t\t\t\t},\n\t\t\t});\n\t\t\tencoding = \"br\";\n\t\t} else {\n\t\t\tcompressed = Bun.gzipSync(buffer);\n\t\t\tencoding = \"gzip\";\n\t\t}\n\n\t\tconst headers = new Headers(result.headers);\n\t\theaders.set(\"Content-Encoding\", encoding);\n\t\theaders.set(\"Vary\", \"Accept-Encoding\");\n\t\theaders.delete(\"Content-Length\");\n\n\t\treturn new Response(compressed, {\n\t\t\tstatus: result.status,\n\t\t\tstatusText: result.statusText,\n\t\t\theaders,\n\t\t});\n\t};\n}\n","import type { Middleware } from \"../app\";\n\nexport interface CorsOptions {\n\torigin?: string | string[] | ((origin: string) => boolean);\n\tmethods?: string[];\n\theaders?: string[];\n\tcredentials?: boolean;\n}\n\nexport const cors = (options: CorsOptions = {}): Middleware => {\n\treturn async (ctx, next) => {\n\t\tconst requestOrigin = ctx.request.headers.get(\"Origin\") || \"*\";\n\t\tlet allowedOrigin = \"*\";\n\n\t\tif (typeof options.origin === \"function\") {\n\t\t\tallowedOrigin = options.origin(requestOrigin) ? requestOrigin : \"\";\n\t\t} else if (Array.isArray(options.origin)) {\n\t\t\tallowedOrigin = options.origin.includes(requestOrigin)\n\t\t\t\t? requestOrigin\n\t\t\t\t: \"\";\n\t\t} else if (options.origin) {\n\t\t\tallowedOrigin = options.origin;\n\t\t}\n\n\t\tif (ctx.request.method === \"OPTIONS\") {\n\t\t\tconst res = new Response(null, { status: 204 });\n\t\t\tres.headers.set(\"Access-Control-Allow-Origin\", allowedOrigin);\n\t\t\tres.headers.set(\n\t\t\t\t\"Access-Control-Allow-Methods\",\n\t\t\t\t(\n\t\t\t\t\toptions.methods || [\n\t\t\t\t\t\t\"GET\",\n\t\t\t\t\t\t\"POST\",\n\t\t\t\t\t\t\"PUT\",\n\t\t\t\t\t\t\"DELETE\",\n\t\t\t\t\t\t\"PATCH\",\n\t\t\t\t\t\t\"OPTIONS\",\n\t\t\t\t\t]\n\t\t\t\t).join(\",\"),\n\t\t\t);\n\t\t\tres.headers.set(\n\t\t\t\t\"Access-Control-Allow-Headers\",\n\t\t\t\t(\n\t\t\t\t\toptions.headers || [\"Content-Type\", \"Authorization\", \"x-api-key\"]\n\t\t\t\t).join(\",\"),\n\t\t\t);\n\t\t\tif (options.credentials)\n\t\t\t\tres.headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n\t\t\tres.headers.set(\"X-Powered-By\", \"Buntok\");\n\t\t\treturn res;\n\t\t}\n\n\t\tconst response = await next();\n\n\t\tresponse.headers.set(\"Access-Control-Allow-Origin\", allowedOrigin);\n\t\tresponse.headers.set(\"X-Powered-By\", \"Buntok\");\n\t\tif (options.credentials)\n\t\t\tresponse.headers.set(\"Access-Control-Allow-Credentials\", \"true\");\n\n\t\treturn response;\n\t};\n};\n","import type { Context } from \"../context\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyApp = {\n\tget: (\n\t\tpath: string,\n\t\thandler: (ctx: Context) => Promise<Response> | Response,\n\t) => void;\n};\n\nexport interface HealthCheckOptions {\n\t/** Health check endpoint path (default: /health) */\n\tpath?: string;\n\t/** Custom health check function */\n\tcheck?: () => Promise<HealthStatus> | HealthStatus;\n\t/** Include uptime in response (default: true) */\n\tincludeUptime?: boolean;\n\t/** Include version in response */\n\tversion?: string;\n}\n\nexport interface HealthStatus {\n\tstatus: \"healthy\" | \"unhealthy\" | \"degraded\";\n\tmessage?: string;\n\tchecks?: Record<\n\t\tstring,\n\t\t{ status: string; message?: string; duration?: number }\n\t>;\n}\n\nconst startTime = Date.now();\n\n/**\n * Register health check endpoint on the app\n */\nexport function healthCheck(app: AnyApp, options: HealthCheckOptions = {}) {\n\tconst path = options.path || \"/health\";\n\n\tapp.get(path, async (ctx: Context) => {\n\t\ttry {\n\t\t\t// Run custom health check if provided\n\t\t\tlet healthStatus: HealthStatus = { status: \"healthy\" };\n\n\t\t\tif (options.check) {\n\t\t\t\thealthStatus = await options.check();\n\t\t\t}\n\n\t\t\tconst response: Record<string, unknown> = {\n\t\t\t\t...healthStatus,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\tuptime:\n\t\t\t\t\toptions.includeUptime !== false\n\t\t\t\t\t\t? Math.floor((Date.now() - startTime) / 1000)\n\t\t\t\t\t\t: undefined,\n\t\t\t\tversion: options.version,\n\t\t\t};\n\n\t\t\t// Clean up undefined values\n\t\t\tObject.keys(response).forEach((key) => {\n\t\t\t\tif (response[key] === undefined) {\n\t\t\t\t\tdelete response[key];\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst statusCode = healthStatus.status === \"healthy\" ? 200 : 503;\n\t\t\treturn ctx.json(response, statusCode);\n\t\t} catch (_error) {\n\t\t\treturn ctx.json(\n\t\t\t\t{\n\t\t\t\t\tstatus: \"unhealthy\",\n\t\t\t\t\terror: \"Unknown error\",\n\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t},\n\t\t\t\t503,\n\t\t\t);\n\t\t}\n\t});\n}\n\n/**\n * Create a database health check function\n */\nexport function createDatabaseCheck(\n\tcheckFn: () => Promise<boolean>,\n): () => Promise<HealthStatus> {\n\treturn async () => {\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst isHealthy = await checkFn();\n\t\t\tconst duration = performance.now() - start;\n\n\t\t\treturn {\n\t\t\t\tstatus: isHealthy ? \"healthy\" : \"unhealthy\",\n\t\t\t\tchecks: {\n\t\t\t\t\tdatabase: {\n\t\t\t\t\t\tstatus: isHealthy ? \"up\" : \"down\",\n\t\t\t\t\t\tduration: Math.round(duration),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tstatus: \"unhealthy\",\n\t\t\t\tchecks: {\n\t\t\t\t\tdatabase: {\n\t\t\t\t\t\tstatus: \"down\",\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\terror instanceof Error ? error.message : \"Connection failed\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t};\n}\n\n/**\n * Create a combined health check function\n */\nexport function createHealthCheck(\n\tchecks: Array<{ name: string; check: () => Promise<boolean> }>,\n): () => Promise<HealthStatus> {\n\treturn async () => {\n\t\tconst results: Record<string, { status: string; duration?: number }> = {};\n\t\tlet overallStatus: \"healthy\" | \"unhealthy\" | \"degraded\" = \"healthy\";\n\n\t\tfor (const { name, check } of checks) {\n\t\t\tconst start = performance.now();\n\t\t\ttry {\n\t\t\t\tconst isHealthy = await check();\n\t\t\t\tconst duration = performance.now() - start;\n\n\t\t\t\tresults[name] = {\n\t\t\t\t\tstatus: isHealthy ? \"up\" : \"down\",\n\t\t\t\t\tduration: Math.round(duration),\n\t\t\t\t};\n\n\t\t\t\tif (!isHealthy) {\n\t\t\t\t\toverallStatus = \"unhealthy\";\n\t\t\t\t}\n\t\t\t} catch (_error) {\n\t\t\t\tresults[name] = {\n\t\t\t\t\tstatus: \"down\",\n\t\t\t\t};\n\t\t\t\toverallStatus = \"unhealthy\";\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tstatus: overallStatus,\n\t\t\tchecks: results,\n\t\t};\n\t};\n}\n","import type { Middleware } from \"../app\";\n\nexport interface HelmetOptions {\n\t/** X-Content-Type-Options (default: \"nosniff\") */\n\tcontentTypeOptions?: string;\n\t/** X-Frame-Options (default: \"DENY\") */\n\tframeOptions?: string;\n\t/** X-XSS-Protection (default: \"0\") */\n\txssProtection?: string;\n\t/** Referrer-Policy (default: \"no-referrer\") */\n\treferrerPolicy?: string;\n\t/** Strict-Transport-Security (default: \"max-age=31536000; includeSubDomains\") */\n\thsts?: string;\n\t/** X-DNS-Prefetch-Control (default: \"on\") */\n\tdnsPrefetch?: string;\n\t/** Permissions-Policy (default: \"camera=(), microphone=(), geolocation=()\") */\n\tpermissionsPolicy?: string;\n\t/** Custom headers to add */\n\tadditionalHeaders?: Record<string, string>;\n}\n\nconst DEFAULT_HEADERS: Record<string, string> = {\n\t\"X-Content-Type-Options\": \"nosniff\",\n\t\"X-Frame-Options\": \"DENY\",\n\t\"X-XSS-Protection\": \"0\",\n\t\"Referrer-Policy\": \"no-referrer\",\n\t\"Strict-Transport-Security\": \"max-age=31536000; includeSubDomains\",\n\t\"X-DNS-Prefetch-Control\": \"on\",\n\t\"Permissions-Policy\": \"camera=(), microphone=(), geolocation=()\",\n};\n\n/**\n * Security headers middleware — adds common security headers to all responses.\n *\n * @example\n * import { helmet } from \"@buntok/core\";\n *\n * // Default — all standard headers\n * app.use(helmet());\n *\n * // Custom options\n * app.use(helmet({\n *   frameOptions: \"SAMEORIGIN\",\n *   hsts: \"max-age=63072000\",\n * }));\n */\nexport function helmet(options?: HelmetOptions): Middleware {\n\tconst headers: Record<string, string> = { ...DEFAULT_HEADERS };\n\n\tif (options?.contentTypeOptions)\n\t\theaders[\"X-Content-Type-Options\"] = options.contentTypeOptions;\n\tif (options?.frameOptions) headers[\"X-Frame-Options\"] = options.frameOptions;\n\tif (options?.xssProtection)\n\t\theaders[\"X-XSS-Protection\"] = options.xssProtection;\n\tif (options?.referrerPolicy)\n\t\theaders[\"Referrer-Policy\"] = options.referrerPolicy;\n\tif (options?.hsts) headers[\"Strict-Transport-Security\"] = options.hsts;\n\tif (options?.dnsPrefetch)\n\t\theaders[\"X-DNS-Prefetch-Control\"] = options.dnsPrefetch;\n\tif (options?.permissionsPolicy)\n\t\theaders[\"Permissions-Policy\"] = options.permissionsPolicy;\n\tif (options?.additionalHeaders)\n\t\tObject.assign(headers, options.additionalHeaders);\n\n\treturn async (_ctx, next) => {\n\t\tconst response = await next();\n\t\t// Set headers directly on the response — avoids copying Headers + creating new Response\n\t\tfor (const [key, value] of Object.entries(headers)) {\n\t\t\tif (!response.headers.has(key)) {\n\t\t\t\tresponse.headers.set(key, value);\n\t\t\t}\n\t\t}\n\t\treturn response;\n\t};\n}\n","import type { Middleware } from \"../app\";\nimport type { Context } from \"../context\";\n\nexport interface RateLimiterOptions {\n\t/** Maximum requests per window */\n\tmax?: number;\n\t/** Window duration in milliseconds (default: 60000 = 1 minute) */\n\twindowMs?: number;\n\t/** Custom key function (default: IP address) */\n\tkeyGenerator?: (ctx: Context) => string;\n\t/** Custom message when rate limit exceeded */\n\tmessage?: string;\n\t/** HTTP status code when rate limit exceeded (default: 429) */\n\tstatusCode?: number;\n\t/** Skip rate limiting for certain requests */\n\tskip?: (ctx: Context) => boolean;\n\t/** Headers to include in response */\n\theaders?: boolean;\n\t/**\n\t * Where counters are stored. Defaults to an in-memory Map, which is lost\n\t * on restart and not shared across processes/instances. Pass\n\t * `sqliteStore(path)` to persist counters in a bun:sqlite database instead\n\t * (e.g. shared across a clustered deployment via a shared file, or simply\n\t * to survive restarts without adding an external dependency like Redis).\n\t */\n\tstore?: RateLimitStore<unknown>;\n}\n\ninterface RateLimitEntry {\n\tcount: number;\n\tresetTime: number;\n}\n\n/**\n * Minimal Map-like interface the rate limiters need. Implemented by both the\n * default in-memory store and the optional bun:sqlite-backed store below.\n */\nexport interface RateLimitStore<T> {\n\tget(key: string): T | undefined;\n\tset(key: string, value: T): void;\n\tdelete(key: string): void;\n\tentries(): IterableIterator<[string, T]>;\n}\n\nfunction memoryStore<T>(): RateLimitStore<T> {\n\treturn new Map<string, T>();\n}\n\n/**\n * Persist rate-limit counters in a bun:sqlite database file instead of an\n * in-memory Map. Useful when you want counters to survive process restarts,\n * or to be shared across multiple instances pointed at the same file, without\n * pulling in an external dependency like Redis.\n *\n * Requires the Bun runtime (uses `bun:sqlite`).\n */\nexport function sqliteStore<T>(\n\tpath = \"rate-limiter.sqlite\",\n): RateLimitStore<T> {\n\tconst { Database } = require(\"bun:sqlite\") as typeof import(\"bun:sqlite\");\n\tconst db = new Database(path);\n\tdb.run(\n\t\t\"CREATE TABLE IF NOT EXISTS rate_limit_entries (key TEXT PRIMARY KEY, value TEXT NOT NULL)\",\n\t);\n\n\tconst getStmt = db.query(\n\t\t\"SELECT value FROM rate_limit_entries WHERE key = ?\",\n\t);\n\tconst setStmt = db.query(\n\t\t\"INSERT INTO rate_limit_entries (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value\",\n\t);\n\tconst deleteStmt = db.query(\"DELETE FROM rate_limit_entries WHERE key = ?\");\n\tconst allStmt = db.query(\"SELECT key, value FROM rate_limit_entries\");\n\n\treturn {\n\t\tget(key: string): T | undefined {\n\t\t\tconst row = getStmt.get(key) as { value: string } | null;\n\t\t\treturn row ? (JSON.parse(row.value) as T) : undefined;\n\t\t},\n\t\tset(key: string, value: T): void {\n\t\t\tsetStmt.run(key, JSON.stringify(value));\n\t\t},\n\t\tdelete(key: string): void {\n\t\t\tdeleteStmt.run(key);\n\t\t},\n\t\t*entries(): IterableIterator<[string, T]> {\n\t\t\tconst rows = allStmt.all() as Array<{ key: string; value: string }>;\n\t\t\tfor (const row of rows) {\n\t\t\t\tyield [row.key, JSON.parse(row.value) as T];\n\t\t\t}\n\t\t},\n\t};\n}\n\nconst DEFAULT_OPTIONS: Required<\n\tOmit<RateLimiterOptions, \"keyGenerator\" | \"skip\" | \"store\">\n> = {\n\tmax: 100,\n\twindowMs: 60000,\n\tmessage: \"Too many requests, please try again later\",\n\tstatusCode: 429,\n\theaders: true,\n};\n\n/**\n * Simple in-memory rate limiter\n */\nexport function rateLimiter(options: RateLimiterOptions = {}): Middleware {\n\tconst opts = { ...DEFAULT_OPTIONS, ...options };\n\tconst store =\n\t\t(options.store as RateLimitStore<RateLimitEntry>) ??\n\t\tmemoryStore<RateLimitEntry>();\n\n\t// Cleanup old entries periodically\n\tconst cleanup = setInterval(() => {\n\t\tconst now = Date.now();\n\t\tfor (const [key, entry] of store.entries()) {\n\t\t\tif (now > entry.resetTime) {\n\t\t\t\tstore.delete(key);\n\t\t\t}\n\t\t}\n\t}, opts.windowMs);\n\n\t// Prevent cleanup from keeping process alive\n\tif (typeof cleanup === \"object\" && cleanup.unref) {\n\t\tcleanup.unref();\n\t}\n\n\tconst getKey =\n\t\toptions.keyGenerator ||\n\t\t((ctx: Context) => {\n\t\t\treturn (\n\t\t\t\tctx.request.headers.get(\"x-forwarded-for\")?.split(\",\")[0]?.trim() ||\n\t\t\t\tctx.request.headers.get(\"x-real-ip\") ||\n\t\t\t\t\"unknown\"\n\t\t\t);\n\t\t});\n\n\treturn async (ctx, next) => {\n\t\t// Skip if custom skip function returns true\n\t\tif (options.skip?.(ctx)) {\n\t\t\treturn next();\n\t\t}\n\n\t\tconst key = getKey(ctx);\n\t\tconst now = Date.now();\n\t\tconst entry = store.get(key);\n\n\t\tlet count = 1;\n\t\tlet resetTime = now + opts.windowMs;\n\n\t\tif (entry && now < entry.resetTime) {\n\t\t\tcount = entry.count + 1;\n\t\t\tresetTime = entry.resetTime;\n\t\t}\n\n\t\tstore.set(key, { count, resetTime });\n\n\t\t// Check if rate limit exceeded\n\t\tif (count > opts.max) {\n\t\t\tconst response = new Response(JSON.stringify({ error: opts.message }), {\n\t\t\t\tstatus: opts.statusCode,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\"Retry-After\": String(Math.ceil((resetTime - now) / 1000)),\n\t\t\t\t\t\"X-RateLimit-Limit\": String(opts.max),\n\t\t\t\t\t\"X-RateLimit-Remaining\": \"0\",\n\t\t\t\t\t\"X-RateLimit-Reset\": String(Math.ceil(resetTime / 1000)),\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn response;\n\t\t}\n\n\t\tconst result = await next();\n\n\t\t// Add rate limit headers to successful response\n\t\tif (opts.headers && result instanceof Response) {\n\t\t\tresult.headers.set(\"X-RateLimit-Limit\", String(opts.max));\n\t\t\tresult.headers.set(\n\t\t\t\t\"X-RateLimit-Remaining\",\n\t\t\t\tString(Math.max(0, opts.max - count)),\n\t\t\t);\n\t\t\tresult.headers.set(\n\t\t\t\t\"X-RateLimit-Reset\",\n\t\t\t\tString(Math.ceil(resetTime / 1000)),\n\t\t\t);\n\t\t}\n\n\t\treturn result;\n\t};\n}\n\n/**\n * Sliding window rate limiter (more accurate but uses more memory)\n */\nexport function slidingWindowRateLimiter(\n\toptions: RateLimiterOptions = {},\n): Middleware {\n\tconst opts = { ...DEFAULT_OPTIONS, ...options };\n\tconst store =\n\t\t(options.store as RateLimitStore<number[]>) ?? memoryStore<number[]>();\n\n\tconst cleanup = setInterval(() => {\n\t\tconst windowStart = Date.now() - opts.windowMs;\n\t\tfor (const [key, timestamps] of store.entries()) {\n\t\t\tconst valid = timestamps.filter((t) => t > windowStart);\n\t\t\tif (valid.length === 0) {\n\t\t\t\tstore.delete(key);\n\t\t\t} else if (valid.length !== timestamps.length) {\n\t\t\t\tstore.set(key, valid);\n\t\t\t}\n\t\t}\n\t}, opts.windowMs);\n\n\tif (typeof cleanup === \"object\" && cleanup.unref) {\n\t\tcleanup.unref();\n\t}\n\n\tconst getKey =\n\t\toptions.keyGenerator ||\n\t\t((ctx: Context) => {\n\t\t\treturn (\n\t\t\t\tctx.request.headers.get(\"x-forwarded-for\")?.split(\",\")[0]?.trim() ||\n\t\t\t\tctx.request.headers.get(\"x-real-ip\") ||\n\t\t\t\t\"unknown\"\n\t\t\t);\n\t\t});\n\n\treturn async (ctx, next) => {\n\t\tif (options.skip?.(ctx)) {\n\t\t\treturn next();\n\t\t}\n\n\t\tconst key = getKey(ctx);\n\t\tconst now = Date.now();\n\t\tconst windowStart = now - opts.windowMs;\n\n\t\t// Get existing timestamps\n\t\tconst timestamps = store.get(key) || [];\n\n\t\t// Filter to only timestamps within window\n\t\tconst validTimestamps = timestamps.filter((t) => t > windowStart);\n\n\t\tif (validTimestamps.length >= opts.max) {\n\t\t\tconst oldestTimestamp = validTimestamps[0] || 0;\n\t\t\tconst retryAfter = Math.ceil(\n\t\t\t\t(oldestTimestamp + opts.windowMs - now) / 1000,\n\t\t\t);\n\n\t\t\treturn new Response(JSON.stringify({ error: opts.message }), {\n\t\t\t\tstatus: opts.statusCode,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\"Retry-After\": String(retryAfter),\n\t\t\t\t\t\"X-RateLimit-Limit\": String(opts.max),\n\t\t\t\t\t\"X-RateLimit-Remaining\": \"0\",\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\t// Add current timestamp\n\t\tvalidTimestamps.push(now);\n\t\tstore.set(key, validTimestamps);\n\n\t\tconst result = await next();\n\n\t\tif (result instanceof Response) {\n\t\t\tresult.headers.set(\"X-RateLimit-Limit\", String(opts.max));\n\t\t\tresult.headers.set(\n\t\t\t\t\"X-RateLimit-Remaining\",\n\t\t\t\tString(opts.max - validTimestamps.length),\n\t\t\t);\n\t\t}\n\n\t\treturn result;\n\t};\n}\n","import type { Middleware } from \"../app\";\n\nexport interface RequestIdOptions {\n\t/** Header name (default: x-request-id) */\n\theader?: string;\n\t/** Custom generator function */\n\tgenerator?: () => string;\n\t/** Store request ID in ctx.store (default: true) */\n\tstore?: boolean;\n\t/** Property name in ctx.store (default: requestId) */\n\tstoreKey?: string;\n}\n\n/**\n * Generate a unique request ID\n */\nfunction generateRequestId(): string {\n\treturn crypto.randomUUID();\n}\n\n/**\n * Middleware to add unique request ID to every request\n */\nexport function requestId(options: RequestIdOptions = {}): Middleware {\n\tconst header = options.header || \"x-request-id\";\n\tconst storeKey = options.storeKey || \"requestId\";\n\tconst generator = options.generator || generateRequestId;\n\tconst useStore = options.store !== false;\n\n\treturn async (ctx, next) => {\n\t\t// Check for existing request ID (from upstream proxy)\n\t\tconst existingId = ctx.request.headers.get(header);\n\t\tconst id = existingId || generator();\n\n\t\t// Store in ctx.store if enabled\n\t\tif (useStore) {\n\t\t\tctx.store[storeKey] = id;\n\t\t}\n\n\t\tconst result = await next();\n\n\t\t// Add request ID to response headers\n\t\tif (result instanceof Response) {\n\t\t\tresult.headers.set(header, id);\n\t\t}\n\n\t\treturn result;\n\t};\n}\n\n/**\n * Simple UUID v4 generator (no dependencies)\n */\nexport function uuid(): string {\n\treturn \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n\t\tconst r = (Math.random() * 16) | 0;\n\t\tconst v = c === \"x\" ? r : (r & 0x3) | 0x8;\n\t\treturn v.toString(16);\n\t});\n}\n\n/**\n * Short ID generator (8 characters)\n */\nexport function shortId(): string {\n\treturn crypto.randomUUID().replace(/-/g, \"\").slice(0, 8);\n}\n","import type { Middleware } from \"../app\";\n\nexport interface ResponseTimeOptions {\n\t/** Header name (default: x-response-time) */\n\theader?: string;\n\t/** Format: 'ms' | 's' (default: 'ms') */\n\tformat?: \"ms\" | \"s\";\n\t/** Store response time in ctx.store (default: false) */\n\tstore?: boolean;\n\t/** Property name in ctx.store (default: responseTime) */\n\tstoreKey?: string;\n}\n\n/**\n * Middleware to measure and add response time to response headers\n */\nexport function responseTime(options: ResponseTimeOptions = {}): Middleware {\n\tconst header = options.header || \"x-response-time\";\n\tconst format = options.format || \"ms\";\n\tconst storeKey = options.storeKey || \"responseTime\";\n\n\treturn async (ctx, next) => {\n\t\tconst start = performance.now();\n\n\t\tconst result = await next();\n\n\t\tconst duration = performance.now() - start;\n\t\tconst formatted =\n\t\t\tformat === \"s\"\n\t\t\t\t? `${(duration / 1000).toFixed(3)}s`\n\t\t\t\t: `${duration.toFixed(2)}ms`;\n\n\t\t// Store in ctx.store if enabled\n\t\tif (options.store) {\n\t\t\tctx.store[storeKey] = formatted;\n\t\t}\n\n\t\t// Add response time header\n\t\tif (result instanceof Response) {\n\t\t\tresult.headers.set(header, formatted);\n\t\t}\n\n\t\treturn result;\n\t};\n}\n","import type { Middleware } from \"../app\";\n\n/**\n * Request timeout middleware — automatically aborts the handler if it takes\n * longer than `ms` milliseconds, returning 408 Request Timeout.\n *\n * @example\n * import { timeout } from \"@buntok/core\";\n *\n * app.get(\"/slow\", timeout(5000), async (ctx) => {\n *   await longOperation();\n *   return ctx.json({ ok: true });\n * });\n *\n * // Custom error message\n * app.post(\"/upload\", timeout(30000, \"Upload timed out\"), handler);\n */\nexport function timeout(ms: number, message = \"Request timed out\"): Middleware {\n\treturn async (_ctx, next) => {\n\t\tlet timeoutId: ReturnType<typeof setTimeout>;\n\n\t\tconst timeoutPromise = new Promise<never>((_, reject) => {\n\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\treject(new TimeoutError(message, ms));\n\t\t\t}, ms);\n\t\t});\n\n\t\ttry {\n\t\t\tconst response = await Promise.race([next(), timeoutPromise]);\n\t\t\treturn response;\n\t\t} finally {\n\t\t\tclearTimeout(timeoutId!);\n\t\t}\n\t};\n}\n\nexport class TimeoutError extends Error {\n\tpublic readonly timeoutMs: number;\n\n\tconstructor(message: string, timeoutMs: number) {\n\t\tsuper(message);\n\t\tthis.name = \"TimeoutError\";\n\t\tthis.timeoutMs = timeoutMs;\n\t}\n}\n","/**\n * Role-Based Access Control (RBAC) middleware.\n *\n * @example\n * ```ts\n * import { requireRole, requirePermission } from \"buntok\";\n *\n * // Require specific role\n * app.get(\"/admin\", requireAuth(secret), requireRole(\"admin\"), adminHandler);\n *\n * // Require any of multiple roles\n * app.get(\"/mod\", requireAuth(secret), requireRole(\"admin\", \"moderator\"), modHandler);\n *\n * // Require specific permission\n * app.delete(\"/users/:id\", requireAuth(secret), requirePermission(\"users:delete\"), deleteUser);\n *\n * // Custom role resolver\n * app.use(requireRole({\n *   resolver: (user) => user.roles,  // extract roles from JWT payload\n *   roles: [\"admin\"],\n * }));\n * ```\n */\n\ntype UserWithRoles = {\n\trole?: string;\n\troles?: string[];\n\t[key: string]: any;\n};\n\nexport interface RequireRoleOptions {\n\t/** Extract roles from user object. Default: (user) => user.role || user.roles */\n\tresolver?: (user: any) => string | string[] | undefined;\n\n\t/** Required roles (user must have at least one) */\n\troles: string[];\n\n\t/** Custom error message */\n\tmessage?: string;\n}\n\n/**\n * Middleware that requires the user to have at least one of the specified roles.\n * Must be used AFTER requireAuth middleware.\n */\nexport function requireRole(\n\t...roles: string[]\n): (ctx: any, next: () => Promise<void>) => Promise<void>;\nexport function requireRole(\n\toptions: RequireRoleOptions,\n): (ctx: any, next: () => Promise<void>) => Promise<void>;\nexport function requireRole(\n\t...args: any[]\n): (ctx: any, next: () => Promise<void>) => Promise<void> {\n\t// Parse arguments\n\tlet options: RequireRoleOptions;\n\tif (args.length === 1 && typeof args[0] === \"object\" && !Array.isArray(args[0])) {\n\t\toptions = args[0];\n\t} else {\n\t\toptions = { roles: args.flat() };\n\t}\n\n\tconst { roles: requiredRoles, resolver, message } = options;\n\n\treturn async (ctx, next) => {\n\t\tconst user = ctx.user as UserWithRoles | undefined;\n\n\t\tif (!user) {\n\t\t\tctx.status = 401;\n\t\t\tctx.json({ success: false, message: \"Authentication required\" });\n\t\t\treturn;\n\t\t}\n\n\t\t// Resolve user roles\n\t\tlet userRoles: string[];\n\t\tif (resolver) {\n\t\t\tconst resolved = resolver(user);\n\t\t\tuserRoles = Array.isArray(resolved) ? resolved : resolved ? [resolved] : [];\n\t\t} else {\n\t\t\tuserRoles = [];\n\t\t\tif (user.role) userRoles.push(user.role);\n\t\t\tif (user.roles) userRoles.push(...user.roles);\n\t\t}\n\n\t\t// Check if user has any required role\n\t\tconst hasRole = requiredRoles.some((r) => userRoles.includes(r));\n\n\t\tif (!hasRole) {\n\t\t\tctx.status = 403;\n\t\t\tctx.json({\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"Forbidden\",\n\t\t\t\tmessage: message ?? `Requires one of: ${requiredRoles.join(\", \")}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tawait next();\n\t};\n}\n\nexport interface RequirePermissionOptions {\n\t/** Extract permissions from user object. Default: (user) => user.permissions */\n\tresolver?: (user: any) => string[] | undefined;\n\n\t/** Required permissions (user must have ALL) */\n\tpermissions: string[];\n\n\t/** Custom error message */\n\tmessage?: string;\n}\n\n/**\n * Middleware that requires the user to have ALL specified permissions.\n * Must be used AFTER requireAuth middleware.\n */\nexport function requirePermission(\n\t...permissions: string[]\n): (ctx: any, next: () => Promise<void>) => Promise<void>;\nexport function requirePermission(\n\toptions: RequirePermissionOptions,\n): (ctx: any, next: () => Promise<void>) => Promise<void>;\nexport function requirePermission(\n\t...args: any[]\n): (ctx: any, next: () => Promise<void>) => Promise<void> {\n\tlet options: RequirePermissionOptions;\n\tif (args.length === 1 && typeof args[0] === \"object\" && !Array.isArray(args[0])) {\n\t\toptions = args[0];\n\t} else {\n\t\toptions = { permissions: args.flat() };\n\t}\n\n\tconst { permissions: requiredPermissions, resolver, message } = options;\n\n\treturn async (ctx, next) => {\n\t\tconst user = ctx.user as UserWithRoles | undefined;\n\n\t\tif (!user) {\n\t\t\tctx.status = 401;\n\t\t\tctx.json({ success: false, message: \"Authentication required\" });\n\t\t\treturn;\n\t\t}\n\n\t\t// Resolve user permissions\n\t\tlet userPermissions: string[];\n\t\tif (resolver) {\n\t\t\tuserPermissions = resolver(user) ?? [];\n\t\t} else {\n\t\t\tuserPermissions = (user as any).permissions ?? [];\n\t\t}\n\n\t\t// Check if user has all required permissions\n\t\tconst hasAll = requiredPermissions.every((p) => userPermissions.includes(p));\n\n\t\tif (!hasAll) {\n\t\t\tconst missing = requiredPermissions.filter((p) => !userPermissions.includes(p));\n\t\t\tctx.status = 403;\n\t\t\tctx.json({\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"Forbidden\",\n\t\t\t\tmessage: message ?? `Missing permissions: ${missing.join(\", \")}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tawait next();\n\t};\n}\n","import { z } from \"zod\";\nimport type { Middleware } from \"../app\";\n\nexport interface ValidatorSchema {\n\tparse: (data: unknown) => unknown;\n}\n\nexport interface ValidateOptions {\n\tbody?: ValidatorSchema;\n\tparams?: ValidatorSchema;\n}\n\n/** @deprecated Prefer `zValidator()`, which gives you `ctx.valid()` with full type inference. */\nexport const validate = (schemas: ValidateOptions): Middleware => {\n\treturn async (ctx, next) => {\n\t\tconst errors: string[] = [];\n\n\t\tif (schemas.body) {\n\t\t\ttry {\n\t\t\t\tconst bodyData = await ctx.body();\n\t\t\t\tctx.store.validatedBody = schemas.body.parse(bodyData);\n\t\t\t} catch (err: unknown) {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Invalid body\";\n\t\t\t\terrors.push(`body: ${message}`);\n\t\t\t}\n\t\t}\n\n\t\tif (schemas.params) {\n\t\t\ttry {\n\t\t\t\tctx.store.validatedParams = schemas.params.parse(ctx.params);\n\t\t\t} catch (err: unknown) {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Invalid params\";\n\t\t\t\terrors.push(`params: ${message}`);\n\t\t\t}\n\t\t}\n\n\t\tif (errors.length > 0) {\n\t\t\treturn ctx.json(\n\t\t\t\t{\n\t\t\t\t\terror: \"Validation Failed\",\n\t\t\t\t\tdetails: errors,\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\treturn next();\n\t};\n};\n\n/** @deprecated Prefer `zValidator(\"body\", schema)`. */\nexport const validateBody = (schema: ValidatorSchema): Middleware => {\n\treturn validate({ body: schema });\n};\n\n/** @deprecated Prefer `zValidator(\"params\", schema)`. */\nexport const validateParams = (schema: ValidatorSchema): Middleware => {\n\treturn validate({ params: schema });\n};\n\nexport type ValidationTarget = \"body\" | \"query\" | \"params\";\n\n/**\n * Content types supported by `zValidator(\"body\", schema, { contentType })`.\n * Defaults to `application/json` when `contentType` is omitted.\n */\nexport type BodyContentType =\n\t/**\n\t * Standard JSON body — default behavior when `contentType` is omitted.\n\t *\n\t * Parsed via `JSON.parse`. Zod schema receives the parsed JavaScript object.\n\t *\n\t * @example\n\t * zValidator(\"body\", z.object({ name: z.string() }))\n\t * // equivalent to: { contentType: \"application/json\" }\n\t */\n\t| \"application/json\"\n\t/**\n\t * Parse fields from `multipart/form-data`.\n\t * Supports both text fields (as strings) and file fields (as File objects).\n\t * Validate file fields using `z.file()` (requires Zod v4+).\n\t *\n\t * Zod schema receives `Record<string, string | File>`. of all non-file fields.\n\t *\n\t * @example\n\t * zValidator(\"body\", z.object({ name: z.string() }), { contentType: \"multipart/form-data\" })\n\t */\n\t| \"multipart/form-data\"\n\t/**\n\t * Parse fields from an `application/x-www-form-urlencoded` body.\n\t * All values are strings — use `z.coerce.number()`, `z.coerce.boolean()`, etc. for coercion.\n\t *\n\t * Zod schema receives `Record<string, string>`.\n\t *\n\t * @example\n\t * zValidator(\"body\", z.object({ email: z.string().email(), age: z.coerce.number() }), {\n\t *   contentType: \"application/x-www-form-urlencoded\",\n\t * })\n\t */\n\t| \"application/x-www-form-urlencoded\"\n\t/**\n\t * Parse a plain text body.\n\t * Zod schema receives the raw body as a `string`.\n\t *\n\t * @example\n\t * zValidator(\"body\", z.string().min(1), { contentType: \"text/plain\" })\n\t */\n\t| \"text/plain\"\n\t/**\n\t * Parse an XML body (W3C standard MIME type).\n\t * Zod schema receives the raw XML as a `string` — parse it further with your preferred XML library.\n\t *\n\t * @example\n\t * zValidator(\"body\", z.string(), { contentType: \"application/xml\" })\n\t */\n\t| \"application/xml\"\n\t/**\n\t * Parse an XML body (legacy/vendor MIME type, functionally identical to `application/xml`).\n\t * Zod schema receives the raw XML as a `string`.\n\t *\n\t * @example\n\t * zValidator(\"body\", z.string(), { contentType: \"text/xml\" })\n\t */\n\t| \"text/xml\"\n\t/**\n\t * Parse a raw binary body.\n\t * Zod schema receives an `ArrayBuffer` — use `z.instanceof(ArrayBuffer)` or process it manually.\n\t *\n\t * @example\n\t * zValidator(\"body\", z.instanceof(ArrayBuffer), { contentType: \"application/octet-stream\" })\n\t */\n\t| \"application/octet-stream\";\n\nexport interface ZValidatorOptions {\n\t/**\n\t * Override the expected request body content type.\n\t * Only applies when `target` is `\"body\"`. Defaults to `application/json`.\n\t *\n\t * - `\"multipart/form-data\"` — text and file fields from FormData; validate files with `z.file()`\n\t * - `\"application/x-www-form-urlencoded\"` — URL-encoded key=value body\n\t *\n\t * Omit this option (or the entire `options` argument) for standard JSON bodies.\n\t */\n\tcontentType?: BodyContentType;\n}\n\nexport type SchemaType = z.ZodType | Record<string, z.ZodTypeAny>;\n\nfunction wrapSchema(schema: SchemaType): z.ZodType {\n\t// biome-ignore lint/suspicious/noExplicitAny: Required to check internal Zod fields\n\treturn schema instanceof z.ZodType || (schema as any)?._def\n\t\t? (schema as z.ZodType)\n\t\t: z.object(schema as Record<string, z.ZodTypeAny>);\n}\n\n/**\n * Validate request body/query/params against a Zod schema and expose the\n * parsed, typed result via `ctx.valid(target)` — no manual casting needed.\n *\n * ```ts\n * const schema = z.object({ name: z.string(), age: z.number() });\n *\n * // JSON body (default)\n * app.post(\"/users\", zValidator(\"body\", schema), (ctx) => {\n *   const data = ctx.valid<z.infer<typeof schema>>(\"body\");\n *   return ctx.json(data);\n * });\n *\n * // multipart/form-data text fields (pair with uploader() for files)\n * app.post(\"/profile\", zValidator(\"body\", schema, { contentType: \"multipart/form-data\" }), ...);\n *\n * // application/x-www-form-urlencoded\n * app.post(\"/login\", zValidator(\"body\", schema, { contentType: \"application/x-www-form-urlencoded\" }), ...);\n * ```\n *\n * On failure, responds with 400 and Zod's flattened error details.\n */\nexport function zValidator(\n\ttarget: ValidationTarget,\n\tschema: SchemaType | (new () => unknown),\n\toptions?: ZValidatorOptions,\n): Middleware {\n\tconst finalSchema = wrapSchema(schema as SchemaType);\n\tconst resolvedContentType: BodyContentType =\n\t\toptions?.contentType ?? \"application/json\";\n\n\tconst middleware: Middleware = async (ctx, next) => {\n\t\tlet raw: unknown;\n\n\t\tif (target === \"body\") {\n\t\t\tif (resolvedContentType === \"multipart/form-data\") {\n\t\t\t\t// Parse both text and file fields from multipart/form-data\n\t\t\t\tconst ct = ctx.request.headers.get(\"content-type\") || \"\";\n\t\t\t\tif (!ct.includes(\"multipart/form-data\")) {\n\t\t\t\t\treturn ctx.error(\"Validation Failed\", 400, [\n\t\t\t\t\t\t\"body: expected multipart/form-data content-type\",\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst formData = await ctx.formData();\n\t\t\t\t\tconst fields: Record<string, string | File> = {};\n\t\t\t\t\tfor (const [key, value] of formData.entries()) {\n\t\t\t\t\t\tif (value instanceof File) {\n\t\t\t\t\t\t\tfields[key] = value;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfields[key] = value.toString();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\traw = fields;\n\t\t\t\t} catch {\n\t\t\t\t\treturn ctx.error(\"Validation Failed\", 400, [\n\t\t\t\t\t\t\"body: failed to parse multipart/form-data\",\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t} else if (resolvedContentType === \"application/x-www-form-urlencoded\") {\n\t\t\t\tconst ct = ctx.request.headers.get(\"content-type\") || \"\";\n\t\t\t\tif (!ct.includes(\"application/x-www-form-urlencoded\")) {\n\t\t\t\t\treturn ctx.error(\"Validation Failed\", 400, [\n\t\t\t\t\t\t\"body: expected application/x-www-form-urlencoded content-type\",\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst text = await ctx.request.text();\n\t\t\t\t\tconst params = new URLSearchParams(text);\n\t\t\t\t\tconst fields: Record<string, string> = {};\n\t\t\t\t\tfor (const [key, value] of params.entries()) {\n\t\t\t\t\t\tfields[key] = value;\n\t\t\t\t\t}\n\t\t\t\t\traw = fields;\n\t\t\t\t} catch {\n\t\t\t\t\treturn ctx.error(\"Validation Failed\", 400, [\n\t\t\t\t\t\t\"body: failed to parse application/x-www-form-urlencoded\",\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\tresolvedContentType === \"text/plain\" ||\n\t\t\t\tresolvedContentType === \"application/xml\" ||\n\t\t\t\tresolvedContentType === \"text/xml\"\n\t\t\t) {\n\t\t\t\tconst ct = ctx.request.headers.get(\"content-type\") || \"\";\n\t\t\t\tif (!ct.includes(resolvedContentType)) {\n\t\t\t\t\treturn ctx.error(\"Validation Failed\", 400, [\n\t\t\t\t\t\t`body: expected ${resolvedContentType} content-type`,\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\traw = await ctx.request.text();\n\t\t\t\t} catch {\n\t\t\t\t\treturn ctx.error(\"Validation Failed\", 400, [\n\t\t\t\t\t\t`body: failed to read ${resolvedContentType} body`,\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t} else if (resolvedContentType === \"application/octet-stream\") {\n\t\t\t\tconst ct = ctx.request.headers.get(\"content-type\") || \"\";\n\t\t\t\tif (!ct.includes(\"application/octet-stream\")) {\n\t\t\t\t\treturn ctx.error(\"Validation Failed\", 400, [\n\t\t\t\t\t\t\"body: expected application/octet-stream content-type\",\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\traw = await ctx.request.arrayBuffer();\n\t\t\t\t} catch {\n\t\t\t\t\treturn ctx.error(\"Validation Failed\", 400, [\n\t\t\t\t\t\t\"body: failed to read application/octet-stream body\",\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Default: application/json\n\t\t\t\ttry {\n\t\t\t\t\traw = await ctx.body();\n\t\t\t\t} catch {\n\t\t\t\t\treturn ctx.error(\"Validation Failed\", 400, [\"body: invalid JSON\"]);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (target === \"query\") {\n\t\t\traw = ctx.query;\n\t\t} else {\n\t\t\traw = ctx.params;\n\t\t}\n\n\t\tconst result = finalSchema.safeParse(raw);\n\t\tif (!result.success) {\n\t\t\treturn ctx.error(\n\t\t\t\t\"Validation Failed\",\n\t\t\t\t400,\n\t\t\t\tresult.error.issues.map(\n\t\t\t\t\t(issue) => `${target}.${issue.path.join(\".\")}: ${issue.message}`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tctx.setValidated(target, result.data);\n\n\t\treturn next();\n\t};\n\n\t// Attach metadata for OpenAPI generation\n\tconst mwMeta = middleware as unknown as Record<string, unknown>;\n\tmwMeta._isBuntokValidator = true;\n\tmwMeta._target = target;\n\tmwMeta._schema = finalSchema;\n\tmwMeta._contentType = target === \"body\" ? resolvedContentType : \"\";\n\n\treturn middleware;\n}\n\n/**\n * Document the response schema for OpenAPI.\n * Note: Currently this is for documentation purposes only and does not perform runtime response validation.\n */\nexport function zResponse(\n\tstatus: number,\n\tschema: SchemaType | (new () => unknown) | [new () => unknown],\n\tdescription: string = \"Success\",\n): Middleware {\n\tconst finalSchema = wrapSchema(schema as SchemaType);\n\n\t// Wrap in standard Buntok response envelope\n\tconst envelopedSchema = z.object({\n\t\tsuccess: z.boolean(),\n\t\tmessage: z.string(),\n\t\tdata: finalSchema,\n\t});\n\n\tconst middleware: Middleware = async (_ctx, next) => {\n\t\treturn next();\n\t};\n\n\t// Attach metadata for OpenAPI generation\n\tconst mwMeta = middleware as unknown as Record<string, unknown>;\n\tmwMeta._isBuntokResponse = true;\n\tmwMeta._status = status;\n\tmwMeta._schema = envelopedSchema;\n\tmwMeta._description = description;\n\n\treturn middleware;\n}\n","import { mkdir, stat, unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { Middleware } from \"./app\";\nimport type { Context } from \"./context\";\nimport { BadRequestError } from \"./helpers/async-handler\";\n\nexport interface UploadedFile {\n\t/** Original name of the file */\n\toriginalName: string;\n\t/** Generated filename without extension (e.g., \"avatar-123\") */\n\tname: string;\n\t/** File extension with dot (e.g., \".png\") */\n\text: string;\n\t/** Size of the file in bytes */\n\tsize: number;\n\t/** MIME type of the file */\n\ttype: string;\n\t/** For MemoryStorage: the actual file data as ArrayBuffer */\n\tbuffer?: ArrayBuffer;\n\t/** For LocalDiskStorage: the absolute path where it was saved */\n\tpath?: string;\n}\n\nexport interface StorageDriver {\n\t/** Handle a single file from the FormData stream */\n\thandleFile(\n\t\tfile: File,\n\t\tname: string,\n\t\text: string,\n\t): Promise<UploadedFile> | UploadedFile;\n\t/** Delete a file by its path or filename. Returns true if deleted. */\n\tdeleteFile?(path: string): Promise<boolean>;\n}\n\nexport type MimeType =\n\t// Images\n\t| \"image/jpeg\"\n\t| \"image/png\"\n\t| \"image/gif\"\n\t| \"image/webp\"\n\t| \"image/svg+xml\"\n\t| \"image/bmp\"\n\t| \"image/tiff\"\n\t| \"image/x-icon\"\n\t| \"image/avif\"\n\t| \"image/heic\"\n\t| \"image/heif\"\n\n\t// Videos\n\t| \"video/mp4\"\n\t| \"video/webm\"\n\t| \"video/ogg\"\n\t| \"video/quicktime\"\n\t| \"video/x-msvideo\"\n\t| \"video/x-matroska\"\n\t| \"video/mpeg\"\n\n\t// Audio\n\t| \"audio/mpeg\"\n\t| \"audio/mp3\"\n\t| \"audio/wav\"\n\t| \"audio/ogg\"\n\t| \"audio/webm\"\n\t| \"audio/aac\"\n\t| \"audio/flac\"\n\t| \"audio/mp4\"\n\t| \"audio/x-m4a\"\n\n\t// Documents\n\t| \"application/pdf\"\n\t| \"application/rtf\"\n\t| \"text/plain\"\n\t| \"text/csv\"\n\t| \"text/html\"\n\t| \"text/css\"\n\t| \"text/javascript\"\n\t| \"application/javascript\"\n\t| \"application/json\"\n\t| \"application/xml\"\n\t| \"text/xml\"\n\n\t// Microsoft Office\n\t| \"application/msword\"\n\t| \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\"\n\t| \"application/vnd.ms-excel\"\n\t| \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"\n\t| \"application/vnd.ms-powerpoint\"\n\t| \"application/vnd.openxmlformats-officedocument.presentationml.presentation\"\n\n\t// OpenDocument\n\t| \"application/vnd.oasis.opendocument.text\"\n\t| \"application/vnd.oasis.opendocument.spreadsheet\"\n\t| \"application/vnd.oasis.opendocument.presentation\"\n\n\t// Archives\n\t| \"application/zip\"\n\t| \"application/x-7z-compressed\"\n\t| \"application/x-rar-compressed\"\n\t| \"application/gzip\"\n\t| \"application/x-tar\"\n\t| \"application/x-bzip2\"\n\n\t// Fonts\n\t| \"font/woff\"\n\t| \"font/woff2\"\n\t| \"font/ttf\"\n\t| \"font/otf\"\n\n\t// Other\n\t| \"application/octet-stream\";\n\nexport interface UploadFieldConfig {\n\t/** Whether this file field is required. Defaults to false. */\n\trequired?: boolean;\n\t/** Max file size in bytes for this field */\n\tmaxFileSize?: number;\n\t/** Allowed MIME types for this field */\n\tallowedMimeTypes?: MimeType[] | string[];\n\t/** Custom filename generator for this field (overrides global filename) */\n\tfilename?: (originalName: string, file: File) => { name: string; ext: string };\n}\n\nexport interface UploadOptions {\n\t/** Destination storage driver (e.g., LocalDiskStorage or MemoryStorage) */\n\tstorage: StorageDriver;\n\t/** Global default filename generator (overridden by per-field filename) */\n\tfilename?: (originalName: string, file: File) => { name: string; ext: string };\n\t/**\n\t * Global max file size in bytes.\n\t * Applied to all fields unless overridden by per-field `maxFileSize`.\n\t */\n\tmaxFileSize?: number;\n\t/**\n\t * Global allowed MIME types.\n\t * Applied to all fields unless overridden by per-field `allowedMimeTypes`.\n\t */\n\tallowedMimeTypes?: MimeType | string[];\n\t/**\n\t * Whitelist of accepted file field names.\n\t * Files with a field name not listed here will be silently ignored.\n\t * Each field has its own maxFileSize, allowedMimeTypes, and filename config\n\t * that override the global defaults when set.\n\t *\n\t * @example\n\t * fields: {\n\t *   avatar: { required: true, maxFileSize: 2 * 1024 * 1024, allowedMimeTypes: ['image/png'] },\n\t *   document: { required: true, maxFileSize: 10 * 1024 * 1024 },\n\t * }\n\t */\n\tfields?: Record<string, UploadFieldConfig>;\n}\n\nexport type UploadOptionsWithFields<F extends Record<string, UploadFieldConfig>> =\n\tOmit<UploadOptions, \"fields\"> & { fields?: F };\n\nexport interface ParseUploadResult<\n\tF extends Record<string, UploadFieldConfig> = Record<string, UploadFieldConfig>,\n> {\n\t/**\n\t * All form fields — text fields are `string`, file fields are typed based on config.\n\t *\n\t * @example\n\t * result.fields.name      // string (text field)\n\t * result.fields.avatar    // UploadedFile | undefined (file field)\n\t * result.fields.gallery   // UploadedFile | UploadedFile[] | undefined (file field)\n\t */\n\tfields: {\n\t\t[K in keyof F]: F[K] extends { required: true }\n\t\t? UploadedFile\n\t\t: UploadedFile | UploadedFile[];\n\t} & Record<string, string>;\n\t/** Array of files that were successfully uploaded/processed (all files, flattened) */\n\tfiles: UploadedFile[];\n}\n\nexport class LocalDiskStorage implements StorageDriver {\n\tconstructor(private destination: string) { }\n\n\tasync handleFile(\n\t\tfile: File,\n\t\tname: string,\n\t\text: string,\n\t): Promise<UploadedFile> {\n\t\t// Ensure directory exists\n\t\ttry {\n\t\t\tawait stat(this.destination);\n\t\t} catch {\n\t\t\tawait mkdir(this.destination, { recursive: true });\n\t\t}\n\n\t\tconst filename = `${name}${ext}`;\n\t\tconst filePath = join(this.destination, filename);\n\t\tawait Bun.write(filePath, file);\n\n\t\treturn {\n\t\t\toriginalName: file.name,\n\t\t\tname,\n\t\t\text,\n\t\t\tsize: file.size,\n\t\t\ttype: file.type,\n\t\t\tpath: filePath,\n\t\t};\n\t}\n\n\tasync deleteFile(filePath: string): Promise<boolean> {\n\t\ttry {\n\t\t\tawait unlink(filePath);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n\nexport class MemoryStorage implements StorageDriver {\n\tasync handleFile(\n\t\tfile: File,\n\t\tname: string,\n\t\text: string,\n\t): Promise<UploadedFile> {\n\t\tconst buffer = await file.arrayBuffer();\n\t\treturn {\n\t\t\toriginalName: file.name,\n\t\t\tname,\n\t\t\text,\n\t\t\tsize: file.size,\n\t\t\ttype: file.type,\n\t\t\tbuffer,\n\t\t};\n\t}\n\n\tasync deleteFile(_filePath: string): Promise<boolean> {\n\t\t// MemoryStorage holds files in memory — nothing to delete on disk.\n\t\treturn true;\n\t}\n}\n\nfunction getFileExtension(originalName: string): string {\n\tconst extIndex = originalName.lastIndexOf(\".\");\n\tif (extIndex !== -1) {\n\t\treturn originalName.substring(extIndex);\n\t}\n\treturn \"\";\n}\n\nconst defaultFilenameGenerator = (originalName: string) => {\n\tconst ext = getFileExtension(originalName);\n\tconst name = ext\n\t\t? originalName.substring(0, originalName.length - ext.length)\n\t\t: originalName;\n\treturn { name: `${name}-${crypto.randomUUID()}`, ext };\n};\n\nfunction resolveFilename(\n\toriginalName: string,\n\tfile: File,\n\tfieldFn?: (originalName: string, file: File) => { name: string; ext: string },\n\tglobalFn?: (originalName: string, file: File) => { name: string; ext: string },\n): { name: string; ext: string } {\n\tconst ext = getFileExtension(originalName);\n\tconst generateFn = fieldFn ?? globalFn ?? defaultFilenameGenerator;\n\tconst result = generateFn(originalName, file);\n\n\t// Ensure ext always has the dot prefix\n\tconst finalExt = result.ext.startsWith(\".\") ? result.ext : ext;\n\n\treturn { name: result.name, ext: finalExt };\n}\n\n/**\n * Parses `multipart/form-data` request, separating standard fields from files.\n * Streams files into the configured storage driver with validation.\n *\n * Throws `BadRequestError` if validation fails (size, MIME type, or required fields).\n *\n * @example\n * const result = await parseUploads(ctx, {\n *   storage: new LocalDiskStorage('./uploads'),\n *   maxFileSize: 2 * 1024 * 1024,\n *   allowedMimeTypes: ['image/png', 'image/jpeg'],\n *   fields: {\n *     avatar: { required: true },\n *     document: { required: true, maxFileSize: 10 * 1024 * 1024 },\n *   },\n * });\n * // result.fields.avatar  → UploadedFile (required = true)\n * // result.fields.document → UploadedFile (required = true)\n */\nexport async function parseUploads<\n\tF extends Record<string, UploadFieldConfig> = Record<string, UploadFieldConfig>,\n>(\n\t// biome-ignore lint/suspicious/noExplicitAny: Context is generic\n\tctx: Context<any, any>,\n\toptions: UploadOptionsWithFields<F>,\n): Promise<ParseUploadResult<F>> {\n\tconst contentType = ctx.request.headers.get(\"content-type\") || \"\";\n\tif (!contentType.includes(\"multipart/form-data\")) {\n\t\tthrow new BadRequestError(\"Invalid content-type. Must be multipart/form-data\");\n\t}\n\n\t// biome-ignore lint/suspicious/noExplicitAny: Undici types conflict with lib.dom FormData\n\tlet formData: any;\n\ttry {\n\t\tformData = await ctx.formData();\n\t} catch (_err) {\n\t\tthrow new BadRequestError(\"Failed to parse form data\");\n\t}\n\n\tconst textFields: Record<string, string> = {};\n\tconst files: UploadedFile[] = [];\n\tconst fileMap: Record<string, UploadedFile | UploadedFile[]> = {};\n\n\tconst fieldWhitelist = options.fields;\n\n\tfor (const [key, value] of formData.entries()) {\n\t\tif (value instanceof File) {\n\t\t\t// If a fields whitelist is defined, ignore unknown file fields\n\t\t\tif (fieldWhitelist && !(key in fieldWhitelist)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Per-field config\n\t\t\tconst fieldConfig = fieldWhitelist?.[key];\n\n\t\t\t// Validation: Size — per-field config overrides global\n\t\t\tconst maxFileSize =\n\t\t\t\tfieldConfig?.maxFileSize ?? options.maxFileSize;\n\t\t\tif (maxFileSize && value.size > maxFileSize) {\n\t\t\t\tthrow new BadRequestError(\n\t\t\t\t\t`File \"${value.name}\" in field \"${key}\" exceeds max size of ${maxFileSize} bytes`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Validation: MIME Type — per-field config overrides global\n\t\t\tconst allowedMimeTypes =\n\t\t\t\tfieldConfig?.allowedMimeTypes ?? options.allowedMimeTypes;\n\t\t\tif (allowedMimeTypes && !allowedMimeTypes.includes(value.type)) {\n\t\t\t\tthrow new BadRequestError(\n\t\t\t\t\t`File type \"${value.type}\" is not allowed for field \"${key}\" (file: \"${value.name}\")`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Process file\n\t\t\tconst { name, ext } = resolveFilename(\n\t\t\t\tvalue.name,\n\t\t\t\tvalue,\n\t\t\t\tfieldConfig?.filename,\n\t\t\t\toptions.filename,\n\t\t\t);\n\t\t\tconst uploaded = await options.storage.handleFile(value, name, ext);\n\t\t\tfiles.push(uploaded);\n\n\t\t\t// Build fileMap: if same key appears multiple times → array\n\t\t\tif (key in fileMap) {\n\t\t\t\tconst existing = fileMap[key];\n\t\t\t\tif (Array.isArray(existing)) {\n\t\t\t\t\texisting.push(uploaded);\n\t\t\t\t} else {\n\t\t\t\t\tfileMap[key] = [existing as UploadedFile, uploaded];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfileMap[key] = uploaded;\n\t\t\t}\n\t\t} else {\n\t\t\ttextFields[key] = value.toString();\n\t\t}\n\t}\n\n\t// Validate required fields\n\tif (fieldWhitelist) {\n\t\tfor (const [fieldName, config] of Object.entries(fieldWhitelist)) {\n\t\t\tif (config.required && !(fieldName in fileMap)) {\n\t\t\t\tthrow new BadRequestError(\n\t\t\t\t\t`Required file field \"${fieldName}\" is missing`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { fields: { ...textFields, ...fileMap }, files } as ParseUploadResult<F>;\n}\n\n/**\n * Middleware that automatically parses multipart uploads and populates\n * `ctx.store.files` and `ctx.store.fields`.\n *\n * ⚠️ Throws `BadRequestError` on validation failure — ensure your route\n * handler uses `asyncHandler()` or has try/catch to propagate the error\n * to the global error handler.\n */\nexport function uploader(options: UploadOptions): Middleware {\n\treturn async (ctx, next) => {\n\t\tconst result = await parseUploads(ctx, options);\n\n\t\tctx.store.files = result.files;\n\t\tctx.store.fields = result.fields;\n\n\t\treturn next();\n\t};\n}\n\n/**\n * Delete an uploaded file from the storage driver.\n *\n * @param storage - The StorageDriver instance used for the upload\n * @param file - The UploadedFile object (needs `.path` for LocalDiskStorage)\n * @returns true if deleted, false if not found or error\n *\n * @example\n * const result = await parseUploads(ctx, options);\n * const file = result.fields.avatar as UploadedFile;\n * await deleteUploadedFile(options.storage, file);\n */\nexport async function deleteUploadedFile(\n\tstorage: StorageDriver,\n\tfile: UploadedFile,\n): Promise<boolean> {\n\tif (!storage.deleteFile) {\n\t\treturn false;\n\t}\n\tconst target = file.path ?? `${file.name}${file.ext}`;\n\treturn storage.deleteFile(target);\n}\n"],"mappings":"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","names":["import_zod","import_node_path","result","LogLevel","result","EMPTY_PARAMS","ctx","groupBy","sep","toHex","truncate","DEFAULT_OPTIONS","import_zod","import_node_path"]}