import type { PathRewrite } from './types';
import type { ResolvedAuth } from './auth';
import type { ResolvedRedirect } from './redirect';
import type { ResolvedStaticRoute } from './static-files';
import type { UpstreamPool } from './load-balancer';
/**
 * Cap on client→upstream frames buffered *before the upstream WebSocket opens*.
 * Without it, a fast client (or an upstream that never opens) grows `pending`
 * without bound until the gateway OOMs. Beyond the cap the client socket is
 * closed with 1009 (message too big). Override with `RPX_MAX_WS_PENDING_BYTES`;
 * read once per handler so tests (and reloads) can pick up a new value.
 */
export declare function wsPendingCapBytes(): number;
/**
 * Strip the route's mount prefix (`basePath`) from a request pathname so a
 * target mounted under `/docs` sees `/` for `/docs` and `/guide` for
 * `/docs/guide`. A `/` (or empty) base strips nothing. The result always keeps
 * a leading `/`.
 */
export declare function stripBasePath(pathname: string, basePath?: string): string;
/**
 * Build a Bun.serve-compatible `fetch` handler that routes requests based on
 * the `Host` header. Returns 404 when no route matches and 502 on upstream
 * failures. When a request is a WebSocket upgrade and `server` is supplied, it
 * is upgraded (returns `undefined` so Bun completes the handshake) and the
 * traffic is handled by the `websocket` handler from {@link createProxyWebSocketHandler}.
 */
export declare function createProxyFetchHandler(getRoute: GetRoute, verbose?: boolean, onNoRoute?: OnNoRoute): ProxyFetchHandler;
/**
 * Build the `websocket` handler block for Bun.serve. It opens an upstream
 * `WebSocket` per client socket, buffers client→upstream frames until the
 * upstream connection is open, and pipes messages, closes and errors in both
 * directions with a clean teardown.
 */
export declare function createProxyWebSocketHandler(verbose?: boolean): void;
export declare interface ProxyRoute {
  sourceHost?: string
  upstreamPool?: UpstreamPool
  cleanUrls?: boolean
  changeOrigin?: boolean
  pathRewrites?: PathRewrite[]
  static?: ResolvedStaticRoute
  redirect?: ResolvedRedirect
  basePath?: string
  stripBasePathPrefix?: boolean
  auth?: ResolvedAuth
}
/** Minimal shape of the Bun server needed for WebSocket upgrades. */
export declare interface ProxyServer {
  upgrade: (req: Request, options?: { data?: unknown, headers?: Bun.HeadersInit }) => boolean
}
/*` → app, `/docs*` → static dir). Callers
 * that only route by host can ignore the second argument — it's optional so
 * existing host-only `getRoute` callbacks remain valid.
 */
export type GetRoute = (hostname: string, pathname: string) => ProxyRoute | undefined;
/**
 * Outcome of the no-route fallback ({@link OnNoRoute}):
 *   - a `Response` — serve it as-is (e.g. a "starting…" splash);
 *   - `{ retry: true }` — a route was just published, so re-resolve and proxy;
 *   - `undefined` — no fallback applies, fall through to 404.
 */
export type NoRouteOutcome = Response | { retry: true } | undefined;
/**
 * Called when `getRoute` finds nothing for a request. Lets the daemon lazily
 * boot an on-demand site (see {@link import('./site-supervisor').SiteSupervisor})
 * and either hold the request behind a splash or signal that the route is now live.
 */
export type OnNoRoute = (hostname: string, pathname: string, req: Request) => Promise<NoRouteOutcome>;
export type ProxyFetchHandler = (req: Request, server?: ProxyServer) => Promise<Response | undefined>;
