Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Positional arguments ignore "type": string" #2359

Open
lgarron opened this issue Sep 13, 2023 · 6 comments
Open

Positional arguments ignore "type": string" #2359

lgarron opened this issue Sep 13, 2023 · 6 comments

Comments

@lgarron
Copy link

lgarron commented Sep 13, 2023

Repro:

import yargs from "yargs";

const { argv } = yargs(["333"])
  .scriptName("pirate-parser")
  .usage("$0 [WCA event ID")
  .command("333", "welcome ter yargs!", (yargs) => {
    yargs.positional("eventID", {
      type: "string",
      describe: "WCA event ID",
    });
  })
  .strictOptions();
console.log(argv._[0] === "333"); // should be true
console.log(argv._[0] === 333); // should be false

For example: https://runkit.com/embed/6o5nr4apu9v3

Expected: argv._[0] is a string. (Output: true, false.)

Observed: argv._[0] is converted to a number. (Output: false, true.)

@shadowspawn
Copy link
Member

That does apparently fail in quite a quiet way, but in fact there are some setup issues.

Here is a working example with a few small changes:

  • renamed the subcommand from 333 to abc to make a bit clearer
  • pass in test arguments for both subcommand and positional
  • added position to subcommand setup: abc <eventID>
const { argv } = yargs(["abc", "333"]) // subcommand + positional to test parsing
  .scriptName("pirate-parser")
  .usage("$0 [WCA event ID")
  .command("abc <eventID>", "welcome ter yargs!", (yargs) => {
    yargs.positional("eventID", {
      type: "string",
      describe: "WCA event ID",
    });
    return yargs;
  })
  .strictOptions();
% node index.js 
{
  _: [ 'abc' ],
  '$0': 'pirate-parser',
  eventID: '333',
  'event-i-d': '333'
}

@lgarron
Copy link
Author

lgarron commented Sep 13, 2023

That does apparently fail in quite a quiet way, but in fact there are some setup issues.

The CLI I'm implementing doesn't have subcommands at the moment (which is quite common for commandline applications). What should I be doing in that case?

@lgarron
Copy link
Author

lgarron commented Sep 13, 2023

Oh, I see! I seem to have ended up with some nested command code from debugging. Lemme see if I can take it out.

@lgarron
Copy link
Author

lgarron commented Sep 13, 2023

Hmm, this seems to have the same issue:

import yargs from "yargs";

const { argv } = yargs(["333"])
  .scriptName("pirate-parser")
  .usage("$0 [WCA event ID")
  .positional("eventID", {
    type: "string",
    describe: "WCA event ID",
  })
  .strictOptions();
console.log(argv._[0] === "333"); // should be true?
console.log(argv._[0] === 333); // should be false?
console.log(argv.eventID); // or this should be defined?

@shadowspawn
Copy link
Member

There is a trick. .positional() is not available on the root command, and instead you can configure it using .usage() and define a "default command": https://yargs.js.org/docs/#api-reference-usage-desc-builder-handler

The positional gets stored using its name.

import yargs from "yargs";

const { argv } = yargs(["333"])
  .scriptName("pirate-parser")
  .usage("$0 [eventID]", "welcome ter yargs", (yargs) => {
    yargs.positional("eventID", {
      type: "string",
      describe: "WCA event ID",
    })
  })
  .strictOptions();
console.log(argv);
% node top.mjs 
{ _: [], '$0': 'pirate-parser', eventID: '333', 'event-i-d': '333' }

@lgarron
Copy link
Author

lgarron commented Sep 13, 2023

Ah, I see, thanks. I've used

https://yargs.js.org/docs/#api-reference-positionalkey-opt states that ".positional() … is not available on the top-level yargs instance."

If I now understand that correctly, wouldn't it make more sense for the code to error when called like that?

I'm a big fan of "if it compiles it works", and the current behaviour here is pretty unintuitive to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants