import { type TelescopeModuleOptions } from './telescope.options.js';
import { TelescopeService } from './telescope.service.js';
/**
 * Public front-end error ingestion. Mounted on a SEPARATE controller from the
 * gated dashboard API (like {@link TelescopeAuthController}) so it carries NO
 * `@UseGuards(TelescopeGuard)` — ordinary users' browsers hit it, they have no
 * dashboard session. Security is instead the per-endpoint knobs in
 * {@link ClientErrorsOptions}: an opt-in `enabled` flag (404 while off), a body
 * byte cap, a per-IP token bucket, and an optional `authorize` hook.
 *
 * Records every accepted error as a `client_exception` entry through the normal
 * pipeline so it composes with new-exception alerts, per-type prune/archive, and
 * the dashboard — with a family-hash mirroring server exceptions and the
 * `failed` / `client` / `user:<id>` tags.
 */
export declare class ClientErrorController {
    private readonly options;
    private readonly service;
    private readonly logger;
    /** Per-pod, bounded token bucket (lazily built so a disabled endpoint is free). */
    private rateLimiter;
    /** One warn for an authorize-hook throw, so a flaky hook can't spam logs. */
    private warnedAuthorize;
    constructor(options: TelescopeModuleOptions, service: TelescopeService);
    ingest(body: unknown, request: unknown): Promise<void>;
    /** Build (once) the per-pod token bucket from the resolved rate-limit config. */
    private limiter;
    /**
     * Run the host's authorize hook defensively: a throw is a DENIAL (fail closed)
     * and warn-logged once, so a buggy hook never 500s the public endpoint nor
     * floods the logs.
     */
    private runAuthorize;
    /**
     * Best-effort serialized byte size of the parsed body. The framework already
     * parsed JSON by the time we get here, so we re-serialize to measure bytes
     * (UTF-8) — a tight enough proxy for the wire size to reject oversized
     * payloads. A non-serializable body counts as 0 (it'll fail validation anyway).
     */
    private bodyByteSize;
    /**
     * Extract the reporting client's IP: the first hop of `x-forwarded-for` when
     * present (the original client behind a proxy), else `request.ip` /
     * `socket.remoteAddress`. Returns `null` when nothing usable is found.
     */
    private clientIp;
}
//# sourceMappingURL=client-error.controller.d.ts.map