import { C as ConcurrencyGuard, j as UnifiedAdmitter, k as UnifiedAxis } from './unified-BouIz5EX.js'; import { C as Clock, D as Decision } from './types-DKirIBQt.js'; import { a as CommonAdapterOptions, L as LimiterOrStrategy } from './core-DcpxT2lH.js'; import './store-CQjuAFM_.js'; /** * Next.js middleware adapter — dependency-free. `NextRequest` extends the Web `Request` and * `NextResponse` extends the Web `Response`, so this binds to the Web standards and never imports * `"next"`. Call the limiter at the top of your middleware: on allow it hands back the rate-limit * headers for you to copy onto `NextResponse.next()`; on deny (or a fail-closed store outage) it * hands back a ready `Response` (the `429`/`503`) for you to return directly. The limit key derives * from the request: `cf-connecting-ip` → `x-forwarded-for` → `"anon"`. See THROTTLEKIT.md §§14,15. * * Also exposes {@link nextUnifiedAdmission} and {@link nextAdaptiveConcurrency} (0.9.2, TK-1326) * — HOC-style wrappers around a route handler that wire Response body lifecycle to release. */ type NextRateLimitOptions = LimiterOrStrategy & CommonAdapterOptions & { /** Cost of a request in limiter units. A function computes it per request. Default 1. */ cost?: number | ((request: Request) => number); /** Derive the limit key from a request. Default: `cf-connecting-ip` → `x-forwarded-for` → `"anon"`. */ key?: (request: Request) => string; /** Observability hook fired on every denial. */ onLimited?: (request: Request, decision: Decision) => void; /** Observability hook fired when the store throws (before the fail policy is applied). */ onError?: (request: Request, err: unknown) => void; /** Custom 429 responder. When provided, it fully owns the denial response. */ handler?: (request: Request, decision: Decision) => Response | Promise; }; /** * The result of one rate-limit check, telling the caller what to do next. * * - `{ limited: false; headers }` — allow the request; apply `headers` to `NextResponse.next()`. * On a fail-open store outage this is `{ limited: false; headers: {} }` (nothing to copy). * - `{ limited: true; response }` — return `response` directly; it is the `429` (or, on a * fail-closed store outage, the `503`) Web `Response` with the rate-limit headers attached. */ type NextRateLimitResult = { limited: false; headers: Record; } | { limited: true; response: Response; }; /** * Build a rate limiter for Next.js middleware. The returned function takes the request and returns * a {@link NextRateLimitResult} you branch on. * * @example * // middleware.ts * import { NextResponse, type NextRequest } from "next/server"; * import { nextRateLimit } from "throttlekit/next"; * import { gcra } from "throttlekit"; * * const limit = nextRateLimit({ strategy: gcra({ limit: 30, periodMs: 10_000 }) }); * * export async function middleware(req: NextRequest) { * const r = await limit(req); * if (r.limited) return r.response; * const res = NextResponse.next(); * for (const [k, v] of Object.entries(r.headers)) res.headers.set(k, v); * return res; * } */ declare function nextRateLimit(options: NextRateLimitOptions): (request: Request) => Promise; /** Per-axis Decision snapshot from `admitter.lastDecisions()`. */ type AxisSnapshot = Readonly>>; /** A Next-style handler: `(Request, ...args) => Response`. */ type NextHandler = (request: Request, ...args: unknown[]) => Response | Promise; /** Options for {@link nextUnifiedAdmission}. */ type NextUnifiedAdmissionOptions = Pick & { admitter: UnifiedAdmitter; cost?: number | ((request: Request) => number); key?: (request: Request) => string; clock?: Clock; dropOn5xx?: boolean; onLimited?: (request: Request, decision: Decision, axes: AxisSnapshot) => void; onError?: (request: Request, err: unknown) => void; handler?: (request: Request, decision: Decision, axes: AxisSnapshot) => Response | Promise; }; /** * Wrap a Next.js handler with a {@link UnifiedAdmitter}. Use in App Router route handlers * or in `middleware.ts`. On admit it wraps `Response.body` for lifecycle release. */ declare function nextUnifiedAdmission(handler: NextHandler, options: NextUnifiedAdmissionOptions): (request: Request, ...args: unknown[]) => Promise; /** Options for {@link nextAdaptiveConcurrency}. */ type NextAdaptiveConcurrencyOptions = Pick & { guard: ConcurrencyGuard; clock?: Clock; dropOn5xx?: boolean; onLimited?: (request: Request, decision: Decision) => void; handler?: (request: Request, decision: Decision) => Response | Promise; }; /** Wrap a Next.js handler with an adaptive {@link ConcurrencyGuard}. */ declare function nextAdaptiveConcurrency(handler: NextHandler, options: NextAdaptiveConcurrencyOptions): (request: Request, ...args: unknown[]) => Promise; export { CommonAdapterOptions, LimiterOrStrategy, type NextAdaptiveConcurrencyOptions, type NextHandler, type NextRateLimitOptions, type NextRateLimitResult, type NextUnifiedAdmissionOptions, nextAdaptiveConcurrency, nextRateLimit, nextUnifiedAdmission };