stack-analyze 1.1.4
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 +117 -0
- package/LICENSE +21 -0
- package/about/index.js +126 -0
- package/functions/animeInfo.js +79 -0
- package/functions/bitly.js +43 -0
- package/functions/cryptoList.js +80 -0
- package/functions/gitUser.js +41 -0
- package/functions/hardware.js +241 -0
- package/functions/multipleStack.js +77 -0
- package/functions/pageSpeed.js +104 -0
- package/functions/singleStack.js +65 -0
- package/index.js +458 -0
- package/logo-module.png +0 -0
- package/package.json +64 -0
- package/readme.md +32 -0
package/index.js
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// modules
|
|
4
|
+
const { performance } = require("perf_hooks");
|
|
5
|
+
const inquirer = require("inquirer");
|
|
6
|
+
const { textSync } = require("figlet");
|
|
7
|
+
const {
|
|
8
|
+
yellow,
|
|
9
|
+
green,
|
|
10
|
+
red
|
|
11
|
+
} = require("colors");
|
|
12
|
+
const { printTable, Table } = require("console-table-printer");
|
|
13
|
+
|
|
14
|
+
// options
|
|
15
|
+
const {
|
|
16
|
+
aboutApp,
|
|
17
|
+
developers,
|
|
18
|
+
nonolive,
|
|
19
|
+
projects,
|
|
20
|
+
twitch,
|
|
21
|
+
youtubeDev,
|
|
22
|
+
ideas
|
|
23
|
+
} = require("./about");
|
|
24
|
+
|
|
25
|
+
// analyze web
|
|
26
|
+
const singleStack = require("./functions/singleStack");
|
|
27
|
+
const multipleStack = require("./functions/multipleStack");
|
|
28
|
+
|
|
29
|
+
// pagespeed web
|
|
30
|
+
// const { desktop, mobile } = require("./functions/pageSpeed");
|
|
31
|
+
const pageSpeed = require("./functions/pageSpeed");
|
|
32
|
+
|
|
33
|
+
// github info
|
|
34
|
+
const githubInfo = require("./functions/gitUser");
|
|
35
|
+
|
|
36
|
+
// anime search
|
|
37
|
+
const animeSearch = require("./functions/animeInfo");
|
|
38
|
+
|
|
39
|
+
// hardware modules
|
|
40
|
+
const {
|
|
41
|
+
cpuInfo,
|
|
42
|
+
ramMemInfo,
|
|
43
|
+
osDetail,
|
|
44
|
+
diskInfo,
|
|
45
|
+
controllerInfo,
|
|
46
|
+
displayInfo,
|
|
47
|
+
biosInfo
|
|
48
|
+
} = require("./functions/hardware");
|
|
49
|
+
|
|
50
|
+
// crypto market module
|
|
51
|
+
const cryptoMarket = require("./functions/cryptoList");
|
|
52
|
+
|
|
53
|
+
// bitly module
|
|
54
|
+
const bitlyInfo = require("./functions/bitly");
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @description about selected anw
|
|
58
|
+
* @param { string } result - about option selected
|
|
59
|
+
* @return { void }
|
|
60
|
+
*/
|
|
61
|
+
function aboutSelected(result) {
|
|
62
|
+
|
|
63
|
+
// tables
|
|
64
|
+
const youtubeDevTable = new Table({
|
|
65
|
+
columns: [
|
|
66
|
+
{
|
|
67
|
+
name: "youtubeChannel",
|
|
68
|
+
alignment: "left",
|
|
69
|
+
color: "green"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: "recomendation",
|
|
73
|
+
alignment: "left",
|
|
74
|
+
color: "cyan"
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
});
|
|
78
|
+
const nonoliveTable = new Table({
|
|
79
|
+
columns: [
|
|
80
|
+
{
|
|
81
|
+
name: "nonoID",
|
|
82
|
+
alignment: "left",
|
|
83
|
+
color: "red"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: "name",
|
|
87
|
+
alignment: "left",
|
|
88
|
+
color: "yellow"
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
});
|
|
92
|
+
const ideasTable = new Table({
|
|
93
|
+
columns: [
|
|
94
|
+
{
|
|
95
|
+
name: "author",
|
|
96
|
+
alignment: "left",
|
|
97
|
+
color: "green"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "tool",
|
|
101
|
+
alignment: "left",
|
|
102
|
+
color: "green"
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
switch (result) {
|
|
108
|
+
case "main info":
|
|
109
|
+
console.clear();
|
|
110
|
+
console.table(aboutApp);
|
|
111
|
+
setTimeout(aboutOpts, 1000);
|
|
112
|
+
break;
|
|
113
|
+
case "devolepers lineup":
|
|
114
|
+
console.clear();
|
|
115
|
+
printTable(developers.map((dev, i) => ({ index: i + 1, dev })));
|
|
116
|
+
setTimeout(aboutOpts, 1000);
|
|
117
|
+
break;
|
|
118
|
+
case "youtube streamers recomendation":
|
|
119
|
+
console.clear();
|
|
120
|
+
youtubeDevTable.addRows(youtubeDev);
|
|
121
|
+
youtubeDevTable.printTable();
|
|
122
|
+
setTimeout(aboutOpts, 1000);
|
|
123
|
+
break;
|
|
124
|
+
case "nonolive recomendation":
|
|
125
|
+
console.clear();
|
|
126
|
+
nonoliveTable.addRows(nonolive);
|
|
127
|
+
nonoliveTable.printTable();
|
|
128
|
+
setTimeout(aboutOpts, 1000);
|
|
129
|
+
break;
|
|
130
|
+
case "twitch recomendation":
|
|
131
|
+
console.clear();
|
|
132
|
+
printTable(twitch.map((streamer, i) => ({ index: i + 1, streamer })));
|
|
133
|
+
setTimeout(aboutOpts, 1000);
|
|
134
|
+
break;
|
|
135
|
+
case "projects recomendation":
|
|
136
|
+
console.clear();
|
|
137
|
+
printTable(projects.map((project, i) => ({ index: i + 1, project })));
|
|
138
|
+
setTimeout(aboutOpts, 1000);
|
|
139
|
+
break;
|
|
140
|
+
case "stack-analyze ideas":
|
|
141
|
+
console.clear();
|
|
142
|
+
ideasTable.addRows(ideas);
|
|
143
|
+
ideasTable.printTable();
|
|
144
|
+
setTimeout(aboutOpts, 1000);
|
|
145
|
+
break;
|
|
146
|
+
|
|
147
|
+
default:
|
|
148
|
+
console.clear();
|
|
149
|
+
question();
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @description about menu
|
|
156
|
+
* @return { void }
|
|
157
|
+
*/
|
|
158
|
+
function aboutOpts() {
|
|
159
|
+
inquirer.prompt({
|
|
160
|
+
type: "list",
|
|
161
|
+
name: "about",
|
|
162
|
+
message: "select about option info",
|
|
163
|
+
choices: [
|
|
164
|
+
"main info",
|
|
165
|
+
"devolepers lineup",
|
|
166
|
+
"youtube streamers recomendation",
|
|
167
|
+
"nonolive recomendation",
|
|
168
|
+
"twitch recomendation",
|
|
169
|
+
"projects recomendation",
|
|
170
|
+
"stack-analyze ideas",
|
|
171
|
+
"return to main menu"
|
|
172
|
+
]
|
|
173
|
+
}).then(({ about }) => aboutSelected(about))
|
|
174
|
+
.catch((err) => console.error(red(err.message)));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
*
|
|
180
|
+
* @description call the async function return list to question list
|
|
181
|
+
* @return { Promise<void> } - return in boolean a result question list
|
|
182
|
+
*
|
|
183
|
+
*/
|
|
184
|
+
async function returnQuestion() {
|
|
185
|
+
try {
|
|
186
|
+
const anw = await inquirer.prompt([
|
|
187
|
+
{
|
|
188
|
+
type: "confirm",
|
|
189
|
+
name: "return",
|
|
190
|
+
message: "do you want go to the main menu?",
|
|
191
|
+
}
|
|
192
|
+
]);
|
|
193
|
+
|
|
194
|
+
if (anw.return) {
|
|
195
|
+
console.clear();
|
|
196
|
+
question();
|
|
197
|
+
} else {
|
|
198
|
+
console.info(green("thanks for use stack-analyze"));
|
|
199
|
+
|
|
200
|
+
}
|
|
201
|
+
} catch (err) {
|
|
202
|
+
console.error(red(err.message));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* @description select a hardware option
|
|
208
|
+
* @param { string } result - selected a option hardware
|
|
209
|
+
* @return { void }
|
|
210
|
+
*/
|
|
211
|
+
function hardwareSelected(result) {
|
|
212
|
+
switch (result) {
|
|
213
|
+
case "cpu":
|
|
214
|
+
console.clear();
|
|
215
|
+
cpuInfo();
|
|
216
|
+
setTimeout(hardwareOpts, 1000);
|
|
217
|
+
break;
|
|
218
|
+
case "ram memory":
|
|
219
|
+
console.clear();
|
|
220
|
+
ramMemInfo();
|
|
221
|
+
setTimeout(hardwareOpts, 1000);
|
|
222
|
+
break;
|
|
223
|
+
case "os":
|
|
224
|
+
console.clear();
|
|
225
|
+
osDetail();
|
|
226
|
+
setTimeout(hardwareOpts, 1000);
|
|
227
|
+
break;
|
|
228
|
+
case "disk":
|
|
229
|
+
console.clear();
|
|
230
|
+
diskInfo();
|
|
231
|
+
setTimeout(hardwareOpts, 1000);
|
|
232
|
+
break;
|
|
233
|
+
case "controller":
|
|
234
|
+
console.clear();
|
|
235
|
+
controllerInfo();
|
|
236
|
+
setTimeout(hardwareOpts, 1000);
|
|
237
|
+
break;
|
|
238
|
+
case "display":
|
|
239
|
+
console.clear();
|
|
240
|
+
displayInfo();
|
|
241
|
+
setTimeout(hardwareOpts, 1000);
|
|
242
|
+
break;
|
|
243
|
+
case "bios":
|
|
244
|
+
console.clear();
|
|
245
|
+
biosInfo();
|
|
246
|
+
setTimeout(hardwareOpts, 1000);
|
|
247
|
+
break;
|
|
248
|
+
|
|
249
|
+
default:
|
|
250
|
+
console.clear();
|
|
251
|
+
question();
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* @description call hardware information options
|
|
258
|
+
* @return { void }
|
|
259
|
+
*/
|
|
260
|
+
function hardwareOpts() {
|
|
261
|
+
inquirer.prompt({
|
|
262
|
+
type: "list",
|
|
263
|
+
name: "hardware",
|
|
264
|
+
message: "select a hardware-information option:",
|
|
265
|
+
choices: [
|
|
266
|
+
"cpu",
|
|
267
|
+
"ram memory",
|
|
268
|
+
"os",
|
|
269
|
+
"disk",
|
|
270
|
+
"controller",
|
|
271
|
+
"display",
|
|
272
|
+
"bios",
|
|
273
|
+
"exit to main menu"
|
|
274
|
+
]
|
|
275
|
+
}).then(({ hardware }) => hardwareSelected(hardware));
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
*
|
|
280
|
+
* @description function register option anwser
|
|
281
|
+
* @param { string } result - result option anwser
|
|
282
|
+
* @return { void }
|
|
283
|
+
*
|
|
284
|
+
*/
|
|
285
|
+
function anwOption(result) {
|
|
286
|
+
// options conditional
|
|
287
|
+
switch (result) {
|
|
288
|
+
case "single":
|
|
289
|
+
console.clear();
|
|
290
|
+
inquirer.prompt({
|
|
291
|
+
name: "url",
|
|
292
|
+
message: "enter url for analyze the tech stack:"
|
|
293
|
+
})
|
|
294
|
+
.then(({ url }) => {
|
|
295
|
+
if (url.indexOf("http") === 0) {
|
|
296
|
+
singleStack(url);
|
|
297
|
+
const timeEnd = performance.now();
|
|
298
|
+
setTimeout(returnQuestion, timeEnd);
|
|
299
|
+
} else {
|
|
300
|
+
console.error(red("please insert a URL with parameter http:// or https://"));
|
|
301
|
+
question();
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
break;
|
|
305
|
+
case "multiple":
|
|
306
|
+
console.clear();
|
|
307
|
+
inquirer.prompt({
|
|
308
|
+
name: "urls",
|
|
309
|
+
message: "enter URLs for analyze the tech stacks with whitespace without quotes example 'http://example.com https://nodejs.org': \n"
|
|
310
|
+
})
|
|
311
|
+
.then(({ urls }) => {
|
|
312
|
+
if (
|
|
313
|
+
urls.match(/(http|https)/g) !== null ||
|
|
314
|
+
urls.match(/(http|https)/g) >= 2
|
|
315
|
+
) {
|
|
316
|
+
const websites = urls.split(" ");
|
|
317
|
+
console.clear();
|
|
318
|
+
multipleStack(websites);
|
|
319
|
+
const timeEnd = performance.now();
|
|
320
|
+
setTimeout(returnQuestion, timeEnd);
|
|
321
|
+
} else {
|
|
322
|
+
console.error(red("please in each URL insert a website the parameter https:// or http://"));
|
|
323
|
+
question();
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
break;
|
|
327
|
+
case "pagespeed":
|
|
328
|
+
console.clear();
|
|
329
|
+
inquirer.prompt({
|
|
330
|
+
name: "speedWeb",
|
|
331
|
+
message: "insert URL for page speed analyze:"
|
|
332
|
+
})
|
|
333
|
+
.then(({ speedWeb }) => {
|
|
334
|
+
if (speedWeb.indexOf("http") === 0) {
|
|
335
|
+
console.clear();
|
|
336
|
+
console.info(green(textSync(speedWeb)));
|
|
337
|
+
|
|
338
|
+
// start pagespeed results mobile
|
|
339
|
+
textSync(speedWeb, "Small");
|
|
340
|
+
pageSpeed(speedWeb);
|
|
341
|
+
const timeEnd = performance.now();
|
|
342
|
+
|
|
343
|
+
// start pagespeed results mobile
|
|
344
|
+
/* desktop(speedWeb);
|
|
345
|
+
const timeEndB = performance.now(); */
|
|
346
|
+
|
|
347
|
+
// stop time
|
|
348
|
+
setTimeout(returnQuestion, timeEnd);
|
|
349
|
+
} else {
|
|
350
|
+
console.error(red("please insert a URL with parameter https;// or http://"));
|
|
351
|
+
question();
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
break;
|
|
355
|
+
case "github-info":
|
|
356
|
+
inquirer.prompt({
|
|
357
|
+
name: "user",
|
|
358
|
+
message: "enter a github user"
|
|
359
|
+
})
|
|
360
|
+
.then(({ user }) => {
|
|
361
|
+
if (user !== "") {
|
|
362
|
+
console.clear();
|
|
363
|
+
githubInfo(user);
|
|
364
|
+
setTimeout(returnQuestion, 2000);
|
|
365
|
+
} else {
|
|
366
|
+
console.error(red("please the github username is required"));
|
|
367
|
+
question();
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
break;
|
|
371
|
+
case "anime-search":
|
|
372
|
+
inquirer.prompt({
|
|
373
|
+
name: "anime",
|
|
374
|
+
message: "enter a anime, music or ova search"
|
|
375
|
+
})
|
|
376
|
+
.then(({ anime }) => {
|
|
377
|
+
if (anime !== "") {
|
|
378
|
+
console.clear();
|
|
379
|
+
animeSearch(anime);
|
|
380
|
+
setTimeout(returnQuestion, 5000);
|
|
381
|
+
} else {
|
|
382
|
+
console.error(red("please the anime is required"));
|
|
383
|
+
question();
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
break;
|
|
387
|
+
case "hardware-information":
|
|
388
|
+
console.clear();
|
|
389
|
+
hardwareOpts();
|
|
390
|
+
break;
|
|
391
|
+
case "about":
|
|
392
|
+
// about info cli
|
|
393
|
+
console.clear();
|
|
394
|
+
aboutOpts();
|
|
395
|
+
break;
|
|
396
|
+
case "crypto market":
|
|
397
|
+
console.clear();
|
|
398
|
+
cryptoMarket();
|
|
399
|
+
setTimeout(returnQuestion, 3000);
|
|
400
|
+
break;
|
|
401
|
+
case "bitly info":
|
|
402
|
+
console.clear();
|
|
403
|
+
inquirer.prompt([
|
|
404
|
+
{
|
|
405
|
+
name: "link",
|
|
406
|
+
message: "enter a bitly link without http|https",
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
name: "token",
|
|
410
|
+
message: "enter a bitly token",
|
|
411
|
+
type: "password"
|
|
412
|
+
}
|
|
413
|
+
])
|
|
414
|
+
.then(({link, token})=> {
|
|
415
|
+
bitlyInfo(link, token);
|
|
416
|
+
setTimeout(returnQuestion, 3000);
|
|
417
|
+
});
|
|
418
|
+
break;
|
|
419
|
+
default:
|
|
420
|
+
console.clear();
|
|
421
|
+
console.info(green("thanks for use stack-analyze"));
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
*
|
|
428
|
+
* @description call the function question raw list options
|
|
429
|
+
* @return { void }
|
|
430
|
+
*
|
|
431
|
+
*/
|
|
432
|
+
function question() {
|
|
433
|
+
console.info(yellow(textSync("stack-analyze")));
|
|
434
|
+
inquirer.prompt({
|
|
435
|
+
type: "rawlist",
|
|
436
|
+
name: "analyze",
|
|
437
|
+
message: "what option do you want to analyze stack",
|
|
438
|
+
choices: [
|
|
439
|
+
"single",
|
|
440
|
+
"multiple",
|
|
441
|
+
"pagespeed",
|
|
442
|
+
"github-info",
|
|
443
|
+
"anime-search",
|
|
444
|
+
"hardware-information",
|
|
445
|
+
"crypto market",
|
|
446
|
+
"bitly info",
|
|
447
|
+
"about",
|
|
448
|
+
"exit"
|
|
449
|
+
]
|
|
450
|
+
})
|
|
451
|
+
.then(({ analyze }) => anwOption(analyze))
|
|
452
|
+
.catch((err) => console.error(red(err.message)));
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// call the message title and question list
|
|
456
|
+
console.clear();
|
|
457
|
+
question();
|
|
458
|
+
|
package/logo-module.png
ADDED
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "stack-analyze",
|
|
3
|
+
"version": "1.1.4",
|
|
4
|
+
"description": "cli tech stack analyze and pagespeed with node.js using the wappalyzer module. with google pagespeed api, hardware and crypto market",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"stack-analyze": "index.js"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"axios": "^0.21.4",
|
|
11
|
+
"cli-progress": "^3.9.1",
|
|
12
|
+
"coingecko-api": "^1.0.10",
|
|
13
|
+
"colors": "^1.4.0",
|
|
14
|
+
"console-table-printer": "^2.10.0",
|
|
15
|
+
"figlet": "^1.5.2",
|
|
16
|
+
"inquirer": "^8.1.5",
|
|
17
|
+
"systeminformation": "^5.9.4",
|
|
18
|
+
"timeago.js": "^4.0.2",
|
|
19
|
+
"wappalyzer": "^6.8.12"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"better-docs": "^2.3.2",
|
|
23
|
+
"eslint": "^7.32.0",
|
|
24
|
+
"gh-pages": "^3.2.3",
|
|
25
|
+
"jest": "^26.6.3",
|
|
26
|
+
"jsdoc": "^3.6.7",
|
|
27
|
+
"minami": "^1.2.3"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"start": "node index.js",
|
|
31
|
+
"test": "jest",
|
|
32
|
+
"lint:test": "eslint . --ext .js",
|
|
33
|
+
"lint:fix": "eslint . --ext .js --fix",
|
|
34
|
+
"docs": "jsdoc -c jsdoc.json",
|
|
35
|
+
"docs:deploy": "npm run docs && gh-pages -d docs"
|
|
36
|
+
},
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/intermachine-developers/stack-analyze.git"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"cli",
|
|
43
|
+
"tech stack",
|
|
44
|
+
"intermachine",
|
|
45
|
+
"stack-analyze",
|
|
46
|
+
"stack analyzer",
|
|
47
|
+
"pagespeed analyze",
|
|
48
|
+
"ascii art",
|
|
49
|
+
"github user info",
|
|
50
|
+
"anime search",
|
|
51
|
+
"hardware information",
|
|
52
|
+
"crypto market info"
|
|
53
|
+
],
|
|
54
|
+
"author": "Intermachine Developers",
|
|
55
|
+
"license": "MIT",
|
|
56
|
+
"bugs": {
|
|
57
|
+
"url": "https://github.com/intermachine-developers/stack-analyze/issues"
|
|
58
|
+
},
|
|
59
|
+
"homepage": "https://intermachine-developers.github.io/stack-analyze/",
|
|
60
|
+
"directories": {
|
|
61
|
+
"doc": "docs",
|
|
62
|
+
"test": "test"
|
|
63
|
+
}
|
|
64
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# stack analyze
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
***
|
|
6
|
+
[](https://stackshare.io/intermachine-developers/stack-analyze-cli)
|
|
7
|
+
[](https://badge.fury.io/js/stack-analyze)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
<a href="https://www.buymeacoffee.com/omega5300" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
cli tech stack analyze with **node.js** using the wappalyzer and google pagespeed api the module this node external module or install.
|
|
14
|
+
|
|
15
|
+
use the cli program install
|
|
16
|
+
|
|
17
|
+
## example module
|
|
18
|
+
>npx stack-analyze "using external without install"<br>
|
|
19
|
+
>npm i -g stack-analyze "global install"<br>
|
|
20
|
+
>note: if global install fail using npx
|
|
21
|
+
|
|
22
|
+
[github repo](https://github.com/intermachine-developers/stack-analyze.git)
|
|
23
|
+
|
|
24
|
+
[docs](https://intermachine-developers.github.io/stack-analyze)
|
|
25
|
+
|
|
26
|
+
[gitlab repo](https://gitlab.com/Intermachine-dev/stack-analyze)
|
|
27
|
+
|
|
28
|
+
### extras
|
|
29
|
+
- [changelog module](/CHANGELOG.md)
|
|
30
|
+
## author this project Julian David Cordoba Torres as omega5300
|
|
31
|
+
|
|
32
|
+
**Intermachine Developers LICENSE MIT**
|