stack-analyze 1.1.2 → 1.1.6

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/index.js CHANGED
@@ -1,404 +1,359 @@
1
- #!/usr/bin/env node
2
-
3
1
  // modules
4
- const { performance } = require("perf_hooks");
5
- const inquirer = require("inquirer");
6
- const { textSync } = require("figlet");
2
+ const axios = require("axios").default;
3
+ const CoinGecko = require("coingecko-api");
7
4
  const {
8
- yellow,
9
- green,
10
- red
11
- } = require("colors");
12
- const { printTable, Table } = require("console-table-printer");
5
+ cpu,
6
+ mem,
7
+ osInfo,
8
+ diskLayout,
9
+ graphics,
10
+ bios
11
+ } = require("systeminformation");
12
+ const Wappalyzer = require("wappalyzer");
13
13
 
14
- // options
15
- const {
16
- aboutApp,
17
- developers,
18
- nonolive,
19
- projects,
20
- twitch,
21
- youtubeDev
22
- } = require("./about");
14
+ // init coingecko api
15
+ const CoinGeckoClient = new CoinGecko();
23
16
 
24
- // analyze web
25
- const singleStack = require("./functions/singleStack");
26
- const multipleStack = require("./functions/multipleStack");
17
+ // functions
27
18
 
28
- // pagespeed web
29
- const { desktop, mobile } = require("./functions/pageSpeed");
19
+ const animeSearch = async (query) => {
20
+ /* error manager */
21
+ try {
22
+ // call api
23
+ const { data } = await axios.get("https://api.jikan.moe/v3/search/anime", {
24
+ params: {
25
+ q: query,
26
+ limit: 10
27
+ }
28
+ });
30
29
 
31
- // github info
32
- const githubInfo = require("./functions/gitUser");
30
+ return data.results;
33
31
 
34
- // anime search
35
- const animeSearch = require("./functions/animeInfo");
32
+ } catch (err) { return err; }
33
+ };
36
34
 
37
- // hardware modules
38
- const {
39
- cpuInfo,
40
- ramMemInfo,
41
- osDetail,
42
- diskInfo,
43
- controllerInfo,
44
- displayInfo,
45
- biosInfo
46
- } = require("./functions/hardware");
47
-
48
- /**
49
- * @description about selected anw
50
- * @param { string } result - about option selected
51
- * @return { void }
52
- */
53
- function aboutSelected(result) {
54
-
55
- // tables
56
- const youtubeDevTable = new Table({
57
- columns: [
58
- {
59
- name: "youtubeChannel",
60
- alignment: "left",
61
- color: "green"
62
- },
63
- {
64
- name: "recomendation",
65
- alignment: "left",
66
- color: "cyan"
67
- }
68
- ]
69
- });
70
- const nonoliveTable = new Table({
71
- columns: [
35
+ const bitlyInfo = async (link, token) => {
36
+ try {
37
+ const { data } = await axios.post(
38
+ "https://api-ssl.bitly.com/v4/expand",
72
39
  {
73
- name: "nonoID",
74
- alignment: "left",
75
- color: "red"
40
+ bitlink_id: link
76
41
  },
77
42
  {
78
- name: "name",
79
- alignment: "left",
80
- color: "yellow"
43
+ headers: {
44
+ Authorization: `Bearer ${token}`,
45
+ "Content-Type": "application/json"
46
+ }
81
47
  }
82
- ]
83
- });
84
-
85
- switch (result) {
86
- case "main info":
87
- console.clear();
88
- console.table(aboutApp);
89
- setTimeout(aboutOpts, 1000);
90
- break;
91
- case "devolepers lineup":
92
- console.clear();
93
- printTable(developers.map((dev, i) => ({ index: i + 1, dev })));
94
- setTimeout(aboutOpts, 1000);
95
- break;
96
- case "youtube streamers recomendation":
97
- console.clear();
98
- youtubeDevTable.addRows(youtubeDev);
99
- youtubeDevTable.printTable();
100
- setTimeout(aboutOpts, 1000);
101
- break;
102
- case "nonolive recomendation":
103
- console.clear();
104
- nonoliveTable.addRows(nonolive);
105
- nonoliveTable.printTable();
106
- setTimeout(aboutOpts, 1000);
107
- break;
108
- case "twitch recomendation":
109
- console.clear();
110
- printTable(twitch.map((streamer, i) => ({ index: i + 1, streamer })));
111
- setTimeout(aboutOpts, 1000);
112
- break;
113
- case "projects recomendation":
114
- console.clear();
115
- printTable(projects.map((project, i) => ({ index: i + 1, project })));
116
- setTimeout(aboutOpts, 1000);
117
- break;
118
-
119
- default:
120
- console.clear();
121
- question();
122
- break;
123
- }
124
- }
48
+ );
49
+
50
+ return data;
51
+ } catch (err) { return err; }
52
+ };
125
53
 
126
- /**
127
- * @description about menu
128
- * @return { void }
54
+ /*
55
+ *
56
+ * @descripiton call the crypto market list
57
+ * @returns { Promise<void> } - return results search
58
+ *
129
59
  */
130
- function aboutOpts() {
131
- inquirer.prompt({
132
- type: "list",
133
- name: "about",
134
- message: "select about option info",
135
- choices: [
136
- "main info",
137
- "devolepers lineup",
138
- "youtube streamers recomendation",
139
- "nonolive recomendation",
140
- "twitch recomendation",
141
- "projects recomendation",
142
- "return to main menu"
143
- ]
144
- }).then(({ about }) => aboutSelected(about))
145
- .catch((err) => console.error(red(err.message)));
60
+ const cryptoMarket = async () => {
61
+ try {
62
+ // start crypto
63
+ const coinData = await CoinGeckoClient.coins.markets({
64
+ per_page: 10
65
+ });
66
+
67
+ // map coinData
68
+ return coinData.data;
69
+ } catch (err) { return err; }
70
+ };
71
+
72
+ async function githubInfo(user) {
73
+ try {
74
+ const { data } = await axios.get(`https://api.github.com/users/${user}`);
75
+
76
+ return data;
77
+ } catch (err) { return err; }
146
78
  }
147
79
 
80
+ async function cpuInfo() {
81
+ try {
82
+ const {
83
+ manufacturer,
84
+ brand,
85
+ speed,
86
+ cores,
87
+ physicalCores,
88
+ processors,
89
+ vendor,
90
+ family,
91
+ model
92
+ } = await cpu();
148
93
 
149
- /**
150
- *
151
- * @description call the async function return list to question list
152
- * @return { Promise<void> } - return in boolean a result question list
153
- *
154
- */
155
- async function returnQuestion() {
94
+ // show results
95
+ return {
96
+ manufacturer,
97
+ brand,
98
+ speed,
99
+ cores,
100
+ physicalCores,
101
+ processors,
102
+ vendor,
103
+ family,
104
+ model
105
+ };
106
+ } catch (err) { return err; }
107
+ }
108
+
109
+ async function ramMemInfo() {
156
110
  try {
157
- const anw = await inquirer.prompt([
158
- {
159
- type: "confirm",
160
- name: "return",
161
- message: "do you want go to the main menu?",
162
- }
163
- ]);
164
-
165
- if (anw.return) {
166
- console.clear();
167
- question();
168
- } else {
169
- console.info(green("thanks for use stack-analyze"));
170
-
171
- }
172
- } catch (err) {
173
- console.error(red(err.message));
174
- }
111
+ const {
112
+ total,
113
+ free,
114
+ used,
115
+ active,
116
+ available
117
+ } = await mem();
118
+
119
+ // show results
120
+ return {
121
+ total_mem: `${(total / 1073741824).toFixed(2)} GB`,
122
+ free_mem: `${(free / 1073741824).toFixed(2)} GB`,
123
+ used_mem: `${(used / 1073741824).toFixed(2)} GB`,
124
+ active_mem: `${(active / 1073741824).toFixed(2)} GB`,
125
+ available_mem: `${(available / 1073741824).toFixed(2)} GB`
126
+ };
127
+ } catch (err) { return err; }
175
128
  }
176
129
 
177
- /**
178
- * @description select a hardware option
179
- * @param { string } result - selected a option hardware
180
- * @return { void }
181
- */
182
- function hardwareSelected(result) {
183
- switch (result) {
184
- case "cpu":
185
- console.clear();
186
- cpuInfo();
187
- setTimeout(hardwareOpts, 1000);
188
- break;
189
- case "ram memory":
190
- console.clear();
191
- ramMemInfo();
192
- setTimeout(hardwareOpts, 1000);
193
- break;
194
- case "os":
195
- console.clear();
196
- osDetail();
197
- setTimeout(hardwareOpts, 1000);
198
- break;
199
- case "disk":
200
- console.clear();
201
- diskInfo();
202
- setTimeout(hardwareOpts, 1000);
203
- break;
204
- case "controller":
205
- console.clear();
206
- controllerInfo();
207
- setTimeout(hardwareOpts, 1000);
208
- break;
209
- case "display":
210
- console.clear();
211
- displayInfo();
212
- setTimeout(hardwareOpts, 1000);
213
- break;
214
- case "bios":
215
- console.clear();
216
- biosInfo();
217
- setTimeout(hardwareOpts, 1000);
218
- break;
219
-
220
- default:
221
- console.clear();
222
- question();
223
- break;
224
- }
130
+ async function osDetail() {
131
+ try {
132
+ const {
133
+ hostname,
134
+ platform,
135
+ distro,
136
+ release,
137
+ kernel,
138
+ arch,
139
+ serial,
140
+ uefi
141
+ } = await osInfo();
142
+
143
+ // show results
144
+ return {
145
+ hostname,
146
+ platform,
147
+ distro,
148
+ release,
149
+ kernel,
150
+ arch,
151
+ serial,
152
+ uefi
153
+ };
154
+ } catch (err) { return err; }
225
155
  }
226
156
 
227
- /**
228
- * @description call hardware information options
229
- * @return { void }
230
- */
231
- function hardwareOpts() {
232
- inquirer.prompt({
233
- type: "list",
234
- name: "hardware",
235
- message: "select a hardware-information option:",
236
- choices: [
237
- "cpu",
238
- "ram memory",
239
- "os",
240
- "disk",
241
- "controller",
242
- "display",
243
- "bios",
244
- "exit to main menu"
245
- ]
246
- }).then(({ hardware }) => hardwareSelected(hardware));
157
+ async function diskInfo() {
158
+ try {
159
+ const disks = await diskLayout();
160
+
161
+ const disksList = disks.map(({
162
+ type,
163
+ name,
164
+ vendor,
165
+ size,
166
+ interfaceType
167
+ }) => ({
168
+ type,
169
+ name,
170
+ vendor,
171
+ diskSize: `${(size / 1073741824).toFixed(2)} GB`,
172
+ interfaceType
173
+ }));
174
+
175
+ return disksList;
176
+
177
+ } catch (err) { return err; }
247
178
  }
248
179
 
249
- /**
250
- *
251
- * @description function register option anwser
252
- * @param { string } result - result option anwser
253
- * @return { void }
254
- *
255
- */
256
- function anwOption(result) {
257
- // options conditional
258
- switch (result) {
259
- case "single":
260
- console.clear();
261
- inquirer.prompt({
262
- name: "url",
263
- message: "enter url for analyze the tech stack:"
264
- })
265
- .then(({ url }) => {
266
- if (url.indexOf("http") === 0) {
267
- singleStack(url);
268
- const timeEnd = performance.now();
269
- setTimeout(returnQuestion, timeEnd);
270
- } else {
271
- console.error(red("please insert a URL with parameter http:// or https://"));
272
- question();
273
- }
274
- });
275
- break;
276
- case "multiple":
277
- console.clear();
278
- inquirer.prompt({
279
- name: "urls",
280
- message: "enter URLs for analyze the tech stacks with whitespace without quotes example 'http://example.com https://nodejs.org': \n"
281
- })
282
- .then(({ urls }) => {
283
- if (
284
- urls.match(/(http|https)/g) !== null ||
285
- urls.match(/(http|https)/g) >= 2
286
- ) {
287
- const websites = urls.split(" ");
288
- console.clear();
289
- multipleStack(websites);
290
- const timeEnd = performance.now();
291
- setTimeout(returnQuestion, timeEnd);
292
- } else {
293
- console.error(red("please in each URL insert a website the parameter https:// or http://"));
294
- question();
295
- }
296
- });
297
- break;
298
- case "pagespeed":
299
- console.clear();
300
- inquirer.prompt({
301
- name: "speedWeb",
302
- message: "insert URL for page speed analyze:"
303
- })
304
- .then(({ speedWeb }) => {
305
- if (speedWeb.indexOf("http") === 0) {
306
- console.clear();
307
- console.info(green(textSync(speedWeb)));
308
-
309
- // start pagespeed results mobile
310
- textSync(speedWeb, "Small");
311
- mobile(speedWeb);
312
- const timeEndA = performance.now();
313
-
314
- // start pagespeed results mobile
315
- desktop(speedWeb);
316
- const timeEndB = performance.now();
317
-
318
- // stop time
319
- setTimeout(returnQuestion, (timeEndA + timeEndB));
320
- } else {
321
- console.error(red("please insert a URL with parameter https;// or http://"));
322
- question();
323
- }
324
- });
325
- break;
326
- case "github-info":
327
- inquirer.prompt({
328
- name: "user",
329
- message: "enter a github user"
180
+ async function controllerInfo() {
181
+ try {
182
+ const { controllers } = await graphics();
183
+
184
+ const controllersList = controllers.map(({
185
+ model,
186
+ vendor,
187
+ vram
188
+ }) => ({
189
+ model,
190
+ vendor,
191
+ vramSize: vram < 1024
192
+ ? `${vram} MB`
193
+ : `${(vram / 1024).toFixed(2)} GB`
194
+ }));
195
+
196
+ return controllersList;
197
+ } catch (err) { return err; }
198
+ }
199
+
200
+ async function displayInfo() {
201
+ try {
202
+ const { displays } = await graphics();
203
+
204
+ const displayList = displays.map(({
205
+ model,
206
+ main,
207
+ connection,
208
+ resolutionX,
209
+ resolutionY
210
+ }) => ({
211
+ model,
212
+ main,
213
+ connection,
214
+ resolutionX,
215
+ resolutionY
216
+ }));
217
+
218
+ return displayList;
219
+ } catch (err) { return err; }
220
+ }
221
+
222
+ async function biosInfo() {
223
+ try {
224
+ const {
225
+ releaseDate,
226
+ vendor,
227
+ revision,
228
+ version
229
+ } = await bios();
230
+
231
+ return { releaseDate, vendor, revision, version };
232
+ } catch (err) { return err; }
233
+ }
234
+
235
+ const movieDB = async (api_key, query) => {
236
+ try {
237
+ const { data } = await axios.get("https://api.themoviedb.org/3/search/movie", {
238
+ params: {
239
+ api_key,
240
+ query,
241
+ page: 1
242
+ }
243
+ });
244
+
245
+ const movieData = data.results
246
+ .map(({
247
+ title,
248
+ original_language,
249
+ popularity,
250
+ vote_average,
251
+ release_date
252
+ }) => ({
253
+ title,
254
+ original_language,
255
+ popularity,
256
+ vote_average,
257
+ release_date
258
+ }))
259
+ .sort((x, y) => {
260
+ // date values
261
+ const primaryDate = new Date(x.release_date);
262
+ const secondaryDate = new Date(y.release_date);
263
+
264
+ return primaryDate.getTime() - secondaryDate.getTime();
330
265
  })
331
- .then(({ user }) => {
332
- if (user !== "") {
333
- console.clear();
334
- githubInfo(user);
335
- setTimeout(returnQuestion, 2000);
336
- } else {
337
- console.error(red("please the github username is required"));
338
- question();
339
- }
340
- });
341
- break;
342
- case "anime-search":
343
- inquirer.prompt({
344
- name: "anime",
345
- message: "enter a anime, music or ova search"
266
+ .filter(({ release_date }) => release_date !== undefined && release_date !== "");
267
+
268
+ return movieData;
269
+ } catch (err) { return err; }
270
+ };
271
+
272
+ async function multipleStack(urls) {
273
+ let result;
274
+ const wappalyzer = new Wappalyzer();
275
+ try {
276
+ await wappalyzer.init();
277
+ result = await Promise.all(
278
+ urls.map(async (url) => {
279
+ const { technologies } = await wappalyzer.open(url).analyze();
280
+ return {
281
+ url,
282
+ technologies
283
+ };
346
284
  })
347
- .then(({ anime }) => {
348
- if (anime !== "") {
349
- console.clear();
350
- animeSearch(anime);
351
- setTimeout(returnQuestion, 5000);
352
- } else {
353
- console.error(red("please the anime is required"));
354
- question();
355
- }
356
- });
357
- break;
358
- case "hardware-information":
359
- console.clear();
360
- hardwareOpts();
361
- break;
362
- case "about":
363
- // about info cli
364
- console.clear();
365
- aboutOpts();
366
- break;
367
- default:
368
- console.clear();
369
- console.info(green("thanks for use stack-analyze"));
370
- break;
371
- }
285
+ );
286
+ } catch (err) { result = err; }
287
+ await wappalyzer.destroy();
288
+ return result;
372
289
  }
373
290
 
374
- /**
375
- *
376
- * @description call the function question raw list options
377
- * @return { void }
378
- *
379
- */
380
- function question() {
381
- console.info(yellow(textSync("stack-analyze")));
382
- inquirer.prompt({
383
- type: "rawlist",
384
- name: "analyze",
385
- message: "what option do you want to analyze stack",
386
- choices: [
387
- "single",
388
- "multiple",
389
- "pagespeed",
390
- "github-info",
391
- "anime-search",
392
- "hardware-information",
393
- "about",
394
- "exit"
395
- ]
396
- })
397
- .then(({ analyze }) => anwOption(analyze))
398
- .catch((err) => console.error(red(err.message)));
291
+ const pageSpeed = async (url) => {
292
+ try {
293
+ const resMobile = await axios.get("https://www.googleapis.com/pagespeedonline/v5/runPagespeed", {
294
+ params: {
295
+ url,
296
+ key: "AIzaSyBEDaW4FxSZ2s1vz5CdD5Ai6PGZGdAzij0",
297
+ strategy: "mobile"
298
+ }
299
+ });
300
+
301
+ const resDesktop = await axios.get("https://www.googleapis.com/pagespeedonline/v5/runPagespeed", {
302
+ params: {
303
+ url,
304
+ key: "AIzaSyBEDaW4FxSZ2s1vz5CdD5Ai6PGZGdAzij0",
305
+ strategy: "desktop"
306
+ }
307
+ });
308
+
309
+ // extract results
310
+ const mobile = Math.round(resMobile.data.lighthouseResult.categories.performance.score * 100);
311
+ const desktop = Math.round(resDesktop.data.lighthouseResult.categories.performance.score * 100);
312
+
313
+ return {mobile, desktop};
314
+ } catch (err) { return err; }
315
+ };
316
+
317
+ async function singleStack(url) {
318
+ const wappalyzer = await new Wappalyzer;
319
+
320
+ let result;
321
+ try {
322
+ await wappalyzer.init();
323
+
324
+ const { technologies } = await wappalyzer.open(url).analyze();
325
+
326
+ result = technologies.map(({
327
+ name,
328
+ website,
329
+ categories
330
+ }) => ({
331
+ techName: name,
332
+ techWebsite: website,
333
+ techCategories: categories.map(({ name }) => name).join(", ")
334
+ }));
335
+ } catch (err) { result = err; }
336
+
337
+ await wappalyzer.destroy();
338
+ return result;
399
339
  }
400
340
 
401
- // call the message title and question list
402
- console.clear();
403
- question();
404
341
 
342
+ // exports
343
+ exports = {
344
+ animeSearch,
345
+ bitlyInfo,
346
+ cryptoMarket,
347
+ githubInfo,
348
+ controllerInfo,
349
+ osDetail,
350
+ diskInfo,
351
+ displayInfo,
352
+ biosInfo,
353
+ cpuInfo,
354
+ ramMemInfo,
355
+ movieDB,
356
+ multipleStack,
357
+ pageSpeed,
358
+ singleStack
359
+ };