Dependency Injection with Providers

Demonstrates using .provide() and getCommandContext() to register and inject services without threading them through function calls.

The logger provider is registered once on the CLI with a factory that receives parsed args, then any command handler can access it via getCommandContext(app).inject('logger') — no prop drilling needed.

All Example Files

FILE EXPLORER
cli.ts
1import { cli } from 'cli-forge';
2import { runDeploy } from './deploy';
3
4export const app = cli('deploy-tool')
5  .option('logLevel', {
6    type: 'string',
7    default: 'info',
8    description: 'Logging level',
9  })
10  .option('apiUrl', {
11    type: 'string',
12    required: true,
13    description: 'API base URL',
14  })
15  // Register a logger provider whose factory receives the parsed args.
16  // Any command handler can inject it without threading it through calls.
17  .provide('logger', {
18    factory: (args) => ({
19      info: (msg: string) => console.log(`[${args.logLevel}] ${msg}`),
20    }),
21  })
22  .command('deploy', {
23    description: 'Deploy to a target environment',
24    builder: (cmd) =>
25      cmd.option('target', {
26        type: 'string',
27        required: true,
28        description: 'Deployment target',
29      }),
30    handler: async () => {
31      await runDeploy();
32    },
33  });
34
35if (require.main === module) {
36  app.forge();
37}
38