/// <reference types="node" />
/// <reference types="node" />
import { HttpRequest, HttpResponse } from "@rjweb/uws";
import Status from "../../misc/statusEnum";
import Server from "../server";
import { LocalContext } from "../../types/context";
import { Content } from "../../functions/parseContent";
import HTMLBuilder from "../HTMLBuilder";
import { Readable } from "stream";
import Base from "./Base";
export declare const toArrayBuffer: (buffer: Buffer) => ArrayBuffer;
export default class HTTPRequest<Context extends Record<any, any> = {}, Body = unknown, Path extends string = '/'> extends Base<Context, Path> {
    /**
     * Initializes a new Instance of a Web Context
     * @since 7.0.0
    */ constructor(controller: Server<any, any>, localContext: LocalContext, req: HttpRequest, res: HttpResponse, type: 'http' | 'upgrade');
    /**
     * The Type of this Request
     * @since 5.7.0
    */ readonly type: 'http' | 'upgrade';
    /**
     * The Raw HTTP Server Req Variable
     * @since 0.2.2
    */ readonly rawReq: HttpRequest;
    /**
     * The Raw HTTP Server Res Variable
     * @since 0.2.2
    */ readonly rawRes: HttpResponse;
    /**
     * The Type of the HTTP Body
     * @since 7.8.0
    */ get bodyType(): LocalContext['body']['type'];
    /**
     * The Request Body (JSON Automatically parsed if enabled)
     * @since 0.4.0
    */ get body(): Body;
    /**
     * The Raw Request Body
     * @since 5.5.2
    */ get rawBody(): string;
    /**
     * The Raw Request Body as Buffer
     * @since 8.1.4
    */ get rawBodyBytes(): Buffer;
    /**
     * 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((s) => s.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;
    /**
     * 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((c) => c.IM_A_TEAPOT).print('Im a Teapot, mate!')
     * ```
     * @since 0.0.2
    */ status(code: number | ((codes: typeof Status) => 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!'
     * }, {
     *   prettify: 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, options?: {
        /**
         * Whether to prettify output (currently just JSONs)
         * @default false
         * @since 6.2.0
        */ prettify?: boolean;
    }): this;
    /**
     * Print a Message to the client (without resetting the previous message state)
     *
     * This will add content to the current response body, if being called without `.print()`
     * before, the response body will be only this, basically the first call is the same as `.print()`.
     * this could be used when for example you want to loop over an array asynchronously without some
     * `await Promise.all(array.map(async() => ...))` voodo magic. Basically just call `.printPart()`
     * after finishing an iteration.
     * @example
     * ```
     * ctr.printPart('hi')
     * ctr.printPart(' ')
     * ctr.printPart('mate')
     *
     * // content will be `hi mate`
     * ```
     * @since 8.2.0
    */ printPart(content: Content, options?: {
        /**
         * Whether to prettify end output (currently just JSONs)
         * @default false
         * @since 8.2.0
        */ prettify?: boolean;
    }): this;
    /**
     * Print a Message made using the HTML Builder & Formatter
     *
     * This will set the http response body to an automatically generated html template
     * defined by the callback function. This also allows some quality of life features such
     * as `.every()` to change your html every x miliseconds without writing the frontend js
     * manually.
     * @example
     * ```
     * const userInput = '<script>alert("xss!!!!")</script>'
     *
     * ctr.printHTML((html) => html
     *   .t('head', {}, (t) => t
     *     .t('title', {}, (t) => t
     *       .escaped(userInput) // no xss attack because of .escaped()
     *     )
     *   )
     *   .t('body', {}, (t) => t
     *     .t(
     *       'h1',
     *       { style: { color: 'red' } },
     *       (t) => t
     *         .raw('Hello world matey!')
     *     )
     *   )
     * )
     * ```
     * @since 6.6.0
    */ printHTML(callback: (html: HTMLBuilder) => HTMLBuilder, options?: {
        /**
         * The HTML Language to show at the top html tag
         * @default "en"
         * @since 6.6.0
        */ htmlLanguage?: string;
    }): 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?: {
        /**
         * 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;
        /**
         * Whether to Cache the sent Files after accessed once (only renew after restart)
         * @default false
         * @since 2.2.0
        */ cache?: boolean;
    }): this;
    /**
     * Print the `data` event of a Stream to the Client
     *
     * This will print the `data` event of a stream to the client and makes the connection
     * stay alive until the stream is closed or the client disconnects. Best usecase of this is
     * probably Server Side Events for something like a front page as websockets can be quite
     * expensive. Remember to set the correct content type header when doing that.
     * @example
     * ```
     * const fileStream = fs.createReadStream('./profile.png')
     * ctr.printStream(fileStream)
     *
     * // in this case though just use ctr.printFile since it does exactly this
     * ```
     * @since 4.3.0
    */ printStream(stream: Readable, options?: {
        /**
         * Whether to end the Request after the Stream finishes
         * @default true
         * @since 4.3.5
        */ endRequest?: boolean;
        /**
         * Whether to prettify output (currently just JSONs)
         * @default false
         * @since 7.4.0
        */ prettify?: boolean;
        /**
         * Whether to Destroy the Stream when the Request gets aborted
         * @default true
         * @since 4.3.5
        */ destroyAbort?: boolean;
    }): this;
}
