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 CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  stack-analyze all version and notable changes, fixed, remove and new additions in code.
4
4
 
5
+ ## version 1.2.1
6
+ ### fixed
7
+ - rewrite form arrow functions to named function with export default.
8
+ - rewrite some test functions.
9
+ - add regexp form bitly info tool
10
+ ### change
11
+ - renove menu now using categories.
12
+ - add api params.
13
+ - comeback multibar from pagespeed tool
14
+
15
+ ## version 1.2.0
16
+ ### Added
17
+ - new tool password generator
18
+ ### fixed
19
+ - update anime search tool
20
+ - the files modules now using callbacks and remove no using vars
21
+ ### change
22
+ - the web scraping tool decided to use the question returns to the main menu instead of going to the main menu
23
+
5
24
  ## version 1.1.9
6
25
  ### Added
7
26
  - new module cheerio
package/about.js CHANGED
@@ -8,11 +8,11 @@ import { createRequire } from "module";
8
8
  const require = createRequire(import.meta.url);
9
9
  const { license, version } = require("./package.json");
10
10
 
11
+ const timeout = 1e3;
12
+
11
13
  /**
12
14
  * types for about tools
13
15
  *
14
- * @typedef {Object.<string, function(): void>} aboutTable
15
- *
16
16
  * @typedef {Object} info
17
17
  * @property {string} info.mainDeveloper
18
18
  * @property {string} info.version
@@ -35,9 +35,8 @@ const { license, version } = require("./package.json");
35
35
  * @property {string} project.desc
36
36
  */
37
37
 
38
- /** @type {aboutTable} */
39
38
  const aboutTool = {
40
- mainInfo() {
39
+ mainInfo(refreshCallback) {
41
40
  /** @type {info} */
42
41
  const aboutApp = {
43
42
  mainDeveloper: "omega5300",
@@ -47,8 +46,9 @@ const aboutTool = {
47
46
 
48
47
  console.clear();
49
48
  console.table(aboutApp);
49
+ setTimeout(refreshCallback, timeout);
50
50
  },
51
- lineup() {
51
+ lineup(refreshCallback) {
52
52
  /** @type {developerList[]} */
53
53
  const developers = [
54
54
  {
@@ -59,8 +59,9 @@ const aboutTool = {
59
59
 
60
60
  console.clear();
61
61
  printTable(developers);
62
+ setTimeout(refreshCallback, timeout);
62
63
  },
63
- youtubeRecomendation() {
64
+ youtubeRecomendation(refreshCallback) {
64
65
  /** @type {youtube[]} */
65
66
  const youtubeDev = [
66
67
  { youtubeChannel: "fazt", recomendation: "recommend" },
@@ -73,8 +74,9 @@ const aboutTool = {
73
74
 
74
75
  console.clear();
75
76
  printTable(youtubeDev);
77
+ setTimeout(refreshCallback, timeout);
76
78
  },
77
- twitchRecomendation() {
79
+ twitchRecomendation(refreshCallback) {
78
80
  /** @type {twitch[]} */
79
81
  const twitchUsers = [
80
82
  {
@@ -82,14 +84,15 @@ const aboutTool = {
82
84
  },
83
85
  {
84
86
  user: "Lunanny",
85
- details: "audiovisual student even though if has ADHD has a great variety regardless of whether or not he has ADHD."
87
+ details: "audiovisual student with ADHD."
86
88
  }
87
89
  ];
88
90
 
89
91
  console.clear();
90
92
  printTable(twitchUsers);
93
+ setTimeout(refreshCallback, timeout);
91
94
  },
92
- projectsRecomendation() {
95
+ projectsRecomendation(refreshCallback) {
93
96
  /** @type {project[]} */
94
97
  const projects = [
95
98
  {
@@ -98,12 +101,13 @@ const aboutTool = {
98
101
  },
99
102
  {
100
103
  name: "black metal promotion",
101
- desc: "upload new albums and sometimes tracks from upcoming albums with the permission of bands and/or labels"
104
+ desc: "promos albums and community"
102
105
  }
103
106
  ];
104
107
 
105
108
  console.clear();
106
109
  printTable(projects);
110
+ setTimeout(refreshCallback, timeout);
107
111
  }
108
112
  };
109
113
 
package/api/webApis.js ADDED
@@ -0,0 +1,25 @@
1
+ import Wappalyzer from "wappalyzer";
2
+ import { default as axios } from "axios";
3
+
4
+ const wappalyzer = new Wappalyzer();
5
+
6
+ /**
7
+ * It takes a strategy as a parameter and returns a promise that resolves to the response from the
8
+ * Google PageSpeed Insights API
9
+ * @typedef {"mobile"|"desktop"} StrategyOpt
10
+ * @async
11
+ * @param {string} url
12
+ * @param {StrategyOpt} strategy
13
+ */
14
+ const pagespeedApi = async (url, strategy) => await axios.get("https://www.googleapis.com/pagespeedonline/v5/runPagespeed", {
15
+ params: {
16
+ url,
17
+ key: "AIzaSyBEDaW4FxSZ2s1vz5CdD5Ai6PGZGdAzij0",
18
+ strategy
19
+ }
20
+ });
21
+
22
+ export {
23
+ wappalyzer,
24
+ pagespeedApi
25
+ };
package/cli.js CHANGED
@@ -1,431 +1,167 @@
1
1
  #!/usr/bin/env node
2
-
3
- // modules
4
- import { performance } from "perf_hooks";
2
+ import Gauge from "gauge";
3
+ import colors from "colors";
5
4
  import inquirer from "inquirer";
6
5
  import figlet from "figlet";
7
- import colors from "colors";
8
6
 
9
- // hash tables
7
+ import webTools from "./hash/webTools.js";
8
+ import queryTools from "./hash/queryTools.js";
10
9
  import hardwareTools from "./functions/hardware.js";
11
10
  import aboutTool from "./about.js";
12
11
 
13
- import singleStack from "./functions/singleStack.js";
14
- import multipleStack from "./functions/multipleStack.js";
15
- import pageSpeed from "./functions/pageSpeed.js";
16
- import githubInfo from "./functions/gitUser.js";
17
- import animeSearch from "./functions/animeInfo.js";
18
- import cryptoMarket from "./functions/cryptoList.js";
19
- import bitlyInfo from "./functions/bitly.js";
20
- import movieDB from "./functions/moviesInfo.js";
21
- import twitchInfo from "./functions/twitch.js";
22
- import scrape from "./functions/scraping.js";
12
+ import {
13
+ menuOpts,
14
+ menuQueryOpts,
15
+ menuWebOpts,
16
+ menuAboutOpts,
17
+ menuHardwareOpts
18
+ } from "./utils.js";
19
+
20
+ const [ gauge, totalTime, pageSize ] = [ new Gauge(), 1e4, 9 ];
21
+
22
+ /** @returns {void} */
23
+ const exitCli = () => {
24
+ console.clear();
25
+ console.info("thanks for use stack-analyze".green);
26
+ };
23
27
 
24
28
  /**
25
- * @description web scraping menu
26
- * @return { Promise<void>} web scraping options
29
+ * @async
30
+ * @returns {Promise<void>}
27
31
  */
28
- async function scrapingOpts (url) {
29
- console.info("web:", url);
30
-
31
- const { option } = await inquirer.prompt({
32
+ async function webOpts() {
33
+ const { web } = await inquirer.prompt({
32
34
  type: "list",
33
- name: "option",
34
- message: "select a options for scraping",
35
- pageSize: 15,
36
- choices: [
37
- "pageTitle",
38
- "pageImages",
39
- "pageMetadata",
40
- "pageHeadings",
41
- "pageTableHead",
42
- "pageTableData",
43
- "pageLinks",
44
- "pageCites",
45
- "exit to main menu"
46
- ]
35
+ pageSize,
36
+ name: "web",
37
+ message: "enter a web tool option",
38
+ choices: menuWebOpts
47
39
  });
48
-
49
- const {
50
- cites,
51
- headings,
52
- images,
53
- links,
54
- title,
55
- metadata,
56
- table_data,
57
- table_heading
58
- } = scrape(url);
59
40
 
60
- /** @type {Object.<string, function(): void>} */
61
- const scrapeOpt = {
62
- pageTitle() {
63
- title();
64
- const timeScrape = performance.now();
65
- setTimeout(question, timeScrape);
66
- },
67
- pageImages() {
68
- images();
69
- const timeScrape = performance.now();
70
- setTimeout(question, timeScrape);
71
- },
72
- pageMetadata() {
73
- metadata();
74
- const timeScrape = performance.now();
75
- setTimeout(question, timeScrape);
76
- },
77
- pageHeadings() {
78
- headings();
79
- const timeScrape = performance.now();
80
- setTimeout(question, timeScrape);
81
- },
82
- pageTableHead() {
83
- table_heading();
84
- const timeScrape = performance.now();
85
- setTimeout(question, timeScrape);
86
- },
87
- pageTableData() {
88
- table_data();
89
- const timeScrape = performance.now();
90
- setTimeout(question, timeScrape);
91
- },
92
- pageLinks() {
93
- links();
94
- const timeScrape = performance.now();
95
- setTimeout(question, timeScrape);
96
- },
97
- pageCites() {
98
- cites();
99
- const timeScrape = performance.now();
100
- setTimeout(question, timeScrape);
101
- },
102
- };
41
+ web !== "return main menu"
42
+ ? webTools[web](returnMain)
43
+ : mainMenu();
44
+ }
103
45
 
104
- option === "exit to main menu"
105
- ? question()
106
- : scrapeOpt[option]();
46
+ /**
47
+ * @async
48
+ * @returns {Promise<void>}
49
+ */
50
+ async function infoOpts() {
51
+ const { info } = await inquirer.prompt({
52
+ type: "list",
53
+ pageSize,
54
+ name: "info",
55
+ message: "enter a info tool option",
56
+ choices: menuQueryOpts
57
+ });
58
+
59
+ info === "return main menu"
60
+ ? mainMenu()
61
+ : queryTools[info](returnMain);
107
62
  }
108
63
 
109
64
  /**
110
- * @description web scraping menu
111
- * @return { Promise<void>} web scraping options
65
+ * @async
66
+ * @returns {Promise<void>}
112
67
  */
113
- async function scrapingLink() {
114
- console.clear();
115
- const { link } = await inquirer.prompt({
116
- type: "input",
117
- name: "link",
118
- message: "enter a web scraping options?"
68
+ async function hardwareOpts() {
69
+ const { hardware } = await inquirer.prompt({
70
+ type: "list",
71
+ name: "hardware",
72
+ pageSize,
73
+ message: "select a hardware-information option:",
74
+ choices: menuHardwareOpts
119
75
  });
120
76
 
121
- if(link.indexOf("http") === -1) {
122
- console.error("https:// or http:// is required".red);
123
- setTimeout(question, 5000);
124
- } else {
125
- scrapingOpts(link);
126
- }
77
+ hardware !== "return main menu"
78
+ ? hardwareTools[hardware](hardwareOpts)
79
+ : mainMenu();
127
80
  }
128
81
 
129
- /**
130
- * @description about menu
131
- * @return { Promise<void> } about option sections answer
82
+ /**
83
+ * @async
84
+ * @returns {Promise<void>}
132
85
  */
133
86
  async function aboutOpts() {
134
87
  const { about } = await inquirer.prompt({
135
88
  type: "list",
136
- pageSize: 9,
89
+ pageSize,
137
90
  name: "about",
138
91
  message: "select about option info",
139
- choices: [
140
- "mainInfo",
141
- "lineup",
142
- "youtubeRecomendation",
143
- "twitchRecomendation",
144
- "projectsRecomendation",
145
- "return to main menu"
146
- ]
92
+ choices: menuAboutOpts
147
93
  });
148
94
 
149
- if (about !== "return to main menu") {
150
- aboutTool[about]();
151
- setTimeout(aboutOpts, 1000);
152
- } else {
153
- question();
154
- }
95
+ about !== "return main menu"
96
+ ? aboutTool[about](aboutOpts)
97
+ : mainMenu();
155
98
  }
156
99
 
157
100
  /**
158
- *
159
- * @description call the async function return list to question list
160
- * @return { Promise<void> } - return in boolean a result question list
161
- *
101
+ * @async
102
+ * @returns {Promise<void>}
162
103
  */
163
- async function returnQuestion() {
164
- try {
165
- const anw = await inquirer.prompt([
166
- {
167
- type: "confirm",
168
- name: "return",
169
- message: "do you want go to the tools menu?",
170
- }
171
- ]);
104
+ async function mainMenu() {
105
+ console.clear();
106
+ console.info(colors.yellow(figlet.textSync("stack-analyze")));
107
+
108
+ const { option } = await inquirer.prompt({
109
+ type: "list",
110
+ name: "option",
111
+ message: "what option do you want to analyze stack",
112
+ choices: menuOpts
113
+ });
172
114
 
173
- if (anw.return) {
115
+ const menuList = {
116
+ web() {
117
+ console.clear();
118
+ webOpts();
119
+ },
120
+ query() {
121
+ console.clear();
122
+ infoOpts();
123
+ },
124
+ hardware() {
174
125
  console.clear();
175
- question();
176
- } else {
126
+ hardwareOpts();
127
+ },
128
+ about() {
177
129
  console.clear();
178
- console.info("thanks for use stack-analyze".green);
130
+ aboutOpts();
179
131
  }
180
- } catch (err) {
181
- console.error(colors.red(err.message));
182
- }
132
+ };
133
+
134
+ option !== "exit" ?menuList[option]() : exitCli();
183
135
  }
184
136
 
185
137
  /**
186
- * @description This is a hash table with the options of the tools menu.
187
- * @type {Object.<string, function(): void>}
138
+ * @async
139
+ * @returns {Promise<void>}
188
140
  */
189
- const toolsOpts = {
190
- single() {
191
- console.clear();
192
- inquirer.prompt({
193
- name: "url",
194
- message: "enter url for analyze the tech stack:"
195
- }).then(({ url }) => {
196
- if (url.indexOf("http") === 0) {
197
- singleStack(url);
198
- const timeEnd = performance.now();
199
- setTimeout(returnQuestion, timeEnd);
200
- } else {
201
- console.error("please insert a URL with parameter http:// or https://".red);
202
- }
203
- });
204
- },
205
- multiple() {
206
- console.clear();
207
- inquirer.prompt({
208
- name: "urls",
209
- message: "enter URLs for analyze the tech stacks with whitespace without quotes example 'http://example.com https://nodejs.org': \n"
210
- }).then(({ urls }) => {
211
-
212
- if (
213
- urls.match(/(http|https)/g) !== null ||
214
- urls.match(/(http|https)/g) >= 2
215
- ) {
216
- const websites = urls.split(" ");
217
- console.clear();
218
- multipleStack(websites);
219
- const timeEnd = performance.now();
220
- setTimeout(returnQuestion, timeEnd);
221
- } else {
222
- console.error("please in each URL insert a website the parameter https:// or http://".red);
223
- }
224
- });
225
- },
226
- pagespeed() {
227
- console.clear();
228
- inquirer.prompt({
229
- name: "speedWeb",
230
- message: "insert URL for page speed analyze:"
231
- }).then(({ speedWeb }) => {
232
- if (speedWeb.indexOf("http") === 0) {
233
- console.clear();
234
-
235
- // start pagespeed results mobile
236
- figlet.textSync(speedWeb, "Small");
237
- pageSpeed(speedWeb);
238
- const timeEnd = performance.now();
239
- setTimeout(returnQuestion, timeEnd);
240
- } else {
241
- console.error("please insert a URL with parameter https;// or http://".red);
242
- }
243
- });
244
- },
245
- github_info() {
246
- console.clear();
247
- inquirer.prompt({
248
- name: "user",
249
- message: "enter a github user"
250
- }).then(({ user }) => {
251
- if (user !== "") {
252
- console.clear();
253
- githubInfo(user);
254
- setTimeout(returnQuestion, 2000);
255
- } else {
256
- console.error("please the github username is required".red);
257
- }
258
- });
259
- },
260
- anime_search() {
261
- console.clear();
262
- inquirer.prompt({
263
- name: "anime",
264
- message: "enter a anime, movie or ova search"
265
- }).then(({ anime }) => {
266
- if (anime !== "") {
267
- console.clear();
268
- animeSearch(anime);
269
- setTimeout(returnQuestion, 2000);
270
- } else {
271
- console.error("please the anime is required".red);
272
- }
273
- });
274
- },
275
- crypto_market() {
276
- console.clear();
277
- cryptoMarket();
278
- setTimeout(returnQuestion, 5000);
279
- },
280
- bitly_info() {
281
- console.clear();
282
- inquirer.prompt([
283
- {
284
- name: "link",
285
- message: "enter a bitly link without http|https",
286
- },
287
- {
288
- name: "token",
289
- message: "enter a bitly token",
290
- type: "password",
291
- mask: "?"
292
- }
293
- ])
294
- .then(({ link, token }) => {
295
- bitlyInfo(link, token);
296
- setTimeout(returnQuestion, 3000);
297
- });
298
- },
299
- movie_info() {
300
- console.clear();
301
- inquirer.prompt([
302
- {
303
- name: "api_key",
304
- message: "insert api key",
305
- type: "password",
306
- mask: "?"
307
- },
308
- {
309
- name: "query",
310
- message: "please search a movie search",
311
- }
312
- ]).then(({ api_key, query }) => {
313
- console.clear();
314
- movieDB(query, api_key);
315
- setTimeout(returnQuestion, 3000);
316
- });
317
- },
318
- twitch_info() {
319
- console.clear();
320
- inquirer.prompt([
321
- {
322
- name: "user",
323
- message: "get twitch user"
324
- },
325
- {
326
- name: "twitch_client",
327
- message: "enter a twitch token client",
328
- type: "password",
329
- mask: "*"
330
- },
331
- {
332
- name: "twitch_token",
333
- message: "enter a twitch token without the key Bearer",
334
- type: "password",
335
- mask: "?"
336
- }
337
- ]).then(({ user, twitch_client, twitch_token }) => {
338
- if (user !== "" && twitch_client !== "" && twitch_token !== "") {
339
- console.clear();
340
- twitchInfo(user, twitch_client, twitch_token);
341
- setTimeout(returnQuestion, 3000);
342
- } else {
343
- console.error("twitch info fields is required".red);
344
- }
141
+ async function returnMain() {
142
+ try {
143
+ const { returnMain } = await inquirer.prompt({
144
+ type: "confirm",
145
+ name: "returnMain",
146
+ message: "do you want go to the main menu?",
345
147
  });
346
- }
347
- };
348
148
 
349
- /**
350
- * @description call hardware information options
351
- * @returns { Promise<void> } hardware options tool
352
- */
353
- async function hardwareOpts() {
354
- const { hardware } = await inquirer.prompt({
355
- type: "list",
356
- name: "hardware",
357
- pageSize: 9,
358
- message: "select a hardware-information option:",
359
- choices: [
360
- "cpuInfo",
361
- "ramMemInfo",
362
- "osDetail",
363
- "diskInfo",
364
- "controllerInfo",
365
- "displayInfo",
366
- "biosInfo",
367
- "exit to main menu"
368
- ]
369
- });
370
-
371
- if (hardware !== "exit to main menu") {
372
- hardwareTools[hardware]();
373
- setTimeout(hardwareOpts, 1000);
374
- } else {
375
- question();
149
+ returnMain ? mainMenu(): exitCli();
150
+ } catch (err) {
151
+ console.error(colors.bgRed(err.message));
376
152
  }
377
153
  }
378
154
 
379
- /**
380
- *
381
- * @description call the function question raw list options
382
- * @returns { Promise<void> } return exit question
383
- *
384
- */
385
- async function question() {
386
- console.clear();
387
- console.info(colors.yellow(figlet.textSync("stack-analyze")));
388
- const { analyze } = await inquirer.prompt({
389
- type: "list",
390
- pageSize: 15,
391
- name: "analyze",
392
- message: "what option do you want to analyze stack",
393
- choices: [
394
- "single",
395
- "multiple",
396
- "pagespeed",
397
- "github_info",
398
- "anime_search",
399
- "crypto_market",
400
- "bitly_info",
401
- "movie_info",
402
- "twitch_info",
403
- "hardware tools",
404
- "scraping",
405
- "about",
406
- "exit"
407
- ]
408
- });
155
+ for (let i = 50; i < totalTime; i += 50) {
156
+ const percentage = i / totalTime;
409
157
 
410
- switch (analyze) {
411
- case "hardware tools":
412
- hardwareOpts();
413
- break;
414
- case "about":
415
- aboutOpts();
416
- break;
417
- case "scraping":
418
- scrapingLink();
419
- break;
420
- case "exit":
421
- console.clear();
422
- console.info("thanks for use stack-analyze".green);
423
- break;
424
- default:
425
- toolsOpts[analyze]();
426
- break;
427
- }
158
+ setTimeout(() => {
159
+ gauge.pulse();
160
+ gauge.show(`Loading app... ${percentage * 100}%`.random, percentage);
161
+ }, i);
428
162
  }
429
163
 
430
- // call the message title and question list
431
- question();
164
+ setTimeout(() => {
165
+ gauge.hide();
166
+ mainMenu();
167
+ }, totalTime);