import { ClassType, ExtractClassType } from '@deepkit/core';
import { ConfigLoader, ServiceContainer } from './service-container.js';
import { ConfigureProviderOptions, InjectorContext, ResolveToken, Scope, Token } from '@deepkit/injector';
import { AppModule, RootModuleDefinition } from './module.js';
import { DataEventToken, DispatchArguments, EventDispatcherDispatchType, EventListenerCallback, EventToken } from '@deepkit/event';
import { ReceiveType, ReflectionClass } from '@deepkit/type';
export declare function setPartialConfig(target: {
    [name: string]: any;
}, partial: {
    [name: string]: any;
}, incomingPath?: string): void;
type EnvNamingStrategy = 'same' | 'upper' | 'lower' | ((name: string) => string | 'same' | 'upper' | 'lower' | undefined);
/**
 * Options for configuring an instance of the EnvConfigLoader
 */
interface EnvConfigOptions {
    /**
     * A path or paths to optional .env files that will be processed and mapped to app/module config
     */
    envFilePath?: string | string[];
    /**
     * A naming strategy for converting env variables to app/module config. Defaults to 'upper'.
     * For example, allows converting DB_HOST to dbHost
     */
    namingStrategy?: EnvNamingStrategy;
    /**
     * A prefix for environment variables that helps to avoid potential collisions
     * By default this will be set to APP_
     *
     * Eg.
     * APP_DATABASE_URL="mongodb://localhost/mydb" will be mapped to databaseUrl when using the upper
     * naming strategy
     *
     */
    prefix?: string;
}
declare class EnvConfigLoader {
    private readonly prefix;
    private readonly envFilePaths;
    private readonly namingStrategy;
    constructor(options?: EnvConfigOptions);
    load(module: AppModule<any>, config: {
        [p: string]: any;
    }, schema: ReflectionClass<any>): void;
}
export declare class RootAppModule<T extends RootModuleDefinition> extends AppModule<T> {
}
export interface AppEvent {
    /**
     * The command that is about to be executed.
     */
    command: string;
    parameters: {
        [name: string]: any;
    };
    /**
     * Scoped 'cli' injector context.
     */
    injector: InjectorContext;
}
export interface AppExecutedEvent extends AppEvent {
    exitCode: number;
}
export interface AppErrorEvent extends AppEvent {
    error: Error;
}
/**
 * When a CLI command is about to be executed, this event is emitted.
 *
 * This is different to @deepkit/framework's onBootstrap event, which is only executed
 * when the server:start is execute. This event is executed for every CLI command (including server:start).
 */
export declare const onAppExecute: DataEventToken<AppEvent>;
/**
 * When a CLI command is successfully executed, this event is emitted.
 */
export declare const onAppExecuted: DataEventToken<AppExecutedEvent>;
/**
 * When a CLI command failed to execute, this event is emitted.
 */
export declare const onAppError: DataEventToken<AppErrorEvent>;
/**
 * When the application is about to shut down, this event is emitted.
 * This is always executed, even when an error occurred. So it's a good place to clean up.
 */
export declare const onAppShutdown: DataEventToken<AppEvent>;
/**
 * This is the smallest available application abstraction in Deepkit.
 *
 * It is based on a module and executes registered CLI controllers in `execute`.
 *
 * @deepkit/framework extends that with a more powerful Application class, that contains also HTTP and RPC controllers.
 *
 * You can use this class for more integrated unit-tests.
 */
export declare class App<T extends RootModuleDefinition> {
    protected envConfigLoader?: EnvConfigLoader;
    readonly serviceContainer: ServiceContainer;
    appModule: AppModule<ExtractClassType<T['config']>>;
    constructor(appModuleOptions: T, serviceContainer?: ServiceContainer, appModule?: AppModule<any>);
    static fromModule<T extends RootModuleDefinition>(module: AppModule<T>): App<T>;
    /**
     * Allows to change the module after the configuration has been loaded, right before the service container is built.
     *
     * This enables you to change the module or its imports depending on the configuration the last time before their services are built.
     *
     * At this point no services can be requested as the service container was not built.
     */
    setup(...args: Parameters<this['appModule']['setup']>): this;
    /**
     * Allows to call services before the application bootstraps.
     *
     * This enables you to configure modules and request their services.
     */
    use(setup: (...args: any[]) => void): this;
    /**
     * Calls a function immediately and resolves all parameters using the
     * current service container.
     */
    call<T>(fn: (...args: any[]) => T, module?: AppModule<any>): T;
    command(name: string | ((...args: any[]) => any), callback?: (...args: any[]) => any): this;
    addConfigLoader(loader: ConfigLoader): this;
    configure(config: Partial<ExtractClassType<T['config']>>): this;
    /**
     * Register a new event listener for given token.
     *
     * order: The lower the order, the sooner the listener is called. Default is 0.
     */
    listen<T extends EventToken<any>>(eventToken: T, callback: EventListenerCallback<T>, order?: number): this;
    dispatch<T extends EventToken<any>>(eventToken: T, ...args: DispatchArguments<T>): EventDispatcherDispatchType<T>;
    /**
     * Loads environment variables and optionally reads from .env files in order to find matching configuration options
     * in your application and modules in order to set their values.
     *
     * Prefixing ENV variables is encouraged to avoid collisions and by default a prefix of APP_ is used
     * Example:
     *
     * APP_databaseUrl="mongodb://localhost/mydb"
     *
     * new App({}).loadConfigFromEnvVariables('APP_').run();
     *
     *
     * `envFilePath` can be either an absolute or relative path. For relative paths the first
     * folder with a package.json starting from process.cwd() upwards is picked.
     *
     * So if you use 'local.env' make sure a 'local.env' file is located beside your 'package.json'.
     *
     * @param options Configuration options for retrieving configuration from env
     * @returns
     */
    loadConfigFromEnv(options?: EnvConfigOptions): this;
    /**
     * Loads a JSON encoded environment variable and applies its content to the configuration.
     *
     * Example:
     *
     * APP_CONFIG={'databaseUrl": "mongodb://localhost/mydb", "moduleA": {"foo": "bar'}}
     *
     * new App().run().loadConfigFromEnvVariable('APP_CONFIG').run();
     */
    loadConfigFromEnvVariable(variableName?: string): this;
    run(argv?: any[], bin?: string[]): Promise<void>;
    get<T>(token?: ReceiveType<T> | Token<T>, moduleOrClass?: AppModule<any> | ClassType<AppModule<any>>, scope?: Scope): ResolveToken<T>;
    getInjector<T>(moduleOrClass?: AppModule<any> | ClassType<AppModule<any>>): import("@deepkit/injector").Injector;
    getInjectorContext(): InjectorContext;
    /**
     * @see InjectorModule.configureProvider
     */
    configureProvider<T>(configure: (instance: T, ...args: any[]) => any, options?: Partial<ConfigureProviderOptions>, type?: ReceiveType<T>): this;
    execute(argv?: string[], bin?: string[] | string): Promise<number>;
}
export {};
export declare type __ΩAppEvent = any[];
export declare type __ΩAppExecutedEvent = any[];
export declare type __ΩAppErrorEvent = any[];
