stack-analyze 1.2.0 → 1.2.2

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.
@@ -1,11 +1,11 @@
1
- import colors from "colors";
1
+ // save password
2
+ import { stackSave } from "../utils.js";
2
3
 
3
- /**
4
- *
5
- * @description generate a new password
6
- * @returns { void }
7
- */
8
- const genPassword = () => {
4
+ /**
5
+ * It generates a random password
6
+ * @returns {void}
7
+ */
8
+ export default function genPassword() {
9
9
  const chars = "0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*()ABCDEFGHIJKLMNOPQRSTUVWXYZ";
10
10
 
11
11
  // blank password var
@@ -19,7 +19,6 @@ const genPassword = () => {
19
19
  }
20
20
 
21
21
  // print new passwors
22
- console.info(colors.yellow("new password:"), password);
23
- };
24
-
25
- export default genPassword;
22
+ console.info("new password:", password);
23
+ stackSave("password.txt", `new password: ${password}`)
24
+ }
@@ -3,151 +3,131 @@ import { load } from "cheerio";
3
3
  import colors from "colors";
4
4
  import { printTable } from "console-table-printer";
5
5
 
6
+ // stack save
7
+ import { stackSave } from "../utils.js";
8
+
6
9
  /**
7
- * @typedef {Object} options
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
10
+ * @typedef {"title"|"images"|"metadata"|"headings"|"table_heading"|"table_data"|"links"|"cites"} Options
16
11
  *
12
+ * It takes a URL and an option as arguments, and then it scrapes the page at the URL for the option
17
13
  * @param {string} url
18
- * @returns {options}
14
+ * @param {Options} options
15
+ * @returns {Promise<void>}
19
16
  */
20
- export default function scrape(url) {
21
- let $;
22
-
23
- const scraping = axios.create({
24
- baseURL: url
25
- });
26
-
27
- const title = async () => {
28
- try {
29
- const { data } = await scraping.get("");
30
- $ = load(data);
31
-
32
- console.info("title page:", $("title").text());
33
- } catch (err) { console.error(colors.red(err.message)); }
34
- };
35
-
36
- const images = async () => {
37
- try {
38
- const { data } = await scraping.get("");
39
- $ = load(data);
40
-
41
- const imgs = $("img").map((i, el) => ({
42
- imagePath: $(el).attr("src"),
43
- imageTitle: $(el).attr("alt")
44
- })).toArray();
45
-
46
- imgs.length === 0
47
- ? console.info("no found images")
48
- : printTable(imgs);
49
- } catch (err) { console.error(colors.red(err.message)); }
50
- };
51
-
52
- const metadata = async () => {
53
- try {
54
- const { data } = await scraping.get("");
55
- $ = load(data);
56
-
57
- const metadataList = $("meta").map((i, el) => ({
58
- metaInfo: $(el).attr("name"),
59
- metaContent: $(el).attr("content")
60
- })).toArray()
61
- .filter(({ metaInfo }) => metaInfo !== undefined);
62
-
63
- printTable(metadataList);
64
- } catch (err) { console.error(colors.red(err.message)); }
65
- };
66
-
67
- const headings = async () => {
68
- try {
69
- const { data } = await scraping.get("");
70
- $ = load(data);
71
-
72
- const headingList = $("h1, h2, h3, h4, h5, h6").map((i, el) => ({
73
- headingTag: $(el).prop("tagName"),
74
- headingText: $(el).text()
75
- })).toArray();
76
-
77
- printTable(headingList);
78
- } catch (err) { console.error(colors.red(err.message)); }
79
- };
80
-
81
- const table_heading = async () => {
82
- try {
83
- const { data } = await scraping.get("");
84
- $ = load(data);
85
-
86
- const tableHeadList = $("th").map((i, el) => ({
87
- headingRow: i,
88
- text: $(el).text()
89
- })).toArray();
90
-
91
- tableHeadList.length === 0
92
- ? console.info("no found th tags")
93
- : printTable(tableHeadList);
94
- } catch (err) { console.error(colors.red(err.message)); }
95
- };
96
-
97
- const table_data = async () => {
98
- try {
99
- const { data } = await scraping.get("");
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
- };
17
+ export default async function scrape(url, options) {
18
+ try {
19
+ const { data } = await axios.get(url);
20
+ const $ = load(data);
21
+
22
+ let result;
23
+
24
+ const scraping = {
25
+ title() {
26
+ result = `url title: ${$("title").text()}`;
27
+ console.info($("title").text());
28
+ },
29
+ images() {
30
+ const imageList = $("img").map((i, el) => ({
31
+ imagePath: $(el).attr("src"),
32
+ imageTitle: $(el).attr("alt")
33
+ })).toArray();
34
+
35
+ result = imageList.length === 0
36
+ ? "no found images"
37
+ : imageList;
38
+
39
+ typeof result === "string"
40
+ ? console.info(result)
41
+ : printTable(result);
42
+ },
43
+ metadata() {
44
+ const metadataList = $("meta").map((i, el) => ({
45
+ metaInfo: $(el).attr("name"),
46
+ metaContent: $(el).attr("content")
47
+ })).toArray()
48
+ .filter((data) => data?.metaInfo);
49
+
50
+ result = metadataList;
51
+
52
+ printTable(metadataList);
53
+ },
54
+ headings() {
55
+ const headingList = $("h1, h2, h3, h4, h5, h6").map((i, el) => ({
56
+ headingTag: $(el).prop("tagName"),
57
+ headingText: $(el).text()
58
+ })).toArray();
59
+
60
+ result = headingList.length === 0
61
+ ? "no found heading tags"
62
+ : headingList;
63
+
64
+ typeof result === "string"
65
+ ? console.info("no found heading tags")
66
+ :printTable(headingList);
67
+ },
68
+ tableHead() {
69
+ const tableHeadList = $("th").map((i, el) => ({
70
+ thCol: $(el).index(),
71
+ thData: $(el).text()
72
+ })).toArray();
73
+
74
+ result = tableHeadList.length === 0
75
+ ? "no found th tags"
76
+ : tableHeadList;
77
+
78
+ typeof result === "string"
79
+ ? console.info("no found th tags")
80
+ : printTable(tableHeadList);
81
+ },
82
+ tableData() {
83
+ const tableColumnList = $("td").map((i, el) => ({
84
+ rowID: $(el).parent().index(),
85
+ colID: $(el).index(),
86
+ colData: $(el).text(),
87
+ })).toArray();
88
+
89
+ result = tableColumnList.length === 0
90
+ ? "no found td tags"
91
+ : tableColumnList;
92
+
93
+ typeof result === "string"
94
+ ? console.info(result)
95
+ : console.table(result.slice(0, 10));
96
+ },
97
+ links() {
98
+ const linkList = $("a").map((i, el) => ({
99
+ url: $(el).attr("href"),
100
+ text: $(el).text()
101
+ })).toArray()
102
+ .filter(({ url }) => url.indexOf("#") !== 0);
103
+
104
+ result = linkList
105
+
106
+ printTable(linkList);
107
+ },
108
+ cites() {
109
+ const citeList = $("q, blockquote").map((i, el) => ({
110
+ citeTag: $(el).prop("tagName"),
111
+ citeLink: $(el).attr("cite"),
112
+ citeText: $(el).text()
113
+ })).toArray();
114
+
115
+ result = citeList.length === 0
116
+ ? "no found q and/or blockquote tags"
117
+ : citeList;
118
+
119
+ typeof result === "string"
120
+ ? console.info("no found q and/or blockquote tags")
121
+ : printTable(citeList);
122
+ }
123
+ };
124
+
125
+ scraping[options]();
126
+
127
+ typeof result === "string"
128
+ ? stackSave('scraping.txt', result)
129
+ : stackSave('scraping.json', JSON.stringify(result, null, 2));
130
+ } catch (err) {
131
+ console.error(colors.red(err.message));
132
+ }
153
133
  }
@@ -1,22 +1,21 @@
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
- // list format
8
- import { listFormat } from "../utils.js";
5
+ // utils
6
+ import { listFormat, stackSave } from "../utils.js";
7
+
8
+ // wappalyzer
9
+ import { wappalyzer } from "../api/webApis.js";
9
10
 
10
11
  /**
11
12
  *
12
13
  * @description call single website tech stack analyze
14
+ * @async
13
15
  * @param { string } url - analyze single website stack
14
16
  * @returns { Promise<void> } - return async results single web
15
- *
16
17
  */
17
18
  export default async function singleStack(url) {
18
- const wappalyzer = await new Wappalyzer;
19
-
20
19
  try {
21
20
  await wappalyzer.init();
22
21
 
@@ -36,9 +35,11 @@ export default async function singleStack(url) {
36
35
  };
37
36
  });
38
37
 
39
- console.info(colors.green(figlet.textSync(url)));
38
+ console.info(url.green);
39
+
40
+ printTable(stackResult.slice(0, 10));
40
41
 
41
- printTable(stackResult);
42
+ stackSave("single-stack.json", JSON.stringify(stackResult, null, 2));
42
43
  } catch (err) {
43
44
  console.error(colors.red(err.message));
44
45
  }
@@ -1,24 +1,52 @@
1
1
  // modules
2
2
  import { default as axios } from "axios";
3
3
  import { format } from "timeago.js";
4
+ import { printTable } from "console-table-printer";
4
5
  import colors from "colors";
5
6
 
6
- // table
7
- import { printTable } from "console-table-printer";
7
+ // save twitch users
8
+ import { stackSave } from "../utils.js";
9
+
10
+ /**
11
+ * types for twitch info
12
+ *
13
+ * @typedef {Object} Twitch
14
+ * @property {string} Twitch.twitchUsers
15
+ * @property {string} Twitch.twitchSeparator
16
+ * @property {string} Twitch.twitchToken
17
+ * @property {string} Twitch.twitchClient
18
+ */
8
19
 
9
20
  /**
10
- *
11
21
  * @description twitch user info
12
- * @param {string} twitchUser - twitch user for search
13
- * @param {string} apiToken - twitch api token
22
+ * @async
23
+ * @param {Twitch} param
14
24
  * @returns { Promise<void> } - return twitch results
15
25
  */
16
- const twitchInfo = async (twitchUser, twitchClient, apiToken) => {
26
+ export default async function twitchInfo({
27
+ twitchUsers,
28
+ twitchSeparator,
29
+ twitchToken,
30
+ twitchClient
31
+ }) {
32
+
33
+ const userList = twitchUsers.split(twitchSeparator);
34
+
35
+ if(userList.length === 10) {
36
+ console.error("twitch users must be 10".bgRed);
37
+ }
38
+
39
+ const params = new URLSearchParams();
40
+
41
+ userList.forEach((item) => {
42
+ params.append("login", item);
43
+ });
17
44
 
18
45
  try {
19
- const { data: twitchData } = await axios.get(`https://api.twitch.tv/helix/users?login=${twitchUser}`, {
46
+ const { data: twitchData } = await axios.get("https://api.twitch.tv/helix/users", {
47
+ params,
20
48
  headers: {
21
- Authorization: `Bearer ${apiToken}`,
49
+ Authorization: `Bearer ${twitchToken}`,
22
50
  "Client-Id": twitchClient
23
51
  }
24
52
  });
@@ -29,16 +57,16 @@ const twitchInfo = async (twitchUser, twitchClient, apiToken) => {
29
57
  view_count,
30
58
  created_at
31
59
  }) => ({
32
- display_name,
33
- broadcaster_type,
34
- view_count,
35
- createdTime: format(created_at)
60
+ username: display_name,
61
+ broadcaster: broadcaster_type || "user",
62
+ viewCount: view_count,
63
+ accountDate: new Date(created_at).toLocaleDateString(),
64
+ accountAge: format(created_at)
36
65
  }));
37
66
 
38
67
  printTable(result);
68
+ stackSave("twitch-users.json", JSON.stringify(result, null, 2));
39
69
  } catch (err) {
40
70
  console.error(colors.red(err));
41
71
  }
42
- };
43
-
44
- export default twitchInfo;
72
+ }
@@ -0,0 +1,46 @@
1
+ // inquirer
2
+ import inquirer from "inquirer";
3
+
4
+ // functions
5
+ import bitlyInfo from "../functions/bitly.js";
6
+ import cryptoMarket from "../functions/cryptoList.js";
7
+ import githubInfo from "../functions/gitUser.js";
8
+
9
+
10
+ // fields
11
+ import {
12
+ bitlyQuery,
13
+ promptParams,
14
+ promptKey
15
+ } from "../validations/infoValidations.js";
16
+
17
+ const infoTools = {
18
+ github_info(refreshCallback) {
19
+ console.clear();
20
+ inquirer.prompt([
21
+ promptParams("gitUser", "enter a github user for search")
22
+ ])
23
+ .then(({ gitUser }) => {
24
+ githubInfo(gitUser);
25
+ setTimeout(refreshCallback, 2e3);
26
+ });
27
+ },
28
+ bitly_info(refreshCallback) {
29
+ console.clear();
30
+ inquirer.prompt([
31
+ bitlyQuery,
32
+ promptKey("token", "enter a bitly token")
33
+ ])
34
+ .then(({ bitlyLink, token }) => {
35
+ bitlyInfo(bitlyLink, token);
36
+ setTimeout(refreshCallback, 2e3);
37
+ });
38
+ },
39
+ crypto_market(refreshCallback) {
40
+ console.clear();
41
+ cryptoMarket();
42
+ setTimeout(refreshCallback, 5e3);
43
+ },
44
+ };
45
+
46
+ export default infoTools;
@@ -0,0 +1,52 @@
1
+ // inquirer
2
+ import inquirer from "inquirer";
3
+
4
+ // functions
5
+ import animeSearch from "../functions/animeInfo.js";
6
+ import movieDB from "../functions/moviesInfo.js";
7
+ import twitchInfo from "../functions/twitch.js";
8
+
9
+ // fields
10
+ import {
11
+ promptParams,
12
+ promptKey
13
+ } from "../validations/infoValidations.js";
14
+
15
+ /** query tools */
16
+ const queryTools = {
17
+
18
+ anime_Search(refreshCallback) {
19
+ console.clear();
20
+ inquirer.prompt([promptParams("query", "")])
21
+ .then(({ query }) => {
22
+ animeSearch(query);
23
+ setTimeout(refreshCallback, 2e3);
24
+ });
25
+ },
26
+ movie_info(refreshCallback) {
27
+ console.clear();
28
+ inquirer.prompt([
29
+ promptParams("query", "enter movie for search DB"),
30
+ promptKey("token", "enter a token key")
31
+ ])
32
+ .then(({ query, token }) => {
33
+ movieDB(query, token);
34
+ setTimeout(refreshCallback, 2e3);
35
+ });
36
+ },
37
+ twitch_info(refreshCallback) {
38
+ console.clear();
39
+ inquirer.prompt([
40
+ promptParams("twitchSeparator", "enter a separator for split"),
41
+ promptParams("twitchUsers", "enter a twitch user"),
42
+ promptKey("twitchClient", "enter a twitch client ID"),
43
+ promptKey("twitchToken", "enter a twitch token"),
44
+ ])
45
+ .then(({ twitchSeparator, twitchUsers, twitchClient, twitchToken }) => {
46
+ twitchInfo({ twitchSeparator, twitchUsers, twitchClient, twitchToken });
47
+ setTimeout(refreshCallback, 2e3);
48
+ });
49
+ }
50
+ };
51
+
52
+ export default queryTools;
@@ -0,0 +1,21 @@
1
+ // functions
2
+ import genPassword from "../functions/password.js";
3
+ import hardware from "../functions/hardware.js";
4
+
5
+ // opts
6
+ import { menuHardwareOpts } from "../utils.js";
7
+
8
+ const utilityTools = {
9
+ password(refreshCallback) {
10
+ console.clear();
11
+ genPassword();
12
+ setTimeout(refreshCallback, 3e3);
13
+ },
14
+ async hardware(refreshCallback) {
15
+ console.clear();
16
+ hardware();
17
+ setTimeout(refreshCallback, 3e3);
18
+ }
19
+ };
20
+
21
+ export default utilityTools;
@@ -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;