DEV Community

Thanh Tien Phat Nguyen
Thanh Tien Phat Nguyen

Posted on

New branches growing from the tree!

Introduction

Lately, I have been working on my newly-built CLI link-checker-tool which allows us to display the status of all URLs in a file or to check whether a single URL is available or not. However, I would like to add more features to my CLI to improve it more for users.

Add -j, --json flag to output json format result of an URL

To be honest, it seems a pretty good idea for a feature to add. Moreover, the idea to implement the feature is not difficult at all. Here is how I did it.

Firstly, let's add the flag in yargs

.alias('j', 'json')
.nargs(['f', 'u', 'a', 'j'], 1)
//...
.describe('j', 'Output json result of an URL')
Enter fullscreen mode Exit fullscreen mode

Secondly, we need to implement a function that takes an URL as a parameter and output JSON format

const jsonResult = async (url) => {

    let result = {
        url: url,
        status: ''
    }
    try{
        const response = await axios.head(url);
        result.status = response.status;
    }
    catch(err)
    {
        if (err.response)
        {
            result.status = err.response.status;
        }
        else{
            result.status = 'unknown';
        }
    }
    console.log(result);
}
Enter fullscreen mode Exit fullscreen mode

I will explain a bit about the concept I did here:

  1. Since the ouput must be json format, we have to create a result object.
  2. We use an error handler here to help our app avoid being crashed if there is any error.
  3. Call a header request from axios. If the request is successful, result.status = response.status;
  4. if there is error happening and the err.response is not empty, result.status = err.response.status;
  5. Otherwise, set result.status = 'unknown';

Add --all, --good, and --bad flags.

The idea is when reading a file, if we put a --good or --bad flag, it will display only good/bad URLs according to the flag we input. And --all is the default flag which help output all the valid URLs in a file.

Like we did above, we have to add those flags first

//...
.alias('g', 'good')
.alias('b', 'bad')
.alias('a', 'all')
//...
Enter fullscreen mode Exit fullscreen mode

Next, I need to modify my checkURL function a bit

const checkURL = async (url, flag = "all") => {
    try {
        const response = await axios.head(url);
        if ((flag == "all") || (flag == "good"))
            console.log(chalk.green("[GOOD]" + "[" + response.status + "]" + " " + url))
    }
    catch (err) {
        if (err.response) {
            if (err.response.status == 404 || err.response.status == 400) {
                if ((flag == "all") || (flag == "bad"))
                    console.log(chalk.red("[BAD]" + "[" + err.response.status + "]" + " " + url))
            }
            else
                if (flag == "all")
                    console.log(chalk.gray("[UNKOWN]" + "[" + err.response.status + "]" + " " + url))
        }
        else {
            if (flag == "all")
                console.log(chalk.gray("[UNKOWN][ENOTFOUND] " + url));
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  1. I have added a second parameter flag = "all" which show the option of the flag good, bad, all, while all is the default one.
  2. Since all output all valid URLs in the file, we have to set it for all conditions.
  3. Under a good/ bad condition only prints out good/bad URLs

Lastly, change handleArgument a bit.

const handleArgument = (argv) => {
//...
 else if (argv.f || argv.all || argv.good || argv.bad) {
        let fileName = argv.f || argv.a || argv.good || argv.bad;
        console.log(fileInteraction(fileName, argv))
        for (i = 0; i < argv._.length; i++) {
            fileInteraction(argv._[i], argv)
        }
//...
}
Enter fullscreen mode Exit fullscreen mode
  1. Since all, good, bad, f technically do the samething, I put them all as one condition.
  2. let fileName = argv.f || argv.a || argv.good || argv.bad;

Top comments (0)