Command line interface (CLI) framework for TypeScript with service container, module system, hooks, and easy to define commands.
Features
Commands
Write CLI commands with class methods or simple async functions.
All CLI arguments and flags are extracted out of the function signature and are automatically deserialized and validated based on its types.
import { App } from '@deepkit/app'; class MyCommand { async execute(name: string = 'body') { console.log('Hello', name); } } const app = new App({ controllers: [MyCommand], }); app.run();
import { App } from '@deepkit/app'; const app = new App(); app.command('test', async (name: string = 'body') => { console.log('Hello', name); }); app.run();
Arguments and Flags
Arguments and flags are automatically deserialized based on its types, validated and can be provided with additional constraints.
import { Flag, App } from '@deepkit/app'; const app = new App(); app.command('user:find', async ( name: string & Flag = '', age: number & Flag = '', active: boolean & Flag = false, ) => { // name is a string, age a number, active a boolean }); // ts-node app.ts user:find --name Peter --age 20 --active
Dependency Injection
The service container allows you to inject dependencies into your commands, controllers, and hooks, without any boilerplate code.
import { App } from '@deepkit/app'; class MyDatabase extends Database {} //your database class const app = new App({ providers: [MyDatabase], }); app.command('user:find', async ( name: string & Flag = '', db: MyDatabase, // automatically injected ) => { const users = await db.query(User).filter({name}).find(); console.log(users); }); app.run();
Configuration
Define your configuration as class including validation constraint and load it automatically from environment variables, dotfiles, or JSON files.
Configuration options can be injected into your commands, controllers, and hooks.
import { App } from '@deepkit/app'; class Config { domain: string = 'localhost'; } const app = new App({ config: Config, providers: [MyDatabase], }); app.command('url', async ( name: string & Flag = '', db: MyDatabase, // automatically injected domain: Config['domain'], // automatically injected ) => { const user = await db.query(User).filter({ name }).findOne(); console.log('url', `https://${domain}/user/${user.username}`); }); app.run();
Modules
Powerful module system with hooks and inheritance that allows to easily extend your application.
Modules can bring their own providers, controllers, event listeners, and configuration.
import { App, AppModule } from '@deepkit/app'; export function myModule(options: {}) { return (module: AppModule) => { module.addProvider(MyDatabase); module.addController(MyController); module.addListener(); //make MyDatabase available for parent modules module.addExport(MyDatabase); }; } const app = new App({ config: Config, imports: [ myModule({}), ] }); app.command('url', async ( name: string & Flag = '', db: MyDatabase, // automatically injected from module ) => { //... }); app.run();
Event System
The event system allows you to hook into the application lifecycle and react to events.
All listeners have full access to the service container and can receive dependencies allowing to write nicely decoupled code.
import { App, onAppExecute } from '@deepkit/app'; const app = new App(); app.listen(onAppExecute, async (event, logger: Logger) => { logger.log('app started'); }); app.run();