stack-analyze 1.1.9 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/about.js +14 -10
- package/api/webApis.js +25 -0
- package/cli.js +117 -381
- package/functions/animeInfo.js +15 -21
- package/functions/bitly.js +11 -16
- package/functions/cryptoList.js +6 -14
- package/functions/gitUser.js +13 -18
- package/functions/hardware.js +32 -16
- package/functions/moviesInfo.js +5 -6
- package/functions/multipleStack.js +11 -26
- package/functions/pageSpeed.js +52 -96
- package/functions/password.js +20 -0
- package/functions/scraping.js +84 -143
- package/functions/singleStack.js +3 -6
- package/functions/twitch.js +15 -22
- package/hash/queryTools.js +81 -0
- package/hash/webTools.js +58 -0
- package/index.cjs +162 -197
- package/index.mjs +160 -191
- package/package.json +12 -12
- package/readme.md +27 -4
- package/utils.js +40 -4
- package/validations/infoValidations.js +37 -0
- package/validations/webValidations.js +33 -0
- package/demo.js +0 -20
package/functions/scraping.js
CHANGED
|
@@ -4,150 +4,91 @@ import colors from "colors";
|
|
|
4
4
|
import { printTable } from "console-table-printer";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* @typedef {
|
|
8
|
-
* @property {function(): Promise<void>} options.title
|
|
9
|
-
* @property {function(): Promise<void>} options.images
|
|
10
|
-
* @property {function(): Promise<void>} options.metadata
|
|
11
|
-
* @property {function(): Promise<void>} options.headings
|
|
12
|
-
* @property {function(): Promise<void>} options.table_heading
|
|
13
|
-
* @property {function(): Promise<void>} options.table_data
|
|
14
|
-
* @property {function(): Promise<void>} options.links
|
|
15
|
-
* @property {function(): Promise<void>} options.cites
|
|
7
|
+
* @typedef {"title"|"images"|"metadata"|"headings"|"table_heading"|"table_data"|"links"|"cites"} Options
|
|
16
8
|
*
|
|
9
|
+
* It takes a URL and an option as arguments, and then it scrapes the page at the URL for the option
|
|
17
10
|
* @param {string} url
|
|
18
|
-
* @
|
|
11
|
+
* @param {Options} options
|
|
12
|
+
* @returns {Promise<void>}
|
|
19
13
|
*/
|
|
20
|
-
export default function scrape(url) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
$ = load(data);
|
|
101
|
-
|
|
102
|
-
const tableColumnList = $("td").map((i, el) => $(el).text()).toArray();
|
|
103
|
-
|
|
104
|
-
tableColumnList.length === 0
|
|
105
|
-
? console.info("no found td tags")
|
|
106
|
-
: printTable(tableColumnList);
|
|
107
|
-
} catch (err) { console.error(colors.red(err.message)); }
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const links = async () => {
|
|
112
|
-
try {
|
|
113
|
-
const { data } = await scraping.get("");
|
|
114
|
-
$ = load(data);
|
|
115
|
-
|
|
116
|
-
const linkList = $("a").map((i, el) => ({
|
|
117
|
-
url: $(el).attr("href"),
|
|
118
|
-
text: $(el).text()
|
|
119
|
-
})).toArray()
|
|
120
|
-
.filter(({ url }) => url.indexOf("#") !== 0);
|
|
121
|
-
|
|
122
|
-
printTable(linkList);
|
|
123
|
-
} catch (err) { console.error(colors.red(err.message)); }
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
const cites = async () => {
|
|
127
|
-
try {
|
|
128
|
-
const { data } = await scraping.get("");
|
|
129
|
-
$ = load(data);
|
|
130
|
-
|
|
131
|
-
const citeList = $("q, blockquote").map((i, el) => ({
|
|
132
|
-
citeTag: $(el).prop("tagName"),
|
|
133
|
-
citeLink: $(el).attr("cite"),
|
|
134
|
-
citeText: $(el).text()
|
|
135
|
-
})).toArray();
|
|
136
|
-
|
|
137
|
-
citeList.length === 0
|
|
138
|
-
? console.info("no found q and/or blockquote tags")
|
|
139
|
-
: printTable(citeList);
|
|
140
|
-
} catch (err) { console.error(colors.red(err.message)); }
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
title,
|
|
145
|
-
images,
|
|
146
|
-
metadata,
|
|
147
|
-
headings,
|
|
148
|
-
table_heading,
|
|
149
|
-
table_data,
|
|
150
|
-
links,
|
|
151
|
-
cites
|
|
152
|
-
};
|
|
14
|
+
export default async function scrape(url, options) {
|
|
15
|
+
try {
|
|
16
|
+
const { data } = await axios.get(url);
|
|
17
|
+
const $ = load(data);
|
|
18
|
+
|
|
19
|
+
const scraping = {
|
|
20
|
+
title: () => console.info($("title").text()),
|
|
21
|
+
images() {
|
|
22
|
+
const imageList = $("img").map((i, el) => ({
|
|
23
|
+
imagePath: $(el).attr("src"),
|
|
24
|
+
imageTitle: $(el).attr("alt")
|
|
25
|
+
})).toArray();
|
|
26
|
+
|
|
27
|
+
imageList.length === 0
|
|
28
|
+
? console.info("no found images")
|
|
29
|
+
: printTable(imageList);
|
|
30
|
+
},
|
|
31
|
+
metadata() {
|
|
32
|
+
const metadataList = $("meta").map((i, el) => ({
|
|
33
|
+
metaInfo: $(el).attr("name"),
|
|
34
|
+
metaContent: $(el).attr("content")
|
|
35
|
+
})).toArray()
|
|
36
|
+
.filter((data) => data?.metaInfo);
|
|
37
|
+
|
|
38
|
+
printTable(metadataList);
|
|
39
|
+
},
|
|
40
|
+
headings() {
|
|
41
|
+
const headingList = $("h1, h2, h3, h4, h5, h6").map((i, el) => ({
|
|
42
|
+
headingTag: $(el).prop("tagName"),
|
|
43
|
+
headingText: $(el).text()
|
|
44
|
+
})).toArray();
|
|
45
|
+
|
|
46
|
+
printTable(headingList);
|
|
47
|
+
},
|
|
48
|
+
tableHead() {
|
|
49
|
+
const tableHeadList = $("th").map((i, el) => ({
|
|
50
|
+
headingRow: i,
|
|
51
|
+
text: $(el).text()
|
|
52
|
+
})).toArray();
|
|
53
|
+
|
|
54
|
+
tableHeadList.length === 0
|
|
55
|
+
? console.info("no found th tags")
|
|
56
|
+
: printTable(tableHeadList);
|
|
57
|
+
},
|
|
58
|
+
tableData() {
|
|
59
|
+
const tableColumnList = $("td").map((i, el) => ({
|
|
60
|
+
tableRow: i + 1,
|
|
61
|
+
tableData: $(el).text(),
|
|
62
|
+
})).toArray();
|
|
63
|
+
|
|
64
|
+
tableColumnList.length === 0
|
|
65
|
+
? console.info("no found td tags")
|
|
66
|
+
: console.table(tableColumnList.slice(0, 10), ["tableData"]);
|
|
67
|
+
},
|
|
68
|
+
links() {
|
|
69
|
+
const linkList = $("a").map((i, el) => ({
|
|
70
|
+
url: $(el).attr("href"),
|
|
71
|
+
text: $(el).text()
|
|
72
|
+
})).toArray()
|
|
73
|
+
.filter(({ url }) => url.indexOf("#") !== 0);
|
|
74
|
+
|
|
75
|
+
printTable(linkList);
|
|
76
|
+
},
|
|
77
|
+
cites() {
|
|
78
|
+
const citeList = $("q, blockquote").map((i, el) => ({
|
|
79
|
+
citeTag: $(el).prop("tagName"),
|
|
80
|
+
citeLink: $(el).attr("cite"),
|
|
81
|
+
citeText: $(el).text()
|
|
82
|
+
})).toArray();
|
|
83
|
+
|
|
84
|
+
citeList.length === 0
|
|
85
|
+
? console.info("no found q and/or blockquote tags")
|
|
86
|
+
: printTable(citeList);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
scraping[options]();
|
|
91
|
+
} catch (err) {
|
|
92
|
+
console.error(colors.red(err.message));
|
|
93
|
+
}
|
|
153
94
|
}
|
package/functions/singleStack.js
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
// module
|
|
2
|
-
import Wappalyzer from "wappalyzer";
|
|
3
|
-
import figlet from "figlet";
|
|
4
2
|
import colors from "colors";
|
|
5
3
|
import { printTable } from "console-table-printer";
|
|
6
4
|
|
|
7
5
|
// list format
|
|
8
6
|
import { listFormat } from "../utils.js";
|
|
7
|
+
import { wappalyzer } from "../api/webApis.js";
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
*
|
|
12
11
|
* @description call single website tech stack analyze
|
|
12
|
+
* @async
|
|
13
13
|
* @param { string } url - analyze single website stack
|
|
14
14
|
* @returns { Promise<void> } - return async results single web
|
|
15
|
-
*
|
|
16
15
|
*/
|
|
17
16
|
export default async function singleStack(url) {
|
|
18
|
-
const wappalyzer = await new Wappalyzer;
|
|
19
|
-
|
|
20
17
|
try {
|
|
21
18
|
await wappalyzer.init();
|
|
22
19
|
|
|
@@ -36,7 +33,7 @@ export default async function singleStack(url) {
|
|
|
36
33
|
};
|
|
37
34
|
});
|
|
38
35
|
|
|
39
|
-
console.info(
|
|
36
|
+
console.info(url.green);
|
|
40
37
|
|
|
41
38
|
printTable(stackResult);
|
|
42
39
|
} catch (err) {
|
package/functions/twitch.js
CHANGED
|
@@ -3,42 +3,35 @@ import { default as axios } from "axios";
|
|
|
3
3
|
import { format } from "timeago.js";
|
|
4
4
|
import colors from "colors";
|
|
5
5
|
|
|
6
|
-
// table
|
|
7
|
-
import { printTable } from "console-table-printer";
|
|
8
|
-
|
|
9
6
|
/**
|
|
10
7
|
*
|
|
11
8
|
* @description twitch user info
|
|
12
|
-
* @
|
|
13
|
-
* @param {string}
|
|
9
|
+
* @async
|
|
10
|
+
* @param { string } twitchUser - twitch user for search
|
|
11
|
+
* @param { string } twitchClient - twitch client code
|
|
12
|
+
* @param { string } apiToken - twitch api token
|
|
14
13
|
* @returns { Promise<void> } - return twitch results
|
|
15
14
|
*/
|
|
16
|
-
|
|
15
|
+
export default async function twitchInfo(twitchUser, twitchClient, apiToken) {
|
|
17
16
|
|
|
18
17
|
try {
|
|
19
|
-
const { data: twitchData } = await axios.get(
|
|
18
|
+
const { data: twitchData } = await axios.get("https://api.twitch.tv/helix/users", {
|
|
19
|
+
params: { login: twitchUser },
|
|
20
20
|
headers: {
|
|
21
21
|
Authorization: `Bearer ${apiToken}`,
|
|
22
22
|
"Client-Id": twitchClient
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
const result =
|
|
27
|
-
display_name,
|
|
28
|
-
broadcaster_type,
|
|
29
|
-
view_count,
|
|
30
|
-
created_at
|
|
31
|
-
}
|
|
32
|
-
display_name,
|
|
33
|
-
broadcaster_type,
|
|
34
|
-
view_count,
|
|
35
|
-
createdTime: format(created_at)
|
|
36
|
-
}));
|
|
26
|
+
const result = {
|
|
27
|
+
username: twitchData.data[0].display_name,
|
|
28
|
+
broadcaster: twitchData.data[0]?.broadcaster_type || "user",
|
|
29
|
+
viewCount: twitchData.data[0].view_count,
|
|
30
|
+
accountAge: format(twitchData.data[0].created_at)
|
|
31
|
+
};
|
|
37
32
|
|
|
38
|
-
|
|
33
|
+
console.table(result);
|
|
39
34
|
} catch (err) {
|
|
40
35
|
console.error(colors.red(err));
|
|
41
36
|
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export default twitchInfo;
|
|
37
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// inquirer
|
|
2
|
+
import inquirer from "inquirer";
|
|
3
|
+
|
|
4
|
+
// functions
|
|
5
|
+
import genPassword from "../functions/password.js";
|
|
6
|
+
import bitlyInfo from "../functions/bitly.js";
|
|
7
|
+
import cryptoMarket from "../functions/cryptoList.js";
|
|
8
|
+
import githubInfo from "../functions/gitUser.js";
|
|
9
|
+
import animeSearch from "../functions/animeInfo.js";
|
|
10
|
+
import movieDB from "../functions/moviesInfo.js";
|
|
11
|
+
import twitchInfo from "../functions/twitch.js";
|
|
12
|
+
|
|
13
|
+
// fields
|
|
14
|
+
import {
|
|
15
|
+
bitlyQuery,
|
|
16
|
+
promptParams,
|
|
17
|
+
promptKey
|
|
18
|
+
} from "../validations/infoValidations.js";
|
|
19
|
+
|
|
20
|
+
/** query tools */
|
|
21
|
+
const queryTools = {
|
|
22
|
+
github_info(refreshCallback) {
|
|
23
|
+
console.clear();
|
|
24
|
+
inquirer.prompt([promptParams("gitUser", "enter a github user for search")])
|
|
25
|
+
.then(({ gitUser }) => {
|
|
26
|
+
githubInfo(gitUser);
|
|
27
|
+
setTimeout(refreshCallback, 2e3);
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
anime_Search(refreshCallback) {
|
|
31
|
+
console.clear();
|
|
32
|
+
inquirer.prompt([promptParams("query", "")])
|
|
33
|
+
.then(({ query }) => {
|
|
34
|
+
animeSearch(query);
|
|
35
|
+
setTimeout(refreshCallback, 2e3);
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
bitly_info(refreshCallback) {
|
|
39
|
+
console.clear();
|
|
40
|
+
inquirer.prompt([bitlyQuery, promptKey("token", "enter a bitly token")])
|
|
41
|
+
.then(({ bitlyLink, token }) => {
|
|
42
|
+
bitlyInfo(bitlyLink, token);
|
|
43
|
+
setTimeout(refreshCallback, 2e3);
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
movie_info(refreshCallback) {
|
|
47
|
+
console.clear();
|
|
48
|
+
inquirer.prompt([
|
|
49
|
+
promptParams("query", "enter movie for search DB"),
|
|
50
|
+
promptKey("token", "enter a token key")
|
|
51
|
+
])
|
|
52
|
+
.then(({ query, token }) => {
|
|
53
|
+
movieDB(query, token);
|
|
54
|
+
setTimeout(refreshCallback, 2e3);
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
twitch_info(refreshCallback) {
|
|
58
|
+
console.clear();
|
|
59
|
+
inquirer.prompt([
|
|
60
|
+
promptParams("twitchUser", "enter a twitch user"),
|
|
61
|
+
promptKey("twitchClient", "enter a twitch client ID"),
|
|
62
|
+
promptKey("twitchToken", "enter a twitch token"),
|
|
63
|
+
])
|
|
64
|
+
.then(({twitchUser, twitchClient, twitchToken}) => {
|
|
65
|
+
twitchInfo(twitchUser, twitchClient, twitchToken);
|
|
66
|
+
setTimeout(refreshCallback, 2e3);
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
crypto_market(refreshCallback) {
|
|
70
|
+
console.clear();
|
|
71
|
+
cryptoMarket();
|
|
72
|
+
setTimeout(refreshCallback, 5e3);
|
|
73
|
+
},
|
|
74
|
+
password(refreshCallback) {
|
|
75
|
+
console.clear();
|
|
76
|
+
genPassword();
|
|
77
|
+
setTimeout(refreshCallback, 3e3);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export default queryTools;
|
package/hash/webTools.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// stock module
|
|
2
|
+
import { performance } from "node:perf_hooks";
|
|
3
|
+
|
|
4
|
+
// inquirer
|
|
5
|
+
import inquirer from "inquirer";
|
|
6
|
+
|
|
7
|
+
// functions
|
|
8
|
+
import singleStack from "../functions/singleStack.js";
|
|
9
|
+
import multipleStack from "../functions/multipleStack.js";
|
|
10
|
+
import pageSpeed from "../functions/pageSpeed.js";
|
|
11
|
+
import scrape from "../functions/scraping.js";
|
|
12
|
+
|
|
13
|
+
// validations
|
|
14
|
+
import {
|
|
15
|
+
multipleWebQuery,
|
|
16
|
+
singleWebQuery,
|
|
17
|
+
webScrapingQuery
|
|
18
|
+
} from "../validations/webValidations.js";
|
|
19
|
+
|
|
20
|
+
const webTools = {
|
|
21
|
+
single(refreshCallback) {
|
|
22
|
+
console.clear();
|
|
23
|
+
inquirer.prompt([singleWebQuery])
|
|
24
|
+
.then(({ url }) => {
|
|
25
|
+
singleStack(url);
|
|
26
|
+
const timeEnd = performance.now();
|
|
27
|
+
setTimeout(refreshCallback, timeEnd);
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
multiple(refreshCallback) {
|
|
31
|
+
console.clear();
|
|
32
|
+
inquirer.prompt([multipleWebQuery])
|
|
33
|
+
.then(({webList}) => {
|
|
34
|
+
multipleStack(webList.split(" "));
|
|
35
|
+
const timeEnd = performance.now();
|
|
36
|
+
setTimeout(refreshCallback, timeEnd);
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
pagespeed(refreshCallback) {
|
|
40
|
+
console.clear();
|
|
41
|
+
inquirer.prompt([singleWebQuery])
|
|
42
|
+
.then(({ url }) => {
|
|
43
|
+
pageSpeed(url);
|
|
44
|
+
const timeEnd = performance.now();
|
|
45
|
+
setTimeout(refreshCallback, timeEnd);
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
scraping(refreshCallback) {
|
|
49
|
+
console.clear();
|
|
50
|
+
inquirer.prompt([singleWebQuery, webScrapingQuery])
|
|
51
|
+
.then(({ url, option }) => {
|
|
52
|
+
scrape(url, option);
|
|
53
|
+
setTimeout(refreshCallback, 3000);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export default webTools;
|