ARIF MAHMUD RANA
ARIF MAHMUD RANA

Reputation: 5166

yargs demand one of builder option

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

Upvotes: 3

Views: 7139

Answers (3)

khodekazemi
khodekazemi

Reputation: 143

you can use demandOption = true to solve the problem

Upvotes: 1

ARIF MAHMUD RANA
ARIF MAHMUD RANA

Reputation: 5166

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.

Upvotes: 0

Sourabh
Sourabh

Reputation: 1615

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

Upvotes: 5

Related Questions