NodeJS Terminal app

ยท

10 min read

By the end of this post, you will learn to create your own commands for Linux to make your life simpler.

Lets Begin

First of all, you need node and npm installed in your system to install node and npm you can follow install node & npm download and install the latest stable version of node and npm.

* Creating the project

$ mkdir node-cli
$ cd node-cli
$ npm init -y

hurray we created a node application ๐Ÿ˜ƒ

step 1

you can open the project in any code editor of choice mine is vs code.

there will be a file called package.json that is used by NPM (Node Package Manager) uses this package.json file information about Node JS Application information or Node JS Package details.

{
  "name": "node-cli",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

your package.json will be looking like this after npm init -y

let's add a property "bin":"./index.js" to this package.json file.

Step 2 (a walk through)

Let us start doing the real thing now, make a file index.js and

//index.js
console.log("Hello, world!");

now for testing purpose, we will do

$ node index.js
Hello, world!

Yes, it is working, great ๐Ÿ˜ƒ, let's now focus on the real thing.

in your index.js file

#!/usr/bin/env node;
console.log("Hello, world!");

#!/usr/bin/env node this line should be the first line of your file basically when you execute this file it will tell that the system what interpreter to pass that file to for execution, via the command line following the magic #! prefix (called shebang).

let's make this index.js file executable, in the terminal run the following command

$ chmod +x index.js

it will make the file executable ./index.js to run your application.

let me tell you the capability of our command: It is capable of doing creating a react app and pushing to your Github account, to keep you synced. creating a new project and pushing it to Github is redundant, it's needed to be automated.

Step 3 Modules which we will use

node modules we need for the project
$ yarn add minimist axios path

the use of minimist : the guts of optimist's argument parser without all the fanciful decoration.

the use of axios : it is used for passing the HTTP request.

the use of path : The path module provides utilities for working with file and directory paths.

we will also use child_process it comes prebuild with node.

use of minimist

suppose you want to run our index.js file you do ./index.js but if you want to pass arguments to the program like ./index.js --file ./ --n first minimist will give you an object like this

{
   file : './',
   n : 'first'
}

we can use minimist in this way

var args = require("minimist")(process.argv.slice(2), {
  boolean: ["help", "check"],
  string: ["n", "path", "setup"],
});

the type of help and check will be boolean and n, path, and setup will be of type string.

use of Axios

Axios is used to make HTTP request, you can use Axios like this.

const { default: Axios } = require("axios");
const payload = {
          name: `${args.n}`,
          description: "this is text",
          homepage: "https://github.com",
          private: false,
        };
        Axios.post("https://api.github.com/user/repos", payload, {
          headers: {
            "Content-Type": "application/json",
            Authorization: `token ${Key}`,
          },
        }).then(res => console.log(res.data")).catch(e => console.err(e));

Axios returns a promise that we check if the promise is fulfilled .then() will we called and if it fails .catch() will be called

use of path

The path module provides utilities for working with file and directory paths.

use of child_process

The child_process module provides the ability to spawn child processes in a manner that is similar, but not identical, to popen(3). This capability is primarily provided by the child_process.spawn() function, but here we will mainly use exec() method

const exec = require("child_process").exec;
exec(` {your linux terminal commands or anything goes here }`,
     function (err, stdout, stderr) {
                if (err) {
                  console.error(`error: ${err.message}`);
                  return;
                }

                if (stderr) {
                  console.error(`stderr: ${stderr}`);
                }
                console.log("");
                if (stdout) {
                  console.error(`stdout: ${stdout}`);
                }
              }
            );

Now we know all about the packages we will be using.

Step 4 The Code

Content of index.js

I guess it is understandable and makes sense!

you can get your key here create personal access token

#!/usr/bin/env node
var path = require("path");
const exec = require("child_process").exec;
const { default: Axios } = require("axios");
const Key = <your_key />
var args = require("minimist")(process.argv.slice(2), {
  boolean: ["help", "check"],
  string: ["n", "path"],
});

const BASEPATH = path.resolve(process.env.BASEPATH || __dirname);
if (args.help) {
  printHelp();
} else if (args.n) {
  if (args.path) {
    var pathto = path.join(BASEPATH, args.path);
    console.log("\x1b[32m", "work is in progress, please wait!");
    exec(
      `cd ${pathto} && mkdir ${args.n} && cd ${args.n} && create-react-app ./`,
      (err, stdout, stderr) => {
        if (err) {
          console.error(`error: ${err.message}`);
          return;
        }

        if (stderr) {
          console.error(`stderr: ${stderr}`);
          //return;
        }

        console.log("\x1b[32m", "Creating github repo!");

        const payload = {
          name: `${args.n}`,
          description: "this is text",
          homepage: "https://github.com",
          private: false,
        };
        Axios.post("https://api.github.com/user/repos", payload, {
          headers: {
            "Content-Type": "application/json",
            Authorization: `token ${Key}`,
          },
        })
          .then((res) => {
            console.log(res.data);
            exec(
              `cd ${pathto}/${args.n} && git init && git remote add origin ${res.data.ssh_url} && git add . && git branch -M master && git push -u origin master `,
              function (err, stdout, stderr) {
                if (err) {
                  console.error(`error: ${err.message}`);
                  return;
                }

                if (stderr) {
                  console.error(`stderr: ${stderr}`);
                }
                console.log("");
                console.log(`cd ${pathto}/${args.n}`);
                console.log("yarn start");
                console.log("Happy hacking");
              }
            );
          })
          .catch((e) => console.log("NetWork Error", e));
      }
    );
  } else {
    printHelp();
  }
} else {
  printHelp();
}
//************************************************
function printHelp() {
  console.log("github usage:");
  console.log("");
  console.log(
    "This package can be used while creating a react app and at the same time get synced with github"
  );
  console.log("");
  console.log("--help                             Gives you help window");
  console.log(
    "--n ={fineName} --path ={path}                    File name of the project"
  );
}

Creating a named function

let's create a command-line function for this

$ npm link
npm WARN react-app@1.0.0 No description
npm WARN react-app@1.0.0 No repository field.

audited 35 packages in 0.769s

3 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

/usr/local/bin/react-app -> /usr/local/lib/node_modules/react-app/index.js
/usr/local/lib/node_modules/react-app -> /home/aman/Github

you are all done.๐Ÿ˜ƒ

Link to the repo