Nodejs terminal app
Tags: node, ubuntu, javascript
Published: 2020-09-04 04:16:51

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](https://nodejs.org/en/) 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.

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 
```//index.js
#!/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. 

###### 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.



## Content of index.js 
I guess it is understandable and makes sense!

you can get your key here [create personal access token](https://github.com/settings/apps)
```
#!/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"
  );
}
```

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](https://github.com/AmanKumarSingh01/react-app-cli)