/// <reference types="node" />
import { Server as ProxyServer } from 'proxy-chain';
import type * as ProxyChain from 'proxy-chain';
import { ProxyRouterStats } from './stats';
declare type ProxyServerOpts = ConstructorParameters<typeof ProxyServer>[0];
export interface Proxies {
    /** The default proxy for the browser (format: `http://user:pass@proxyhost:port`), if omitted or `null` no proxy will be used by default */
    DEFAULT?: string | null;
    /** Any other custom proxy names which can be used for routing later (e.g. `'DATACENTER_US': 'http://user:pass@proxyhost:port'`) */
    [key: string]: string | null;
}
export declare type ProxyName = 'DIRECT' | 'DEFAULT' | 'ABORT' | string;
/** Data available to the `routeByHost` function */
export interface RouteByHostArgs {
    /** Request URL host */
    host: string;
    /** Whether the request is http or not */
    isHttp: boolean;
    /** Request port (typically 443 or 80) */
    port: number;
}
export declare type RouteByHostResponse = ProxyName | void;
export declare type RouteByHostFn = (args: RouteByHostArgs) => Promise<RouteByHostResponse>;
export interface ProxyRouterOpts {
    /**
     * A dictionary of proxies to be made available to the browser and router.
     *
     * An optional entry named `DEFAULT` will be used for all requests, unless overriden by `routeByHost`.
     * If the `DEFAULT` entry is omitted no proxy will be used by default.
     *
     * The value of an entry can be a string (format: `http://user:pass@proxyhost:port`) or `null` (direct connection).
     * Proxy authentication is handled automatically by the router.
     *
     * @example
     * proxies: {
     *   DEFAULT: "http://user:pass@proxyhost:port", // use this proxy by default
     *   RESIDENTIAL_US: "http://user:pass@proxyhost2:port" // use this for specific hosts with `routeByHost`
     * }
     */
    proxies?: Proxies;
    /**
     * An optional function to allow proxy routing based on the target host of the request.
     *
     * A return value of nothing, `null` or `DEFAULT` will result in the DEFAULT proxy being used as configured.
     * A return value of `DIRECT` will result in no proxy being used.
     * A return value of `ABORT` will cancel/block this request.
     *
     * Any other string as return value is assumed to be a reference to the configured `proxies` dict.
     *
     * @note The browser will most often establish only a single proxy connection per host.
     *
     * @example
     * routeByHost: async ({ host }) => {
     *   if (host.includes('google')) { return "DIRECT" }
     *   return 'RESIDENTIAL_US'
     * }
     *
     */
    routeByHost?: RouteByHostFn;
    /** Collect traffic and connection stats, default: true */
    collectStats?: boolean;
    /** Don't print any proxy connection errors to stderr, default: false */
    muteProxyErrors?: boolean;
    /** Suppress proxy errors for specific hosts */
    muteProxyErrorsForHost?: string[];
    /** Options for the local proxy-chain server  */
    proxyServerOpts?: ProxyServerOpts;
}
export declare class ProxyRouter {
    /** The underlying local proxy server used for routing to upstream proxies */
    proxyServer: ProxyChain.Server;
    /** An optional function to route hosts  */
    routeByHost: RouteByHostFn | null;
    /**
     * The dictionary of proxies made available (format: `FOOBAR: 'http://user:pass@proxyhost:port'`).
     * Can be modified at runtime.
     */
    proxies: Proxies;
    /** Traffic stats collector */
    readonly stats: ProxyRouterStats;
    isListening: boolean;
    protected serverStartPromise: Promise<number> | null;
    protected collectStats: boolean;
    protected muteProxyErrors: boolean;
    protected muteProxyErrorsForHost: string[];
    /** Internal list of failed connections to only print the same connection issue once */
    protected failedConnections: {
        host: string;
        proxy: string;
    }[];
    constructor(opts?: ProxyRouterOpts);
    /** Proxy server URL of the local proxy server used for routing */
    get proxyServerUrl(): string;
    get effectiveProxies(): {
        /** The default proxy for the browser (format: `http://user:pass@proxyhost:port`), if omitted or `null` no proxy will be used by default */
        DEFAULT?: string;
        DIRECT: any;
    };
    /** Start the local proxy server and accept connections */
    listen(): Promise<number>;
    /** Stop the local proxy server */
    close(): Promise<NodeJS.ErrnoException | null>;
    getProxyForName(name: ProxyName): string | null;
    /** Handle requests to the proxy server */
    protected handleProxyServerRequest({ request, hostname: host, port, connectionId, isHttp, }: ProxyChain.PrepareRequestFunctionOpts): Promise<void | ProxyChain.PrepareRequestFunctionResult>;
}
/** Standalone proxy router not requiring plugin events */
export declare const ProxyRouterStandalone: typeof ProxyRouter;
export {};
