/**
 * kassette is a development server, used mainly for testing, which proxies requests and is able to easily manage local mocks.
 *
 * @packageDocumentation
 */

import * as crypto_2 from 'crypto';
import { Http2ServerRequest } from 'http2';
import { Http2ServerResponse } from 'http2';
import { IncomingHttpHeaders } from 'http';
import { IncomingMessage } from 'http';
import { ServerHttp2Stream } from 'http2';
import { ServerResponse } from 'http';
import { Socket } from 'net';
import { URL as URL_2 } from 'url';

/**
 * Specifies the argument expected to start kassette programmatically with {@link runFromAPI}.
 *
 * @public
 */
export declare interface APIOptions {
    /**
     * kassette configuration passed through the API.
     *
     * @remarks
     *
     * If {@link APIOptions.configurationPath|configurationPath} is also specified, both configurations are merged,
     * but `apiConfiguration` has the least precedence.
     * However, this object is also forwarded to the configuration file's {@link IConfigurationFile.getConfiguration|getConfiguration}
     * method, as {@link GetConfigurationProps.apiConfiguration|apiConfiguration}, so you can apply your own logic to determine what configuration
     * to actually use.
     */
    readonly apiConfiguration?: ConfigurationSpec;
    /**
     * Path to a configuration file, if the configuration should be loaded from a configuration file.
     */
    readonly configurationPath?: string;
    /**
     * Specifies the context argument passed to the {@link IConfigurationFile.getConfiguration|getConfiguration} function defined in the
     * configuration file (only used if {@link APIOptions.configurationPath|configurationPath} is specified).
     */
    readonly fileConfigurationContext?: any;
}

/**
 * Type of the argument expected by {@link IMock.checksum|checksum}.
 * It specifies which data from the request to include in the checksum.
 *
 * @remarks
 * To include or exclude data, not every kind of data from the request has the
 * same complexity. For instance, the HTTP method is simple: use it or don't
 * use it. But for things like query parameters, headers, body: you might want to
 * select/filter.
 *
 * @public
 */
export declare interface ChecksumArgs {
    /**
     * Specifies the hash algorithm. Default value is `sha256`.
     * Check Node.js API for more information: {@link https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm_options|crypto.createHash(type)}.
     */
    type?: string;
    /**
     * Specifies the output format. Default value is `hex`.
     * Check Node.js API for more information: {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding|hash.digest(format)}.
     */
    format?: crypto_2.BinaryToTextEncoding;
    /**
     * Specifies whether to include the protocol in the hash. The default value is `false`.
     */
    protocol?: IncludableSpec | boolean;
    /**
     * Specifies whether and how to include the hostname in the hash. The default value is `false`.
     */
    hostname?: FilterableSpec<string> | boolean;
    /**
     * Specifies whether to include the port in the hash. The default value is `false`.
     */
    port?: IncludableSpec | boolean;
    /**
     * Specifies whether to include the method in the hash. The default value is `false`.
     */
    method?: IncludableSpec | boolean;
    /**
     * Specifies whether and how to include the pathname part of the url in the hash. The default value is `false`.
     */
    pathname?: FilterableSpec<string> | boolean;
    /**
     * Specifies whether and how to include the body of the request in the hash. The default value is `true`.
     */
    body?: FilterableSpec<Buffer, Buffer | string> | boolean;
    /**
     * Specifies whether and how to include the query part of the url in the hash. The default value is `true`.
     */
    query?: ListOrFilter | boolean;
    /**
     * Specifies whether and how to include the headers in the hash.
     * The default value is `false`.
     */
    headers?: ListOrFilter | boolean;
    /**
     * Any custom value (which can be JSON stringified) to be added in the content
     * to be hashed.
     */
    customData?: any | null;
}

/**
 * The set of possible properties defined through the CLI
 * (it is reduced since it can't contain runtime values)
 *
 * @public
 */
export declare interface CLIConfigurationSpec {
    /**
     * If true, will simplify the logging output, logging only one line
     * when the request is received but nothing else afterwards.
     */
    readonly skipLog?: boolean;
    /**
     * The port on which the proxy should listen. Note that kassette accepts both http and https connections on this port.
     *
     * @remarks
     *
     * If the port is not available, it will fail and stop the program; try again with another, available port.
     * If the port is set to 0, the proxy will listen on a random port
     * (actually depends on the OS implementation): use the callback {@link ConfigurationSpec.onListen|onListen} to catch its value.
     */
    readonly port?: number;
    /**
     * The hostname on which the proxy should listen.
     * Uses `127.0.0.1` by default, which only allows local connections.
     * To allow remote connections, use the ip address of the specific network interface that should be allowed to connect
     * or the unspecified IPv4 (`0.0.0.0`) or IPv6 (`::`) address.
     *
     * @remarks
     *
     * Note that kassette has not been reviewed for security issues.
     * It is intended to be used in a safe local/testing environment.
     * Binding it to an open connection can result in compromising your
     * computer or your network.
     */
    readonly hostname?: string;
    /**
     * The default mode.
     *
     * @remarks
     *
     * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method
     * through {@link IMock.setMode|mock.setMode}.
     */
    readonly mode?: Mode;
    /**
     * The default mocks format.
     *
     * @remarks
     *
     * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method
     * through {@link IMock.setMocksFormat|mock.setMocksFormat}.
     *
     * The default value of the global `mocksFormat` setting is `folder`, except in the following case:
     * if the global {@link CLIConfigurationSpec.mocksHarFile|mocksHarFile} setting is defined
     * and the global {@link CLIConfigurationSpec.mocksFolder|mocksFolder} setting is not defined,
     * then the default value of the global `mocksFormat` setting is `har`.
     */
    readonly mocksFormat?: MocksFormat;
    /**
     * Whether to save the content used to create a checksum when creating a new mock with a checksum.
     *
     * @remarks
     *
     * The default value of the global `saveChecksumContent` setting is `true`.
     *
     * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method
     * through {@link IMock.setSaveChecksumContent|mock.setSaveChecksumContent}.
     */
    readonly saveChecksumContent?: boolean;
    /**
     * Whether to save {@link RequestTimings | detailed timings} when creating a new mock.
     *
     * @remarks
     *
     * The default value of the global `saveDetailedTimings` setting is `true`.
     *
     * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method
     * through {@link IMock.setSaveDetailedTimings|mock.setSaveDetailedTimings}.
     */
    readonly saveDetailedTimings?: boolean;
    /**
     * Whether to save the input request data (headers, method, URL) when creating a new mock.
     *
     * @remarks
     *
     * The default value of the global `saveInputRequestData` setting is `true`.
     *
     * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method
     * through {@link IMock.setSaveInputRequestData|mock.setSaveInputRequestData}.
     */
    readonly saveInputRequestData?: boolean;
    /**
     * Whether to save the content of the input request body when creating a new mock.
     *
     * @remarks
     *
     * The default value of the global `saveInputRequestBody` setting is `true`.
     *
     * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method
     * through {@link IMock.setSaveInputRequestBody|mock.setSaveInputRequestBody}.
     */
    readonly saveInputRequestBody?: boolean;
    /**
     * Whether to save the forwarded request data (headers, method, URL) when creating a new mock.
     *
     * @remarks
     *
     * The default value of the global `saveForwardedRequestData` setting is `null`, which means
     * `true` when `mocksFormat` is `folder` (for backward-compatibility), and
     * `false` when `mocksFormat` is `har`.
     *
     * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method
     * through {@link IMock.setSaveForwardedRequestData|mock.setSaveForwardedRequestData}.
     */
    readonly saveForwardedRequestData?: boolean | null;
    /**
     * Whether to save the forwarded request body when creating a new mock.
     *
     * @remarks
     *
     * The default value of the global `saveForwardedRequestData` setting is `null`, which means
     * `true` when `mocksFormat` is `folder` (for backward-compatibility), and
     * `false` when `mocksFormat` is `har`.
     *
     * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method
     * through {@link IMock.setSaveForwardedRequestBody|mock.setSaveForwardedRequestBody}.
     */
    readonly saveForwardedRequestBody?: boolean | null;
    /**
     * The default delay.
     *
     * @remarks
     *
     * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method
     * through {@link IMock.setDelay|mock.setDelay}.
     */
    readonly delay?: Delay;
    /**
     * When the {@link CLIConfigurationSpec.mocksFormat|mocks format} is 'folder', specifies
     * the default root folder of all mocks, from which specific mocks paths will be resolved.
     *
     * @remarks
     *
     * It can be changed at a request level in the {@link ConfigurationSpec.hook|hook} method
     * through {@link IMock.setMocksFolder|mock.setMocksFolder}.
     */
    readonly mocksFolder?: string;
    /**
     * When the {@link CLIConfigurationSpec.mocksFormat|mocks format} is 'har', specifies
     * the default har file to use. If the file name has the `.yml` or `.yaml` extension, the YAML format
     * is used instead of the standard JSON format to read and write the file.
     *
     * @remarks
     *
     * It can be changed at a request level in the {@link ConfigurationSpec.hook|hook} method
     * through {@link IMock.setMocksHarFile|mock.setMocksHarFile}.
     */
    readonly mocksHarFile?: string;
    /**
     * Time in milliseconds during which a har file is kept in memory after its last usage.
     */
    readonly harFileCacheTime?: number;
    /**
     * The URL of the remote backend, from which only the protocol, hostname and port are used.
     * Can be left `null`, in which case anything leading to sending the request to the remote backend will trigger an exception.
     * Can also contain the special `"*"` value, which means reading from the request the remote backend to target. This is useful when using kassette as a browser proxy.
     *
     * @remarks
     *
     * It can be changed at a request level in the {@link ConfigurationSpec.hook|hook} method
     * through {@link IMock.setRemoteURL|mock.setRemoteURL}.
     */
    readonly remoteURL?: string | null;
    /**
     * Default mode for `CONNECT` requests.
     *
     * @remarks
     *
     * It can be changed at a request level in the {@link ConfigurationSpec.onProxyConnect|onProxyConnect} method
     * through {@link IProxyConnectAPI.setMode|setMode}.
     */
    readonly proxyConnectMode?: ProxyConnectMode;
    /**
     * Path to a PEM-encoded CA (Certificate Authority) certificate and key file,
     * created if it does not exist. If not provided, the certificate and key are
     * generated but only kept in memory. This certificate and key are used as needed
     * to sign certificates generated on the fly for any HTTPS connection intercepted
     * by kassette.
     *
     * @remarks
     *
     * You can optionally import in the browser the TLS certificate from this
     * file in order to remove the warning when connecting to HTTPS websites
     * through kassette.
     */
    readonly tlsCAKeyPath?: string | null;
    /**
     * Size in bits of generated RSA keys.
     */
    readonly tlsKeySize?: number;
    /**
     * Enables http/2.0 protocol in the kassette server.
     */
    readonly http2?: boolean;
}

/* Excluded from this release type: CLIOptions */

/**
 * The id of the source of the resolved value.
 *
 * @public
 */
export declare type ConfigurationPropertySource = 'cli' | 'file' | 'api' | 'default';

/**
 * Augments the CLI spec to add all pure runtime properties,
 * that can be defined through the configuration file only
 *
 * @public
 */
export declare interface ConfigurationSpec extends CLIConfigurationSpec {
    /**
     * Callback called for every HTTP request that kassette receives (with the exception of `CONNECT` requests,
     * which trigger the call of {@link ConfigurationSpec.onProxyConnect|onProxyConnect} instead).
     * @param parameters - exposes the API to control how to process the request
     */
    hook?(parameters: HookAPI): void | Promise<void>;
    /**
     * Function called to get or set the key of a mock in a har file, as explained in {@link HarKeyManager}.
     *
     * @remarks
     *
     * It can be changed at a request level in the {@link ConfigurationSpec.hook|hook} method
     * through {@link IMock.setMocksHarKeyManager|mock.setMocksHarKeyManager}.
     */
    readonly mocksHarKeyManager?: HarKeyManager;
    /**
     * Callback called when kassette receives a request with the
     * {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT|HTTP CONNECT method},
     * which usually happens when kassette is used as a browser proxy and the browser is trying to
     * connect to a secure web site with the https protocol.
     * @param parameters - exposes the API to control how to process the request
     */
    onProxyConnect?(parameters: IProxyConnectAPI): void | Promise<void>;
    /**
     * Callback called when the proxy is started and listening.
     *
     * @param parameters - the port property contains the port on which the
     * proxy is listening.
     */
    onListen?(parameters: {
        port: number;
    }): void;
    /**
     * Callback called when the proxy is programmatically closed (which can
     * be done by using the callback returned from {@link runFromAPI})
     */
    onExit?(): void;
    /**
     * Custom implementation of the {@link ConsoleSpec} interface, with methods
     * {@link ConsoleSpec.log|log} and {@link ConsoleSpec.error|error},
     * each receiving one single argument of any type.
     * Useful to capture the logs of the application.
     */
    readonly console?: ConsoleSpec;
    /**
     * Used only when the {@link IMock.mocksFormat|mocks format} is 'har',
     * specifies a list of mime types that will attempt to parse the request/response body as JSON.
     * If the list includes an empty string: '' and there is no mimeType set in the request, it will attempt to parse the body as JSON.
     * This will only be applicable to request bodies if {@link IMock.saveInputRequestBody|saveInputRequestBody} is set to true
     * Default value will be [] and will only be overridden by {@link IMock.setHarMimeTypesParseJson|setHarMimeTypesParseJson}
     */
    readonly harMimeTypesParseJson?: string[];
}

/**
 * A connection intercepted by kassette
 *
 * @public
 */
export declare interface Connection {
    /** protocol such as `http` or `https`, without the trailing `:` */
    protocol: string;
    /** target hostname */
    hostname: string;
    /** target port */
    port: number;
}

/**
 * Console with logging methods.
 * @public
 */
export declare interface ConsoleSpec {
    /**
     * Logs a message.
     * @param message - message to log
     */
    log(message: any): void;
    /**
     * Logs an error message.
     * @param message - error message to log
     */
    error(message: any): void;
}

/**
 * Delay that will be used to send the response to the client
 * when the data is taken from the local mock.
 *
 * @remarks
 *
 * It can be expressed either as a direct value (in milliseconds) or as the
 * `'recorded'` string, which means to use the delay recorded
 * in the local mock (in the {@link MockData.time|time} field).
 *
 * @public
 */
export declare type Delay = 'recorded' | number;

/**
 * Interface used in {@link ChecksumArgs} for each piece of data that can be filtered (i.e. modified) before it is included
 * in the hash computed by the {@link IMock.checksum|checksum} method.
 *
 * @public
 */
export declare interface FilterableSpec<I, O = I> extends IncludableSpec {
    /**
     * A function used to filter (i.e. modify) the piece of data before it is included in the hash.
     * If no function is given, the unmodified piece of data is used.
     * @param input - piece of data to filter
     * @returns The modified piece of data. Note that the filter function can optionally be
     * asynchronous, in which case it is expected to return a promise of the modified piece
     * of data.
     */
    filter?(input: I): O | Promise<O>;
}

/**
 * Parameter of the {@link IConfigurationFile.getConfiguration|getConfiguration} function
 * (which a kassette configuration file is supposed to export).
 *
 * @public
 */
export declare interface GetConfigurationProps {
    /**
     * If run from the CLI, this is the configuration coming from the CLI.
     * Otherwise it is an empty object.
     */
    cliConfiguration: CLIConfigurationSpec;
    /**
     * If run from the API, this is the configuration coming from the {@link runFromAPI} call.
     * Otherwise it is an empty object.
     */
    apiConfiguration: ConfigurationSpec;
    /**
     * If run from the API, this is the context value provided (if any) through {@link runFromAPI}.
     * Otherwise it is undefined.
     */
    context: any;
}

/**
 * Information about the response body, as stored in a har file.
 *
 * @public
 */
export declare interface HarFormatContent {
    /**
     * Size of the content in bytes.
     */
    size?: number;
    /**
     * Number of bytes saved by compression. This is not implemented by kassette.
     */
    compression?: number;
    /**
     * Value of the `Content-Type` response header.
     */
    mimeType?: string;
    /**
     * Response body.
     *
     * @remarks
     *
     * The response body can be encoded in base64 if this is specified in the {@link HarFormatContent.encoding | encoding} field.
     */
    text?: string;
    /**
     * Encoding used for the {@link HarFormatContent.text | text} field, such as "base64".
     */
    encoding?: string;
    /**
     * Any comment as a string. This is not used by kassette.
     */
    comment?: string;
    /**
     * Response body saved as an object.
     */
    json?: any;
}

/**
 * Detailed information about a request and its response, as stored in a har file.
 *
 * @public
 */
export declare interface HarFormatEntry {
    /**
     * Content used to create a checksum
     *
     * @remarks
     *
     * kassette only includes this field if {@link IMock.saveChecksumContent | saveChecksumContent} is true and
     * if the {@link IMock.checksum | checksum} method was called.
     */
    _kassetteChecksumContent?: string;
    /**
     * Key used by kassette to select the correct mock to replay.
     *
     * @remarks
     *
     * This field contains the value passed to {@link IMock.setMockHarKey} when used with the default
     * {@link ConfigurationSpec.mocksHarKeyManager | mocksHarKeyManager}.
     */
    _kassetteMockKey?: string;
    /**
     * Detailed information about the request forwarded to the remote server.
     *
     * @remarks
     *
     * kassette only includes this field if {@link IMock.saveForwardedRequestData | saveInputRequestData} is true.
     */
    _kassetteForwardedRequest?: HarFormatRequest;
    /**
     * Reference to the parent page. This is not implemented in kassette.
     */
    pageref?: string;
    /**
     * Date and time of the request start, as a string in ISO format (YYYY-MM-DDThh:mm:ss.sTZD).
     */
    startedDateTime?: string;
    /**
     * Total time of the request, in milliseconds. This is the sum of all timings in the {@link HarFormatEntry.timings | timings object}.
     */
    time?: number;
    /**
     * Detailed information about the input request.
     *
     * @remarks
     *
     * kassette only includes this field if {@link IMock.saveInputRequestData | saveInputRequestData} is true.
     */
    request?: HarFormatRequest;
    /**
     * Detailed information about the response.
     */
    response?: HarFormatResponse;
    /**
     * Information about the cache. This is not implemented in kassette.
     */
    cache?: any;
    /**
     * Detailed timing information about request/response round trip.
     *
     * @remarks
     *
     * kassette only includes this field if {@link IMock.saveDetailedTimings | saveDetailedTimings} is true.
     */
    timings?: HarFormatTimings;
    /**
     * Server IP address. This is not implemented in kassette.
     */
    serverIPAddress?: string;
    /**
     * Unique ID of the TCP/IP connection. This is not implemented in kassette.
     */
    connection?: string;
    /**
     * Any comment as a string. This is not used by kassette.
     */
    comment?: string;
}

/**
 * Information about a header or a query parameter, as stored in a har file.
 *
 * @public
 */
export declare interface HarFormatNameValuePair {
    /**
     * Name of the header or query parameter.
     */
    name: string;
    /**
     * Value of the header or the query parameter.
     */
    value: string;
    /**
     * Any comment as a string. This is not used by kassette.
     */
    comment?: string;
}

/**
 * Information about a request body, as stored in a har file.
 *
 * @public
 */
export declare interface HarFormatPostData {
    /**
     * Value of the `Content-Type` request header, if present.
     */
    mimeType?: string;
    /**
     * List of posted parameters. This is not implemented in kassette.
     *
     * @remarks
     *
     * kassette always fills the {@link HarFormatPostData.text | text field} and never uses the params field.
     */
    params?: any[];
    /**
     * Posted data, as a (binary) string.
     */
    text?: string;
    /**
     * Any comment as a string. This is not used by kassette.
     */
    comment?: string;
    /**
     * Response body saved as an object.
     */
    json?: any;
}

/**
 * Detailed information about a request, as stored in a har file.
 *
 * @public
 */
export declare interface HarFormatRequest {
    /**
     * Request method, such as "GET" or "POST".
     */
    method?: string;
    /**
     * Request URL.
     */
    url?: string;
    /**
     * Request HTTP version, such as "HTTP/1.1".
     */
    httpVersion?: string;
    /**
     * Information about cookies. This is not implemented in kassette.
     */
    cookies?: any[];
    /**
     * List of request headers.
     */
    headers?: HarFormatNameValuePair[];
    /**
     * List of query parameters.
     */
    queryString?: HarFormatNameValuePair[];
    /**
     * Information about the request body.
     *
     * @remarks
     *
     * kassette only includes this field if {@link IMock.saveInputRequestBody | saveInputRequestBody} is true
     * (or, for the {@link HarFormatEntry._kassetteForwardedRequest | _kassetteForwardedRequest}.postData field,
     * if {@link IMock.saveForwardedRequestBody | saveForwardedRequestBody} is true).
     */
    postData?: HarFormatPostData;
    /**
     * Total number of bytes from the start of the HTTP request message until (and including) the double CRLF before the body,
     * or -1 if it is unknown. kassette always sets -1 for this field.
     */
    headersSize?: number;
    /**
     * Size of the request body in bytes or -1 if it is unknown.
     */
    bodySize?: number;
    /**
     * Any comment as a string. This is not used by kassette.
     */
    comment?: string;
}

/**
 * Detailed information about a response, as stored in a har file.
 *
 * @public
 */
export declare interface HarFormatResponse {
    /**
     * Response status.
     */
    status?: number;
    /**
     * Response status text.
     */
    statusText?: string;
    /**
     * Response HTTP version, such as "HTTP/1.1".
     */
    httpVersion?: string;
    /**
     * Information about cookies. This is not implemented in kassette.
     */
    cookies?: any[];
    /**
     * List of response headers.
     */
    headers?: HarFormatNameValuePair[];
    /**
     * Information about the response body.
     */
    content?: HarFormatContent;
    /**
     * Content of the `Location` response header if present.
     */
    redirectURL?: string;
    /**
     * Total number of bytes from the start of the HTTP response message until (and including) the double CRLF before the body,
     * or -1 if it is unknown. kassette always sets -1 for this field.
     */
    headersSize?: number;
    /**
     * Size of the response body in bytes, or -1 if it is unknown.
     */
    bodySize?: number;
    /**
     * Any comment as a string. This is not used by kassette.
     */
    comment?: string;
}

/**
 * Details about the time spent for each phase of a request-response round trip, as stored in a har file.
 *
 * @public
 */
export declare interface HarFormatTimings extends RequestTimings {
    /**
     * Any comment as a string. This is not used by kassette.
     */
    comment?: string;
}

/**
 * Each entry in a har file is supposed to have a corresponding unique key (a string).
 * The har key manager is both a getter and a setter for the key of an entry.
 *
 * @remarks
 *
 * The har key manager is a function that is called either to get the key of an entry (when
 * the key parameter is undefined) or to set it (when the key parameter is defined).
 *
 * It should not modify the entry when the key parameter is undefined.
 *
 * When the key parameter is defined, the har key manager is supposed to change the provided entry, in order to store the
 * key in it, because after the call, the entry will be persisted in the har file. In this case, the key parameter either
 * comes from a call to {@link IMock.setMockHarKey}, or from {@link IMock.defaultMockHarKey | defaultMockHarKey}.
 *
 * In order to compute the {@link IMock.defaultMockHarKey | defaultMockHarKey} property, the har key manager
 * is called with an entry that includes the request but not the response (and with an undefined key parameter).
 *
 * In all cases, the har key manager is expected to return the key of the entry. If an array is returned (which can
 * be nested), it is flattened with null items removed, and joined with forward slashes to produce a string.
 *
 * The default har key manager is expected to work fine for most use cases, especially when working with a har file recorded
 * with kassette. With the default har key manager, if a key is set with {@link IMock.setMockHarKey}, it is stored in the
 * {@link HarFormatEntry._kassetteMockKey | _kassetteMockKey} field. Otherwise, the default key is the concatenation of the request
 * method and url, with a separating forward slash. It can be useful to replace the default har key manager with a custom one especially
 * when working with har files that are produced by other applications than kassette, if the default key is not convenient.
 *
 * @example
 *
 * Here is the default har key manager:
 * ```ts
 * export const defaultHarKeyManager: HarKeyManager = (entry: HarFormatEntry, key?: string) => {
 *   const defaultKey = joinPath(entry._kassetteMockKey ?? [entry.request?.method, entry.request?.url]);
 *   if (key && key !== defaultKey) {
 *     entry._kassetteMockKey = key;
 *     return key;
 *   }
 *   return defaultKey;
 * };
 * ```
 *
 * @public
 */
export declare type HarKeyManager = (entry: HarFormatEntry, key?: string) => RecursiveArray<string | null | undefined>;

/**
 * A map from strings to strings or array of strings
 *
 * @public
 */
declare type Headers_2 = IncomingHttpHeaders;
export { Headers_2 as Headers }

/**
 * Parameter of the {@link ConfigurationSpec.hook|hook} callback, that is called for every
 * HTTP request that kassette receives.
 * @public
 */
export declare interface HookAPI {
    /**
     * Provides the API to specify how to handle the HTTP request.
     */
    mock: IMock;
    /**
     * The console object as specified in the {@link ConfigurationSpec.console|configuration},
     * otherwise it is the global console object (usually the one of the platform).
     */
    console: ConsoleSpec;
}

/**
 * Interface that a kassette configuration file should export.
 *
 * @public
 */
export declare interface IConfigurationFile {
    /**
     * Function returning the configuration to be used by kassette.
     * @param arg - contains information that can be used to build
     * the configuration.
     */
    getConfiguration(arg: GetConfigurationProps): ConfigurationSpec | Promise<ConfigurationSpec>;
}

/**
 * Contains the value and origin of a configuration property.
 * @public
 */
export declare interface IConfigurationProperty<PropertyType> {
    /** The resolved value of the property */
    readonly value: PropertyType;
    /** The id of the source of the resolved value of the property */
    readonly origin: ConfigurationPropertySource;
}

/**
 * A handier wrapper around a request
 *
 * @public
 */
export declare interface IFetchedRequest {
    /** The original Node.js object representing the request */
    readonly original: IncomingMessage | Http2ServerRequest;
    /** The connections stack */
    readonly connectionsStack: readonly Readonly<Connection>[];
    /** The last connection in connectionsStack */
    readonly connection: Readonly<Connection>;
    /** The URL */
    readonly url: URL_2;
    /** The headers */
    readonly headers: IncomingHttpHeaders;
    /** The query parameters taken from the URL, as a read-only map of strings */
    readonly queryParameters: Readonly<Record<string, string>>;
    /** The protocol part of the URL, without the trailing `:` */
    readonly protocol: string;
    /** The hostname part of the URL */
    readonly hostname: string;
    /** The port part of the URL */
    readonly port: string;
    /** The HTTP method */
    readonly method: string;
    /** The path part of the URL */
    readonly pathname: string;
    /** The body content */
    readonly body: Buffer;
}

/**
 * The resulting configuration that was merged from its different {@link ConfigurationPropertySource|sources}.
 *
 * @remarks
 *
 * It contains the path to the configuration file in `filePath`, and also for each property defined in {@link ConfigurationSpec},
 * there is an {@link IConfigurationProperty} object describing the {@link IConfigurationProperty.origin|origin} of the property
 * and its {@link IConfigurationProperty.value|value}.
 *
 * @public
 */
export declare type IMergedConfiguration = {
    /**
     * The path of the configuration file
     */
    readonly filePath: string | null;
} & {
    readonly [k in keyof ConfigurationSpec]-?: IConfigurationProperty<Required<ConfigurationSpec>[k]>;
};

/**
 * The public interface exposed to the end user to handle a given request and the associated mock and response.
 *
 * An object implementing this interface is passed to the {@link ConfigurationSpec.hook|hook} function, under property `mock` of the single argument object.
 *
 * @public
 */
export declare interface IMock {
    /**
     * The wrapper around the input request
     */
    readonly request: IFetchedRequest;
    /**
     * The wrapper around the output response
     */
    readonly response: IResponse;
    /**
     * Link to global configuration options
     */
    readonly options: MockingOptions;
    /**
     * The current mode, configured either by a call to {@link IMock.setMode|setMode},
     * or by {@link CLIConfigurationSpec.mode|the global setting}.
     */
    readonly mode: Mode;
    /**
     * Sets the {@link IMock.mode|mode} for the current request.
     * @param mode - mode to set, or null to use the default value from {@link CLIConfigurationSpec.mode|the global setting}
     */
    setMode(mode: Mode | null): void;
    /**
     * The current remote URL, configured either by a call to {@link IMock.setRemoteURL|setRemoteURL},
     * or by {@link CLIConfigurationSpec.remoteURL|the global setting}.
     */
    readonly remoteURL: string | null;
    /**
     * Sets the {@link IMock.remoteURL|remote URL} for the current request.
     * @param url - the URL to set, or null to use the default value from {@link CLIConfigurationSpec.remoteURL|the global setting}
     */
    setRemoteURL(url: string | null): void;
    /**
     * The currently computed delay that will be applied, configured either by a call to {@link IMock.setDelay|setDelay},
     * or by {@link CLIConfigurationSpec.delay|the global setting}. Note that if the delay is set to `recorded` and the local mock
     * to use is not yet loaded, the value returned by this getter will be the default delay and not the recorded delay.
     */
    readonly delay: number;
    /**
     * Sets the {@link IMock.delay|delay} that will be used to send the response to the client
     * when the data is taken from the local mock.
     * @param delay - can be either a number (to directly specify the delay in milliseconds),
     * `'recorded'` (to read the delay from the {@link MockData.time|time} property of an already recorded mock if any)
     * or `null` (to remove the effect of any previous call of `setDelay` and use the default value from {@link CLIConfigurationSpec.delay|the global setting} instead).
     */
    setDelay(delay: Delay | null): void;
    /**
     * Used only when the {@link IMock.mocksFormat|mocks format} is 'folder', specifies the root folder of all mocks,
     * from which specific mocks paths will be resolved
     * (resolved against {@link MockingOptions.root|options.root}).
     */
    readonly mocksFolder: string;
    /**
     * Sets the {@link IMock.mocksFolder|mocksFolder} value.
     *
     * @param value - any combination of arrays of path parts,
     * (as it is also possible for {@link IMock.setLocalPath|setLocalPath}).
     * You can pass an absolute path, or a relative one which will be resolved against {@link MockingOptions.root|options.root}.
     * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.mocksFolder|the global setting}.
     */
    setMocksFolder(value: RecursiveArray<string | null | undefined> | null): void;
    /**
     * Used only when the {@link IMock.mocksFormat|mocks format} is 'har', contains the full path of the the har file to use.
     * If the file name has the `.yml` or `.yaml` extension, the YAML format is used instead of the standard JSON format to read and write the file.
     */
    readonly mocksHarFile: string;
    /**
     * Sets the {@link IMock.mocksHarFile|mocksHarFile} value.
     *
     * @param value - any combination of arrays of path parts.
     * You can pass an absolute path, or a relative one which will be resolved against {@link MockingOptions.root|options.root}.
     * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.mocksHarFile|the global setting}.
     */
    setMocksHarFile(value: RecursiveArray<string | null | undefined> | null): void;
    /**
     * Used only when the {@link IMock.mocksFormat|mocks format} is 'har', specifies the default mock har key to use in case
     * {@link IMock.setMockHarKey | setMockHarKey} is not called with a non-null value.
     * It is computed by calling the {@link IMock.mocksHarKeyManager|mocks har key manager} with the current request.
     *
     * @remarks
     *
     * Note that it is lazily computed, but once computed, it is not re-computed even if
     * {@link IMock.mocksHarKeyManager | mocksHarKeyManager} changes.
     */
    readonly defaultMockHarKey?: string;
    /**
     * Used only when the {@link IMock.mocksFormat|mocks format} is 'har', specifies the key to use inside the har file to either
     * read or write a mock.
     *
     * @remarks
     *
     * The way the key is stored inside the har file depends on the value of {@link IMock.mocksHarKeyManager|mocksHarKeyManager}.
     */
    readonly mockHarKey?: string;
    /**
     * Sets the {@link IMock.mockHarKey|mockHarKey} value.
     *
     * @param value - specifies the key to use inside the har file to either read or write a mock. If an array is set (which can be nested),
     * it is flattened with null items removed, and joined with forward slashes to produce a string.
     * Passing null resets the value to {@link IMock.defaultMockHarKey|the default value}.
     */
    setMockHarKey(value: RecursiveArray<string | null | undefined> | null): void;
    /**
     * Used only when the {@link IMock.mocksFormat|mocks format} is 'har', specifies the {@link HarKeyManager|har key manager} to use.
     */
    readonly mocksHarKeyManager: HarKeyManager;
    /**
     * Sets the {@link IMock.mocksHarKeyManager|mocksHarKeyManager} value.
     *
     * @param value - the {@link HarKeyManager|har key manager} to use for this request.
     * Passing null resets the value to the default coming from {@link ConfigurationSpec.mocksHarKeyManager|the global setting}.
     */
    setMocksHarKeyManager(value: HarKeyManager | null): void;
    /**
     * Used only when the {@link IMock.mocksFormat|mocks format} is 'har',
     * specifies a list of mime types that will attempt to parse the request/response body as JSON.
     * This will only be applicable to request bodies if {@link IMock.saveInputRequestBody|saveInputRequestBody} is set to true
     * Default value will be [] and will only be overridden by {@link IMock.setHarMimeTypesParseJson|setHarMimeTypesParseJson}
     */
    readonly harMimeTypesParseJson: string[];
    /**
     * Sets the {@link IMock.harMimeTypesParseJson|harMimeTypesParseJson} value.
     *
     * @param value - The mime types that should attempt to parse the body as json
     */
    setHarMimeTypesParseJson(value: string[]): void;
    /**
     * Used only when the {@link IMock.mocksFormat|mocks format} is 'folder', specifies the local path of the mock, relative to {@link IMock.mocksFolder|mocksFolder}.
     * It is either the one set by the user through {@link IMock.setLocalPath|setLocalPath} or {@link IMock.defaultLocalPath|defaultLocalPath}.
     */
    readonly localPath: string;
    /**
     * Used only when the {@link IMock.mocksFormat|mocks format} is 'folder', specifies the default local path of the mock, relative to {@link IMock.mocksFolder|mocksFolder}, .
     * It uses the URL pathname to build an equivalent folders hierarchy,
     * and appends the HTTP method as a leaf folder.
     */
    readonly defaultLocalPath: string;
    /**
     * Used only when the {@link IMock.mocksFormat|mocks format} is 'folder', specifies the full, absolute path of the mock, built from {@link IMock.localPath|localPath}/{@link IMock.defaultLocalPath|defaultLocalPath}, {@link IMock.mocksFolder|mocksFolder}
     * and possibly {@link MockingOptions.root|options.root} if {@link IMock.mocksFolder|mocksFolder} is not absolute.
     */
    readonly mockFolderFullPath: string;
    /**
     * Content produced by the last call to the {@link IMock.checksum|checksum} method,
     * as it was passed to the hash algorithm.
     */
    readonly checksumContent: string | null;
    /**
     * Compute a checksum using content from the request.
     *
     * @remarks
     * The computed checksum is intended to be added to the path of the mock
     * so that semantically different requests use different mocks.
     *
     * It is difficult to predict what will actually be relevant to include in
     * the checksum or not for your use case, and that's why we provide many options
     * to include/exclude/transform data (cf {@link ChecksumArgs}).
     *
     * Note that we designed the API so that it is usually not needed to
     * call the checksum method more than once for a given request/mock.
     *
     * The method stores the computed content (which is passed to the hash
     * algorithm) in property {@link IMock.checksumContent|checksumContent}
     * (in the `mock` object), as a string. It is built according to your options
     * and the request's data. It is also persisted, so that you can debug more easily,
     * especially by committing it into your SCM to analyze changes across versions of
     * your code. File is along with the other files of the mock under file name `checksum`.
     *
     * @param spec - specifies which data from the request to include in the checksum
     * @returns The actual checksum value, that you can then
     * use for instance to add to the mock's path.
     */
    checksum(spec: ChecksumArgs): Promise<string>;
    /**
     * Sets the {@link IMock.localPath|localPath} value.
     *
     * @param pathParts - Any combination of values and array of values,
     * which will eventually all be flattened, converted to strings and
     * joined to build a path.
     *
     * @example
     * The following example will use the HTTP method followed by the URL pathname:
     * ```
     * mock.setLocalPath([mock.request.method, mock.request.pathname])
     * ```
     * @example
     * The following example will concatenate `prefix`, all portions of the
     * URL pathname except the first one (also excluding the very first one which is empty since {@link IFetchedRequest.pathname} has a leading slash)
     * and optionally a suffix sequence depending on a boolean.
     *
     * ```
     * mock.setLocalPath([prefix, mock.request.pathname.split('/').slice(2), addSuffix ? [suffix, '-static-suffix'] : null])
     * ```
     */
    setLocalPath(pathParts: RecursiveArray<string | null | undefined>): void;
    /**
     * Returns true if the mock exists locally.
     *
     * @deprecated Use {@link IMock.hasLocalMock} instead.
     *
     * @remarks
     *
     * {@link IMock.hasNoLocalFiles|hasNoLocalFiles} returns the opposite boolean value.
     */
    hasLocalFiles(): Promise<boolean>;
    /**
     * Returns true if the mock does not exist locally.
     *
     * @deprecated Use {@link IMock.hasNoLocalMock} instead.
     *
     * @remarks
     *
     * {@link IMock.hasLocalFiles|hasLocalFiles} returns the opposite boolean value.
     */
    hasNoLocalFiles(): Promise<boolean>;
    /**
     * Returns true if the mock exists locally.
     *
     * @remarks
     *
     * {@link IMock.hasNoLocalMock|hasNoLocalMock} returns the opposite boolean value.
     */
    hasLocalMock(): Promise<boolean>;
    /**
     * Returns true if the mock does not exist locally.
     *
     * @remarks
     *
     * {@link IMock.hasLocalMock|hasLocalMock} returns the opposite boolean value.
     */
    hasNoLocalMock(): Promise<boolean>;
    /**
     * The mocks format used for this request.
     */
    readonly mocksFormat: MocksFormat;
    /**
     * Sets the {@link IMock.mocksFormat|mocksFormat} value.
     *
     * @param value - the mocks format to use for this request.
     * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.mocksFormat|the global setting}.
     */
    setMocksFormat(value: MocksFormat | null): void;
    /**
     * Whether to save the content used to create a checksum when creating a new mock with a checksum for this request.
     */
    readonly saveChecksumContent: boolean;
    /**
     * Sets the {@link IMock.saveChecksumContent|saveChecksumContent} value.
     *
     * @param value - whether to save the content used to create a checksum when creating a new mock with a checksum for this request.
     * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.saveChecksumContent|the global setting}.
     */
    setSaveChecksumContent(value: boolean | null): void;
    /**
     * Whether to save {@link RequestTimings | detailed timings} when creating a new mock for this request.
     */
    readonly saveDetailedTimings: boolean;
    /**
     * Sets the {@link IMock.saveDetailedTimings|saveDetailedTimings} value.
     *
     * @param value - whether to save {@link RequestTimings | detailed timings} when creating a new mock with a checksum for this request.
     * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.saveDetailedTimings|the global setting}.
     */
    setSaveDetailedTimings(value: boolean | null): void;
    /**
     * Whether to save the input request data (headers, method, URL) when creating a new mock for this request.
     */
    readonly saveInputRequestData: boolean;
    /**
     * Sets the {@link IMock.saveInputRequestData|saveInputRequestData} value.
     *
     * @param value - whether to save the input request data (headers, method, URL) when creating a new mock for this request.
     * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.saveInputRequestData|the global setting}.
     */
    setSaveInputRequestData(value: boolean | null): void;
    /**
     * Whether to save the content of the input request body when creating a new mock for this request.
     */
    readonly saveInputRequestBody: boolean;
    /**
     * Sets the {@link IMock.saveInputRequestBody|saveInputRequestBody} value.
     *
     * @param value - whether to save the content of the input request body when creating a new mock for this request.
     * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.saveInputRequestBody|the global setting}.
     */
    setSaveInputRequestBody(value: boolean | null): void;
    /**
     * Whether to save the forwarded request data (headers, method, URL) when creating a new mock for this request.
     */
    readonly saveForwardedRequestData: boolean;
    /**
     * Sets the {@link IMock.saveForwardedRequestData|saveForwardedRequestData} value.
     *
     * @param value - whether to save the forwarded request data (headers, method, URL) when creating a new mock for this request.
     * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.saveForwardedRequestData|the global setting}.
     */
    setSaveForwardedRequestData(value: boolean | null): void;
    /**
     * Whether to save the forwarded request body when creating a new mock for this request.
     */
    readonly saveForwardedRequestBody: boolean;
    /**
     * Sets the {@link IMock.saveForwardedRequestBody|saveForwardedRequestBody} value.
     *
     * @param value - whether to save the forwarded request body when creating a new mock for this request.
     * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.saveForwardedRequestBody|the global setting}.
     */
    setSaveForwardedRequestBody(value: boolean | null): void;
    /**
     * Returns a wrapped payload built from data persisted in local files.
     * If no local file is present, returns `undefined`.
     */
    readLocalPayload(): Promise<PayloadWithOrigin<'local' | 'user'> | undefined>;
    /**
     * Take the given wrapped payload and persist it in local files.
     * @param payload - payload to persist in local files
     */
    persistPayload(payload: PayloadWithOrigin): Promise<void>;
    /**
     * Forward the client request to the remote backend and get a wrapped payload from the response in output.
     */
    fetchPayload(): Promise<RemotePayload>;
    /**
     * Create a wrapped payload (with `user` origin) from the given payload data.
     * @param payload - payload data
     */
    createPayload(payload: Payload): PayloadWithOrigin<'user'>;
    /**
     * Sets the current local payload, with a custom one you would have created.
     * @param payload - payload to set
     */
    setPayload(payload: PayloadWithOrigin<'local' | 'user'>): void;
    /**
     * Combines {@link IMock.fetchPayload|fetchPayload} and {@link IMock.persistPayload|persistPayload}
     * and returns the wrapped payload.
     */
    downloadPayload(): Promise<RemotePayload>;
    /**
     * Returns the wrapped local payload using {@link IMock.readLocalPayload|readLocalPayload} if it exists,
     * otherwise use {@link IMock.downloadPayload|downloadPayload} and returns this wrapped payload.
     */
    readOrDownloadPayload(): Promise<PayloadWithOrigin<'local' | 'user'> | RemotePayload>;
    /**
     * Returns the wrapped local payload using {@link IMock.readLocalPayload|readLocalPayload} if it exists,
     * otherwise use {@link IMock.fetchPayload|fetchPayload} and returns this wrapped payload.
     */
    readOrFetchPayload(): Promise<PayloadWithOrigin<'local' | 'user'> | RemotePayload>;
    /**
     * As soon as response is filled with a payload, this property holds the reference to that
     * payload's wrapper. The wrapper is useful here to know where the payload comes from.
     * Before that, this property is `undefined`.
     */
    sourcePayload: PayloadWithOrigin | undefined;
    /**
     * Use data present in given wrapped payload to fill in the response.
     * @param payload - payload to use to fill the response.
     *
     * @remarks
     *
     * This method changes {@link IMock.sourcePayload|sourcePayload}.
     * It does nothing if {@link IMock.sourcePayload|sourcePayload} is already set.
     */
    fillResponseFromPayload(payload: PayloadWithOrigin): void;
    /**
     * Depending on the {@link IMock.mode|mode}, gets the payload (remote / local / default)
     * and uses {@link IMock.fillResponseFromPayload|fillResponseFromPayload} with that payload.
     * If {@link IMock.mode|mode} is `manual`, does nothing.
     */
    getPayloadAndFillResponse(): Promise<void>;
    /**
     * Combines {@link IMock.readLocalPayload|readLocalPayload} and {@link IMock.fillResponseFromPayload|fillResponseFromPayload} if there is a
     * local payload then returns `true`, otherwise does nothing and return `false`.
     */
    readLocalPayloadAndFillResponse(): Promise<boolean>;
    /**
     * Sends the response back to the client, with the previously specified delay
     * if the payload origin is not `remote`.
     */
    sendResponse(): Promise<void>;
    /**
     * Combines {@link IMock.getPayloadAndFillResponse|getPayloadAndFillResponse} and {@link IMock.sendResponse|sendResponse}.
     *
     * @remarks
     *
     * If {@link IMock.mode|mode} is `manual`, this method does nothing.
     * It also uses a private guard to make sure it is executed only once.
     * Therefore, if you call it from the {@link ConfigurationSpec.hook|hook} method, the automatic call made for you after the
     * hook execution will actually not do anything (and the same if you call it yourself multiple times).
     */
    process(): Promise<void>;
}

/**
 * Base interface used in {@link ChecksumArgs} for each piece of data that can be included or not in the hash computed
 * by the {@link IMock.checksum|checksum} method.
 *
 * @public
 */
export declare interface IncludableSpec {
    /**
     * Whether to include this piece of data in the hash. It is `true` by default (if an object is passed).
     */
    include?: boolean;
}

/**
 * A handier wrapper around a CONNECT request
 *
 * @public
 */
export declare interface IProxyConnectAPI {
    /**
     * The original Node.js object representing the request
     */
    readonly request: IncomingMessage | Http2ServerRequest;
    /**
     * The underlying socket
     */
    readonly socket: Socket | ServerHttp2Stream;
    /**
     * The connections stack
     */
    readonly connectionsStack: readonly Readonly<Connection>[];
    /**
     * The last connection in {@link IProxyConnectAPI.connectionsStack|connectionsStack}
     */
    readonly connection: Readonly<Connection>;
    /**
     * The target hostname in the CONNECT request
     */
    readonly hostname: string;
    /**
     * The target port in the CONNECT request
     */
    readonly port: number;
    /**
     * The destination hostname that will be used in `forward` mode.
     * By default, it is equal to {@link IProxyConnectAPI.hostname|hostname}.
     * Can be changed with {@link IProxyConnectAPI.setDestination|setDestination}.
     */
    readonly destinationHostname: string;
    /**
     * The destination port that will be used in `forward` mode.
     * By default, it is equal to {@link IProxyConnectAPI.port|port}.
     * Can be changed with {@link IProxyConnectAPI.setDestination|setDestination}.
     */
    readonly destinationPort: number;
    /**
     * Sets the destination {@link IProxyConnectAPI.destinationHostname|hostname} and {@link IProxyConnectAPI.destinationPort|port}
     * that will be used when the {@link IProxyConnectAPI.process|process} method is called.
     * Also changes the {@link IProxyConnectAPI.mode|mode} to `forward`.
     * @param hostname - Destination hostname
     * @param port - Destination port
     */
    setDestination(hostname: string, port: number): void;
    /**
     * The currently selected mode, configured either by a call to {@link IProxyConnectAPI.setMode|setMode}
     * or by {@link CLIConfigurationSpec.proxyConnectMode|the global setting}
     */
    readonly mode: ProxyConnectMode;
    /**
     * Changes the {@link IProxyConnectAPI.mode|mode} that will be used when the {@link IProxyConnectAPI.process|process} method is called.
     * @param mode - mode to set
     */
    setMode(mode: ProxyConnectMode): void;
    /**
     * Processes the socket according to the mode stored in {@link IProxyConnectAPI.mode|mode}. This method is called automatically when the
     * {@link ConfigurationSpec.onProxyConnect|onProxyConnect} function finishes, but it can also be called manually before.
     */
    process(): void;
}

/**
 * A handier wrapper around a server response
 *
 * @public
 */
export declare interface IResponse {
    /**
     * The original Node.js object representing the response
     */
    readonly original: ServerResponse | Http2ServerResponse;
    /**
     * An object `{code, message}`, where each property is optional.
     * If `code` is never given, a default value of `200` is applied.
     */
    status: Partial<Readonly<Status>> | null;
    /**
     * Whether the {@link IResponse.body|body} field should be serialized into JSON (and `content-type` header should be set to `application/json`).
     *
     * @remarks
     * When not explicitly set, the returned value will still be true
     * if the `body` value is not a string, not a `Buffer`, and not `null` either.
     */
    json: boolean;
    /**
     * The body of the response.
     *
     * @remarks
     * If `json` is explicitly set to `true`, it will be serialized into JSON (and `content-type` header will be set to `application/json`).
     * It will also be if `json` is not explicitly set but the `body` value is not a string, not a `Buffer`, and not `null` either.
     * After that, the result will eventually be converted to a `Buffer` to be sent.
     */
    body: any;
    /**
     * A convenient method to set the {@link IResponse.body|body} value and
     * set {@link IResponse.json|json} to `true`.
     * @param data - json object to use as the response body
     */
    setData(data: any): void;
    /**
     * The currently set headers.
     * Use {@link IResponse.setHeaders|setHeaders} to change them.
     */
    readonly headers: Readonly<IncomingHttpHeaders>;
    /**
     * Merge given `headers` map with the previously set headers (initial set is an empty map).
     * @param headers - Headers to set. Each header value can be a number, a string, or an array of strings. Put a `null` value to suppress a header
     */
    setHeaders(headers?: Readonly<IncomingHttpHeaders>): Readonly<IncomingHttpHeaders>;
    /**
     * Sends the response, applying some data previously specified but not set yet
     */
    send(): Promise<void>;
}

/**
 * Type used in {@link ChecksumArgs} for each piece of data that has a map structure, such as the query and headers,
 * to specify if and how they are included in the hash computed by the {@link IMock.checksum|checksum} method.
 *
 * @remarks
 *
 * This can be an object with the following properties:
 *
 * - `include`: `true` or `false` as defined in {@link IncludableSpec.include|IncludableSpec}
 *
 * - `filter`: a function as defined in {@link FilterableSpec.filter|FilterableSpec}. Note that if filter is provided, the other options below are ignored.
 *
 * - `caseSensitive`: whether keys should be treated case sensitive or not. `true` by default. When set to `false`, the output object contains lower cased keys.
 *
 * - `keys`: a list of keys to keep if in `whitelist` mode or to reject if in `blacklist` mode. If `caseSensitive` is `false`, comparison of keys is not case sensitive.
 * If `keys` is not specified, all keys are included by default.
 *
 * - `mode`: `whitelist` (default) or `blacklist`
 *
 * @public
 */
export declare type ListOrFilter = FilterableSpec<Record<string, any>, any> | (IncludableSpec & {
    /**
     * Configures whether keys are case sensitive (i.e. whether keys differing only with the case, such as `a` and `A`, are considered different).
     * If keys are not case sensitive, their case will be changed to lower case before being hashed or being compared with the provided whitelist or blacklist.
     * By default, keys are considered case sensitive for the query and case insensitive for the headers.
     */
    caseSensitive?: boolean;
} & ({} | {
    /**
     * Configures whether the list of keys is
     * a `whitelist` (specifying explicitly all the items to include, any other item being excluded)
     * or a `blacklist` (specifying explicitly all the items to exclude, any other item being included).
     * Defaults to `whitelist`.
     */
    mode?: 'whitelist' | 'blacklist';
    /**
     * The list of items to either include or exclude depending on the mode property.
     */
    keys: string[];
}));

/**
 * The data representing the mock, which is persisted and used for serving the mock
 *
 * @public
 */
export declare interface MockData {
    /**
     * Http version of the server when the mock was recorded. Will most likely be '1.1' or perhaps '1.0'.
     * It is not used when replaying responses.
     */
    readonly httpVersion?: string;
    /**
     * Recorded headers to be served back, without the ignored ones.
     */
    readonly headers?: Readonly<IncomingHttpHeaders>;
    /**
     * Ignored headers, which are recorded headers that should not be served back.
     * In practice, this is mainly the `content-length` header (because the `content-length` header that is
     * actually served back is computed based on the actual data to send).
     */
    readonly ignoredHeaders?: Readonly<IncomingHttpHeaders>;
    /**
     * The name of the local file containing the body content (needed since the name is dynamic)
     */
    readonly bodyFileName: string;
    /**
     * HTTP status.
     */
    readonly status: Readonly<Status>;
    /**
     * Time used by the server to process the request.
     * It is used to simulate the real processing time when mocking the server if the {@link CLIConfigurationSpec.delay|delay} is set to `recorded`.
     */
    readonly time: number;
    /**
     * Detailed timings recorded during the request.
     */
    readonly timings?: RequestTimings;
    /**
     * Timestamp when the payload was created.
     */
    readonly creationDateTime?: Date;
}

/**
 * Configuration options, including the root folder used to resolve
 * relative paths and the current global configuration.
 * @public
 */
export declare interface MockingOptions {
    /** The root folder from which to resolve given relative paths */
    readonly root: string;
    /** The current global user configuration */
    readonly userConfiguration: IMergedConfiguration;
}

/**
 * Specifies the mocks format to use. It can be defined globally through
 * the {@link CLIConfigurationSpec.mocksFormat|mocksFormat} setting
 * or per-request from the {@link ConfigurationSpec.hook|hook} method through
 * {@link IMock.setMocksFormat|setMocksFormat}.
 *
 * @remarks
 *
 * Here are the two possible formats:
 *
 * - the `folder` format is specific to kassette and stores each request with its response in
 * one folder containing up to 7 files:
 * `data.json` (headers, status code and message of the response, as specified in {@link MockData}),
 * `body.[ext]` (content of the body of the backend response),
 * `input-request.json` (headers, method, URL and body file name of the input request, from client to proxy, for debug),
 * `input-request-body.[ext]` (content of the body of the input request),
 * `forwarded-request.json` (headers, method, URL, whether body was eventually a string or a Buffer and body file name
 * of the forwarded request, from proxy to backend, for debug),
 * `forwarded-request-body.[ext]` (the content of the body of the forwarded request),
 * `checksum` (if a checksum was computed, the content generated to compute it).
 * `[ext]` is an extension computed based on the actual type of the content in the file.
 *
 * - the `har` {@link http://www.softwareishard.com/blog/har-12-spec | format } is supported
 * {@link http://www.softwareishard.com/blog/har-adopters/ | by several other tools} and can store
 * multiple requests with their responses in a single (json-based) file. In this file, each
 * request/response couple follows the structure specified in {@link HarFormatEntry}.
 *
 * @public
 */
export declare type MocksFormat = 'folder' | 'har';

/**
 * The main working mode of the proxy. It can be defined globally through
 * the {@link CLIConfigurationSpec.mode|mode} setting
 * or per-request from the {@link ConfigurationSpec.hook|hook} method through
 * {@link IMock.setMode|setMode}.
 *
 * @remarks
 *
 * The mode drives how {@link IMock.getPayloadAndFillResponse|getPayloadAndFillResponse} and {@link IMock.process|process}
 * will behave. Here are the possible modes:
 *
 * - `manual`: don't do anything, leaving the responsibility to the user to call proper APIs to manage local files and/or
 * backend querying, and response filling
 *
 * - `remote`: forward the request to the remote backend and never touch the local mock
 *
 * - `download`: get payload from remote backend by forwarding request, create the local mock from this payload, and fill
 * the response with it
 *
 * - `local_or_remote`: if local mock exists, read it and fill the response with it, if local mock doesn't exist, do as for `remote` mode
 *
 * - `local_or_download`: if local mock exists, read it and fill the response with it, if local mock doesn't exist, do as for `download` mode
 *
 * - `local`: if local mock exists, read it and fill the response with it, if local mock doesn't exist, create a minimal payload with a 404 status
 * code, do not persist it and fill the response with it
 *
 * @public
 */
export declare type Mode = 'local' | 'remote' | 'download' | 'local_or_remote' | 'local_or_download' | 'manual';

/**
 * The payload represents the content of an HTTP response from the backend, no matter if it actually comes from it or if it was created manually.
 *
 * @remarks
 *
 * A payload is often wrapped in {@link PayloadWithOrigin}. To create the wrapped payload, you can use {@link IMock.createPayload|createPayload}.
 *
 * From the wrapped payload, response to the client can be filled with {@link IMock.fillResponseFromPayload|fillResponseFromPayload}.
 *
 * The payload can also be persisted and read, to avoid contacting the backend later on.
 *
 * @public
 */
export declare interface Payload {
    /**
     * Data such as http status and headers, response delay.
     */
    data: MockData;
    /**
     * Body of the HTTP response.
     */
    body: Buffer | string | null;
}

/**
 * Origin of the payload.
 *
 * @remarks
 *
 * Here are the possible values:
 *
 * - `local`: if the payload was read from local mock
 *
 * - `remote`: if the payload was fetched from the remote backend by forwarding the request
 *
 * - `user`: if the payload has been created from the user, manually using {@link IMock.createPayload|createPayload}
 *
 * - `proxy`: if the payload has been created from kassette itself, especially for `404 Not found` errors (in `local` mode)
 * and `502 Bad Gateway` errors (when kassette cannot reach the remote server)
 *
 * @public
 */
export declare type PayloadOrigin = 'local' | 'proxy' | 'remote' | 'user';

/**
 * Contains the payload along with its origin.
 * @public
 */
export declare interface PayloadWithOrigin<Origin extends PayloadOrigin = PayloadOrigin> {
    /**
     * Origin of the payload.
     */
    origin: Origin;
    /**
     * Content of the payload.
     */
    payload: Payload;
}

/**
 * The mode describing how to process `CONNECT` requests. It can be defined globally through
 * the {@link CLIConfigurationSpec.proxyConnectMode|proxyConnectMode} setting
 * or per-request from the {@link ConfigurationSpec.onProxyConnect|onProxyConnect} method through
 * {@link IProxyConnectAPI.setMode|setMode}.
 *
 * @remarks
 *
 * Here are the possible modes for `CONNECT` requests:
 *
 * - `intercept`: kassette answers with `HTTP/1.1 200 Connection established` and pretends to be the target server. If the browser then makes http or https requests on the socket after this `CONNECT` request, they will be processed by kassette and pass through the {@link ConfigurationSpec.hook|hook} method (if any). That's the default mode.
 *
 * - `forward`: kassette blindly connects to the remote destination {@link IProxyConnectAPI.hostname|hostname} and {@link IProxyConnectAPI.port|port} specified in the `CONNECT` request and forwards all data in both directions. This is what a normal proxy server is supposed to do. The destination hostname and port can optionally be modified in the {@link ConfigurationSpec.onProxyConnect|onProxyConnect} method through the {@link IProxyConnectAPI.setDestination|setDestination} method.
 *
 * - `close`: kassette simply closes the underlying socket. This is what servers which do not support the `CONNECT` method do.
 *
 * - `manual`: kassette does nothing special with the socket, leaving it in its current state. This setting allows to use any custom logic in the {@link ConfigurationSpec.onProxyConnect|onProxyConnect} callback. It only makes sense if the {@link ConfigurationSpec.onProxyConnect|onProxyConnect} callback is implemented, otherwise the browser will wait indefinitely for an answer.
 *
 * @public
 */
export declare type ProxyConnectMode = 'close' | 'intercept' | 'forward' | 'manual';

/**
 * A single value or a virtually unlimitedly nested array of this type of value
 *
 * @public
 */
export declare type RecursiveArray<T> = T | Array<RecursiveArray<T>>;

/**
 * Remote payload and the request that was made to get it.
 * @public
 */
export declare interface RemotePayload extends PayloadWithOrigin<'remote'> {
    /**
     * Request used to get this remote payload.
     */
    requestOptions: RequestPayload;
}

/**
 * Content of an HTTP request.
 * @public
 */
export declare interface RequestPayload {
    /**
     * HTTP url
     */
    url: string;
    /**
     * HTTP method
     */
    method: string;
    /**
     * HTTP headers
     */
    headers: IncomingHttpHeaders;
    /**
     * HTTP request body
     */
    body?: string | Buffer;
}

/**
 * Details about the time spent for each phase of a request-response round trip. All times are specified in milliseconds.
 *
 * @public
 */
export declare interface RequestTimings {
    /**
     * Time spent in a queue waiting for a network connection.
     * Can be -1 if the timing does not apply to the current request.
     */
    blocked?: number;
    /**
     * The time required to resolve a host name.
     * Can be -1 if the timing does not apply to the current request.
     */
    dns?: number;
    /**
     * Time required to create TCP connection.
     * Can be -1 if the timing does not apply to the current request.
     */
    connect?: number;
    /**
     * Time required to send HTTP request to the server.
     */
    send?: number;
    /**
     * Time waiting for a response from the server.
     */
    wait?: number;
    /**
     * Time required to read entire response from the server.
     */
    receive?: number;
    /**
     * Time required for SSL/TLS negotiation.
     * This time is also included in the {@link RequestTimings.connect|RequestTimings.connect} field.
     * Can be -1 if the timing does not apply to the current request.
     */
    ssl?: number;
}

/**
 * Launch the proxy programmatically.
 *
 * @param options - kassette configuration options
 * @returns a callback that can be used to shutdown the proxy, calling the {@link ConfigurationSpec.onExit|onExit} callback defined in configuration (if provided).
 *
 * @public
 */
export declare function runFromAPI(options: APIOptions): Promise<() => void>;

/* Excluded from this release type: runFromCLI */

/**
 * The response status
 *
 * @public
 */
export declare interface Status {
    /** The status code */
    code: number;
    /** The status message */
    message: string;
}

export { }
