add default numerical value to optional argument with yargs

Viewed 988

I have a cli script that accepts commandline parameters.
For the pages parameter I would like the behaviour to be:

> script.js

-> pages parameter not set. don't process pages

> script.js -p 100

-> pages parameter set with value 100: process 100 pages

> script.js -p

-> pages parameter set without value: process infinite (however much available) pages

In other words: I want to give an optional parameter a default value. The problem is that I can't figure out how to distinguish between the situation where it's set by the user without value and when it's not set.

When defined like this:

  var argv = require('yargs')
  // omitted code
  .alias('p', 'pages')
  .describe('p', 'number of pages; infinite by default')
  .default('p', -1)
  .number('p')

argv.pages is always -1 whether I set -p or not

And when defined like this:

  .alias('p', 'pages')
  .describe('p', 'number of pages; infinite by default')
  .number('p')

typeof argv.pages is always undefined, whether I set -p or not

How can I give a default value while treating the parameter as an optional argument; so, no default when it's not set and only a default when it's set without value.


(of course there is a workaround : I could manually parse the arguments by looping through process.argv, but I want to avoid that as that defeats the purpose of using yargs)

1 Answers

I don't believe yargs has a method for something like this, I thought of using #coerce(), but that function gets called regardless if the command line has -p or not, so it wouldn't work (unless you checked for '-p' and '--pages' in the process.argv).

One solution would be to remove the default and modify it after yargs is done. If you remove the default and specify -p, in argv it will just be undefined. If you don't specify -p at all it won't be a property at all.

script -p 100 // => { _: [], $: "", pages: 100, p: 100 }
script -p // => { _: [], $: "" pages: undefined, p: undefined }
script // => { _: [], $: "" }

Now we can check if pages exists in the object but is undefined, and then do whatever:

var argv = require('yargs')
    // omitted code
    .alias('p', 'pages')
    .describe('p', 'number of pages; infinite by default')
    .number('p').argv;

if ('pages' in argv && typeof argv.pages === 'undefined') {
    // set to whatever you want
    argv.pages = Infinity;
    argv.p = Infinity;
}

console.log(argv);
Related