import express from 'express';
import { Server } from 'http';
import { CookieParseOptions } from 'cookie-parser';
import { OptionsJson, OptionsUrlencoded } from 'body-parser';
import qs from 'qs';
import { CelosiaRequest, CelosiaRouter, CelosiaRouterOptions, JSON, ListenOptions, NoInputMiddleware } from '..';
import LoggerBase from '../LoggerBase';
export declare enum QueryParserMode {
    /**
     * Use node's `querystring` module.
     */
    Simple = 0,
    /**
     * Use `qs` module.
     */
    Extended = 1
}
export interface JSONBodyParserOptions extends OptionsJson {
    /**
     * Whether this parser is enabled.
     */
    enabled?: boolean;
}
export interface UrlencodedBodyParserOptions extends OptionsUrlencoded {
    /**
     * Whether this parser is enabled.
     */
    enabled?: boolean;
}
export interface CookieParserOptions extends CookieParseOptions {
    /**
     * Whether this parser is enabled.
     */
    enabled?: boolean;
    /**
     * Cookie signing secret(s).
     */
    secret?: string | string[];
}
export interface QueryParserOptions {
    /**
     * Whether this parser is enabled.
     */
    enabled?: boolean;
    /**
     * Mode to use when parsing query.
     */
    mode?: QueryParserMode;
    /**
     * Options passed to `qs` package for extended mode.
     */
    extendedOptions?: qs.IParseOptions<qs.BooleanOptional>;
}
export interface ResponseOptions {
    /**
     * Customize `CelosiaResponse.sendInternalServerError` response.
     */
    internalServerErrorResponse?: JSON;
}
export interface CelosiaInstanceConstructorOptions<Strict extends boolean = true> {
    strict: Strict;
    /**
     * A generator function to generate a unique id for each request. Defaults to `crypto.randomUUID`.
     */
    generateRequestId?: (request: CelosiaRequest<any, any, any, any>) => string;
    /**
     * Options for query parser.
     */
    queryParser?: QueryParserOptions;
    /**
     * Options supplied for `cookieParser`.
     */
    cookieParser?: CookieParserOptions;
    /**
     * Options supplied for `bodyParser.json`.
     */
    jsonBodyParser?: JSONBodyParserOptions;
    /**
     * Options supplied for `bodyParser.urlencoded`.
     */
    urlencodedBodyParser?: UrlencodedBodyParserOptions;
    /**
     * Options supplied for the root router.
     */
    rootRouter?: Omit<CelosiaRouterOptions, 'mergeParams'>;
    /**
     * Options for trust proxy.
     *
     * When setting to `true`, make sure the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value.
     * A string can be a single ip address, subnet, or comma separated subnets.
     * Pre-configured subnet names:
     *   `loopback` - 127.0.0.1/8, ::1/128
     *   `linklocal` - 169.254.0.0/16, fe80::/10
     *   `uniquelocal` - 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7
     *
     * An array can be passed instead of comma separated subnets.
     * When a number is used, this will use the address that is at most `n` number of hops away from the application.
     * `request.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `request.socket.remoteAddress`, i.e. there is no reverse proxy.
     *
     * A custom function which receive ip as parameter and returns boolean can be passed.
     */
    trustProxy?: boolean | string | string[] | ((ip: string) => boolean) | number;
    /**
     * Options for response.
     */
    response?: ResponseOptions;
}
declare class CelosiaInstance<Strict extends boolean> extends LoggerBase {
    protected _cachedExtensionsProxy: CelosiaJS.CelosiaInstance<Strict> | null;
    protected readonly _express: ReturnType<typeof express>;
    protected _server: Server | null;
    protected _options: CelosiaInstanceConstructorOptions<Strict>;
    protected hasErrorHandlerAdded: boolean;
    constructor(options: CelosiaInstanceConstructorOptions<Strict>);
    /**
     * Returns express instance.
     */
    get express(): import("express-serve-static-core").Express;
    /**
     * Returns the options used to initialize this instance.
     */
    get options(): CelosiaInstanceConstructorOptions<Strict>;
    /**
     * User-defined extensions method.
     * Register by using `ExtensionsRegistry.registerCelosiaInstanceExtension`.
     */
    get extensions(): CelosiaJS.CelosiaInstance<Strict>;
    get server(): Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse> | null;
    get isListening(): boolean;
    /**
     * Add a catch all error handler.
     * Must be called last after all router is registered.
     */
    addErrorHandler(): void;
    /**
     * Listen for connections.
     */
    listen(options: ListenOptions): Promise<void>;
    /**
     * Stops the server from accepting new connections and keeps existing connections.
     */
    close(): Promise<void>;
    /**
     * Use a router with a path.
     */
    useRouters(path: string, ...routers: [CelosiaRouter<Strict>, ...CelosiaRouter<Strict>[]]): this;
    /**
     * Use a router on base url.
     */
    useRouters(...routers: [CelosiaRouter<Strict>, ...CelosiaRouter<Strict>[]]): this;
    /**
     * For middlewares without any input or output
     */
    useMiddlewares(path: string, ...middlewares: [NoInputMiddleware, ...NoInputMiddleware[]]): this;
    /**
     * For middlewares without any input or output
     */
    useMiddlewares(...middlewares: [NoInputMiddleware, ...NoInputMiddleware[]]): this;
    /**
     * Generate a request id for every new request. If supplied this will use `options.generateRequestId` else it will use `crypto.randomUUID`.
     */
    generateRequestId(request: CelosiaRequest<any, any, any, any>): string;
}
export default CelosiaInstance;
