/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import InternalRequestContext from "../../types/internal/classes/RequestContext";
import { HttpContext } from "../../types/implementation/contexts/http";
import { Content, ParsedBody, RatelimitInfos } from "../../types/global";
import Base from "./Base";
import { ZodResponse } from "../../types/internal";
import { z } from "zod";
import { Writable } from "stream";
export default class HttpRequestContext<Context extends Record<any, any> = {}> extends Base<Context> {
    private rawContext;
    private abort;
    constructor(context: InternalRequestContext, rawContext: HttpContext, abort: AbortSignal);
    /**
     * The Type of this Request
     * @since 5.7.0
    */ readonly type: 'http' | 'ws';
    /**
     * HTTP Status Codes Enum
     * @since 9.0.0
    */ $status: Readonly<{
        CONTINUE: 100;
        SWITCHING_PROTOCOLS: 101;
        PROCESSING: 102;
        EARLY_HINTS: 103;
        OK: 200;
        CREATED: 201;
        ACCEPTED: 202;
        NON_AUTHORATIVE_INFORMATION: 203;
        NO_CONTENT: 204;
        RESET_CONTENT: 205;
        PARTIAL_CONTENT: 206;
        MULTI_STATUS: 207;
        ALREADY_REPORTED: 208;
        IM_USED: 226;
        MULTIPLE_CHOICES: 300;
        MOVED_PERMANENTLY: 301;
        FOUND: 302;
        SEE_OTHER: 303;
        NOT_MODIFIED: 304;
        USE_PROXY: 305;
        TEMPORARY_REDIRECT: 307;
        PERMANENT_REDIRECT: 308;
        BAD_REQUEST: 400;
        UNAUTHORIZED: 401;
        PAYMENT_REQUIRED: 402;
        FORBIDDEN: 403;
        NOT_FOUND: 404;
        METHOD_NOT_ALLOWED: 405;
        NOT_ACCEPTABLE: 406;
        PROXY_AUTHENTICATION_REQUIRED: 407;
        REQUEST_TIMEOUT: 408;
        CONFLICT: 409;
        GONE: 410;
        LENGTH_REQUIRED: 411;
        PRECONDITION_FAILED: 412;
        PAYLOAD_TOO_LARGE: 413;
        URI_TOO_LONG: 414;
        UNSUPPORTED_MEDIA_TYPE: 415;
        RANGE_NOT_SATISFIABLE: 416;
        EXPECTATION_FAILED: 417;
        IM_A_TEAPOT: 418;
        MISDIRECTED_REQUEST: 421;
        UNPROCESSABLE_ENTITY: 422;
        LOCKED: 423;
        FAILED_DEPENDENCY: 424;
        TOO_EARLY: 425;
        UPGRADE_REQUIRED: 426;
        PRECONDITION_REQUIRED: 428;
        TOO_MANY_REQUESTS: 429;
        REQUEST_HEADER_FIELDS_TOO_LARGE: 431;
        UNAVAILABLE_FOR_LEGAL_REASONS: 451;
        INTERNAL_SERVER_ERROR: 500;
        NOT_IMPLEMENTED: 501;
        BAD_GATEWAY: 502;
        SERVICE_UNAVAILABLE: 503;
        GATEWAY_TIMEOUT: 504;
        HTTP_VERSION_NOT_SUPPORTED: 505;
        VARIANT_ALSO_NEGOTIATES: 506;
        INSUFFICIENT_STORAGE: 507;
        LOOP_DETECTED: 508;
        BANDWIDTH_LIMIT_EXCEEDED: 509;
        NOT_EXTENDED: 510;
        NETWORK_AUTHENTICATION_REQUIRED: 511;
    }>;
    /**
     * HTTP Abort Controller (please use to decrease server load)
     * @since 9.0.0
    */ $abort(callback?: () => void): boolean;
    /**
     * The Request Body (JSON and Urlencoding Automatically parsed if enabled)
     * @since 0.4.0
    */ body(): Promise<ParsedBody>;
    /**
     * The HTTP Body Type
     * @since 9.0.0
    */ bodyType(): Promise<'raw' | 'json' | 'url-encoded'>;
    /**
     * The Raw Request Body
     * @since 5.5.2
    */ rawBody(encoding: BufferEncoding): Promise<string>;
    /**
     * The Raw Request Body as Buffer
     * @since 8.1.4
    */ rawBodyBytes(): Promise<Buffer>;
    /**
     * Bind the Body using Zod
     *
     * This uses `.body` internally so no binary data
     * @example
     * ```
     * const [ data, error ] = await ctr.bindBody((z) => z.object({
     *   name: z.string().max(24),
     *   gender: z.union([ z.literal('male'), z.literal('female') ])
     * }))
     *
     * if (!data) return ctr.status((s) => s.BAD_REQUEST).print(error.toString())
     *
     * ctr.print('Everything valid! 👍')
     * ctr.printPart(`
     *   your name is ${data.name}
     *   and you are a ${data.gender}
     * `)
     * ```
     * @since 8.8.0
    */ bindBody<Schema extends z.ZodTypeAny>(schema: Schema | ((z: typeof import('zod')) => Schema)): Promise<ZodResponse<Schema>>;
    /**
     * HTTP WWW-Authentication Checker
     *
     * This will validate the Authorization Header using the WWW-Authentication Standard,
     * you can choose between `basic` and `digest` authentication, in most cases `digest`
     * should be used unless you are using an outdated client or want to test easily.
     * When not matching any user the method will return `null` and the request should be
     * ended with a `Status.UNAUTHORIZED` (401) status code.
     * @example
     * ```
     * const user = ctr.wwwAuth('basic', 'Access this Page.', { // Automatically adds www-authenticate header
     *   bob: '123!',
     *   rotvproHD: 'password'
     * })
     *
     * if (!user) return ctr.status(ctr.$status.UNAUTHORIZED).print('Invalid credentials')
     *
     * ctr.print(`You authenticated with user: ${user}`)
     * ```
     * @since 8.0.0
    */ wwwAuth<Users extends Record<string, string>>(type: 'basic' | 'digest', reason: string, users: Users): keyof Users | null;
    /**
     * Clear the active Ratelimit of the Client
     *
     * This Clears the currently active Ratelimit (on this endpoint) of the Client, remember:
     * you cant call this in a normal endpoint if the max hits are already reached since well...
     * they are already reached.
     * @since 8.6.0
    */ clearRateLimit(): this;
    /**
     * Skips counting the request to the Client IPs Rate limit (if there is one)
     *
     * When a specific IP makes a request to an endpoint under a ratelimit, the maxhits will be
     * increased instantly to prevent bypassing the rate limit by spamming requests faster than the host can
     * handle. When this function is called, the server removes the set hit again.
     * @since 8.6.0
    */ skipRateLimit(): this;
    /**
     * Get Infos about the current Ratelimit
     *
     * This will get all information about the currently applied ratelimit
     * to the endpoint. If none is active, will return `null`.
     * @since 8.6.0
    */ getRateLimit(): RatelimitInfos | null;
    /**
     * The Request Status to Send
     *
     * This will set the status of the request that the client will recieve, by default
     * the status will be `200`, the server will not change this value unless calling the
     * `.redirect()` method. If you want to add a custom message to the status you can provide
     * a second argument that sets that, for RFC documented codes this will automatically be
     * set but can be overridden, the mapping is provided by `http.STATUS_CODES`
     * @example
     * ```
     * ctr.status(401).print('Unauthorized')
     *
     * // or
     * ctr.status(666, 'The Devil').print('The Devil')
     *
     * // or
     * ctr.status(ctr.$status.IM_A_TEAPOT).print('Im a Teapot, mate!')
     * ```
     * @since 0.0.2
    */ status(code: number, message?: string): this;
    /**
     * Redirect a Client to another URL
     *
     * This will set the location header and the status to either to 301 or 302 depending
     * on whether the server should tell the browser that the page has permanently moved
     * or temporarily. Obviously this will only work correctly if the client supports the
     * 30x Statuses combined with the location header.
     * @example
     * ```
     * ctr.redirect('https://example.com', 'permanent') // Will redirect to that URL
     * ```
     * @since 2.8.5
    */ redirect(location: string, type?: 'temporary' | 'permanent'): this;
    /**
     * Print a Message to the Client (automatically Formatted)
     *
     * This Message will be the one actually sent to the client, nothing
     * can be "added" to the content using this function, it can only be replaced using `.print()`
     * To add content to the response body, use `.printPart()` instead.
     * @example
     * ```
     * ctr.print({
     *   message: 'this is json!'
     * })
     *
     * // content will be `{"message":"this is json!"}`
     *
     * /// or
     *
     * ctr.print({
     *   message: 'this is json!'
     * }, true)
     * // content will be `{\n  "message": "this is json!"\n}`
     *
     * /// or
     *
     * ctr.print('this is text!')
     * // content will be `this is text!`
     * ```
     * @since 0.0.2
    */ print(content: Content, prettify?: boolean): this;
    /**
     * Print a Message to the client (without resetting the previous message state)
     *
     * This will turn your response into a chunked response, this means that you cannot
     * add headers or cookies after this function has been called. This function is useful
     * if you want to add content to the response body without resetting the previous content.
     * And when you manually want to print massive amounts of data to the client without having
     * to store it in memory.
     * @example
     * ```
     * const file = fs.createReadStream('./10GB.bin')
     *
     * ctr.printChunked((print) => new Promise<void>((end) => {
     *   file.on('data', (chunk) => {
     *     file.pause()
     *     print(chunk)
     *       .then(() => file.resume())
     *   })
     *
     *   file.on('end', () => {
     *     end()
     *   })
     * }))
     * ```
     * @since 8.2.0
    */ printChunked<Callback extends ((print: (content: Content) => Promise<void>) => Promise<any>) | null>(callback: Callback): Callback extends null ? Writable : this;
    /**
     * Print the Content of a File to the Client
     *
     * This will print a file to the client using transfer encoding chunked and
     * if `addTypes` is enabled automatically add some content types based on the
     * file extension. This function wont respect any other http response body set by
     * `.print()` or any other normal print as this overwrites the custom ctx execution
     * function.
     * @example
     * ```
     * ctr.printFile('./profile.png', {
     *   addTypes: true // Automatically add Content types
     * })
     * ```
     * @since 0.6.3
    */ printFile(file: string, options?: {
        /**
         * The Name of the File (if not set, the basename of the file will be used)
         *
         * Only applied if the `content-disposition` header is not set and options.download is true
         * @default path.basename(file)
         * @since 9.1.4
        */ name?: string;
        /**
         * Whether to download the file or display it in the browser
         * @default ctr.headers.get('content-type') === 'application/octet-stream'
         * @since 9.1.4
        */ download?: boolean;
        /**
         * Whether some Content Type Headers will be added automatically
         * @default true
         * @since 2.2.0
        */ addTypes?: boolean;
        /**
         * Whether to compress this File
         * @default true
         * @since 7.9.0
        */ compress?: boolean;
    }): this;
}
