3

How can I make require one of my options from builder object from command

require('yargs')
  .usage('Usage: $0 <cmd> [options]')
  .command(
    'read',
    'Read a note',
    {
      id: {
        demand: true,
        string: true
      },
      first: {
        demand: true,
        boolean: true
      }
    },
    argv => {
      note.read(argv.id).then(data => {
        console.log('==================note read==================');
        console.log(data);
        console.log('==================note read==================');
      });
    }
  )
  .help()
  .strict().argv;

Here I want user to pass either id or first option for read command

Also when running this command with invalid options it doesn't show errors

node app.js read --id=1 --first=1

yargs: ^12.0.5

ARIF MAHMUD RANA
  • 5,026
  • 3
  • 31
  • 58

3 Answers3

5

You may use check API.

// code is written for logic purpose. Not tested.
.check(function (argv) {
        if ((argv.id && !argv.first) || (!argv.id && argv.first)) {
           return true;
        } else if (argv.id && argv.first) {
           throw(new Error('Error: pass either id or first option for read command'));
        } else {
           throw(new Error('Error: pass either id or first option for read command'));
        }
    })

PS: 1 can be string or boolean for option values

Sourabh
  • 1,515
  • 1
  • 14
  • 21
1

you can use demandOption = true to solve the problem

khodekazemi
  • 143
  • 10
0

This is the solution I am currently using. Though I am looking for a better solution.

require('yargs')
  .usage('Usage: $0 <cmd> [options]')
  .command(
    'read',
    'Read a note',
    yargs =>
      yargs
        .option('id', {
          string: true
        })
        .option('first', {
          boolean: true
        })
        .check(({ id, first }) => {
          if (!id.trim() && !first) {
            throw new Error('id or first option is required');
          }

          return true
        }),
    argv => {
      if (argv.first) {
        note.readFirst().then(data => {
          console.log('==================note read==================');
          console.log(data);
          console.log('==================note read==================');
        });
      } else {
        note.read(argv.id).then(data => {
          console.log('==================note read==================');
          console.log(data);
          console.log('==================note read==================');
        });
      }      
    }
  )
  .help()
  .strict().argv;

yargs command takes 4 options. Command, description, builder & handler. Builder can be an object or a function. Using function can be used to provide advanced command specific help.

Also I removed demand for both of them as using demand it will ask both the option but I wanted only one.

Also when setting an option to string or boolean what it does it only casts to that type it doesn't validates the type. So here if no option provided argv.first default value will be false & argv.id default value will be '' empty string.

Also when throwing an Error from check function it actually shows the error message of Error object but if we return false it will show the function body in console as message to help trace the error.

Also without accessing argv yargs will not parse.

see https://yargs.js.org/docs/#api-commandcmd-desc-builder-handler, https://yargs.js.org/docs/#api-argv.

ARIF MAHMUD RANA
  • 5,026
  • 3
  • 31
  • 58