import Hooks from '@poppinss/hooks';
import type { Assert } from '@japa/assert';
import Macroable from '@poppinss/macroable';
import { type SuperAgentRequest } from 'superagent';
import { ApiResponse } from './response.js';
import type { SetupHandler, RequestConfig, MultipartValue, RequestCookies, TeardownHandler, SuperAgentParser, SuperAgentSerializer, ApiRequestHooks } from './types.js';
export declare class ApiRequest extends Macroable {
    #private;
    config: RequestConfig;
    /**
     * The serializer to use for serializing request query params
     */
    static qsSerializer: SuperAgentSerializer;
    /**
     * Register/remove custom superagent parser, Parsers are used
     * to parse the incoming response
     */
    static addParser: (contentType: string, parser: SuperAgentParser) => void;
    static removeParser: (contentType: string) => void;
    /**
     * Register/remove custom superagent serializers. Serializers are used
     * to serialize the request body
     */
    static addSerializer: (contentType: string, serializer: SuperAgentSerializer) => void;
    static removeSerializer: (contentType: string) => void;
    /**
     * Specify the serializer for query strings. Serializers are used to convert
     * request querystring values to a string
     */
    static setQsSerializer: (serializer: SuperAgentSerializer) => void;
    static removeQsSerializer: () => void;
    /**
     * Reference to registered hooks
     */
    hooks: Hooks<ApiRequestHooks>;
    /**
     * The underlying super agent request
     */
    request: SuperAgentRequest;
    /**
     * Cookies to be sent with the request
     */
    cookiesJar: RequestCookies;
    constructor(config: RequestConfig, assert?: Assert);
    /**
     * Register a setup hook. Setup hooks are called before
     * making the request
     */
    setup(handler: SetupHandler): this;
    /**
     * Register a teardown hook. Teardown hooks are called after
     * making the request
     */
    teardown(handler: TeardownHandler): this;
    /**
     * Set cookie as a key-value pair to be sent to the server
     */
    cookie(key: string, value: any): this;
    /**
     * Set cookies as an object to be sent to the server
     */
    cookies(cookies: Record<string, any>): this;
    /**
     * Define request header as a key-value pair.
     *
     * @example
     * request.header('x-foo', 'bar')
     * request.header('x-foo', ['bar', 'baz'])
     */
    header(key: string, value: string | string[]): this;
    /**
     * Define request headers as an object.
     *
     * @example
     * request.headers({ 'x-foo': 'bar' })
     * request.headers({ 'x-foo': ['bar', 'baz'] })
     */
    headers(headers: Record<string, string | string[]>): this;
    /**
     * Define the field value for a multipart request.
     *
     * @note: This method makes a multipart request. See [[this.form]] to
     * make HTML style form submissions.
     *
     * @example
     * request.field('name', 'virk')
     * request.field('age', 22)
     */
    field(name: string, value: MultipartValue | MultipartValue[]): this;
    /**
     * Define fields as an object for a multipart request
     *
     * @note: This method makes a multipart request. See [[this.form]] to
     * make HTML style form submissions.
     *
     * @example
     * request.fields({'name': 'virk', age: 22})
     */
    fields(values: {
        [name: string]: MultipartValue | MultipartValue[];
    }): this;
    /**
     * Upload file for a multipart request. Either you can pass path to a
     * file, a readable stream, or a buffer
     *
     * @example
     * request.file('avatar', 'absolute/path/to/file')
     * request.file('avatar', createReadStream('./path/to/file'))
     */
    file(name: string, value: MultipartValue, options?: string | {
        filename?: string | undefined;
        contentType?: string | undefined;
    }): this;
    /**
     * Set form values. Calling this method will set the content type
     * to "application/x-www-form-urlencoded".
     *
     * @example
     * request.form({
     *   email: 'virk@adonisjs.com',
     *   password: 'secret'
     * })
     */
    form(values: string | object): this;
    /**
     * Set JSON body for the request. Calling this method will set
     * the content type to "application/json".
     *
     * @example
     * request.json({
     *   email: 'virk@adonisjs.com',
     *   password: 'secret'
     * })
     */
    json(values: string | object): this;
    /**
     * Set querystring for the request.
     *
     * @example
     * request.qs('order_by', 'id')
     * request.qs({ order_by: 'id' })
     */
    qs(key: string, value: any): this;
    qs(values: string | object): this;
    /**
     * Set timeout for the request.
     *
     * @example
     * request.timeout(5000)
     * request.timeout({ response: 5000, deadline: 60000 })
     */
    timeout(ms: number | {
        deadline?: number | undefined;
        response?: number | undefined;
    }): this;
    /**
     * Set content-type for the request
     *
     * @example
     * request.type('json')
     */
    type(value: string): this;
    /**
     * Set "accept" header in the request
     *
     * @example
     * request.accept('json')
     */
    accept(type: string): this;
    /**
     * Follow redirects from the response
     *
     * @example
     * request.redirects(3)
     */
    redirects(count: number): this;
    /**
     * Set basic auth header from user and password
     *
     * @example
     * request.basicAuth('foo@bar.com', 'secret')
     */
    basicAuth(user: string, password: string): this;
    /**
     * Pass auth bearer token as authorization header.
     *
     * @example
     * request.apiToken('tokenValue')
     */
    bearerToken(token: string): this;
    /**
     * Set the ca certificates to trust
     */
    ca(certificate: string | string[] | Buffer | Buffer[]): this;
    /**
     * Set the client certificates
     */
    cert(certificate: string | string[] | Buffer | Buffer[]): this;
    /**
     * Set the client private key(s)
     */
    privateKey(key: string | string[] | Buffer | Buffer[]): this;
    /**
     * Set the client PFX or PKCS12 encoded private key and certificate chain
     */
    pfx(key: string | string[] | Buffer | Buffer[] | {
        pfx: string | Buffer;
        passphrase: string;
    }): this;
    /**
     * Does not reject expired or invalid TLS certs. Sets internally rejectUnauthorized=true
     */
    disableTLSCerts(): this;
    /**
     * Trust broken HTTPs connections on localhost
     */
    trustLocalhost(trust?: boolean): this;
    /**
     * Dump request headers
     */
    dumpHeaders(): this;
    /**
     * Dump request cookies
     */
    dumpCookies(): this;
    /**
     * Dump request body
     */
    dumpBody(): this;
    /**
     * Dump request
     */
    dump(): this;
    /**
     * Retry a failing request. Along with the count, you can also define
     * a callback to decide how long the request should be retried.
     *
     * The max count is applied regardless of whether callback is defined
     * or not
     *
     * The following response codes are considered failing.
     * - 408
     * - 413
     * - 429
     * - 500
     * - 502
     * - 503
     * - 504
     * - 521
     * - 522
     * - 524
     *
     * The following error codes are considered failing.
     * - 'ETIMEDOUT'
     * - 'ECONNRESET'
     * - 'EADDRINUSE'
     * - 'ECONNREFUSED'
     * - 'EPIPE'
     * - 'ENOTFOUND'
     * - 'ENETUNREACH'
     * - 'EAI_AGAIN'
     */
    retry(count: number, retryUntilCallback?: (error: any, response: ApiResponse) => boolean): this;
    /**
     * Make the API request
     */
    send(): Promise<ApiResponse>;
    /**
     * Implementation of `then` for the promise API
     */
    then<TResult1 = ApiResponse, TResult2 = never>(resolve?: ((value: ApiResponse) => TResult1 | PromiseLike<TResult1>) | undefined | null, reject?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
    /**
     * Implementation of `catch` for the promise API
     */
    catch<TResult = never>(reject?: ((reason: ApiResponse) => TResult | PromiseLike<TResult>) | undefined | null): Promise<ApiResponse | TResult>;
    /**
     * Implementation of `finally` for the promise API
     */
    finally(fullfilled?: (() => void) | undefined | null): Promise<ApiResponse>;
    /**
     * Required when Promises are extended
     */
    get [Symbol.toStringTag](): string;
}
