"yargs" won't trigger any command of a script

119 Views Asked by At

I have a NodeJs script in which I need parse command line arguments.

I've written this code:

import yargs from "yargs";
import { hideBin } from 'yargs/helpers';

  //....
  yargs(hideBin(process.argv)).command('--add-item <val1> <val2>', 'desc', {},
      async (argv) => {
        const { val1, val2 } = argv;
        if (val1 && val2) {
          /**/
        } else {
          console.log('Wrong command line arguments');
        }
    })
    .command('--print <val1>', 'description 123', {},
      async (argv) => {
        const { val1 } = argv;
        if (val1) {
            /**/
        } else {
           console.log('Wrong command line arguments');
        }
    })
    .demandCommand(1, 'You need to provide at least one command')
    .help()
    .alias('help', 'h')
    .parse();
    //......

Then I'll run it:

$ node my_script.js --add-item 1 2
// or
// $ node my_script.js --print 33

And will always get:

my_script.js <command>

Commands:
my_script.js --add-item <val1> <val2>
// ...........

That is, it'll show the help info; none of the commands will get triggered.

the version is 17.x

What's the matter?

update #1

I've removed 2 dashes:

.command('add-item <val1> <val2>', 'desc', {},

Yet, it won't work:

 $ node my_script.js add-item --val1 3 --val2 55
 // or 
 // $ node my_script.js add-item  3  55

===>

  (1) Not enough non-option arguments: got 0, need at least 2
  (2) (silence)
1

There are 1 best solutions below

6
Eric Haynes On BEST ANSWER

.command('add-item <val1> <val2>' means, "A command named add-item that has 2 required arguments". Arguments are plain text, not flags.

If you run it like:

node my_script.js 123 456

argv will be:

{
  _: [ 'add-item' ],
  '$0': 'my_script.js',
  val1: 123,
  val2: 456,
}

Any additional flags will also be put in argv, e.g.

node my_script.js add-item 123 456 --val3=789 --val4=whatever

argv will be:

{
  _: [ 'add-item' ],
  '$0': 'my_script.js',
  val1: 123,
  val2: 456,
  val3: 789,
  val4: 'whatever',
}

If instead you want val1 and val2 to be flags, don't make them part of the command:

import yargs from 'yargs'
import { hideBin } from 'yargs/helpers'

void yargs(hideBin(process.argv))
  .command(
    'add-item',
    'desc',
    {
      val1: {
        demand: true,
        desc: 'the first value',
        type: 'string',
      },
      val2: {
        demand: true,
        desc: 'the second value',
        type: 'number',
      },
    },
    async (argv) => {
      console.log('***** argv:', argv)
    },
  )
  .demandCommand(1, 'You need to provide at least one command')
  .help()
  .alias('help', 'h')
  .parse()

Then you can call it like:

node my_script.js add-item --val1=3 --val2=55

and argv will be:

{
  _: ['add-item'],
  $0: 'my_script.js',
  val1: 3,
  val2: 55,
}