import type { App } from './app.js';
import type { ChildLogger } from './logger.js';
import type { Plan } from './router/plan.js';
import type { ServerRequest } from './server/request.js';
import type { ServerResponse } from './server/response.js';
import type { BackendInfo, MojoAction, MojoModels, MojoRenderOptions, MojoURLOptions, ScopedNestedHelpers, SessionData, UploadOptions, ValidatorFunction } from './types.js';
import type { UserAgent } from './user-agent.js';
import type { WebSocket } from './websocket.js';
import type Path from '@mojojs/path';
import EventEmitter from 'node:events';
import { Params } from './body/params.js';
import { SafeString } from './util.js';
type WebSocketHandler = (ws: WebSocket) => void | Promise<void>;
interface ContextEvents {
    connection: (ws: WebSocket) => void;
    finish: () => void;
}
declare interface ContextEventEmitter {
    on: <T extends keyof ContextEvents>(event: T, listener: ContextEvents[T]) => this;
    emit: <T extends keyof ContextEvents>(event: T, ...args: Parameters<ContextEvents[T]>) => boolean;
}
/**
 * Context class.
 */
declare class Context extends EventEmitter implements ContextEventEmitter {
    /**
     * Application this context belongs to.
     */
    app: App;
    /**
     * Backend information for server that received the request.
     * @example
     * // Backend name (usually "server", "cgi", or "mock")
     * const {name} = ctx.backend;
     *
     * // Use low level Node.js APIs with "server" backend
     * const {res} = ctx.backend;
     * res.writeHead(200);
     * res.end('Hello World!');
     */
    backend: BackendInfo;
    /**
     * Partial content. Always returns at least an empty string, even for sections that have not been defined with
     * `ctx.contentFor()`.
     * @example
     * // Get content for "head" section
     * const head = ctx.content.head;
     */
    content: Record<string, string>;
    /**
     * Format for HTTP exceptions ("html", "json", or "txt").
     */
    exceptionFormat: string;
    /**
     * WebSocket JSON mode.
     */
    jsonMode: boolean;
    /**
     * Logger with request id.
     * @example
     * // Pass logger with context to model
     * const log = ctx.log;
     * ctx.model.users.create({name: 'kraih'}, log);
     */
    log: ChildLogger;
    /**
     * Router dispatch plan.
     */
    plan: Plan | null;
    /**
     * HTTP request information.
     * @example
     * // Extract request information
     * const id      = ctx.req.requestId;
     * const method  = ctx.req.method;
     * const baseURL = ctx.req.baseURL;
     * const url     = ctx.req.url;
     * const query   = ctx.req.query;
     * const info    = ctx.req.userinfo;
     * const agent   = ctx.req.get('User-Agent');
     * const buffer  = await ctx.req.buffer();
     * const text    = await ctx.req.text();
     * const form    = await ctx.req.form();
     * const value   = await ctx.req.json();
     * const html    = await ctx.req.html();
     * const xml     = await ctx.req.xml();
     */
    req: ServerRequest;
    /**
     * HTTP response information.
     * @example
     * // Force file download by setting a response header
     * ctx.res.set('Content-Disposition', 'attachment; filename=foo.png;');
     *
     * // Make sure response is cached correctly
     * ctx.res.set('Cache-Control', 'public, max-age=300');
     * ctx.res.headers.append('Vary', 'Accept-Encoding');
     */
    res: ServerResponse;
    /**
     * Non-persistent data storage and exchange for the current request.
     */
    stash: Record<string, any>;
    _flash: SessionData | undefined;
    _nestedHelpersCache: Record<string, ScopedNestedHelpers>;
    _params: Params | undefined;
    _session: Record<string, any> | undefined;
    _ws: WeakRef<WebSocket> | null;
    constructor(app: App, req: ServerRequest, res: ServerResponse, backend: BackendInfo);
    [EventEmitter.captureRejectionSymbol](error: Error): void;
    /**
     * Select best possible representation for resource.
     */
    accepts(allowed?: string[]): string[] | null;
    /**
     * Application config shortcut.
     * @example
     * // Longer version
     * const config = ctx.app.config;
     */
    get config(): Record<string, any>;
    /**
     * Append partial content to `ctx.content` buffers.
     * @example
     * // Add content for "head" section
     * await ctx.contentFor('head', '<link rel="icon" href="/static/favicon.ico">');
     */
    contentFor(name: string, content: string | SafeString | Promise<string | SafeString> | (() => Promise<string | SafeString>)): Promise<void>;
    /**
     * Data storage persistent only for the next request.
     * @example
     * // Show message after redirect
     * const flash = await ctx.flash();
     * flash.message = 'User created successfully!';
     * await ctx.redirectTo('show_user', {values: {id: 23}});
     */
    flash(): Promise<Record<string, any>>;
    /**
     * Handle WebSocket upgrade, used by servers.
     */
    handleUpgrade(ws: WebSocket): void;
    /**
     * Home directory shortcut.
     * @example
     * // Generate path
     * const path = ctx.home.child('views', 'foo', 'bar.html.tmpl');
     */
    get home(): Path;
    /**
     * Check if WebSocket connection has been accepted.
     */
    get isAccepted(): boolean;
    /**
     * Check if WebSocket connection has been established.
     */
    get isEstablished(): boolean;
    /**
     * Check if session is active.
     */
    get isSessionActive(): boolean;
    /**
     * Check if HTTP request is a WebSocket handshake.
     */
    get isWebSocket(): boolean;
    /**
     * Accept WebSocket connection and activate JSON mode.
     * @example
     * // Echo WebSocket messages
     * ctx.json(async ws => {
     *   for await (const data of ws) {
     *     // Add a Futurama quote to JSON objects
     *     if (typeof data === 'object') {
     *       data.quote = 'Shut up and take my money!';
     *       await ws.send(data);
     *     }
     *   }
     * });
     */
    json(fn: WebSocketHandler): this;
    /**
     * Model shortcut.
     * @example
     * // Access arbitrary model objects
     * const db = await ctx.models.pg.db();
     */
    get models(): MojoModels;
    /**
     * GET and POST parameters.
     * @example
     * // Get a specific parameter
     * const params = await ctx.params();
     * const foo = params.get('foo');
     *
     * // Ignore all empty parameters
     * const params = await ctx.params({notEmpty: true});
     */
    params(options?: UploadOptions & {
        notEmpty?: boolean;
    }): Promise<Params>;
    /**
     * Accept WebSocket connection.
     * @example
     * // Echo incoming WebSocket messages
     * ctx.plain(async ws => {
     *   for await (const message of ws) {
     *     await ws.send(`echo: ${message}`);
     *   }
     * });
     */
    plain(fn: WebSocketHandler): this;
    /**
     * Send `302` redirect response.
     * @example
     * // Moved Permanently
     * await ctx.redirect_to('some_route', {status: 301});
     */
    redirectTo(target: string, options?: MojoURLOptions & {
        status?: number;
    }): Promise<void>;
    /**
     * Render dynamic content.
     * @example
     * // Render text
     * await ctx.render({text: 'Hello World!'});
     *
     * // Render JSON
     * await ctx.render({json: {hello: 'world'}});
     *
     * // Render view "users/list.*.*" and pass it a stash value
     * await ctx.render({view: 'users/list'}, {foo: 'bar'});
     */
    render(options?: MojoRenderOptions, stash?: Record<string, any>): Promise<boolean>;
    /**
     * Try to render dynamic content to string.
     */
    renderToString(options: MojoRenderOptions, stash?: Record<string, any>): Promise<string | null>;
    /**
     * Automatically select best possible representation for resource.
     */
    respondTo(spec: Record<string, MojoAction | MojoRenderOptions>): Promise<void>;
    /**
     * Send static file.
     */
    sendFile(file: Path): Promise<void>;
    /**
     * Get JSON schema validation function.
     */
    schema(schema: Record<string, any> | string): ValidatorFunction;
    /**
     * Persistent data storage for the next few requests.
     */
    session(): Promise<SessionData>;
    /**
     * HTTP/WebSocket user-agent shortcut.
     */
    get ua(): UserAgent;
    /**
     * Generate URL for route or path.
     * @example
     * // Current URL with query parameter
     * const url = ctx.urlFor('current', {query: {foo: 'bar'}});
     *
     * // URL for route with placeholder values
     * const url = ctx.urlFor('users', {values: {id: 23}});
     *
     * // Absolute URL for path with fragment
     * const url = ctx.urlFor('/some/path', {absolute: true, fragment: 'whatever'});
     */
    urlFor(target?: string, options?: MojoURLOptions): string;
    /**
     * Generate URL for static asset.
     */
    urlForAsset(path: string, options?: MojoURLOptions): string;
    /**
     * Generate URL for static file.
     */
    urlForFile(path: string, options?: MojoURLOptions): string;
    /**
     * Generate URL for route or path and preserve the current query parameters.
     * @example
     * // Remove a specific query parameter
     * const url = ctx.urlWith('current', {query: {foo: null}});
     */
    urlWith(target?: string, options?: MojoURLOptions): string;
    /**
     * Established WebSocket connection.
     */
    get ws(): WebSocket | null;
    _urlForPath(path: string, isWebSocket: boolean, options: MojoURLOptions): string;
}
export { Context };
