/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import { Agent as HttpAgent } from "http";
import { Agent as HttpsAgent } from "https";
import type RestRequest from "./RestRequest";
import type RestResponse from "./RestResponse";
/**
 * An event which is passed to an external logger (see RestOptions).
 */
export interface RestLogEvent {
    attempt: number;
    req: RestRequest;
    res: RestResponse | "backoff_delay" | null;
    exception: any | null;
    timestamp: number;
    elapsed: number;
    isFinalAttempt: boolean;
    privateDataInResponse: boolean;
    comment: string;
}
/**
 * Middlewares allow to modify RestRequest and RestResponse objects during the
 * request processing.
 */
export interface Middleware {
    (req: RestRequest, next: (req: RestRequest) => Promise<RestResponse>): Promise<RestResponse>;
}
/**
 * @ignore
 * Parameters for Agents.
 */
interface AgentOptions {
    keepAlive: boolean;
    timeout?: number;
    maxSockets?: number;
    rejectUnauthorized?: boolean;
    family?: 4 | 6 | 0;
}
/**
 * @ignore
 * An internal class which keeps the list of HttpAgent instances used in a
 * particular RestClient instance.
 */
export declare class Agents {
    http(options: AgentOptions): HttpAgent;
    https(options: AgentOptions): HttpsAgent;
}
/**
 * Options passed to RestClient. More options can be added by cloning an
 * instance of RestClient, withOption() method.
 */
export default interface RestOptions {
    /** Max number of retries. Default is 0, because some requests are from the
     * web app, and we don't want to retry them. */
    retries: number;
    /** How much time to wait by default on the 1st retry attempt. */
    retryDelayFirstMs: number;
    /** How much to increase the retry delay on each retry. */
    retryDelayFactor: number;
    /** Use this fraction (random) of the current retry delay to jitter both ways
     * (e.g. 0.1 means 90%...110% of the delay to be actually applied). */
    retryDelayJitter: number;
    /** Maximum delay between each retry. */
    retryDelayMaxMs: number;
    /** A logic which runs on different IO stages (delay and heartbeats). */
    heartbeater: {
        heartbeat(): Promise<void>;
        /** A function which, when runs, resolves in the provided number of ms. Can
         * be used for several purposes, like overriding in unit tests or to pass a
         * custom delay implementation which can throw on some external event (like
         * when the process wants to gracefully stop). */
        delay(ms: number): Promise<void>;
    };
    /** Allows to limit huge requests and throw instead. */
    throwIfResIsBigger: number | undefined;
    /** Passed to the logger which may decide, should it log details of the
     * response or not. */
    privateDataInResponse: boolean;
    /** If true, non-public IP addresses are allowed too; otherwise, only unicast
     * addresses are allowed. */
    allowInternalIPs: boolean;
    /** Overrides the default encoding heuristics for responses. */
    responseEncoding: NodeJS.BufferEncoding | undefined;
    /** If true, logs request-response pairs to console. */
    isDebug: boolean;
    /** @ignore Holds HttpsAgent/HttpAgent instances; used internally only. */
    agents: Agents;
    /** Sets Keep-Alive parameters (persistent connections). */
    keepAlive: {
        /** How much time to keep an idle connection alive in the pool. If 0, closes
         * the connection immediately after the response. */
        timeoutMs: number;
        /** How many sockets at maximum will be kept open. */
        maxSockets?: number;
    };
    /** When resolving DNS, use IPv4, IPv6 or both (see dns.lookup() docs). */
    family: 4 | 6 | 0;
    /** Max timeout to wait for a response. */
    timeoutMs: number;
    /** Logger to be used for each responses (including retried) plus for backoff
     * delay events logging. */
    logger: (event: RestLogEvent) => void;
    /** Middlewares to wrap requests. May alter both request and response. */
    middlewares: Middleware[];
    /** If set, makes decision whether the response is successful or not. The
     * response will either be returned to the client, or an error will be thrown.
     * This allows to treat some non-successful HTTP statuses as success if the
     * remote API is that weird. Return values:
     * * "SUCCESS" - the request will be considered successful, no further checks
     *   will be performed;
     * * "BEST_EFFORT" - inconclusive, the request may be either successful or
     *   unsuccessful, additional tests (e.g. will check HTTP status code) will be
     *   performed;
     * * "THROW" - the request resulted in error. Additional tests will be
     *   performed to determine is the error is retriable, is OAuth token good,
     *   and etc. */
    isSuccessResponse: (res: RestResponse) => "SUCCESS" | "THROW" | "BEST_EFFORT";
    /** Decides whether the response is a rate-limit error or not. Returning
     * non-zero value is treated as retry delay (if retries are set up). In case
     * the returned value is "SOMETHING_ELSE", the response ought to be either
     * success or some other error. Returning "BEST_EFFORT" turns on built-in
     * heuristic (e.g. relying on HTTP status code and Retry-After header). In
     * case we've made a decision that it's a rate limited error, the request is
     * always retried; this covers a very common case when we have both
     * isRateLimitError and isRetriableError handlers set up, and they return
     * contradictory information; then isRateLimitError wins. */
    isRateLimitError: (res: RestResponse) => "SOMETHING_ELSE" | "RATE_LIMIT" | "BEST_EFFORT" | number;
    /** Decides whether the response is a token-invalid error or not. In case it's
     * not, the response ought to be either success or some other error. */
    isTokenInvalidError: (res: RestResponse) => boolean;
    /** Called only if we haven't decided earlier that it's a rate limit error.
     * Decides whether the response is a retriable error or not. In case the
     * returned value is "NEVER_RETRY", the response ought to be either success or
     * some other error, but it's guaranteed that the request won't be retried.
     * Returning "BEST_EFFORT" turns on built-in heuristics (e.g. never retry "not
     * found" errors). Returning a number is treated as "RETRY", and the next
     * retry will happen in not less than this number of milliseconds. */
    isRetriableError: (res: RestResponse, _error: any) => "NEVER_RETRY" | "RETRY" | "BEST_EFFORT" | number;
}
/** @ignore */
export declare const DEFAULT_OPTIONS: RestOptions;
export {};
//# sourceMappingURL=RestOptions.d.ts.map