diff --git a/src/modules/core/helpers/app.ts b/src/modules/core/helpers/app.ts index 00167bf..87490f8 100644 --- a/src/modules/core/helpers/app.ts +++ b/src/modules/core/helpers/app.ts @@ -16,7 +16,7 @@ import { AppInterceptor } from '../providers/app.interceptor'; import { AppPipe } from '../providers/app.pipe'; import { App, AppConfig, CreateOptions } from '../types'; -import { CreateModule } from './utils'; +import { createCommands, CreateModule } from './utils'; export const app: App = { configure: new Configure(), commands: [] }; @@ -34,6 +34,7 @@ export const createApp = (options: CreateOptions) => async (): Promise => { app.container = await builder({ configure: app.configure, BootModule }); useContainer(app.container.select(BootModule), { fallbackOnErrors: true }); + app.commands = await createCommands(options.commands, app as Required); return app; }; diff --git a/src/modules/core/helpers/utils.ts b/src/modules/core/helpers/utils.ts index a759828..7e38395 100644 --- a/src/modules/core/helpers/utils.ts +++ b/src/modules/core/helpers/utils.ts @@ -3,7 +3,9 @@ import chalk from 'chalk'; import deepmerge from 'deepmerge'; import { isNil } from 'lodash'; -import { PanicOption } from '../types'; +import { Arguments, CommandModule } from 'yargs'; + +import { App, CommandCollection, PanicOption } from '../types'; export function toBoolean(value?: string | boolean): boolean { if (isNil(value)) { @@ -14,7 +16,7 @@ export function toBoolean(value?: string | boolean): boolean { } try { return JSON.parse(value.toLowerCase()); - } catch (error) { + } catch { return value as unknown as boolean; } } @@ -41,7 +43,7 @@ export function isAsyncFunction>( callback: (...args: P) => T | Promise, ): callback is (...args: P) => Promise { const AsyncFunction = (async () => {}).constructor; - return callback instanceof AsyncFunction === true; + return callback instanceof AsyncFunction; } export function CreateModule( @@ -82,3 +84,21 @@ export async function panic(option: PanicOption | string) { process.exit(1); } } + +export async function createCommands( + factory: () => CommandCollection, + app: Required, +): Promise[]> { + const collection: CommandCollection = [...factory()]; + const commands = await Promise.all(collection.map(async (command) => command(app))); + return commands.map((command) => ({ + ...command, + handler: async (args: Arguments) => { + await app.container.close(); + await command.handler(args); + if (command.instant) { + process.exit(); + } + }, + })); +} diff --git a/src/modules/core/types.ts b/src/modules/core/types.ts index 9f69fa5..fe1ec52 100644 --- a/src/modules/core/types.ts +++ b/src/modules/core/types.ts @@ -34,6 +34,8 @@ export interface CreateOptions { storage: ConfigStorageOption; }; + + commands: () => CommandCollection; } export interface ContainerBuilder { diff --git a/src/options.ts b/src/options.ts index 4dd4de1..4889211 100644 --- a/src/options.ts +++ b/src/options.ts @@ -17,6 +17,7 @@ import { RestfulModule } from './modules/restful/restful.module'; import { ApiConfig } from './modules/restful/types'; export const createOptions: CreateOptions = { + commands: () => [], config: { factories: configs as any, storage: { enable: true } }, modules: async (configure) => [ DatabaseModule.forRoot(configure),