/**
 * SPDX-PackageName: kwaeri/node-kit
 * SPDX-PackageVersion: 0.4.2
 * SPDX-FileCopyrightText: © 2014 - 2022 Richard Winters <kirvedx@gmail.com> and contributors
 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR MIT
 */
/**
 * TODO: Evaluate this.
 *
 * See https://morioh.com/p/fe2b92cc38f3 for a thorough explanation;
 *
 * What were doing is using symbols from JavaScript and unique symbols from
 * Typescript, in order to leverage symbols as we would enums, whilst gaining
 * the benefit of symbols (consider the contexts)
 *
 * This is the manual way to establish what we're trying to do:
 *const DEVELOPMENT_MODE: unique symbol = Symbol( "DEVELOPMENT MODE" );
 *const PRODUCTION_MODE: unique symbol = Symbol( "PRODUCTION MODE" );
 *
 *const Modes = {
 *    DEVELOPMENT_MODE,
 *    PRODUCTION_MODE0
 *} as const;
 *
 * We had to const the enums, so that the enum values become the type of the
 * symbol, rather than the symbol values overarching type (symbol)
 *
 * And it requires a helper:
 *
 *type ValuesWithKeys<T, K extends keyof T> = T[K];
 *type Values<T> = ValuesWithKeys<T, keyof T>
 *
 * We can then use the symbols themseleves as enums in a function that accepts
 * an argument of type "Values<typeof 'enum'>"
 *
 *
 * And the syntactical sugar way of doing it allows us to forego setting enums
 * as const, nor using the helper types - by leveraging symbol keys and values
 * in the enum declaration:
 *
 *
 *const ModeEnum = {
 *  [DEVELOPMENT_MODE]: DEVELOPMENT_MODE,
 *  [PRODUCTION_MODE]: PRODUCTION_MODE
 *};
 *
 *
 *function getModeTypeWithModeKeys( mode: keyof typeof ModeEnum ) {
 *    switch( mode ) {
 *        case DEVELOPMENT_MODE:
 *            break;
 *
 *        case PRODUCTION_MODE:
 *            break;
 *    }
 *};
 */
declare const Modes: {
    readonly default: "default";
    readonly development: "development";
    readonly production: "production";
};
export declare namespace NodeKit {
    namespace App {
        namespace Configuration {
            type Database = {
                client?: string;
                host: string;
                port: string;
                db: string;
                user: string;
                password: string;
                debug: boolean;
            };
            type MailServiceAuthBits = {
                user: string;
                pass: string;
            };
            type MailOptions = {
                service: string;
                auth: MailServiceAuthBits;
            };
            type Mail = {
                fromaddress: string;
                transport: string;
                options: MailOptions;
            };
            type PortBits = {
                app: string;
                admin: string;
            };
            type Server = {
                host: string;
                port: PortBits;
            };
            type Sessions = {
                provider: string;
                type: string;
                async: boolean;
                paths: {
                    cache: string;
                };
                locations: string | string[];
            };
        }
        type Paths = {
            base: string;
            root: string;
            controller_path: string;
            model_path: string;
            view_path: string;
            asset_path: string;
            asset_provider: string;
            layout_path: string;
            theme: string;
            extension_path: string;
        };
        type OptionBits = {
            environment?: string;
            appType?: string;
            debug?: boolean;
            local: boolean;
            domain: string;
            forceAdminSSL: boolean;
            mail: Configuration.Mail;
            admin?: Paths;
            app: Paths;
            database: Configuration.Database;
            server: Configuration.Server;
            session?: App.Instance.OptionBits;
        };
        type Options = {
            [k in keyof typeof Modes]: OptionBits;
        };
        type Environment = {};
        namespace Instance {
            type UtilityBits = {
                hash_md5: any | string;
                html: any | string;
            };
            type OptionBits = {
                session: any | string;
                router: any | string;
                controller: any | string;
                driver: any | string;
                connector?: any | string;
                model: any | string;
                renderer: any | string;
                utilities: UtilityBits;
                ssr: boolean;
                xrm: boolean;
                layout: string | undefined;
            };
        }
    }
}
export declare class NodeKitError extends Error {
    message: string;
    name: string;
    constructor(message?: string, name?: string);
}
/**
 * This is the nodekit entry point. For cuteness, we've
 * decided to term it 'js', such that instantiation of
 * the platform will derive `nodekit.js()`
 */
export declare class nodekit {
    /**
     * @var configuration
     */
    configuration: NodeKit.App.OptionBits;
    /**
     * @var admin
     */
    admin: boolean;
    /**
     * @var _version
     */
    _version: string;
    /**
     * Class constructor
     *
     * @param { NodeKit.App.Options }  configuration
     *
     * @returns { nodekit }
     */
    constructor(configuration: NodeKit.App.OptionBits | NodeKit.App.Instance.OptionBits | (NodeKit.App.OptionBits & NodeKit.App.Instance.OptionBits) | NodeKit.App.Options);
    /**
     * Listen starts a server in simple (non-platform mode)
     *
     * @param { number } port The port to listen on
     * @param { string } host The IP or HOSTNAME of the host to listen from
     *
     * @returns { void }
     */
    listen(port?: number, host?: string): void;
    /**
     * Initializes the application platform
     *
     * @param { configuration } options
     *
     * @return { void }
     */
    init(options?: NodeKit.App.Instance.OptionBits, port?: number, host?: string): Promise<void>;
}
export {};
