Create awesome cli tools with Node.js

Tulsi Sapkota
Enliv Information Technologies
6 min readAug 9, 2018

JavaScript was developed in 1995, primarily as a language for browsers. Though, the language was invented in hurry, It had powerful features from the starting. It became even more powerful after invention of Node.js in 2009. Node.js opened a platform where JS developer could write command line tools(cli) and do server-side scripting. Not only it gave a way, it soon became a powerful tool for developing network applications. Recent stack overflow survey says that JavaScript is used by 71.5% and Node.js by 49.9% of professional developers among the respondent of it's survey. These days, JS developers are in demand as never before. We are going to build a cli with Node.js.

tl;dr

JavaScript is great language, and we will build awesome cli with JavaScript.

What we are going to build

We will create a command line tool which will connect user to their google account, and manage their google events. We will let user view and create google events in this tutorial. We will also:

  1. Package the command line utility 📦
  2. Publish it to npm ✨

Initialize your project 🎉

To setup your node project:

$ npm init

It will automatically create a package.json file which will store all of our dependencies in one manageable place.

Packages we will need

We need to add these dependencies to our package.json file. googleapis is official client for google, vorpal is the framework we will be using to create our command line tool. And, opn is used to open browser(though opn can be used to open any other things too, we will only be using it to open browser for this project). Other packages we will be explained later on.

"dependencies": {
"chrono-node": "^1.3.5",
"cli-spinner": "^0.2.8",
"googleapis": "^32.0.0",
"moment": "^2.22.2",
"opn": "^5.3.0",
"vorpal": "^1.12.0"
}

Let's start coding 🖥

Without further due, we will jump into writing our first command. vorpal provides us easy to use chain-able functions to create commands. Your first command can be easy as below 💪

We will need to know three things from vorpal to jump start building our cli. First, a command, we will need to specify the command name and arguments that our command will take. In the above example, we set the command name say and a variadic argument words (Please look at vorpal documentation to know different types of argument they support). Second, a description, this function will provide description of the command it's attached to. And, finally, action, this is where your command logic resides. An action function will be provided with two parameters args and callback . All the arguments, that an user pass with the command will be provided through args. For example, words in above example will be provided as args.words.

vorpal.command('say [words…]');
// $ say foo bar and so on -> {words: ['foo', 'bar' , 'and', 'so', 'on']}

The callback function is called when the process for that command is completed.

Let's jump to what we are building 🚀

In this section, we are going to build simple commands to connect google account and authorize it with Google OAuth 2.0. OAuth is a authentication process which will let our command line tool to perform certain action on the user's google calendar.

Authenticating our app with Google OAuth 2.0 will require us to follow below processes:

  1. We need to resister our app to google and get our CLIENT_ID and CLIENT_SECRET
  2. Now, as we are making a cli, we will not register any redirect url, instead we will use copy/paste process.
  3. We need to create a authentication url, where user will give consent that they give access to their calendar to our cli. And, open a browser and redirect user to that url.
  4. Now, user will paste the code they get from step 3 to our cli and we will get access_token and refresh_token which will be using to perform action on google calendar later on.

In the index.js file, we are going to add two commands, namely connect and authorize. connect command will open user's default browser and redirect to the authentication url, where they will get a code that is used in authorize command. In authorize command access_token and refresh_token is generated.

Let’s save tokens for next use 🔒

Now that we have already implemented authentication we should store the token so that user can use same account later on. We will be simply using a JSON file config.json to store access_token, refresh_token, expiry_date etc. We will add a utils.js file to perform read and write operation on JSON file.

We will update our index.js file in order to check if user is already connected to their google calendar or not. We are also making sure that the client can logout of their account.

List Events 🚀

We have already authenticated user's google account, now it's time to show events that user have in their primary calendar. For this we will be using calendar of googleapis. In order to list google events, we have to:

GET https://www.googleapis.com/calendar/v3/calendars/calendarId/events

With gooleapis , we can simply list events like below:

We can use many other options with list , some more will be shown later on. We are also using moment.js to format time. Altogether, list command will be like below

Let's add some options 🔥

We can add functionalities to our cli with options. Here, we are adding from and to dates to filter out the events between that date range. Also, results option tells how many results to list.

In vorpal , we can add options by chaining a option function. We can simply provide alternative commands by separating them with a comma.

We have also added chorno-node to parse the natural language date provided by the user.

Create an Event 🚀

To create an event in calendar, we will need start time, end time, a short summary and location of the event. location is an optional field.

We will now add a validate method, which validates if the start time and end time is present on the command. You can also validate that start time is always less than end time.

Let's make our cli interactive 🚀

We have http requests to list and create google events. We were just showing a blank screen until http request completes. We will add a spinner to make it more interactive, and to show that http request is processing instead of a blank screen. We will use a package called cli-spinner.

We can use cli-spinner as below.

With spinner, list command looks like below. You can think of other places where you can add spinner.

Package your command line tool 📦

We will first need to add a line as shown below to our index.js file, this tells the system that node interpreter should be used to run the code.

#!/usr/bin/env node

Now, we will add a bin section in our package.json. bin has a key and a value; which are name of the cli tool and file pointing to source code of cli tool respectively. For us, key is g-event and value is index.js.

"bin": {
"ggl-event": "./index.js"
}

To test we can,

  1. Link it from command line
    $ npm link
  2. Open your cli
    $ ggl-event

Publish your cli to npm ✨

To publish your package in npm,

  1. Create an account in www.npm.org
  2. Add publishing user, $ npm adduser
  3. Publish your package, $ npm publish

Anybody can easily download your cli 👏

$ npm install -g ggl-event

The completed code lives at https://github.com/Tolsee/gevent

The package is also published to https://www.npmjs.com/package/ggl-event

--

--