stack-analyze 1.3.4 → 1.3.5

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
@@ -4,6 +4,21 @@ stack-analyze all version and notable changes, fixed, remove and new additions i
4
4
 
5
5
  ## generation 4 (ver. 1.3.0 - )
6
6
 
7
+ ### version 1.3.5
8
+ #### Added
9
+ - new tool poker game rule selector "poker rule".
10
+
11
+ #### changed
12
+ - change inquirer to @inquirer/prompts.
13
+ - about.js file now using esm with json modules.
14
+ - all tools now using new inquirer methods.
15
+
16
+ #### fixed
17
+ - add question for anime search tool.
18
+
19
+ #### remove
20
+ - remove validations folder.
21
+
7
22
  ### version 1.3.4
8
23
  #### changed
9
24
  - new ui cli for potter search tool & save file.
@@ -1,8 +1,8 @@
1
1
  // print table
2
- const { printTable } = require("console-table-printer");
2
+ import { printTable } from "console-table-printer";
3
3
 
4
4
  // package.json
5
- const { license, version } = require("./package.json");
5
+ const { default: { license, version}} = await import("./package.json", {with: {type: "json" }});
6
6
 
7
7
  const timeout = 1e3;
8
8
 
@@ -118,4 +118,4 @@ const aboutTool = {
118
118
  }
119
119
  };
120
120
 
121
- module.exports = aboutTool;
121
+ export default aboutTool;
@@ -0,0 +1,5 @@
1
+ import axios from "axios";
2
+
3
+ export const pokerApi = axios.create({
4
+ baseURL: "https://bicyclecards.com/how-to-play/",
5
+ });
@@ -2,5 +2,4 @@ import axios from "axios";
2
2
 
3
3
  export const wallpapersURL = axios.create({
4
4
  baseURL: "https://sol-moon-wallpapers.vercel.app/",
5
- responseType: "stream"
6
5
  });
package/cli.js CHANGED
@@ -1,15 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import Gauge from "gauge";
3
3
  import colors from "colors";
4
- import inquirer from "inquirer";
4
+ import { confirm } from "@inquirer/prompts";
5
5
  import figlet from "figlet";
6
6
 
7
+ import { stackMenu } from "./menu.js";
8
+
7
9
  import webTools from "./hash/webTools.js";
8
10
  import queryTools from "./hash/queryTools.js";
9
11
  import infoTools from "./hash/infoTools.js";
10
12
  import utilityTools from "./hash/utilityTools.js";
11
13
  import wallpaperSelect from "./hash/wallpaperSelect.js";
12
- import aboutTool from "./about.cjs";
14
+ import aboutTool from "./about.js";
13
15
 
14
16
  import {
15
17
  menuOpts,
@@ -36,10 +38,8 @@ const exitCli = () => {
36
38
  async function webOpts() {
37
39
  console.info(colors.yellow(figlet.textSync("web options")));
38
40
 
39
- const { web } = await inquirer.prompt({
40
- type: "list",
41
+ const web = await stackMenu({
41
42
  pageSize,
42
- name: "web",
43
43
  message: "enter a web tool option",
44
44
  choices: menuWebOpts
45
45
  });
@@ -56,10 +56,8 @@ async function webOpts() {
56
56
  async function infoOpts() {
57
57
  console.info(colors.yellow(figlet.textSync("info options")));
58
58
 
59
- const { info } = await inquirer.prompt({
60
- type: "list",
59
+ const info = await stackMenu({
61
60
  pageSize,
62
- name: "info",
63
61
  message: "enter a info tool option",
64
62
  choices: menuInfoOpts
65
63
  });
@@ -76,10 +74,8 @@ async function infoOpts() {
76
74
  async function queryOpts() {
77
75
  console.info(colors.yellow(figlet.textSync("query options")));
78
76
 
79
- const { query } = await inquirer.prompt({
80
- type: "list",
77
+ const query = await stackMenu({
81
78
  pageSize,
82
- name: "query",
83
79
  message: "enter a query tool option",
84
80
  choices: menuQueryOpts
85
81
  });
@@ -96,10 +92,8 @@ async function queryOpts() {
96
92
  async function wallpapersOpts() {
97
93
  console.info(colors.yellow(figlet.textSync("wallpapers")));
98
94
 
99
- const { wallpaper } = await inquirer.prompt({
100
- type: "list",
95
+ const wallpaper = await stackMenu({
101
96
  pageSize,
102
- name: "wallpaper",
103
97
  message: "enter a wallpaper selector",
104
98
  choices: menuWallpaperOpts
105
99
  });
@@ -116,10 +110,8 @@ async function wallpapersOpts() {
116
110
  async function utilityOpts() {
117
111
  console.info(colors.yellow(figlet.textSync("utility options")));
118
112
 
119
- const { utility } = await inquirer.prompt({
120
- type: "list",
113
+ const utility = await stackMenu({
121
114
  pageSize,
122
- name: "utility",
123
115
  message: "enter a utility tool option",
124
116
  choices: menuUtilityOpts
125
117
  });
@@ -136,10 +128,8 @@ async function utilityOpts() {
136
128
  async function aboutOpts() {
137
129
  console.info(colors.yellow(figlet.textSync("About Menu")));
138
130
 
139
- const { about } = await inquirer.prompt({
140
- type: "list",
131
+ const about = await stackMenu({
141
132
  pageSize,
142
- name: "about",
143
133
  message: "select about option info",
144
134
  choices: menuAboutOpts
145
135
  });
@@ -157,11 +147,9 @@ async function mainMenu() {
157
147
  console.clear();
158
148
  console.info(colors.yellow(figlet.textSync("stack-analyze")));
159
149
 
160
- const { option } = await inquirer.prompt({
161
- type: "list",
162
- name: "option",
163
- message: "what option do you want to analyze stack",
164
- choices: menuOpts
150
+ const option = await stackMenu({
151
+ message: "what option do you want to analyze stack",
152
+ choices: menuOpts
165
153
  });
166
154
 
167
155
  const menuList = {
@@ -200,9 +188,7 @@ async function mainMenu() {
200
188
  */
201
189
  async function returnMain() {
202
190
  try {
203
- const { returnMain } = await inquirer.prompt({
204
- type: "confirm",
205
- name: "returnMain",
191
+ const returnMain = await confirm({
206
192
  message: "do you want go to the main menu?",
207
193
  });
208
194
 
@@ -0,0 +1,42 @@
1
+ import { load } from "cheerio";
2
+ import colors from "colors";
3
+
4
+ import { pokerApi } from "../api/pokerApi.js";
5
+
6
+ /**
7
+ * @typedef {"go-fish"|"gin-rummy"|"blackjack"|"slapjack"|"basics-of-poker"|"texas-holdem-poker"} Options
8
+ * @params {Options} game
9
+ * @returns {Promise<void>}
10
+ */
11
+ export default async function pokerGame(game) {
12
+ try {
13
+ const { data } = await pokerApi.get(game);
14
+
15
+ // extract rules
16
+ const $ = load(data);
17
+
18
+ const [age, players] = $(".border-brand-blue-pale div:not(.text-brand-blue)").map(
19
+ (i, el) => $(el).text()
20
+ ).get().slice(1);
21
+
22
+ const howPlayTitle = $("h3.text-2xl").map(
23
+ (i, el) => $(el).text()
24
+ ).get();
25
+
26
+ const howPlayDesc = $("h3.text-2xl+p.mb-5").map(
27
+ (i, el) => $(el).text()
28
+ ).toArray();
29
+
30
+ // poker game
31
+ const pokerGame = {
32
+ title: $("title").text(),
33
+ age, players,
34
+ ...(Object.fromEntries(
35
+ howPlayTitle.map((item, i) => [item, howPlayDesc[i]])
36
+ ))
37
+ };
38
+ console.table(pokerGame);
39
+ } catch(err) {
40
+ console.info(colors.red(err.message));
41
+ }
42
+ }
@@ -67,6 +67,6 @@ export default async function twitchInfo({
67
67
  printTable(result);
68
68
  stackSave("twitch-users.json", JSON.stringify(result, null, 2));
69
69
  } catch (err) {
70
- console.error(colors.red(err));
70
+ console.error(colors.red(err.message));
71
71
  }
72
72
  }
package/hash/infoTools.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // inquirer
2
- import inquirer from "inquirer";
2
+ import { input, password } from "@inquirer/prompts";
3
3
 
4
4
  // functions
5
5
  import bitlyInfo from "../functions/bitly.js";
@@ -7,50 +7,54 @@ import cryptoMarket from "../functions/cryptoList.js";
7
7
  import githubInfo from "../functions/gitUser.js";
8
8
  import bundlephobia from "../functions/bundlephobia.js";
9
9
 
10
- // fields
11
- import {
12
- bitlyQuery,
13
- promptParams,
14
- promptKey
15
- } from "../validations/infoValidations.js";
10
+ // bitly regexp
11
+ const bitlyRegexp = /bit\.ly\//g;
16
12
 
17
13
  const infoTools = {
18
- github_info(refreshCallback) {
14
+ async github_info(refreshCallback) {
19
15
  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
- });
16
+
17
+ const gitUser = await input({
18
+ message: "enter a github user for search",
19
+ required: true
20
+ });
21
+
22
+ githubInfo(gitUser);
23
+ setTimeout(refreshCallback, 2e3);
27
24
  },
28
- bitly_info(refreshCallback) {
25
+ async bitly_info(refreshCallback) {
29
26
  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
- });
27
+
28
+ const { bitlyLink, token } = {
29
+ bitlyLink: await input({
30
+ message: "enter a short link:",
31
+ validate: input => bitlyRegexp.test(input) || "only bitly link".yellow
32
+ }),
33
+ token: await password({
34
+ message: "enter a bitly token",
35
+ required: true,
36
+ mask: true
37
+ })
38
+ };
39
+
40
+ bitlyInfo(bitlyLink, token);
41
+ setTimeout(refreshCallback, 2e3);
38
42
  },
39
43
  crypto_market(refreshCallback) {
40
44
  console.clear();
41
45
  cryptoMarket();
42
46
  setTimeout(refreshCallback, 5e3);
43
47
  },
44
- bundlephobia_info(refreshCallback) {
48
+ async bundlephobia_info(refreshCallback) {
45
49
  console.clear();
46
- inquirer.prompt([
47
- promptParams("pkgName", "enter a npm package name for search info size")
48
- ])
49
- .then(({ pkgName }) => {
50
- console.info(pkgName);
51
- bundlephobia(pkgName);
52
- setTimeout(refreshCallback, 5e3);
53
- });
50
+
51
+ const pkgName = await input({
52
+ message: "enter a npm package name for search info size"
53
+ });
54
+
55
+ console.info(pkgName);
56
+ bundlephobia(pkgName);
57
+ setTimeout(refreshCallback, 5e3);
54
58
  },
55
59
  };
56
60
 
@@ -1,5 +1,5 @@
1
1
  // inquirer
2
- import inquirer from "inquirer";
2
+ import { input, password, select, number } from "@inquirer/prompts";
3
3
 
4
4
  // functions
5
5
  import animeSearch from "../functions/animeInfo.js";
@@ -9,110 +9,107 @@ import twitchInfo from "../functions/twitch.js";
9
9
  import deezer from "../functions/deezer.js";
10
10
  import potterSearch from "../functions/potterSearch.js";
11
11
 
12
- // fields
13
- import {
14
- promptParams,
15
- promptKey
16
- } from "../validations/infoValidations.js";
17
-
18
12
  /** query tools */
19
13
  const queryTools = {
20
- anime_Search(refreshCallback) {
14
+ async anime_Search(refreshCallback) {
21
15
  console.clear();
22
- inquirer.prompt([promptParams("query", "")])
23
- .then(({ query }) => {
24
- animeSearch(query);
25
- setTimeout(refreshCallback, 2e3);
26
- });
16
+
17
+ const query = await input({
18
+ message: "enter a anime keyword for search",
19
+ required: true
20
+ });
21
+
22
+ animeSearch(query);
23
+ setTimeout(refreshCallback, 2e3);
27
24
  },
28
- movie_info(refreshCallback) {
25
+ async movie_info(refreshCallback) {
29
26
  console.clear();
30
- inquirer.prompt([
31
- promptParams("query", "enter movie for search DB"),
32
- promptKey("token", "enter a token key")
33
- ])
34
- .then(({ query, token }) => {
35
- movieDB(query, token);
36
- setTimeout(refreshCallback, 2e3);
37
- });
27
+
28
+ const { query, token } = {
29
+ query: await input({
30
+ message: "enter movie for search DB",
31
+ required: true
32
+ }),
33
+ token: await password({
34
+ message: "enter a token key",
35
+ required: true,
36
+ mask: true
37
+ })
38
+ };
39
+
40
+ movieDB(query, token);
41
+ setTimeout(refreshCallback, 2e3);
38
42
  },
39
- pokemon_info(refreshCallback) {
43
+ async pokemon_info(refreshCallback) {
40
44
  console.clear();
41
- inquirer.prompt([
42
- {
43
- type: "list",
44
- name: "pokeOpt",
45
- message: "enter a opt for start search",
46
- choices: ["ID", "Name"],
47
- },
48
- {
49
- type: "number",
50
- name: "pokeId",
51
- message: "enter a poekmon ID:",
52
- validate: value => value > 0 || "this field not allowed empty values, NaN or number less or equal to 0",
53
- filter(value) {
54
- if(!value) return "";
55
-
56
- const int = parseInt(value);
57
-
58
- if(isNaN(int)) return "";
59
-
60
- return int <= 0 ? "" : int;
61
- },
62
- when: ({pokeOpt}) => pokeOpt === "ID",
63
- },
64
- {
65
- type: "input",
66
- name: "pokeName",
67
- message: "enter a poekmon name:",
68
- validate(input) {
69
- const excludeNumbers = /[^0-9]/;
70
-
71
- return excludeNumbers.test(input) || "the pokemon name is required";
72
- },
73
- when: ({pokeOpt}) => pokeOpt === "Name",
74
- },
75
- ])
76
- .then(anw => {
77
- pokemonInfo(anw?.pokeName || anw?.pokeId);
78
- setTimeout(refreshCallback, 6e3);
79
- });
45
+
46
+ const pokeSelect = await select({
47
+ message: "enter a opt for start search",
48
+ choices: ["id", "name"],
49
+ });
50
+
51
+ const opt = pokeSelect === "id"
52
+ ? await number({
53
+ message: "enter a poekmon ID:",
54
+ min: 1,
55
+ required: true
56
+ }) : await input({
57
+ message: "enter a poekmon name:",
58
+ required: true,
59
+ validate: input => /[^0-9]/.test(input) || "the pokemon name is required"
60
+ });
61
+
62
+ pokemonInfo(opt);
63
+ setTimeout(refreshCallback, 6e3);
80
64
  },
81
- twitch_info(refreshCallback) {
65
+ async twitch_info(refreshCallback) {
82
66
  console.clear();
83
67
 
84
- inquirer.prompt([
85
- promptParams("twitchSeparator", "enter a separator for split example ',':"),
86
- promptParams("twitchUsers", "enter a twitch users example 'a,b,c'"),
87
- promptKey("twitchClient", "enter a twitch client ID"),
88
- promptKey("twitchToken", "enter a twitch token"),
89
- ])
90
- .then(({ twitchSeparator, twitchUsers, twitchClient, twitchToken }) => {
91
- twitchInfo({ twitchSeparator, twitchUsers, twitchClient, twitchToken });
92
- setTimeout(refreshCallback, 2e3);
93
- });
68
+ const { twitchSeparator, twitchUsers, twitchClient, twitchToken } = {
69
+ twitchSeparator: await input({
70
+ message: "enter a separator for split example ',':",
71
+ required: true
72
+ }),
73
+ twitchUsers: await input({
74
+ message: "enter a twitch users example 'a,b,c'",
75
+ required: true
76
+ }),
77
+ twitchClient: await password({
78
+ message: "enter a twitch client ID:",
79
+ required: true,
80
+ mask: true
81
+ }),
82
+ twitchToken: await password({
83
+ message: "enter a twitch token:",
84
+ required: true,
85
+ mask: true
86
+ })
87
+ };
88
+
89
+ twitchInfo({ twitchSeparator, twitchUsers, twitchClient, twitchToken });
90
+ setTimeout(refreshCallback, 2e3);
94
91
  },
95
- deezer(refreshCallback) {
92
+ async deezer(refreshCallback) {
96
93
  console.clear();
97
94
 
98
- inquirer.prompt([
99
- promptParams("query", "enter a query for search")
100
- ])
101
- .then(({ query }) => {
102
- deezer(query);
103
- setTimeout(refreshCallback, 5e3);
104
- });
95
+ const query = await input({
96
+ message: "enter a query for search",
97
+ required: true
98
+ });
99
+
100
+ setTimeout(refreshCallback, 5e3);
101
+ deezer(query);
105
102
  },
106
- potter_search(refreshCallback) {
103
+ async potter_search(refreshCallback) {
107
104
  console.clear();
108
105
 
109
- inquirer.prompt([
110
- promptParams("search", "enter a keyword or name for search")
111
- ])
112
- .then(({ search }) => {
113
- potterSearch(search);
114
- setTimeout(refreshCallback, 5e3);
115
- });
106
+ const search = await input({
107
+ message: "enter a keyword or name for search",
108
+ required: true
109
+ });
110
+
111
+ potterSearch(search);
112
+ setTimeout(refreshCallback, 5e3);
116
113
  }
117
114
  };
118
115
 
@@ -1,7 +1,11 @@
1
+ // menu
2
+ import { stackMenu } from "../menu.js";
3
+ import { pokerGameOpts } from "../utils.js";
4
+
1
5
  // functions
2
6
  import genPassword from "../functions/password.js";
3
7
  import hardware from "../functions/hardware.js";
4
-
8
+ import pokerGame from "../functions/poker.js";
5
9
 
6
10
  const utilityTools = {
7
11
  password(refreshCallback) {
@@ -13,6 +17,15 @@ const utilityTools = {
13
17
  console.clear();
14
18
  hardware();
15
19
  setTimeout(refreshCallback, 3e3);
20
+ },
21
+ async poker_game(refreshCallback) {
22
+ const pokeOpt = await stackMenu({
23
+ message: "select a poker game for view instructions:",
24
+ choices: pokerGameOpts
25
+ });
26
+
27
+ pokerGame(pokeOpt);
28
+ setTimeout(refreshCallback, 5e3);
16
29
  }
17
30
  };
18
31
 
@@ -1,6 +1,5 @@
1
1
  // inquirer
2
- import inquirer from "inquirer";
3
- import colors from "colors";
2
+ import { select } from "@inquirer/prompts";
4
3
 
5
4
  import { wallpaperDownload } from "../functions/download.js";
6
5
 
@@ -8,68 +7,52 @@ const message = "select a wallpaper for download:";
8
7
  const backMenu = "back to menu";
9
8
 
10
9
  const wallpaperSelect = {
11
- solMoon(refreshCallback, alternativeCallback) {
10
+ async solMoon(refreshCallback, alternativeCallback) {
12
11
  const solMoonWallpapers = [...Array(20).keys()]
13
12
  .map(i => `sol-moon${i + 1}.jpeg`);
14
13
 
15
- inquirer.prompt([
16
- {
17
- type: "list",
18
- name: "solMoon",
19
- message,
20
- choices: [...solMoonWallpapers, backMenu]
21
- }
22
- ])
23
- .then(({ solMoon }) => {
24
- if (solMoon === backMenu) {
25
- alternativeCallback();
26
- } else {
27
- wallpaperDownload("sol-moon", solMoon);
28
- setTimeout(refreshCallback, 5000);
29
- }
30
- })
31
- .catch(err => console.error(colors.red(err.message)));
14
+
15
+ const solMoon = await select({
16
+ message, choices: [...solMoonWallpapers, backMenu]
17
+ });
18
+
19
+ if (solMoon === backMenu) {
20
+ alternativeCallback();
21
+ } else {
22
+ wallpaperDownload("sol-moon", solMoon);
23
+ setTimeout(refreshCallback, 5000);
24
+ }
32
25
  },
33
- dimensions(refreshCallback, alternativeCallback) {
26
+ async dimensions(refreshCallback, alternativeCallback) {
34
27
  const dimensionsWallpapers = [...Array(12).keys()]
35
28
  .map(i => `dimensions-${i + 1}.jpeg`);
36
29
 
37
- inquirer.prompt([
38
- {
39
- type: "list",
40
- name: "dimensions",
41
- message,
42
- choices: [...dimensionsWallpapers, backMenu]
43
- }
44
- ])
45
- .then(({ dimensions }) => {
46
- if(dimensions === backMenu) {
47
- alternativeCallback();
48
- } else {
49
- wallpaperDownload("dimensions", dimensions);
50
- setTimeout(refreshCallback, 5000);
51
- }
52
- });
30
+
31
+ const dimensions = await select({
32
+ message, choices: [...dimensionsWallpapers, backMenu]
33
+ });
34
+
35
+ if(dimensions === backMenu) {
36
+ alternativeCallback();
37
+ } else {
38
+ wallpaperDownload("dimensions", dimensions);
39
+ setTimeout(refreshCallback, 5000);
40
+ }
53
41
  },
54
- seyyahi2(refreshCallback, alternativeCallback) {
42
+ async seyyahi2(refreshCallback, alternativeCallback) {
55
43
  const seyyahiWallpapers = [...Array(14).keys()]
56
44
  .map(i => `seyyahi2-wallpaper${i + 1}.jpg`);
57
-
58
- inquirer.prompt([
59
- {
60
- type: "list",
61
- name: "seyyahi2",
62
- message,
63
- choices: [...seyyahiWallpapers, backMenu]
64
- }
65
- ])
66
- .then(({ seyyahi2 }) => {
67
- if(seyyahi2 === backMenu) {
68
- alternativeCallback();
69
- } else {
70
- wallpaperDownload("seyyahi2", seyyahi2);
71
- }
72
- });
45
+
46
+ const seyyahi2 = await select({
47
+ message, choices: [...seyyahiWallpapers, backMenu]
48
+ });
49
+
50
+ if(seyyahi2 === backMenu) {
51
+ alternativeCallback();
52
+ } else {
53
+ wallpaperDownload("seyyahi2", seyyahi2);
54
+ setTimeout(refreshCallback, 5000);
55
+ }
73
56
  }
74
57
  };
75
58
 
package/hash/webTools.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { performance } from "node:perf_hooks";
3
3
 
4
4
  // inquirer
5
- import inquirer from "inquirer";
5
+ import { input } from "@inquirer/prompts";
6
6
 
7
7
  // functions
8
8
  import singleStack from "../functions/singleStack.js";
@@ -11,57 +11,81 @@ import pageSpeed from "../functions/pageSpeed.js";
11
11
  import scrape from "../functions/scraping.js";
12
12
  import cssValidate from "../functions/cssValidator.js";
13
13
 
14
- // validations
15
- import {
16
- multipleWebQuery,
17
- singleWebQuery,
18
- webScrapingQuery
19
- } from "../validations/webValidations.js";
14
+ import { stackMenu } from "../menu.js";
15
+ import { scrapingOpts } from "../utils.js";
16
+
17
+ // regex
18
+ const webRegex = /https?:\/\//g;
20
19
 
21
20
  const webTools = {
22
- single(refreshCallback) {
21
+ async single(refreshCallback) {
23
22
  console.clear();
24
- inquirer.prompt([singleWebQuery])
25
- .then(({ url }) => {
26
- singleStack(url);
27
- const timeEnd = performance.now();
28
- setTimeout(refreshCallback, timeEnd);
29
- });
23
+
24
+ const url = await input({
25
+ message: "enter a url:",
26
+ validate: input => webRegex.test(input) || "enter a url valid".yellow
27
+ });
28
+
29
+ singleStack(url);
30
+ const timeEnd = performance.now();
31
+ setTimeout(refreshCallback, timeEnd);
30
32
  },
31
- multiple(refreshCallback) {
33
+ async multiple(refreshCallback) {
32
34
  console.clear();
33
- inquirer.prompt([multipleWebQuery])
34
- .then(({webList}) => {
35
- multipleStack(webList.split(" "));
36
- const timeEnd = performance.now();
37
- setTimeout(refreshCallback, timeEnd);
38
- });
35
+
36
+ const webList = await input({
37
+ message: "enter URLs for analyze the tech stacks with whitespace without quotes example 'http://example.com https://nodejs.org': \n",
38
+ validate(input) {
39
+ const pass = input.match(webRegex);
40
+
41
+ return pass && pass.length === 2 || "must be 2 sites";
42
+ }
43
+ });
44
+
45
+ multipleStack(webList.split(" "));
46
+ const timeEnd = performance.now();
47
+ setTimeout(refreshCallback, timeEnd);
39
48
  },
40
- pagespeed(refreshCallback) {
49
+ async pagespeed(refreshCallback) {
41
50
  console.clear();
42
- inquirer.prompt([singleWebQuery])
43
- .then(({ url }) => {
44
- pageSpeed(url);
45
- const timeEnd = performance.now();
46
- setTimeout(refreshCallback, timeEnd);
47
- });
51
+
52
+ const url = await input({
53
+ message: "enter a url:",
54
+ validate: input => webRegex.test(input) || "enter a url valid".yellow
55
+ });
56
+
57
+ pageSpeed(url);
58
+ const timeEnd = performance.now();
59
+ setTimeout(refreshCallback, timeEnd);
48
60
  },
49
- scraping(refreshCallback) {
61
+ async scraping(refreshCallback) {
50
62
  console.clear();
51
- inquirer.prompt([singleWebQuery, webScrapingQuery])
52
- .then(({ url, option }) => {
53
- scrape(url, option);
54
- setTimeout(refreshCallback, 3000);
55
- });
63
+
64
+ const { url, option } = {
65
+ option: await stackMenu({
66
+ pageSize: 9,
67
+ message: "select a web scraping option:",
68
+ choices: scrapingOpts
69
+ }),
70
+ url: await input({
71
+ message: "enter a url:",
72
+ validate: input => webRegex.test(input) || "enter a url valid".yellow
73
+ })
74
+ };
75
+
76
+ scrape(url, option);
77
+ setTimeout(refreshCallback, 3000);
56
78
  },
57
- css_validate(refreshCallback) {
79
+ async css_validate(refreshCallback) {
58
80
  console.clear();
59
- inquirer.prompt([singleWebQuery])
60
- .then(({ url }) => {
61
- cssValidate(url);
62
- const timeEnd = performance.now();
63
- setTimeout(refreshCallback, timeEnd);
64
- });
81
+ const url = await input({
82
+ message: "enter a url:",
83
+ validate: input => webRegex.test(input) || "enter a url valid".yellow
84
+ });
85
+
86
+ cssValidate(url);
87
+ const timeEnd = performance.now();
88
+ setTimeout(refreshCallback, timeEnd);
65
89
  }
66
90
  };
67
91
 
package/menu.js ADDED
@@ -0,0 +1,13 @@
1
+ import { select } from "@inquirer/prompts";
2
+
3
+ /**
4
+ * @typedef {Object} Menu
5
+ * @property {string} message
6
+ * @property {string[]} choices
7
+ * @property {number} [pageSize]
8
+ * @param {Menu}
9
+ * @returns {Promise<any>}
10
+ */
11
+ export const stackMenu = async ({message, choices, pageSize}) => await select({
12
+ message, choices, pageSize
13
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stack-analyze",
3
- "version": "1.3.4",
3
+ "version": "1.3.5",
4
4
  "type": "module",
5
5
  "description": "cli tech stack analyze and pagespeed with node.js using the wappalyzer module. with google pagespeed api, hardware and crypto market",
6
6
  "main": "cli.js",
@@ -8,6 +8,7 @@
8
8
  "stack-analyze": "cli.js"
9
9
  },
10
10
  "dependencies": {
11
+ "@inquirer/prompts": "^7.3.2",
11
12
  "axios": "^1.7.7",
12
13
  "boxen": "^8.0.1",
13
14
  "cheerio": "^1.0.0",
@@ -0,0 +1,31 @@
1
+ import { input} from "@inquirer/prompts";
2
+
3
+ import { scrapingOpts } from "../utils.js";
4
+
5
+ import { stackMenu } from "../menu.js";
6
+
7
+ // regex
8
+ const webRegex = /https?:\/\//g;
9
+
10
+ // inputs
11
+ const url = await input({
12
+ message: "enter a url:",
13
+ validate: input => webRegex.test(input) || "enter a url valid".yellow
14
+ });
15
+
16
+ const webList = await input({
17
+ message: "enter URLs for analyze the tech stacks with whitespace without quotes example 'http://example.com https://nodejs.org': \n",
18
+ validate(input) {
19
+ const pass = input.match(webRegex);
20
+
21
+ return pass && pass.length === 2 || "must be 2 sites";
22
+ }
23
+ });
24
+
25
+ const webScrapingQuery = await stackMenu({
26
+ pageSize: 9,
27
+ message: "select a web scraping option:",
28
+ choices: scrapingOpts
29
+ });
30
+
31
+ export { url, webList, webScrapingQuery };
package/utils.js CHANGED
@@ -12,7 +12,8 @@ const currency = new Intl.NumberFormat("en-us", {
12
12
  const returnMainOpts = "return main menu";
13
13
 
14
14
  const menuOpts = [
15
- "web", "info", "query", "utility", "wallpapers", "about", "exit"
15
+ "web", "info", "query", "utility", "wallpapers",
16
+ "about", "exit"
16
17
  ];
17
18
 
18
19
  const menuWebOpts = [
@@ -30,7 +31,7 @@ const menuQueryOpts = [
30
31
  ];
31
32
 
32
33
  const menuUtilityOpts = [
33
- "hardware", "password", returnMainOpts
34
+ "hardware", "password", "poker_game", returnMainOpts
34
35
  ];
35
36
 
36
37
  const menuWallpaperOpts = ["solMoon", "dimensions", "seyyahi2", returnMainOpts];
@@ -50,6 +51,11 @@ const scrapingOpts = [
50
51
  "tableHead", "tableData", "links", "cites"
51
52
  ];
52
53
 
54
+ const pokerGameOpts = [
55
+ "go-fish", "gin-rummy", "blackjack", "slapjack",
56
+ "basics-of-poker", "texas-holdem-poker"
57
+ ];
58
+
53
59
  /**
54
60
  *
55
61
  * @param {string} filename
@@ -89,6 +95,7 @@ export {
89
95
  menuAboutOpts,
90
96
  scrapingOpts,
91
97
  stackSave,
98
+ pokerGameOpts,
92
99
  exitCli
93
100
  };
94
101