#NestJS Commander Command/SubCommand design

1 messages · Page 1 of 1 (latest)

unique swift
#

Hello everyone I'm experimenting the https://github.com/jmcdo29/nest-commander package and I'm building an OpenSearch CLI https://github.com/andreafspeziale/opensearch-cli.

I've already putted down my building blocks and I'm wondering the following:

  1. when first running the CLI I get out of the box the expected suggestions
  2. when running the first suggested command, "indices|i", I've NO logs/auto-suggestions
  3. running the same command, "indices|i" along with "-h" (help), I get the correct logs/auto-suggestions printing the sub-command
  4. running the completed command, "indices|i" "list|l", I get the correct command output

I've attached the steps as a screenshot to let you better understand.

My question is, what would be the best way or design changes in order to have step 2 with logs/auto-suggestions like it is automatically happening when running step 1 or step 3?
Or would it be like it is now?

Thanks in advance people!

indigo cedar
#

To be clear: you're wondering how you can get that help output when you call <cli> indices without any operators attached to it, right?

#

Like, you want that usage os-cli indices|i [options] [command] part to show when you pass no options

unique swift
#

Yeah I mean, I believe that would be better than empty response, even if the empty response is not a semantic error because at the end of the day there is no business logic there. The business logic is in the subcommand

#

Eg. the next subcommand will be "os-cli indices|i get|g" which will get an "index detail". I would like that running "os-cli indices|i" will give me hints about the subcommands "list|l" or "get|g" as I would run "os-cli indices --help" rather than empty. I believe it would be a better user experience

indigo cedar
#

Right, right, makes sense. So what you can do is inject the commander instance and call the .help() from it yourself in the indices run method. I'm trying to remember if there's a way to automate that, there's a lot of options for the decorators, so give me a few minutes to re-remember everything in here

unique swift
#

Sure, I'll wait and thanks for the support, I'm really happy with the design so I was looking for suggestions that make more sense also in terms of design as mentioned!

indigo cedar
#

Okay, so yeah, I think I haven't ran into a situation where someone has wanted an abstract top level command where only sub commands are supposed to be ran and the the parent is supposed to be essentially a folder.

That said, it's a use case that makes sense, so waht you could do is in the run of IndicesCommand do something like process.stdout.write(this.command.helpInformation) and it'll print out the help if indices is called without a sub command or options

unique swift
#

So it would be something like this

import { Command, CommandRunner } from 'nest-commander';
import { ListCommand } from './list.command';

@Command({
  name: 'indices',
  description: 'OpenSearch indices related commands',
  aliases: ['i'],
  subCommands: [ListCommand],
})
export class IndexCommand extends CommandRunner {
  constructor() {
    super();
  }

  async run(): Promise<void> {
    process.stdout.write(this.command.helpInformation());
  }
}

and it is actually working as expected! Thanks a lot! Should it be done in any other sugar way like with some decorator / default settings I'm missing or is it the only way? I believe this makes sense BTW. So the command is actually run and its business logic is returning its help: process.stdout.write(this.command.helpInformation());

indigo cedar
#

Currently, no, there's no simpler way for this. Though, if you think it would be a good idea, we might be able to make a help command that defaults to this in the CommandRunner abstract class, and then can be overriden if chosen. Though I can see taht also needing more than just a simple update, so t might not be immediately worth it.

Maybe an option like abstract: true could be used to automate this, that actually could be a decent approach. I might look into that (different option names are always appreciated too)

unique swift
#

Great! I'll follow the repo, in the meanwhile this works perfectly, thanks!