stack-analyze 1.2.0 → 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,16 @@
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
+
5
15
  ## version 1.2.0
6
16
  ### Added
7
17
  - new tool password generator
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,432 +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";
23
- import genPassword from "./functions/password.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
+ };
24
27
 
25
28
  /**
26
- * @description web scraping menu
27
- * @return { Promise<void>} web scraping options
29
+ * @async
30
+ * @returns {Promise<void>}
28
31
  */
29
- async function scrapingOpts (url) {
30
- console.info("web:", url);
31
-
32
- const { option } = await inquirer.prompt({
32
+ async function webOpts() {
33
+ const { web } = await inquirer.prompt({
33
34
  type: "list",
34
- name: "option",
35
- message: "select a options for scraping",
36
- pageSize: 15,
37
- choices: [
38
- "pageTitle",
39
- "pageImages",
40
- "pageMetadata",
41
- "pageHeadings",
42
- "pageTableHead",
43
- "pageTableData",
44
- "pageLinks",
45
- "pageCites",
46
- "exit to main menu"
47
- ]
35
+ pageSize,
36
+ name: "web",
37
+ message: "enter a web tool option",
38
+ choices: menuWebOpts
48
39
  });
49
-
50
- const {
51
- cites,
52
- headings,
53
- images,
54
- links,
55
- title,
56
- metadata,
57
- table_data,
58
- table_heading
59
- } = scrape(url);
60
-
61
- const timeScrape = 2000;
62
40
 
63
- /** @type {Object.<string, function(): void>} */
64
- const scrapeOpt = {
65
- pageTitle() {
66
- title();
67
- setTimeout(returnQuestion, timeScrape);
68
- },
69
- pageImages() {
70
- images();
71
- setTimeout(returnQuestion, timeScrape);
72
- },
73
- pageMetadata() {
74
- metadata();
75
- setTimeout(returnQuestion, timeScrape);
76
- },
77
- pageHeadings() {
78
- headings();
79
- setTimeout(returnQuestion, timeScrape);
80
- },
81
- pageTableHead() {
82
- table_heading();
83
- setTimeout(returnQuestion, timeScrape);
84
- },
85
- pageTableData() {
86
- table_data();
87
- setTimeout(returnQuestion, timeScrape);
88
- },
89
- pageLinks() {
90
- links();
91
- setTimeout(returnQuestion, timeScrape);
92
- },
93
- pageCites() {
94
- cites();
95
- setTimeout(returnQuestion, timeScrape);
96
- },
97
- };
41
+ web !== "return main menu"
42
+ ? webTools[web](returnMain)
43
+ : mainMenu();
44
+ }
98
45
 
99
- option === "exit to main menu"
100
- ? question()
101
- : 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);
102
62
  }
103
63
 
104
64
  /**
105
- * @description web scraping menu
106
- * @return { Promise<void>} web scraping options
65
+ * @async
66
+ * @returns {Promise<void>}
107
67
  */
108
- async function scrapingLink() {
109
- console.clear();
110
- const { link } = await inquirer.prompt({
111
- type: "input",
112
- name: "link",
113
- 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
114
75
  });
115
76
 
116
- if(link.indexOf("http") === -1) {
117
- console.error("https:// or http:// is required".red);
118
- setTimeout(question, 5000);
119
- } else {
120
- scrapingOpts(link);
121
- }
77
+ hardware !== "return main menu"
78
+ ? hardwareTools[hardware](hardwareOpts)
79
+ : mainMenu();
122
80
  }
123
81
 
124
- /**
125
- * @description about menu
126
- * @return { Promise<void> } about option sections answer
82
+ /**
83
+ * @async
84
+ * @returns {Promise<void>}
127
85
  */
128
86
  async function aboutOpts() {
129
87
  const { about } = await inquirer.prompt({
130
88
  type: "list",
131
- pageSize: 9,
89
+ pageSize,
132
90
  name: "about",
133
91
  message: "select about option info",
134
- choices: [
135
- "mainInfo",
136
- "lineup",
137
- "youtubeRecomendation",
138
- "twitchRecomendation",
139
- "projectsRecomendation",
140
- "return to main menu"
141
- ]
92
+ choices: menuAboutOpts
142
93
  });
143
94
 
144
- if (about !== "return to main menu") {
145
- aboutTool[about]();
146
- setTimeout(aboutOpts, 1000);
147
- } else {
148
- question();
149
- }
95
+ about !== "return main menu"
96
+ ? aboutTool[about](aboutOpts)
97
+ : mainMenu();
150
98
  }
151
99
 
152
100
  /**
153
- *
154
- * @description call the async function return list to question list
155
- * @return { Promise<void> } - return in boolean a result question list
156
- *
101
+ * @async
102
+ * @returns {Promise<void>}
157
103
  */
158
- async function returnQuestion() {
159
- try {
160
- const anw = await inquirer.prompt([
161
- {
162
- type: "confirm",
163
- name: "return",
164
- message: "do you want go to the tools menu?",
165
- }
166
- ]);
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
+ });
167
114
 
168
- if (anw.return) {
115
+ const menuList = {
116
+ web() {
117
+ console.clear();
118
+ webOpts();
119
+ },
120
+ query() {
121
+ console.clear();
122
+ infoOpts();
123
+ },
124
+ hardware() {
169
125
  console.clear();
170
- question();
171
- } else {
126
+ hardwareOpts();
127
+ },
128
+ about() {
172
129
  console.clear();
173
- console.info("thanks for use stack-analyze".green);
130
+ aboutOpts();
174
131
  }
175
- } catch (err) {
176
- console.error(colors.red(err.message));
177
- }
132
+ };
133
+
134
+ option !== "exit" ?menuList[option]() : exitCli();
178
135
  }
179
136
 
180
137
  /**
181
- * @description This is a hash table with the options of the tools menu.
182
- * @type {Object.<string, function(): void>}
138
+ * @async
139
+ * @returns {Promise<void>}
183
140
  */
184
- const toolsOpts = {
185
- single() {
186
- console.clear();
187
- inquirer.prompt({
188
- name: "url",
189
- message: "enter url for analyze the tech stack:"
190
- }).then(({ url }) => {
191
- if (url.indexOf("http") === 0) {
192
- singleStack(url);
193
- const timeEnd = performance.now();
194
- setTimeout(returnQuestion, timeEnd);
195
- } else {
196
- console.error("please insert a URL with parameter http:// or https://".red);
197
- }
198
- });
199
- },
200
- multiple() {
201
- console.clear();
202
- inquirer.prompt({
203
- name: "urls",
204
- message: "enter URLs for analyze the tech stacks with whitespace without quotes example 'http://example.com https://nodejs.org': \n"
205
- }).then(({ urls }) => {
206
-
207
- if (
208
- urls.match(/(http|https)/g) !== null ||
209
- urls.match(/(http|https)/g) >= 2
210
- ) {
211
- const websites = urls.split(" ");
212
- console.clear();
213
- multipleStack(websites);
214
- const timeEnd = performance.now();
215
- setTimeout(returnQuestion, timeEnd);
216
- } else {
217
- console.error("please in each URL insert a website the parameter https:// or http://".red);
218
- }
219
- });
220
- },
221
- pagespeed() {
222
- console.clear();
223
- inquirer.prompt({
224
- name: "speedWeb",
225
- message: "insert URL for page speed analyze:"
226
- }).then(({ speedWeb }) => {
227
- if (speedWeb.indexOf("http") === 0) {
228
- console.clear();
229
-
230
- // start pagespeed results mobile
231
- figlet.textSync(speedWeb, "Small");
232
- pageSpeed(speedWeb);
233
- const timeEnd = performance.now();
234
- setTimeout(returnQuestion, timeEnd);
235
- } else {
236
- console.error("please insert a URL with parameter https;// or http://".red);
237
- }
238
- });
239
- },
240
- github_info() {
241
- console.clear();
242
- inquirer.prompt({
243
- name: "user",
244
- message: "enter a github user"
245
- }).then(({ user }) => {
246
- if (user !== "") {
247
- console.clear();
248
- githubInfo(user);
249
- setTimeout(returnQuestion, 2000);
250
- } else {
251
- console.error("please the github username is required".red);
252
- }
253
- });
254
- },
255
- anime_search() {
256
- console.clear();
257
- inquirer.prompt({
258
- name: "anime",
259
- message: "enter a anime, movie or ova search"
260
- }).then(({ anime }) => {
261
- if (anime !== "") {
262
- console.clear();
263
- animeSearch(anime);
264
- setTimeout(returnQuestion, 2000);
265
- } else {
266
- console.error("please the anime is required".red);
267
- }
268
- });
269
- },
270
- crypto_market() {
271
- console.clear();
272
- cryptoMarket();
273
- setTimeout(returnQuestion, 5000);
274
- },
275
- password() {
276
- console.clear();
277
- genPassword();
278
- setTimeout(returnQuestion, 3000);
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
- "password",
406
- "about",
407
- "exit"
408
- ]
409
- });
155
+ for (let i = 50; i < totalTime; i += 50) {
156
+ const percentage = i / totalTime;
410
157
 
411
- switch (analyze) {
412
- case "hardware tools":
413
- hardwareOpts();
414
- break;
415
- case "about":
416
- aboutOpts();
417
- break;
418
- case "scraping":
419
- scrapingLink();
420
- break;
421
- case "exit":
422
- console.clear();
423
- console.info("thanks for use stack-analyze".green);
424
- break;
425
- default:
426
- toolsOpts[analyze]();
427
- break;
428
- }
158
+ setTimeout(() => {
159
+ gauge.pulse();
160
+ gauge.show(`Loading app... ${percentage * 100}%`.random, percentage);
161
+ }, i);
429
162
  }
430
163
 
431
- // call the message title and question list
432
- question();
164
+ setTimeout(() => {
165
+ gauge.hide();
166
+ mainMenu();
167
+ }, totalTime);