import type { Route } from './router/route.js';
import type { AnyArguments, AppOptions, BackendInfo, UserAgentOptions, MojoAction, MojoContext, MojoModels, NestedHelpers, RouteArguments, ServerOptions, TestUserAgentOptions } from './types.js';
import { CLI } from './cli.js';
import { Hooks } from './hooks.js';
import { Logger } from './logger.js';
import { Mime } from './mime.js';
import { Renderer } from './renderer.js';
import { Router } from './router.js';
import { ServerRequest } from './server/request.js';
import { ServerResponse } from './server/response.js';
import { Session } from './session.js';
import { Static } from './static.js';
import { MockUserAgent } from './user-agent/mock.js';
import { TestUserAgent } from './user-agent/test.js';
import { UserAgent } from './user-agent.js';
import { Validator } from './validator.js';
import Path from '@mojojs/path';
type AppHook = (app: App, ...args: any[]) => any;
type ContextHook = (app: MojoContext, ...args: any[]) => any;
type Decoration = ((...args: any[]) => any) | {
    get?: () => any;
    set?: (value: any) => any;
    configurable?: boolean;
};
/**
 * Application class.
 */
export declare class App {
    /**
     * Command line interface.
     * @example
     * // Add another path to load commands from
     * app.cli.commandPaths.push(app.home.child('cli').toString());
     */
    cli: CLI;
    /**
     * Application config.
     * @example
     * // Remove value
     * delete app.config.foo;
     *
     * // Assign multiple values at once
     * Object.assign(app.config, {foo: 'test', bar: 23});
     */
    config: Record<string, any>;
    /**
     * Default stash values.
     * @example
     * // Remove value
     * delete app.defaults.foo;
     *
     * // Assign multiple values at once
     * Object.assign(app.defaults, {foo: 'test', bar: 23});
     */
    defaults: Record<string, any>;
    /**
     * Detect if the application has been imported and disable the command line interface if it has.
     */
    detectImport: boolean;
    /**
     * Format for HTTP exceptions ("html", "json", or "txt").
     * @example
     * // Change default exception format for whole application
     * app.exceptionFormat = 'json';
     */
    exceptionFormat: string;
    /**
     * Application hooks.
     * @example
     * // Run a custom hook
     * await app.hooks.runHook('my:hook', foo, bar);
     */
    hooks: Hooks;
    /**
     * Application home directory.
     * @example
     * // Portably generate path relative to home directory
     * const path = app.home.child('data', 'important.txt');
     */
    home: Path;
    /**
     * Application logger.
     * @example
     * // Log debug message
     * app.log.debug('It works');
     */
    log: Logger;
    /**
     * MIME types.
     * @example
     * // Get MIME type for extension
     * const type = app.mime.extType('txt');
     */
    mime: Mime;
    /**
     * Operating mode for application. Defaults to the value of the `NODE_ENV` environment variable or `development`.
     */
    mode: string;
    /**
     * Storage for user defined models.
     * @example
     * // Store database connection
     * app.models.pg = new Pg('postgres://127.0.0.1:5432/db');
     */
    models: MojoModels;
    /**
     * Application renderer.
     * @example
     * // Disable compression
     * app.renderer.autoCompress = false;
     *
     * // Add another "views" directory
     * app.renderer.viewPaths.push(app.home.child('views').toString());
     */
    renderer: Renderer;
    /**
     * Application router.
     * @example
     * // Add routes
     * const r = app.router;
     * r.get('/foo/bar').to('test#foo', {title: 'Hello Mojo!'});
     * r.post('/baz').to('test#baz');
     *
     * // Add another path to load controllers from
     * app.router.controllerPaths.push(app.home.child('more-controllers').toString());
     */
    router: Router;
    /**
     * Rotating secret passphrases used for signed cookies and the like.
     * @example
     * // Rotate passphrases
     * app.secrets = ['new_passw0rd', 'old_passw0rd', 'very_old_passw0rd'];
     */
    secrets: string[];
    /**
     * Encrypted cookie based session manager.
     * @example
     * // Change name of cookie used for all sessions
     * app.sessions.cookieName = 'mysession';
     *
     * // Disable SameSite feature
     * app.sessions.sameSite = 'none';
     */
    session: Session;
    /**
     * Static file server.
     * @example
     * // Add another "public" directory
     * app.static.publicPaths.push('/home/sri/public');
     *
     * // Add another "public" directory with higher precedence
     * app.static.publicPaths.unshift('/home/sri/themes/blue/public');
     */
    static: Static;
    /**
     * HTTP/WebSocket user-agent.
     * @example
     * # Perform HTTP request
     * const res = await app.ua.get('http://example.com');
     */
    ua: UserAgent;
    /**
     * JSON schema validator.
     * @example
     * // Add a named schema for later use
     * app.validator.addSchema({type: 'object', properties: {test: {type: 'number'}}}, 'testForm');
     */
    validator: Validator;
    _contextClass: any;
    _nestedHelpers: Record<string, NestedHelpers>;
    constructor(options?: AppOptions);
    /**
     * Add an application hook to extend the framework.
     * @example
     * // Run code whenever a server has been started
     * app.addAppHook('server:start', async app => {
     *   ...
     * });
     */
    addAppHook(name: string, fn: AppHook): this;
    /**
     * Add a context hook to extend the framework.
     * @example
     * // Run code after a new request has been received
     * app.addContextHook('dispatch:before', async ctx => {
     *   ...
     * });
     */
    addContextHook(name: string, fn: ContextHook): this;
    /**
     * Add a helper.
     * @example
     * // Render response with header
     * app.addHelper('renderWithHeader', async (ctx, ...args) => {
     *   ctx.res.set('X-Mojo', 'I <3 mojo.js!');
     *   await ctx.render(...args);
     * });
     *
     * // Render response with header using nested helper
     * app.addHelper('renderWith.header', async (ctx, ...args) => {
     *   ctx.res.set('X-Mojo', 'I <3 mojo.js!');
     *   await ctx.render(...args);
     * });
     */
    addHelper(name: string, fn: MojoAction): this;
    /**
     * Generate route matching any of the listed HTTP request methods or all.
     * @example
     * // Route with pattern and destination
     * app.any('/user').to('User#whatever');
     *
     * // Route with HTTP methods, pattern, restrictive placeholders and destination
     * app.any(['DELETE', 'PUT'], '/:foo', {foo: /\w+/}).to('Foo#bar');
     *
     * // Route with pattern, name and destination
     * app.any('/:foo').name('foo_route').to('Foo#bar');
     *
     * // Route with pattern, condition and destination
     * app.any('/').requires({agent: /Firefox/}).to('Foo#bar');
     *
     * // Route with pattern and a closure as destination
     * app.any('/:foo', async ctx => ctx.render({text: 'Hello World!'}));
     */
    any(...args: AnyArguments): Route;
    /**
     * Decorate context class with a method or getter/setter.
     * @example
     * // Decorate context with getter
     * app.decorateContext('helloWorld', {get: () => 'Hello World!'});
     */
    decorateContext(name: string, fn: Decoration): this;
    /**
     * Generate route matching only `DELETE` requests.
     * @example
     * // Route with destination
     * app.delete('/user').to('User#remove');
     */
    delete(...args: RouteArguments): Route;
    /**
     * Generate route matching only `GET` requests.
     * @example
     * // Route with destination
     * app.get('/user').to('User#show');
     */
    get(...args: RouteArguments): Route;
    /**
     * Handle a new incoming request, used by servers.
     */
    handleRequest(ctx: MojoContext): Promise<void>;
    /**
     * Create a context for application.
     */
    newContext(req: ServerRequest, res: ServerResponse, backend: BackendInfo): MojoContext;
    /**
     * Create a mock context for application. Very useful for testing helpers.
     * @example
     * // Use a mock context to call a helper
     * const ctx = app.newMockContext();
     * const html = ctx.assetTag('/app.js');
     */
    newMockContext(options?: {
        headers?: string[];
        method?: string;
        url?: string;
    }): MojoContext;
    /**
     * Create a new mock user-agent for application.
     */
    newMockUserAgent(options?: UserAgentOptions, serverOptions?: ServerOptions): Promise<MockUserAgent>;
    /**
     * Create a new test user-agent for application.
     * @example
     * // Test plain text endpoint
     * const ua = await app.newTestUserAgent();
     * (await ua.getOk('/')).statusIs(200).bodyIs('Hello World!');
     */
    newTestUserAgent(options?: TestUserAgentOptions, serverOptions?: ServerOptions): Promise<TestUserAgent>;
    /**
     * Your main hook into the application, it is a shortcut for the `app:start` hook and runs during application
     * startup. You can use it to perform tasks like preparing database connections.
     * @example
     * // Perform async operations on application startup
     * app.onStart(async app => {
     *   if (app.models.db === undefined) app.models.db = new SomeDatabase();
     *   await app.models.db.connect();
     * });
     */
    onStart(fn: AppHook): this;
    /**
     * The opposite of `onStart`, it is a shortcut for the `app:stop` hook and runs during application shutdown. You can
     * use it to perform tasks like closing database connections gracefully.
     * @example
     * app.onStop(async app => {
     *   await app.models.db.disconnect();
     * });
     */
    onStop(fn: AppHook): this;
    /**
     * Generate route matching only `OPTIONS` requests.
     * @example
     * // Route with destination
     * app.options('/user').to('User#overview');
     */
    options(...args: RouteArguments): Route;
    /**
     * Generate route matching only `PATCH` requests.
     * @example
     * // Route with destination
     * app.patch('/user').to('User#update');
     */
    patch(...args: RouteArguments): Route;
    /**
     * Register plugin.
     * @example
     * // Mount application under "/prefix"
     * app.plugin(mountPlugin, {app: myOtherApp, path: '/prefix'});
     *
     * // Load configuration from file
     * app.plugin(jsonConfigPlugin, {file: 'myapp.conf'});
     */
    plugin<T>(plugin: (app: App, options: Record<string, any>) => T, options?: Record<string, any>): T;
    /**
     * Generate route matching only `POST` requests.
     * @example
     * // Route with destination
     * app.post('/user').to('User#create');
     */
    post(...args: RouteArguments): Route;
    /**
     * Generate route matching only `PUT` requests.
     * @example
     * // Route with destination
     * app.put('/user').to('User#replace');
     */
    put(...args: RouteArguments): Route;
    /**
     * Start the command line interface.
     * @example
     * // Get arguments from "process.argv"
     * app.start();
     *
     * // Always start server (rarely used)
     * app.start('server', '-l', 'http://*:8080');
     */
    start(command?: string, ...args: string[]): Promise<void>;
    /**
     * Generate route for a nested route with its own intermediate destination.
     * @example
     * // Intermediate destination and prefix shared between two routes
     * const auth = app.under('/user').to('User#auth');
     * auth.get('/show').to('User#show');
     * auth.post('/create').to('User#create');
     */
    under(...args: AnyArguments): Route;
    /**
     * Warmup the cache, usually called automatically.
     */
    warmup(): Promise<void>;
    /**
     * Generate route matching only WebSocket handshake requests.
     * @example
     * // Route with destination
     * app.websocket('/echo').to('Example#echo');
     */
    websocket(...args: RouteArguments): Route;
}
export {};
