@deepkit/app
Version:
Deepkit App, CLI framework and service container
176 lines (175 loc) • 7.46 kB
TypeScript
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[];