Daniel Birowsky Popeski
Daniel Birowsky Popeski

Reputation: 9286

How to implement multiple subcommands with Yargs?

I've been trying and trying, but just couldn't digest Yargs' docs.

I need to create a set of commands/subcommands:

~$framework generate routed-module ModuleOne ModuleTwo ModuleThree --animation-style=bounce-up

//would call a handler with:
{ modules: string[], options: {animationStyle?: AnimationStyle}}
type AnimationStyle = 'bounce-up' | 'slide-left'

or

~$framework generate stateful-ui ModuleOne ModuleTwo ModuleThree
//would call a handler with:
{ modules: string[]}

or

~$framework init
//would just call a handler

I'd like aliases: g for generate, r for routed-module, s for stateful-ui.

Autocompletion would be nice.

Here's what I've tried, don't know where to go from here:

  yargs
    .scriptName('elm-framework')
    .command({
      command: 'generate [moduleType] [moduleNames]',
      aliases: ['g'],
      describe: 'Generates a resource',
      handler: config.handleModuleGeneration,
      builder: {
        moduleType: {
          demand: true,
          choices: ['routed', 'stateful'] as const,
          default: 'routed',
        },
        moduleNames: {
          demand: true,
          array: true,
        },
      },
    })

Thanx!

(Doing this with typescript is not necessary. I primarily want to understand how to use the library's api.)

Upvotes: 8

Views: 7107

Answers (2)

David
David

Reputation: 2748

To me, the best way to achieve this was following this Github issue, specifically what suggested in this comment. (another builder nested inside the command builder).

The issue with using the suggestion above ('generate [moduleType] [moduleNames...]') is that you can't use different flags for different sub-commands.

Upvotes: 4

Daniel Birowsky Popeski
Daniel Birowsky Popeski

Reputation: 9286

Figured it out using this crucial piece of documentation:

  yargs
    .scriptName('framework')
    .command({
      command: 'generate [moduleType] [moduleNames...]',
      aliases: ['g'],
      describe: 'Generates a resource',
      handler: parsed => console.log('your handler goes here', parsed),
      builder: {
        moduleType: {
          demand: true,
          choices: ['routed', 'stateful'] as const,
          default: 'routed',
        },
        moduleNames: {
          demand: true,
          array: true,
        },
      },
    }).parse(process.argv.slice(2))

Upvotes: 4

Related Questions