Skip to content

Commit 0a006cb

Browse files
Initial Release v1.0.0
1 parent 9947956 commit 0a006cb

17 files changed

+617
-0
lines changed

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
end_of_line = lf
6+
charset = utf-8
7+
indent_size = 2
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/*

.eslintrc.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"root": true,
3+
"env": {
4+
"es6": true,
5+
"node": true,
6+
"mocha": true
7+
},
8+
"parserOptions": {
9+
"ecmaVersion": 8
10+
},
11+
"extends": [
12+
"eslint:recommended"
13+
]
14+
}

.gitattributes

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Set the default behavior, in case people don't have `core.autocrlf` set.
2+
* text=auto
3+
4+
# Declare files that will always have LF line endings on checkout.
5+
*.js text eol=lf
6+
7+
# Remove files using `git archive`.
8+
.* export-ignore
9+
test/sitemap.js export-ignore
10+
test/urls.js export-ignore

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Dependency directories
2+
node_modules
3+
4+
# misc
5+
.idea
6+
.coverage
7+
.DS_Store

.travis.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
branches:
2+
only:
3+
- main
4+
dist: xenial
5+
language: node_js
6+
node_js:
7+
- 10
8+
- 11
9+
- 12
10+
- 13
11+
- 14
12+
- node
13+
os:
14+
- linux
15+
- osx
16+
install:
17+
npm install --dev
18+
script:
19+
- npm run lint
20+
- npm run test:sitemap
21+
- npm run test:urls

README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# check-http-status
2+
3+
[![NPM version][npm-image]][npm-url]
4+
[![Downloads][downloads-image]][npm-url]
5+
[![Build Status][travis-image]][travis-url]
6+
7+
## Install
8+
9+
Via `npm`
10+
11+
```bash
12+
npm install check-http-status --save-dev
13+
```
14+
15+
Via Yarn
16+
17+
```bash
18+
yarn add check-http-status --dev
19+
```
20+
21+
## Usage
22+
23+
### Sitemap Example
24+
25+
```node
26+
const checkHttpStatus = require('check-http-status');
27+
28+
checkHttpStatus({
29+
'export': {
30+
'format': 'xlsx',
31+
'location': '/Users/trunkcode/Desktop/',
32+
},
33+
'options': {
34+
'auth': {
35+
'password': 'Testing1234',
36+
'username': 'trunkcode'
37+
},
38+
'headers': {
39+
'Accept': 'text/html',
40+
},
41+
},
42+
'sitemap': 'https://www.trunkcode.com/page-sitemap.xml'
43+
});
44+
```
45+
46+
### URLs Example
47+
48+
```node
49+
const checkHttpStatus = require('check-http-status');
50+
51+
checkHttpStatus({
52+
'export': {
53+
'format': 'xlsx',
54+
'location': '/Users/trunkcode/Desktop/',
55+
},
56+
'options': {
57+
'auth': {
58+
'password': 'Testing1234',
59+
'username': 'trunkcode'
60+
},
61+
'headers': {
62+
'Accept': 'text/html',
63+
},
64+
},
65+
'urls': [
66+
'http://trunkcode.com/',
67+
'https://example.com/',
68+
'https://example1234.com/',
69+
'https://www.trunkcode.com/',
70+
'https://www.trunkcode.com/test/'
71+
]
72+
});
73+
```
74+
75+
[npm-image]: https://img.shields.io/npm/v/check-http-status.svg
76+
[npm-url]: https://www.npmjs.com/package/check-http-status
77+
[downloads-image]: https://img.shields.io/npm/dt/check-http-status.svg
78+
79+
[travis-image]: https://api.travis-ci.com/trunkcode/check-http-status.svg?branch=main
80+
[travis-url]: https://travis-ci.com/trunkcode/check-http-status

index.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
'use strict';
2+
3+
const consoleColumns = require('./lib/console-columns');
4+
const fetchFromSitemap = require('./lib/fetch-from-sitemap');
5+
const fs = require('fs');
6+
const generateExcel = require('./lib/generate-excel');
7+
const httpList = require('./lib/http-list');
8+
9+
/**
10+
* Main function that handles config, and trigger functions according to the
11+
* config.
12+
*/
13+
async function checkHttpStatus(config) {
14+
const allowedExportTypes = [
15+
'csv',
16+
'xlsx',
17+
];
18+
var urlsList = [];
19+
20+
if (!config) {
21+
console.error('\x1b[31m%s\x1b[0m', 'Error: Missing required Parameters.');
22+
process.exit();
23+
} else if (!config.options) {
24+
config.options = {};
25+
}
26+
27+
if (config.sitemap) {
28+
urlsList = await fetchFromSitemap(config.sitemap);
29+
} else if (config.urls && Array.isArray(config.urls)) {
30+
urlsList = config.urls;
31+
}
32+
33+
if (urlsList.length === 0) {
34+
console.error('\x1b[31m%s\x1b[0m', 'Error: No URL(s) found.');
35+
process.exit();
36+
} else if (config.export && !config.export.location) {
37+
console.error('\x1b[31m%s\x1b[0m', 'Error: Missing export location.');
38+
process.exit();
39+
} else if (config.export && !fs.existsSync(config.export.location)) {
40+
console.error('\x1b[31m%s\x1b[0m', 'Error: Export Location is undefined.');
41+
process.exit();
42+
}
43+
44+
const httpStatusList = await httpList(urlsList, config.options);
45+
46+
if (config.export && !config.export.format) {
47+
config.export.format = 'xlsx';
48+
}
49+
50+
if (config.export && allowedExportTypes.includes(config.export.format)) {
51+
const urlLength = Math.max(...urlsList.map((el) => el.length));
52+
const rowLength = {
53+
'errorMessage': 50,
54+
'requestedUrl': urlLength,
55+
'url': urlLength + 20
56+
};
57+
58+
generateExcel(httpStatusList, rowLength, config.export);
59+
} else {
60+
consoleColumns(httpStatusList);
61+
}
62+
63+
// Add empty line
64+
console.log();
65+
console.log('\x1b[32m%s\x1b[0m', 'HTTP Status check completed!');
66+
}
67+
68+
module.exports = checkHttpStatus;

lib/check-status-code.js

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
'use strict';
2+
3+
const axios = require('axios');
4+
5+
/**
6+
* Check HTTP Status as per settings and return status code and other
7+
* information for further process.
8+
*/
9+
function axiosRequest(urlToCheck, axiosOptions, redirect) {
10+
var httpStatus = [
11+
'',
12+
0,
13+
'',
14+
urlToCheck,
15+
''
16+
];
17+
18+
if (!redirect) {
19+
httpStatus[0] = urlToCheck;
20+
}
21+
22+
return new Promise((resolve) => {
23+
axios.get(urlToCheck, axiosOptions)
24+
.then((response) => {
25+
httpStatus[2] = response.status;
26+
if (redirect) {
27+
httpStatus[1] = '';
28+
}
29+
30+
resolve(httpStatus);
31+
})
32+
.catch(async (error) => {
33+
var statusLists = [];
34+
35+
if (error.response && error.response.status) {
36+
httpStatus[2] = error.response.status;
37+
if (error.response.status >= 300 && error.response.status < 400) {
38+
const redUrl = error.response.headers.location;
39+
const checkType = await axiosRequest(redUrl, axiosOptions, true);
40+
41+
httpStatus[3] = error.response.headers.location;
42+
statusLists[0] = httpStatus;
43+
44+
if (redirect) {
45+
httpStatus[1] = '';
46+
} else if (typeof checkType[0] === 'object') {
47+
httpStatus[1] = checkType.length;
48+
} else {
49+
httpStatus[1] = 1;
50+
}
51+
52+
if (!redirect && typeof checkType[0] === 'object') {
53+
let childLinks = 1;
54+
checkType.forEach((element) => {
55+
statusLists[childLinks] = element;
56+
childLinks += 1;
57+
});
58+
} else {
59+
statusLists[1] = checkType;
60+
}
61+
} else {
62+
statusLists = httpStatus;
63+
}
64+
} else {
65+
httpStatus[1] = '';
66+
httpStatus[3] = '';
67+
if (error.message) {
68+
httpStatus[4] = error.message;
69+
} else {
70+
httpStatus[4] = error;
71+
}
72+
73+
statusLists = httpStatus;
74+
}
75+
76+
resolve(statusLists);
77+
});
78+
});
79+
}
80+
81+
/**
82+
* Call main function to generate array with all the required information
83+
* and await until that all are not completed.
84+
*/
85+
async function checkStatusCode(urlToCheck, options) {
86+
const statusList = [];
87+
88+
var axiosOptions = {
89+
'maxRedirects': 0
90+
};
91+
var statusArray = [];
92+
93+
// Custom headers to be sent.
94+
if (options.headers) {
95+
axiosOptions.headers = options.headers;
96+
}
97+
98+
// Specifies the number of milliseconds before the request times out.
99+
if (options.timeout) {
100+
axiosOptions.timeout = options.timeout;
101+
}
102+
103+
// Indicates that HTTP Basic auth should be used, and supplies credentials.
104+
if (options.auth) {
105+
axiosOptions.auth = options.auth;
106+
}
107+
108+
statusArray = await axiosRequest(urlToCheck, axiosOptions);
109+
if (typeof statusArray[0] === 'object') {
110+
statusArray.forEach((row) => {
111+
statusList.push(row);
112+
});
113+
} else {
114+
statusList.push(statusArray);
115+
}
116+
117+
return Promise.resolve(statusList);
118+
}
119+
120+
module.exports = checkStatusCode;

lib/console-columns.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'use strict';
2+
3+
const columnify = require('columnify');
4+
5+
/**
6+
* List down all the URLs with the status code in console.
7+
*/
8+
function terminalColumns(statusList) {
9+
const data = [];
10+
11+
// Add empty line
12+
console.log();
13+
14+
statusList.forEach((singleStatus) => {
15+
data.push({
16+
'# Redirects': singleStatus[1],
17+
'Error Message': singleStatus[4],
18+
'Requested URL': singleStatus[0],
19+
'Status Code': singleStatus[2],
20+
'URL': singleStatus[3],
21+
});
22+
});
23+
24+
console.log(columnify(data, {
25+
'columnSplitter': '|',
26+
'columns': [
27+
'Requested URL',
28+
'# Redirects',
29+
'Status Code',
30+
'URL',
31+
'Error Message'
32+
]
33+
}));
34+
}
35+
36+
module.exports = terminalColumns;

0 commit comments

Comments
 (0)