fontcolor_theme
package

API @deepkit/app

npm install @deepkit/app

コマンドラインインターフェイス (CLI) パーサー、service container と dependency injection、event dispatcher、app module system、configuration loader を提供します。

これは Deepkit アプリケーションを作成するためのコアです。 CLI controller、HTTP controller や route、RPC controller(framework module 経由)、およびその他の services を登録できます。

詳しくは Deepkit App ドキュメント を参照してください。

Classes

App [source]
export class App<T extends RootModuleDefinition> {
    readonly serviceContainer: ServiceContainer;
    appModule: AppModule<ExtractClassType<T[]>>;
    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[][]>): 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[]>>): 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;
    async run(argv?: any[], bin?: string[]);
    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>>);
    getInjectorContext(): InjectorContext;
    /**
     * @see InjectorModule.configureProvider
     */
    configureProvider<T>(configure: (instance: T, ...args: any[]) => any, options: Partial<ConfigureProviderOptions> = {}, type?: ReceiveType<T>): this;
    async execute(argv?: string[], bin?: string[] | string): Promise<number>;
}

This is the application abstraction in Deepkit.

It is based on a module (the root module) and executes registered CLI controllers in execute.

AppModule [source]
export class AppModule<C extends InjectorModuleConfig = any> extends InjectorModule<C> {
    setupConfigs: ((module: AppModule<any>, config: any) => void)[];
    imports: AppModule<any>[];
    controllers: ClassType[];
    commands: {
        name?: string;
        callback: Function;
    }[];
    workflows: WorkflowDefinition<any>[];
    listeners: ListenerType[];
    middlewares: MiddlewareFactory[];
    uses: ((...args: any[]) => void)[];
    name: string;
    constructor(config: DeepPartial<C> = {} as DeepPartial<C>, public options: RootModuleDefinition = {}, public setups: ((module: AppModule<any>, config: any) => void)[] = [], public id: number = moduleId++);
    /**
     * When all configuration loaders have been loaded, this method is called.
     * It allows to further manipulate the module state depending on the final config.
     * Possible use-cases:
     *  - Add more providers depending on the configuration.
     *  - Change the module imports depending on the configuration.
     *  - Change provider setup via this.configureProvider<Provider>(provider => {}) depending on the configuration.
     */
    process();
    /**
     * A hook that allows to react on a registered provider in some module.
     */
    processProvider(module: AppModule<any>, token: Token, provider: ProviderWithScope);
    /**
     * A hook that allows to react on a registered controller in some module.
     */
    processController(module: AppModule<any>, config: ControllerConfig);
    /**
     * A hook that allows to react on a registered event listeners in some module.
     */
    processListener(module: AppModule<any>, listener: AddedListener);
    /**
     * After `process` and when all modules have been processed by the service container.
     * This is also after `processController` and `processProvider` have been called and the full
     * final module tree is known. Adding now new providers or modules doesn't have any effect.
     *
     * Last chance to set up the injector context, via this.setupProvider().
     */
    postProcess();
    /**
     * Renames this module instance.
     */
    rename(name: string): this;
    getListeners(): ListenerType[];
    getWorkflows(): WorkflowDefinition<any>[];
    getMiddlewares(): MiddlewareFactory[];
    getControllers(): ClassType[];
    getCommands(): {
        name?: string;
        callback: Function;
    }[];
    addCommand(name: string | undefined, callback: (...args: [
    ]) => any): this;
    addController(...controller: ClassType[]): this;
    addListener(...listener: (EventListener | ClassType)[]): this;
    addMiddleware(...middlewares: MiddlewareFactory[]): this;
    /**
     * Allows to change the module config before `setup` and bootstrap is called.
     * This is the last step right before the config is validated.
     */
    setupConfig(callback: (module: AppModule<C>, config: C) => void): this;
    /**
     * 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(callback: (module: AppModule<C>, config: C) => void): this;
    /**
     * Allows to call services before the application bootstraps.
     *
     * This enables you to configure modules and request their services.
     */
    use(callback: (...args: any[]) => void): this;
    getImports(): AppModule<any>[];
    getName(): string;
    /**
     * Sets configured values.
     */
    configure(config: Partial<C>): this;
}

The AppModule is the base class for all modules.

You can use createModule to create a new module class or extend from AppModule manually.

CliControllerRegistry [source]
export class CliControllerRegistry {
    readonly controllers: ControllerConfig[];
}
MiddlewareRegistry [source]
export class MiddlewareRegistry {
    readonly configs: MiddlewareRegistryEntry[];
}
WorkflowRegistry [source]
export class WorkflowRegistry {
    constructor(public readonly workflows: WorkflowDefinition<any>[]);
    get(name: string): WorkflowDefinition<any>;
    add(workflow: WorkflowDefinition<any>);
}
ServiceContainer [source]
export class ServiceContainer {
    readonly cliControllerRegistry;
    readonly middlewareRegistry;
    readonly workflowRegistry;
    constructor(public appModule: AppModule<any>);
    addConfigLoader(loader: ConfigLoader);
    /**
     * Builds the whole module tree, processes all providers, controllers, and listeners.
     * Makes InjectorContext available. Is usually automatically called when the injector is requested.
     */
    process();
    getInjectorContext(): InjectorContext;
    getInjector<T extends AppModule<any>>(moduleOrClass: ClassType<T> | T): Injector;
    getModule(moduleClass: ClassType<AppModule<any>>): AppModule<any>;
    /**
     * Returns all known instantiated modules.
     */
    getModules(): AppModule<any>[];
    getRootInjector(): Injector;
}

Events

onAppExecute [source]
DataEventToken<AppEvent>

When a CLI command is about to be executed, this event is emitted.

This is different to

onAppExecuted [source]
DataEventToken<AppExecutedEvent>

When a CLI command is successfully executed, this event is emitted.

onAppError [source]
DataEventToken<AppErrorEvent>

When a CLI command failed to execute, this event is emitted.

onAppShutdown [source]
DataEventToken<AppEvent>

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.

Errors

ConfigurationInvalidError [source]
export class ConfigurationInvalidError extends CustomError {
}

Functions

getBinFromEnvironment [source]
(): string[]
getArgsFromEnvironment [source]
(): string[]
parseCliArgs [source]
(args: string[], aliases?: { [name: string]: string; }): { [name: string]: boolean | string | string[]; }
executeCommand [source]
(script: string, argv: string[], eventDispatcher: EventDispatcher, logger: LoggerInterface, injector: InjectorContext, commandsConfigs: ControllerConfig[], writer?: CommandWriter): Promise<number>

bin: the binary name, e.g. ['node', 'app.ts'] argv: the arguments, e.g. ['command', '--help'] writer: a function used to write the output. Defaults to console.log.

cli [source]
ClassDecoratorResult<typeof CommandDecorator>
stringifyListener [source]
(listener: AddedListener): string

Stringifies the listener to a human-readable string.

createModuleClass [source]
<C extends InjectorModuleConfig>(options: CreateModuleDefinition & { config?: ClassType<C>; }): AppModuleClass<C>

Creates a new module class type from which you can extend.

class MyModule extends createModuleClass({}) {}

//and used like this
new App({
    imports: [new MyModule]
});
createModule [source]
<T extends CreateModuleDefinition>(options: T): AppModule<ExtractClassType<T["config"]>>

Creates a new module instance.

This is mainly used for small non-reusable modules. It's recommended to use createModuleClass and extend from it.

findParentPath [source]
(path: string, origin?: string): string | undefined

Types

Flag [source]
type Flag<Options extends {
    char?: string,
    hidden?: boolean,
    description?: string,
    prefix?: string
} = {}> = TypeAnnotation<'cli:flag', Options>;

Flag is a command line argument that is prefixed with -- and can have a value.

Command [source]
interface Command {
    execute(...args: any[]): Promise<number | void> | number | void;
}
MiddlewareFactory [source]
type MiddlewareFactory = () => MiddlewareConfig;
ExportType [source]
type ExportType = AbstractClassType | string | AppModule<any> | Type | NormalizedProvider;
AddedListener [source]
interface AddedListener {
    eventToken: EventToken;
    reflection: ReflectionMethod | ReflectionFunction;
    module?: InjectorModule;
    classType?: ClassType;
    methodName?: string;
    order: number;
}
ModuleDefinition [source]
interface ModuleDefinition {
    /**
     * The name of the module. This is used in the configuration system.
     * It allows you to have multiple instances of the same module with different configurations
     * loaded from a configuration loader (e.g. env variables).
     *
     * The lowercase alphanumeric module name.
     * Choose a short unique name for best usability. If you don't have any configuration
     * or if you want that your configuration options are available without prefix, you can keep this undefined.
     */
    name?: string;

    /**
     * Providers.
     */
    providers?: (ProviderWithScope | ProviderWithScope[])[];

    /**
     * Export providers (its token `provide` value) or modules you imported first.
     */
    exports?: ExportType[];

    /**
     * Module bootstrap class|function.
     * This class is instantiated or function executed on bootstrap and can set up various injected services.
     */
    bootstrap?: ClassType | Function;

    /**
     * Configuration definition.
     *
     * @example
     * ```typescript
     *
     * class MyModuleConfig {
     *     debug: boolean = false;
     * });
     *
     * class MyModule extends createModuleClass({
     *     config: MyModuleConfig
     * });
     * ```
     */
    config?: ClassType;

    /**
     * CLI controllers.
     */
    controllers?: ClassType[];

    /**
     * Register created workflows. This allows the Framework Debugger to collect
     * debug information and display the graph of your workflow.
     */
    workflows?: WorkflowDefinition<any>[];

    /**
     * Event listeners.
     *
     * @example with simple functions
     * ```typescript
     * {
     *     listeners: [
     *         onEvent.listen((event: MyEvent) => {console.log('event triggered', event);}),
     *     ]
     * }
     * ```
     *
     * @example with services
     * ```typescript
     *
     * class MyListener {
     *     @eventDispatcher.listen(onEvent)
     *     onEvent(event: typeof onEvent['type']) {
     *         console.log('event triggered', event);
     *     }
     * }
     *
     * {
     *     listeners: [
     *         MyListener,
     *     ]
     * }
     * ```
     */
    listeners?: (EventListener | ClassType)[];

    /**
     * HTTP middlewares.
     */
    middlewares?: MiddlewareFactory[];
}
CreateModuleDefinition [source]
interface CreateModuleDefinition extends ModuleDefinition {
    /**
     * Whether all services should be moved to the root module/application.
     */
    forRoot?: true;

    /**
     * Modules can not import other modules in the module definitions.
     * Use instead:
     *
     * ```typescript
     * class MyModule extends createModuleClass({}) {
     *     imports = [new AnotherModule];
     * }
     * ```
     *
     * or
     *
     * ```typescript
     * class MyModule extends createModuleClass({}) {
     *     process() {
     *         this.addModuleImport(new AnotherModule);
     *     }
     * }
     * ```
     *
     * or switch to functional modules
     *
     * ```typescript
     * function myModule(module: AppModule) {
     *     module.addModuleImport(new AnotherModule);
     * }
     * ```
     */
    imports?: undefined;
}
FunctionalModule [source]
type FunctionalModule = (module: AppModule<any>) => void;
RootModuleDefinition [source]
interface RootModuleDefinition extends ModuleDefinition {
    /**
     * Import another module.
     */
    imports?: (AppModule<any> | FunctionalModule)[];
}
ListenerType [source]
type ListenerType = EventListener | ClassType;
ControllerConfig [source]
interface ControllerConfig {
    controller?: ClassType,
    name?: string;
    for?: string; //e.g. cli
    callback?: Function;
    module: InjectorModule;
}
MiddlewareRegistryEntry [source]
type MiddlewareRegistryEntry = { config: MiddlewareConfig, module: AppModule<any> };
ConfigLoader [source]
interface ConfigLoader {
    load(module: AppModule<any>, config: { [name: string]: any }, schema: ReflectionClass<any>): void;
}

English中文 (Chinese)한국어 (Korean)日本語 (Japanese)Deutsch (German)