/** * @module @arcis/node/koa * * Koa adapter for Arcis. Returns a Koa middleware function suitable for * `app.use(...)`. Rate-limit + bot detection run BEFORE `next()` (the * handler); security headers are applied AFTER `next()` so they ride on * the buffered response that Koa flushes on its own. * * **Scope:** rate-limit + bot detection + security headers. For * XSS/SQL/SSTI/etc. body-payload blocking, call `sanitizeObject` from * `@arcis/node/sanitizers` inside your handler. v1 keeps the middleware * surface narrow. * * ```ts * import Koa from 'koa'; * import { arcisKoa } from '@arcis/node/koa'; * * const app = new Koa(); * app.use(arcisKoa({ * rateLimit: { max: 100, windowMs: 60_000 }, * bot: true, * })); * app.use(async (ctx) => { ctx.body = { ok: true }; }); * app.listen(3000); * ``` * * No runtime dependency on `koa` — its types are duck-typed enough to * satisfy Koa's actual `Context` shape. Real `Context` is assignable * into `KoaContextLike` without imports. */ import type { HeaderOptions, RateLimitOptions } from '../core/types'; import { type BotProtectionOptions } from './bot-detection'; export interface KoaRequestLike { headers: Record; ip?: string; url?: string; method?: string; socket?: { remoteAddress?: string; }; } export interface KoaResponseLike { status: number; body: unknown; set(name: string, value: string): void; } export interface KoaContextLike { request: KoaRequestLike; response: KoaResponseLike; /** * Koa attaches IP at `ctx.ip` (delegating to `ctx.request.ip`). We read * either; whichever is set wins. */ ip?: string; /** `ctx.set` shortcuts to `ctx.response.set` in real Koa. */ set(name: string, value: string): void; /** Setting `ctx.status` shortcuts to `ctx.response.status`. */ status: number; /** Setting `ctx.body` shortcuts to `ctx.response.body`. */ body: unknown; } export type KoaNext = () => Promise; export type KoaMiddleware = (ctx: KoaContextLike, next: KoaNext) => Promise; export interface ArcisKoaOptions { /** Security headers configuration. Default: enabled. Pass `false` to disable. */ headers?: boolean | HeaderOptions; /** Rate limiter configuration. Default: 100 req/60s in-memory. Pass `false` to disable. */ rateLimit?: boolean | RateLimitOptions; /** * Bot protection. Default: disabled (opt-in to avoid surprising behavior on * legitimate crawlers). Pass `true` for sensible defaults or an options * object for full control. */ bot?: boolean | BotProtectionOptions; } /** * Build a Koa middleware that applies Arcis protections on each request: * rate-limit (returns 429 if exceeded), bot detection (returns * `botStatusCode` if denied), then `await next()`, then security headers * on the buffered response. Order matches the SvelteKit / Fastify / * Next.js adapters so cross-framework behavior is consistent. * * Setting `ctx.status` and `ctx.body` before returning is Koa's idiomatic * way to short-circuit a response — we don't call `next()` on the deny * path so downstream middleware doesn't run. */ export declare function arcisKoa(options?: ArcisKoaOptions): KoaMiddleware; export default arcisKoa; //# sourceMappingURL=koa.d.ts.map