question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Remaining work for yargs v17 release

See original GitHub issue

v17 is a large release, in which I’ve tried to address many long outstanding oddities related to middleware, async handlers, check functions, coerce functions, help output from commands.

There are still a few more tasks I would like to complete before we push it out the door:


If you would like to help QA, npm i yargs@next.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:12 (12 by maintainers)

github_iconTop GitHub Comments

2reactions
seivancommented, Apr 8, 2021

@bcoe I am just fixing things as I go along https://github.com/DefinitelyTyped/DefinitelyTyped/pull/52265

Honestly the types should be in here and generated by in the repo since this is a Typescript project after all, but more importantly should be true to the source code more than anything. Maintaining types externally seems like an accident waiting to happen.

More so, it’s painful to see so much potential for better types and API.

For instance a command should’t take more than a single middleware instead of an array and its return type would be combined with the types defined in builder before being passed to a handler That way a builder defines input’s that are expected and a middleware can then process those before moving to a handler

An example would be that a command that expects --path: string to some file and a middleware would use that to read the content of said file and return the updated arg.

The handler would then get {path: string, fileContent: string | undefined}.

2reactions
seivancommented, Apr 7, 2021

@bcoe That sounds like a great idea, though I’d argue in order to keep things succinct, maybe omit certain approaches that aren’t taking advantage of the type system .

I did some tests of my own and cross-posting here:

export function createAdd(arg: Yargs.Argv): Yargs.Argv {
  return arg.command("add <name> [url]", "sample stuff", (addYarg) => {
    return addYarg
      .positional("name", { type: "string" }, demandOption: true)
      .positional("url", { type: "string" })
  }, (args) => {
     //args.name & args.url will be typed ✅
  })
}

While it does not work (out of the box) with CommandModule

const sourceAddCommand: Yargs.CommandModule = {
  command: ["add <name> [url]"],
  builder: (args) => {
    return args
      .positional("name", { type: "string", demandOption: true })
      .positional("url", { type: "string" })
  },

  handler: (args) => {
  //args & args.url ARE NOT typed ❌
  },
}

However there is partial support for just options and not positional. But you can’t have a builder and you lose descriptions, it literally skips over them when printing usage.

const sourceListCommand: Yargs.CommandModule<{}, {
  "available": {
    boolean: true,
    conflicts: "outdated",
   description: "Not visible ❌" 
   desc: "Not visible ❌",
  }, "outdated": {
    boolean: true,
    conflicts: "available",
   description: "Not visible ❌" 
   desc: "Not visible ❌" 
  }  
}> = {
  describe: "List Command",

  command: "list",
  handler: (args) => {
   // args.available & args.outdated are typed ✅
  },
}

To get typed arguments and avoid polluting the argument interface from other sub-commands in the same parent you need to wrap the entire sub-command in a function. To rephrase: sub-command siblings will get access to each other arguments and positional if they are not wrapped in a function.

   Yargs
    .default(YargsHelper.hideBin(process.argv))
    .scriptName(ProjectPackage.name)
    .command("mother <command>", "One of the main commands", (yargs) => {

      return [yargs]
        .map(makeFirstSubCommand)
        .map(createAdd)
      [0]
})
   . command("father <command>", "Other main command with its own subs", (yargs) => {

      return [yargs]
        .map(createAnotherSubCommandUnderFather)
        .map(someMoreUnderFather)
      [0]
})
.argv
Read more comments on GitHub >

github_iconTop Results From Across the Web

Releases · yargs/yargs - GitHub
completion: choices will now work for all possible aliases of an option and not just the default long option (30edd50) ...
Read more >
docs/api.md | yargs@v17.4.1-deno
When passing in the arguments yourself, note that Yargs expects the passed array to contain only the arguments after the program name, while...
Read more >
yargs show main help after parse - Stack Overflow
I have the following code const yargs = require("yargs"); const parser = yargs.command("test", "description", (yargs) ...
Read more >
demo/node_modules/yargs - GitLab
Yargs be a node.js library fer hearties tryin' ter parse optstrings. ... Build Status Coverage Status NPM version Windows Tests js-standard-style ...
Read more >
concurrently - node_modules - yargs - CHANGELOG.md
middleware should work regardless of when method is called (664b265), ... upgrade to version of yargs-parser that does not populate value for unset...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found