NotesWhat is notes.io?

Notes brand slogan

Notes - notes.io

So what do you Do?
Jay is a member of the NestJS core team, primarily helping out the community on Discord and Github and contributing to various parts of the framework. GAMING NEWS

What's up Nestlings! So you've been developing web servers with NestJS for a while now, and you're in love with the DI context that it brings. You're enthralled by the class first approach, and you have "nest-itis" where you just want everything to work with Nest because, well, it just feels good. But now, after building some web servers and application, you realize you need to be able to run some one-off methods, or maybe you want to provide a full CLI package for one of your projects. You could write these commands using shell scripts (and I wish you the best if so), or you could use a CLI package like yargs or commander. Those are all fine options, but none of them are using Nest, which is sad for those of you with "nest-itis". So what do you do? You go to Google, type in "nest commander package" and search through the results, finding nest-commander. And that's where you see the light.

What sets nest-commander apart from other Nest CLI packages

nestjs-command

- uses yargs as the underlying CLI engine
- uses parameter decorators for command
- has a CommandModuleTest built into the package

nestjs-console

- uses commander for the underlying CLI engine
- has a ConsoleService to create commands or can use decorator
- no immediate testing integration

nest-commander

- uses commander for the underlying CLI engine
- uses a decorator on a class for a command and a decorator on class methods for command options
- has a separate testing package to not bloat the final CLI package size
- has an InquirerService to integrate inquirer into your CLI application
- has a CommandFactory to run similar to NestFactory for a familiar DX

How to use it

Okay, so we've talked about what's different, but let's see how we can actually write a command using nest-commander.

Let's say we want to create a CLI that takes in a name, and an age and outputs a greeting. Our CLI will have the inputs of -n personName and -a age. In commander itself, this would look something like

This works out well, and it pretty easy to run, but as your program grows it may be difficult to keep all of the logic clean and separated. Plus, in some cases you may need to re-instantiate services that Nest already manages for you. So enter, the @Command() decorator and the CommandRunner interface.

All nest-commander commands implement the CommandRunner interface, which says that every @Command() will have an async run(inputs: string[], options?: Record): Promise method. inputs are values that are passed directly to the command, as defined by the arguments property of the @Command() decorator. options are the options passed for the command that correlate back to each @Option() decorator. The above command could be written with nest-commander like so

Now all we need to do is add the SayHelloCommand to the Nest application and make use of CommandFactory in our main.ts.

And there you have it, the command is fully operational. If you end up forgetting to pass in an option, commander will inform you the call is invalid. To run the command from here, compile your code as you normally would (either using nest build or tsc) and then run node dist/main.

Now, this is all fine and dandy, but the real magic, as mentioned before, is that all of Nest's DI context still works! So long as you are using singleton or transient providers, there's no limitation to what the CommandFactory can manage.

InquirerService

So now what? You've got this fancy CLI application and it runs awesome, but what about when you want to get user input during runtime, not just when starting the application. Well, that's where the InquirerService comes in. The first thing that needs to happen is a class with @QuestionSet() needs to be created. This will be the class that holds the questions for the named set. The name is important as it will be used in the InquirerService later. Say that we want to get the name and age at runtime or at start time, first we need to change the options to optional by changing from chevrons to brackets (i.e. to [personName]). Next, we need to create our question set

Now in the SayHelloCommand we need to add in the InquirerService and ask for the information.

The rest of the class follows as above. Now we can pass in the options commander already found, and inquirer will skip over asking for them again, allowing for the a great UX by not having to duplicate their information (now if only resume services were so nice). Now in SayHelloModule we add in the PersonInfoQuestions to the providers and everything else just works ™️

And just like that, we've now created a command line application using nest-commander, allowing for users to pass the info in via flags or using prompts and asking for it at runtime.

For more information on the project you can check the repo here. There's also a testing package to help with testing both the commander input and the inquirer input. Feel free to raise any issues or use the #nest-commander channel on the official NestJS Discord

Discussion (13)

Also, by copying the example from this article, I would get:

Property 'personName' does not exist on type ' name: string; age: number; '.ts(2339)

I had to tweak the commend to look like this (also adding --name to option) before it would work:

paste.laravel.io/b566d7db-4791-48c...

Thanks for reporting that. The post has been updated to have the proper values

Nice, Great work!

- Joined
Jul 31, 2021

Very nice article! Will give it a try

- Joined
Dec 11, 2018

This is cool stuff. I'm going to be using it extensively in the next couple of weeks.

Scott

- Location
Silesia

- Joined
May 30, 2020

I was waiting for something like this. Awesome. Thanks!

Ps. You have a few typos in your code examples.

Thanks for saying something! This is what I get for writing everything in the online editor and not in my IDE

- Location
Global

- Work
Co-Founder at Trilon

- Joined
Jul 3, 2019

Love it Jay, great write up! 👏👏
(Btw tiny typo about in one code block you have @Opiton )

Thanks Mark! Got it fixed

- Location
Kraków

- Work
Software Engineer

- Joined
Jun 4, 2020

I was looking at making my own solution, now I don't have to. Great, thanks!

- Joined
Dec 27, 2019

Fantastic and interesting post! Great!

- Joined
Feb 15, 2020

Would be nice to show how to actually run the command - it took a bit of tinkering to figure out

- Location
Concrete Washington

- Work
Software Architect at Trilon

- Joined
Oct 17, 2019

I added a quick note of how you can run the command after the setup of the src/main.ts file. There's more information as well on the docs site

Website: https://getnews.live/
     
 
what is notes.io
 

Notes.io is a web-based application for taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000 notes created and continuing...

With notes.io;

  • * You can take a note from anywhere and any device with internet connection.
  • * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
  • * You can quickly share your contents without website, blog and e-mail.
  • * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
  • * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.

Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.

Easy: Notes.io doesn’t require installation. Just write and share note!

Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )

Free: Notes.io works for 12 years and has been free since the day it was started.


You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;


Email: [email protected]

Twitter: http://twitter.com/notesio

Instagram: http://instagram.com/notes.io

Facebook: http://facebook.com/notesio



Regards;
Notes.io Team

     
 
Shortened Note Link
 
 
Looding Image
 
     
 
Long File
 
 

For written notes was greater than 18KB Unable to shorten.

To be smaller than 18KB, please organize your notes, or sign in.