0

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 Answers1

3

.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,
}
Eric Haynes
  • 5,126
  • 2
  • 29
  • 36
  • how to make it accept `val1` and `val2` that are a) named b) mandatory? ===> `node my_script.js add-item --val1 3 --val2 55` – Marco C. Stewart Jul 20 '23 at 23:31
  • Update the example. The third argument is a function to further customize yargs for that specific command. Not sure what you mean by "named". They're named `val1` and `val2`. Use any name you like. – Eric Haynes Jul 20 '23 at 23:52
  • Actually, updated again. The third argument can either be a function, or an object containing options and metadata. They have really extensive docs here: https://github.com/yargs/yargs/blob/main/docs/api.md – Eric Haynes Jul 21 '23 at 00:00
  • not sure why you won't me about the thing you're not sure of. because you're not sure? get sure. – Marco C. Stewart Jul 21 '23 at 00:50
  • 1
    "not sure what you mean" was a polite way of saying, "what you're asking is nonsense, and your use of the word 'named' means nothing in this context". Clearly, being polite wasn't warranted. Go figure out what you're actually trying to ask and ask someone else. – Eric Haynes Jul 21 '23 at 02:06
  • Get sure, Eric. Get sure. – Marco C. Stewart Jul 21 '23 at 15:03