stack-analyze 1.0.7 → 1.0.10
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/about.js +24 -0
- package/changelog.md +10 -0
- package/functions/animeInfo.js +43 -0
- package/functions/pokemonInfo.js +32 -0
- package/functions/techStack.js +46 -0
- package/image/logo.png +0 -0
- package/image/menu.png +0 -0
- package/image/queen.jpg +0 -0
- package/index.js +123 -125
- package/models/animeTable.js +33 -0
- package/models/stackTables.js +23 -0
- package/package.json +15 -37
- package/readme.md +16 -17
- package/utils/format.js +1 -0
- package/CHANGELOG.md +0 -42
- package/LICENSE +0 -21
- package/about/index.js +0 -20
- package/docs/logo-module.png +0 -0
- package/functions/multipleStack.js +0 -43
- package/functions/pageSpeed.js +0 -73
- package/functions/singleStack.js +0 -34
- package/question.js +0 -75
package/about.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const { version } = require('./package.json')
|
|
2
|
+
const formatter = require('./utils/format.js')
|
|
3
|
+
|
|
4
|
+
const devs = ['omega5300']
|
|
5
|
+
const keyPeoples = ['dannyaegyo', 'angel amor de danny']
|
|
6
|
+
const dannyLinkList = [
|
|
7
|
+
'instagram',
|
|
8
|
+
'patreon',
|
|
9
|
+
'twitch',
|
|
10
|
+
'tiktok',
|
|
11
|
+
'facebook',
|
|
12
|
+
'twitter'
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
const aboutApp = {
|
|
16
|
+
stackAnalyzeFounder: 'omega5300',
|
|
17
|
+
version,
|
|
18
|
+
dramalandia_leader: keyPeoples[0],
|
|
19
|
+
key_peoples: formatter.format(keyPeoples),
|
|
20
|
+
dannyaegyo_links: formatter.format(dannyLinkList),
|
|
21
|
+
developers: formatter.format(devs),
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = aboutApp
|
package/changelog.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const axios = require('axios')
|
|
2
|
+
const { format } = require('timeago.js')
|
|
3
|
+
const { red } = require('colors')
|
|
4
|
+
|
|
5
|
+
const animeList = require('../models/animeTable')
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @description call the anime serach info
|
|
10
|
+
* @param { string } query - get query results
|
|
11
|
+
* @returns { Promise<void> } - return results serach
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
async function animeSearch (query) {
|
|
15
|
+
try {
|
|
16
|
+
const { data } = await axios.get('https://api.jikan.moe/v3/search/anime', {
|
|
17
|
+
params: {
|
|
18
|
+
q: query,
|
|
19
|
+
limit: 10
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const animeData = data.results.map(({
|
|
24
|
+
title,
|
|
25
|
+
episodes,
|
|
26
|
+
start_date,
|
|
27
|
+
end_date,
|
|
28
|
+
type
|
|
29
|
+
}) => ({
|
|
30
|
+
title,
|
|
31
|
+
type,
|
|
32
|
+
episodes,
|
|
33
|
+
debutDate: format(start_date),
|
|
34
|
+
finalDate: end_date === null ? "current date" : format(end_date)
|
|
35
|
+
}))
|
|
36
|
+
|
|
37
|
+
animeList.addRows(animeData)
|
|
38
|
+
|
|
39
|
+
animeList.printTable();
|
|
40
|
+
} catch(err) { console.error(red(err.message)) }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = animeSearch
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const axios = require('axios')
|
|
2
|
+
const { red } = require('colors')
|
|
3
|
+
|
|
4
|
+
const formatter = require('../utils/format.js')
|
|
5
|
+
|
|
6
|
+
const pokemonInfo = async (pokemon) => {
|
|
7
|
+
try {
|
|
8
|
+
const { data } = await axios.get(`https://pokeapi.co/api/v2/pokemon/${pokemon}`)
|
|
9
|
+
|
|
10
|
+
const { id, name } = data
|
|
11
|
+
|
|
12
|
+
const moveList = data.moves.map(move => move.move.name).slice(0, 10)
|
|
13
|
+
const typeList = data.types.map(type => type.type.name).slice(0, 10)
|
|
14
|
+
|
|
15
|
+
console.table({
|
|
16
|
+
id,
|
|
17
|
+
name,
|
|
18
|
+
hp: data.stats[0].base_stat,
|
|
19
|
+
attack: data.stats[1].base_stat,
|
|
20
|
+
defense: data.stats[2].base_stat,
|
|
21
|
+
special_attack: data.stats[3].base_stat,
|
|
22
|
+
special_defense: data.stats[4].base_stat,
|
|
23
|
+
speed: data.stats[5].base_stat,
|
|
24
|
+
types: formatter.format(typeList),
|
|
25
|
+
moves: formatter.format(moveList)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
moves = moveList
|
|
29
|
+
} catch (err) { console.error(red(err)) }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = pokemonInfo
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const Wappalyzer = require('wappalyzer')
|
|
2
|
+
const { textSync } = require('figlet')
|
|
3
|
+
const { red, green } = require('colors')
|
|
4
|
+
|
|
5
|
+
const stackTable = require("../models/stackTables");
|
|
6
|
+
|
|
7
|
+
const formatter = require('../utils/format.js')
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @description call single website tech stack analyze
|
|
12
|
+
* @param { string } url - analyze single website stack
|
|
13
|
+
* @returns { Promise<void> } - return async results single web
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
async function techStack(url) {
|
|
17
|
+
const wappalyzer = await new Wappalyzer()
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
await wappalyzer.init()
|
|
21
|
+
|
|
22
|
+
const { technologies } = await wappalyzer.open(url).analyze()
|
|
23
|
+
|
|
24
|
+
const results = technologies.map(app => {
|
|
25
|
+
const webCategories = app.categories.map(({ name }) => name)
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
techName: app.name,
|
|
29
|
+
techWebsite: app.website,
|
|
30
|
+
techCategories: formatter.format(webCategories)
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
console.info(green(textSync(url)))
|
|
35
|
+
|
|
36
|
+
stackTable.addRows(results)
|
|
37
|
+
|
|
38
|
+
stackTable.printTable()
|
|
39
|
+
} catch (err) {
|
|
40
|
+
console.error(red(err.message))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
await wappalyzer.destroy()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = techStack
|
package/image/logo.png
ADDED
|
Binary file
|
package/image/menu.png
ADDED
|
Binary file
|
package/image/queen.jpg
ADDED
|
Binary file
|
package/index.js
CHANGED
|
@@ -1,41 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// modules
|
|
4
|
-
const { performance } = require(
|
|
5
|
-
const inquirer = require(
|
|
6
|
-
const { textSync } = require(
|
|
4
|
+
const { performance } = require('perf_hooks')
|
|
5
|
+
const inquirer = require('inquirer')
|
|
6
|
+
const { textSync } = require('figlet')
|
|
7
|
+
const { red, brightMagenta } = require('colors')
|
|
8
|
+
const { printTable } = require('console-table-printer')
|
|
9
|
+
const imgToAscii = require('ascii-img-canvas-nodejs')
|
|
7
10
|
|
|
8
|
-
//
|
|
9
|
-
const aboutApp = require(
|
|
11
|
+
// about
|
|
12
|
+
const aboutApp = require('./about')
|
|
10
13
|
|
|
11
|
-
//
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
// pagespeed web
|
|
16
|
-
const { desktop, mobile } = require("./functions/pageSpeed");
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
20
|
-
* @description call the function question raw list options
|
|
21
|
-
* @return { void }
|
|
22
|
-
*
|
|
23
|
-
*/
|
|
24
|
-
function question() {
|
|
25
|
-
inquirer.prompt({
|
|
26
|
-
type: "rawlist",
|
|
27
|
-
name: "analyze",
|
|
28
|
-
message: "what option do you want to analyze stack",
|
|
29
|
-
choices: [
|
|
30
|
-
"single",
|
|
31
|
-
"multiple",
|
|
32
|
-
"page speed",
|
|
33
|
-
"about",
|
|
34
|
-
"exit"
|
|
35
|
-
]
|
|
36
|
-
})
|
|
37
|
-
.then((anw) => anwOption(anw.analyze));
|
|
38
|
-
}
|
|
14
|
+
// options modules
|
|
15
|
+
const TechStack = require("./functions/techStack")
|
|
16
|
+
const animeSearch = require("./functions/animeInfo")
|
|
17
|
+
const pokemonInfo = require('./functions/pokemonInfo')
|
|
39
18
|
|
|
40
19
|
/**
|
|
41
20
|
*
|
|
@@ -43,102 +22,121 @@ function question() {
|
|
|
43
22
|
* @return { Promise<void> } - return in boolean a result question list
|
|
44
23
|
*
|
|
45
24
|
*/
|
|
46
|
-
async function returnQuestion
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
anw.return
|
|
56
|
-
? question()
|
|
57
|
-
: console.log("\x1b[44mthanks for use stack-analyze\x1b[0m");
|
|
58
|
-
}
|
|
25
|
+
async function returnQuestion() {
|
|
26
|
+
try {
|
|
27
|
+
const anw = await inquirer.prompt([
|
|
28
|
+
{
|
|
29
|
+
type: "confirm",
|
|
30
|
+
name: "return",
|
|
31
|
+
message: "¿Deseas regresar al menú principal?",
|
|
32
|
+
}
|
|
33
|
+
]);
|
|
59
34
|
|
|
60
|
-
|
|
61
|
-
*
|
|
62
|
-
* @description function register option anwser
|
|
63
|
-
* @param { string } result - result option anwser
|
|
64
|
-
* @return { void }
|
|
65
|
-
*
|
|
66
|
-
*/
|
|
67
|
-
function anwOption (result) {
|
|
68
|
-
// options conditional
|
|
69
|
-
switch (result) {
|
|
70
|
-
case "single":
|
|
71
|
-
console.clear();
|
|
72
|
-
inquirer.prompt({
|
|
73
|
-
name: "url",
|
|
74
|
-
message: "enter url for analyze the tech stack:"
|
|
75
|
-
})
|
|
76
|
-
.then((anw) => {
|
|
77
|
-
if (anw.url.indexOf("http" || "https") > -1) {
|
|
78
|
-
singleStack(anw.url);
|
|
79
|
-
const timeEnd = performance.now();
|
|
80
|
-
setTimeout(returnQuestion, timeEnd);
|
|
81
|
-
} else {
|
|
82
|
-
console.error("\x1b[31mplease insert a URL with parameter http:// or https://");
|
|
83
|
-
question();
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
break;
|
|
87
|
-
case "multiple":
|
|
88
|
-
console.clear();
|
|
89
|
-
inquirer.prompt({
|
|
90
|
-
name: "urls",
|
|
91
|
-
message: "enter URLs for analyze the tech stacks with whitespace without quotes example 'http://example.com https://nodejs.org': \n"
|
|
92
|
-
})
|
|
93
|
-
.then((anw) => {
|
|
94
|
-
if (
|
|
95
|
-
anw.urls.match(/(http|https)/g) !== null ||
|
|
96
|
-
anw.urls.match(/(http|https)/g) === 2
|
|
97
|
-
) {
|
|
98
|
-
const websites = anw.urls.split(" ");
|
|
99
|
-
console.clear();
|
|
100
|
-
multipleStack(websites);
|
|
101
|
-
const timeEnd = performance.now();
|
|
102
|
-
setTimeout(returnQuestion, timeEnd);
|
|
103
|
-
} else {
|
|
104
|
-
console.error("\x1b[31mplease in each URL insert a website the parameter https:// or http://");
|
|
105
|
-
question();
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
break;
|
|
109
|
-
case "page speed":
|
|
35
|
+
if (anw.return) {
|
|
110
36
|
console.clear();
|
|
111
|
-
inquirer.prompt({
|
|
112
|
-
name: "speedWeb",
|
|
113
|
-
message: "insert URL for page speed analyze:"
|
|
114
|
-
})
|
|
115
|
-
.then((anw) => {
|
|
116
|
-
if (anw.speedWeb.indexOf("http" || "https") > -1) {
|
|
117
|
-
console.clear();
|
|
118
|
-
textSync(anw.speedWeb, "Small");
|
|
119
|
-
mobile(anw.speedWeb);
|
|
120
|
-
desktop(anw.speedWeb);
|
|
121
|
-
setTimeout(returnQuestion, 83000);
|
|
122
|
-
} else {
|
|
123
|
-
console.error("\x1b[31mplease insert a URL with parameter https;// or http://");
|
|
124
|
-
question();
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
break;
|
|
128
|
-
case "about":
|
|
129
|
-
// about info cli
|
|
130
|
-
console.clear();
|
|
131
|
-
console.dir(aboutApp);
|
|
132
37
|
question();
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
console.
|
|
136
|
-
|
|
38
|
+
} else {
|
|
39
|
+
console.clear();
|
|
40
|
+
console.info("Gracias por usar stack-analyze dramalandia".green);
|
|
41
|
+
}
|
|
42
|
+
} catch (err) {
|
|
43
|
+
console.error(red(err.message));
|
|
137
44
|
}
|
|
138
45
|
}
|
|
139
46
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
47
|
+
/**
|
|
48
|
+
@description This is a hash table with the options of the tools menu.
|
|
49
|
+
@type {{ single(): void, multiple(): void, pagespeed(): void, github_info(): void, anime_search(): void, crypto_market(): void, bitly_info(): void, movie_info(): void, twitch_info(): void }}
|
|
50
|
+
*/
|
|
51
|
+
const toolsOpts = {
|
|
52
|
+
tech_stack() {
|
|
53
|
+
console.clear();
|
|
54
|
+
inquirer.prompt({
|
|
55
|
+
name: "url",
|
|
56
|
+
message: "Ingrese el link para analizar que tecnologías tiene:"
|
|
57
|
+
}).then(({ url }) => {
|
|
58
|
+
if (url.indexOf("http") === 0) {
|
|
59
|
+
TechStack(url);
|
|
60
|
+
const timeEnd = performance.now();
|
|
61
|
+
setTimeout(returnQuestion, timeEnd);
|
|
62
|
+
} else {
|
|
63
|
+
console.error("Por favor ingrese el link con http:// o https://".red);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
anime_search() {
|
|
68
|
+
console.clear();
|
|
69
|
+
inquirer.prompt({
|
|
70
|
+
name: "anime",
|
|
71
|
+
message: "Ingrese el anime, película u ova para buscar"
|
|
72
|
+
}).then(({ anime }) => {
|
|
73
|
+
if (anime !== "") {
|
|
74
|
+
console.clear();
|
|
75
|
+
animeSearch(anime);
|
|
76
|
+
setTimeout(returnQuestion, 2000);
|
|
77
|
+
} else {
|
|
78
|
+
console.error("Por favor el anime es obligatorio".red);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
},
|
|
82
|
+
pokemon_info() {
|
|
83
|
+
console.clear();
|
|
84
|
+
inquirer.prompt({
|
|
85
|
+
name: "pokemon",
|
|
86
|
+
message: "Ingrese el nombre o ID de Pokémon para buscar"
|
|
87
|
+
}).then(({ pokemon }) => {
|
|
88
|
+
if (pokemon !== "" || pokemon !== 0) {
|
|
89
|
+
console.clear();
|
|
90
|
+
pokemonInfo(pokemon);
|
|
91
|
+
|
|
92
|
+
setTimeout(returnQuestion, 2000);
|
|
93
|
+
} else {
|
|
94
|
+
console.error("Por favor el id o el nombre de Pokémon es obligatorio".red);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
async drama_queen() {
|
|
99
|
+
const opts = {
|
|
100
|
+
width: 60
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const image = await imgToAscii('image/queen.jpg', opts)
|
|
104
|
+
|
|
105
|
+
console.clear()
|
|
106
|
+
console.info('danny la reina de drama')
|
|
107
|
+
console.info(image)
|
|
108
|
+
returnQuestion()
|
|
109
|
+
},
|
|
110
|
+
about() {
|
|
111
|
+
console.clear()
|
|
112
|
+
console.table(aboutApp)
|
|
113
|
+
returnQuestion()
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
function question() {
|
|
119
|
+
console.clear()
|
|
120
|
+
console.info(brightMagenta(textSync('dramalandia')))
|
|
121
|
+
console.info('Software de stack-analyze para la comunidad de dramalandia'.brightYellow)
|
|
122
|
+
inquirer.prompt({
|
|
123
|
+
type: 'list',
|
|
124
|
+
name: 'opts',
|
|
125
|
+
message: 'Seleccione la herramienta a usar:',
|
|
126
|
+
choices: [
|
|
127
|
+
'tech_stack',
|
|
128
|
+
'anime_search',
|
|
129
|
+
'pokemon_info',
|
|
130
|
+
'drama_queen',
|
|
131
|
+
'about',
|
|
132
|
+
'exit'
|
|
133
|
+
]
|
|
134
|
+
}).then(({ opts }) => {
|
|
135
|
+
if (opts === 'exit') {
|
|
136
|
+
console.clear()
|
|
137
|
+
console.info('Gracias por usar stack-analyze dramalandia'.green)
|
|
138
|
+
} else { toolsOpts[opts](); }
|
|
139
|
+
})
|
|
140
|
+
}
|
|
144
141
|
|
|
142
|
+
question()
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const { Table } = require("console-table-printer")
|
|
2
|
+
|
|
3
|
+
const animeList = new Table({
|
|
4
|
+
columns: [
|
|
5
|
+
{
|
|
6
|
+
name: "title",
|
|
7
|
+
alignment: "left",
|
|
8
|
+
color: "green"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
name: "type",
|
|
12
|
+
alignment: "left",
|
|
13
|
+
color: "magenta"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: "episodes",
|
|
17
|
+
alignment: "left",
|
|
18
|
+
color: "magenta"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "debutDate",
|
|
22
|
+
alignment: "left",
|
|
23
|
+
color: "magenta"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: "finalDate",
|
|
27
|
+
alignment: "left",
|
|
28
|
+
color: "green"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
module.exports = animeList
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const { Table } = require("console-table-printer")
|
|
2
|
+
|
|
3
|
+
const stackTable = new Table({
|
|
4
|
+
columns: [
|
|
5
|
+
{
|
|
6
|
+
name: "techName",
|
|
7
|
+
alignment: "left",
|
|
8
|
+
color: "cyan"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
name: "techWebsite",
|
|
12
|
+
alignment: "left",
|
|
13
|
+
color: "green"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: "techCategories",
|
|
17
|
+
alignment: "left",
|
|
18
|
+
color: "cyan"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
module.exports = stackTable
|
package/package.json
CHANGED
|
@@ -1,46 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stack-analyze",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.10",
|
|
4
|
+
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
|
-
"engines": {
|
|
7
|
-
"node": ">=12"
|
|
8
|
-
},
|
|
9
6
|
"bin": {
|
|
10
|
-
"stack-
|
|
11
|
-
},
|
|
12
|
-
"dependencies": {
|
|
13
|
-
"axios": "^0.20.0",
|
|
14
|
-
"figlet": "^1.5.0",
|
|
15
|
-
"inquirer": "^7.3.3",
|
|
16
|
-
"wappalyzer": "^6.3.6"
|
|
17
|
-
},
|
|
18
|
-
"devDependencies": {
|
|
19
|
-
"eslint": "^7.9.0",
|
|
20
|
-
"jest": "^26.4.2"
|
|
7
|
+
"stack-dramalandia": "index.js"
|
|
21
8
|
},
|
|
22
9
|
"scripts": {
|
|
23
|
-
"start": "node index.js"
|
|
24
|
-
"test": "jest",
|
|
25
|
-
"lint:test": "eslint . --ext .js",
|
|
26
|
-
"lint:fix": "eslint . --ext .js --fix"
|
|
10
|
+
"start": "node index.js"
|
|
27
11
|
},
|
|
28
|
-
"
|
|
29
|
-
"type": "git",
|
|
30
|
-
"url": "git+https://github.com/intermachine-developers/stack-analyze.git"
|
|
31
|
-
},
|
|
32
|
-
"keywords": [
|
|
33
|
-
"cli",
|
|
34
|
-
"tech stack",
|
|
35
|
-
"intermachine",
|
|
36
|
-
"stack-analyze",
|
|
37
|
-
"pagespeed analyze",
|
|
38
|
-
"ascii art"
|
|
39
|
-
],
|
|
40
|
-
"author": "Intermachine Developers",
|
|
12
|
+
"author": "omega5300",
|
|
41
13
|
"license": "MIT",
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"ascii-img-canvas-nodejs": "^1.8.1",
|
|
16
|
+
"axios": "^0.27.2",
|
|
17
|
+
"colors": "^1.4.0",
|
|
18
|
+
"console-table-printer": "^2.11.0",
|
|
19
|
+
"figlet": "^1.5.2",
|
|
20
|
+
"inquirer": "^8.2.4",
|
|
21
|
+
"timeago.js": "^4.0.2",
|
|
22
|
+
"wappalyzer": "^6.10.26"
|
|
23
|
+
}
|
|
46
24
|
}
|
package/readme.md
CHANGED
|
@@ -1,26 +1,25 @@
|
|
|
1
|
-
# stack
|
|
1
|
+
# stack-analyze dramalandia
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
[](https://badge.fury.io/js/stack-analyze)
|
|
7
|
-
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
sotware de consola enfocado para la comunidad dramalandia del dannyaegyo es una version simplificada de la primera generacion de stack-analyze (1.0.4 a 1.0.9) siendo el primer CLI enfocado a los fanaticos de anime.
|
|
8
6
|
|
|
9
|
-
cli tech stack analyze with **node.js** using the wappalyzer and google pagespeed api the module this node external module or install.
|
|
10
7
|
|
|
11
|
-
|
|
8
|
+
## uso
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
>npx stack-analyze "using external without install"<br>
|
|
15
|
-
>npm i -g stack-analyze "global install"<br>
|
|
16
|
-
>note: if global install fail using npx
|
|
10
|
+
el uso es tanto instalacion global como uso portable
|
|
17
11
|
|
|
18
|
-
|
|
12
|
+
``` sh
|
|
13
|
+
# npm 8.10 inferior
|
|
14
|
+
npm i -g stack-analyze@dramalandia
|
|
19
15
|
|
|
20
|
-
|
|
16
|
+
# npm 8.12 superior
|
|
17
|
+
npm i --location=global stack-analyze@dramalandia
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
|
|
19
|
+
# uso portable
|
|
20
|
+
npx stack-analyze@dramalandia
|
|
21
|
+
```
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
## ejemplo
|
|
24
|
+
|
|
25
|
+

|
package/utils/format.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = new Intl.ListFormat('en', { style: 'short', type: 'conjunction' })
|
package/CHANGELOG.md
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# changelog
|
|
2
|
-
|
|
3
|
-
stack-analyze all version and notable changes, fixed, remove and new additions in code.
|
|
4
|
-
|
|
5
|
-
## version 1.0.7
|
|
6
|
-
### Added
|
|
7
|
-
- add the new modules:
|
|
8
|
-
- figlet the main module
|
|
9
|
-
- jest dev module and testing functions
|
|
10
|
-
- add the options page speed and about the main options
|
|
11
|
-
- add return in a option select except about and exit
|
|
12
|
-
### Fixed
|
|
13
|
-
- the website in blank or website without http:// or https:// return the main options
|
|
14
|
-
- eslint custom rules without style guide
|
|
15
|
-
### Changed
|
|
16
|
-
- changed the inquirer list to inquirer rawlist
|
|
17
|
-
- rewirte jsdoc in all project except test files
|
|
18
|
-
- the tech stack using other console methods console.log only in exit cli
|
|
19
|
-
|
|
20
|
-
## version 1.0.6
|
|
21
|
-
### Added
|
|
22
|
-
- add the new options: multiple (analyze many sites) and exit (exit cli).
|
|
23
|
-
- the code was testing with eslint to avoid errors to execute
|
|
24
|
-
- rewrite the module docs.
|
|
25
|
-
### Changed
|
|
26
|
-
- the list options with inquirer
|
|
27
|
-
- welcome message modified
|
|
28
|
-
|
|
29
|
-
## version 1.0.5
|
|
30
|
-
### Changed
|
|
31
|
-
- modify the code and module structure
|
|
32
|
-
### remove
|
|
33
|
-
- remove the commander module
|
|
34
|
-
|
|
35
|
-
## version 1.0.4
|
|
36
|
-
- fisrt official version in npm with the modules:
|
|
37
|
-
- wappalyzer
|
|
38
|
-
- inquirer
|
|
39
|
-
- commander
|
|
40
|
-
|
|
41
|
-
## version 1.0.1 to 1.0.3
|
|
42
|
-
test version modules without wappalyzer module (only testing)
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2020 julian david cordoba torres
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
package/about/index.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
// version module
|
|
2
|
-
const { version } = require("../package.json");
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* about data object
|
|
7
|
-
* @typedef { Object } aboutApp - structure info app
|
|
8
|
-
* @property { string } aboutApp.mainDeveloper - leader cli app developers
|
|
9
|
-
* @property { string[] } aboutApp.developers - developers author the cli app
|
|
10
|
-
* @property { string[] } aboutApp.devRecommendationYoutube - youtubers recomendation from omega5300
|
|
11
|
-
* @property { string } aboutApp.version - version the cli app
|
|
12
|
-
*/
|
|
13
|
-
const aboutApp = {
|
|
14
|
-
mainDeveloper: "omega5300",
|
|
15
|
-
developers: ["omega5300"],
|
|
16
|
-
devRecommendationYoutube: ["fazt", "doriandesings", "bluuweb"],
|
|
17
|
-
version
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
module.exports = aboutApp;
|
package/docs/logo-module.png
DELETED
|
Binary file
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
const { textSync } = require("figlet");
|
|
2
|
-
const Wappalyzer = require("wappalyzer");
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
*
|
|
6
|
-
* @description call multiple websites tech stack analyze
|
|
7
|
-
* @param { string[] } urls - tech analyze in multiples websites
|
|
8
|
-
* @returns { Promise<void> } - async results in multiples websites
|
|
9
|
-
*
|
|
10
|
-
*/
|
|
11
|
-
const multipleStack = async (urls) => {
|
|
12
|
-
const wappalyzer = await new Wappalyzer();
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
await wappalyzer.init();
|
|
16
|
-
|
|
17
|
-
const results = await Promise.all(
|
|
18
|
-
urls.map(async (url) => ({
|
|
19
|
-
url,
|
|
20
|
-
stack: await wappalyzer.open(url).analyze()
|
|
21
|
-
})));
|
|
22
|
-
|
|
23
|
-
console.info("multiple websites tech stack \n");
|
|
24
|
-
console.group();
|
|
25
|
-
// loop web site tech stack
|
|
26
|
-
for (const result of results) {
|
|
27
|
-
console.info("\x1b[36m", textSync(result.url, "Small"), "\x1b[0m");
|
|
28
|
-
console.group();
|
|
29
|
-
console.table(result.stack.technologies.map((app) => ({
|
|
30
|
-
"tech-name": app.name,
|
|
31
|
-
"tech-website": app.website,
|
|
32
|
-
"tech-categories": Object.values(app.categories).map((categorie) => categorie.name).join(", ")
|
|
33
|
-
})));
|
|
34
|
-
console.groupEnd();
|
|
35
|
-
}
|
|
36
|
-
} catch (err) {
|
|
37
|
-
console.error("\x1b[31m", err.message, "\x1b[0m");
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
await wappalyzer.destroy();
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
module.exports = multipleStack;
|
package/functions/pageSpeed.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
// module
|
|
2
|
-
const axios = require("axios").default;
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @description async function mobile website pagespeed
|
|
6
|
-
* @param { string } url - website from pagespeed mobile results
|
|
7
|
-
* @returns { Promise<void> } - return async mobile results
|
|
8
|
-
*/
|
|
9
|
-
const mobile = async (url) => {
|
|
10
|
-
const res = await axios.get(
|
|
11
|
-
`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=${url}&key=AIzaSyBEDaW4FxSZ2s1vz5CdD5Ai6PGZGdAzij0&strategy=mobile`
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
const movil = res.data.lighthouseResult.categories.performance.score * 100;
|
|
16
|
-
|
|
17
|
-
switch (true) {
|
|
18
|
-
case (movil <=0 || movil <=49):
|
|
19
|
-
console.info(`\x1b[31mresultado en movil es: ${movil} malo\n`);
|
|
20
|
-
break;
|
|
21
|
-
case (movil <=50 || movil <=89):
|
|
22
|
-
console.info(`\x1b[33mresultado en movil es: ${movil} decente\n`);
|
|
23
|
-
break;
|
|
24
|
-
case (movil >=90 || movil ===100):
|
|
25
|
-
console.info(`\x1b[32mresultado en movil es: ${movil} excelente\n`);
|
|
26
|
-
break;
|
|
27
|
-
default:
|
|
28
|
-
console.info(`\x1b[35mresultado indefinido en movil ${movil}\n`);
|
|
29
|
-
break;
|
|
30
|
-
}
|
|
31
|
-
} catch (err) {
|
|
32
|
-
console.error(err.message);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
*
|
|
38
|
-
* @description async function desktop website pagespeed
|
|
39
|
-
* @param { string } url - website from pagespeed desktop
|
|
40
|
-
* @return { Promise<void> } - return async desktop results
|
|
41
|
-
*
|
|
42
|
-
*/
|
|
43
|
-
const desktop = async (url) => {
|
|
44
|
-
const res = await axios.get(
|
|
45
|
-
`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=${url}&key=AIzaSyBEDaW4FxSZ2s1vz5CdD5Ai6PGZGdAzij0&strategy=desktop`
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
const desktop = res.data.lighthouseResult.categories.performance.score * 100;
|
|
50
|
-
|
|
51
|
-
switch (true) {
|
|
52
|
-
case (desktop <= 0 || desktop <=49):
|
|
53
|
-
console.info(`\x1b[31mresultado en ordenador es: ${desktop} malo\x1b[0m\n`);
|
|
54
|
-
break;
|
|
55
|
-
case (desktop <=50 || desktop <=89):
|
|
56
|
-
console.info(`\x1b[33mresultado en ordenador es: ${desktop} decente\x1b[0m\n`);
|
|
57
|
-
break;
|
|
58
|
-
case (desktop >=90 || desktop === 100):
|
|
59
|
-
console.info(`\x1b[32mresultado en ordenador es: ${desktop} excelente\x1b[0m\n`);
|
|
60
|
-
break;
|
|
61
|
-
default:
|
|
62
|
-
console.info(`\x1b[35mresultado indefinido en ordenador ${desktop}\x1b[0m\n`);
|
|
63
|
-
break;
|
|
64
|
-
}
|
|
65
|
-
} catch (err) {
|
|
66
|
-
console.error("\x1b[31m", err.message, "\x1b[0m");
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
module.exports = {
|
|
71
|
-
mobile,
|
|
72
|
-
desktop
|
|
73
|
-
};
|
package/functions/singleStack.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// module
|
|
2
|
-
const Wappalyzer = require("wappalyzer");
|
|
3
|
-
const { textSync } = require("figlet");
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
*
|
|
7
|
-
* @description call single website tech stack analyze
|
|
8
|
-
* @param { string } url - analyze single website stack
|
|
9
|
-
* @returns { Promise<void> } - return async results single web
|
|
10
|
-
*
|
|
11
|
-
*/
|
|
12
|
-
async function singleStack (url) {
|
|
13
|
-
const wappalyzer = await new Wappalyzer;
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
await wappalyzer.init();
|
|
17
|
-
|
|
18
|
-
const results = await wappalyzer.open(url).analyze();
|
|
19
|
-
|
|
20
|
-
console.info("\x1b[32m", textSync(url), "\x1b[0m");
|
|
21
|
-
|
|
22
|
-
console.table(results.technologies.map((app) => ({
|
|
23
|
-
"tech-name": app.name,
|
|
24
|
-
"tech-website": app.website,
|
|
25
|
-
"tech-categories": Object.values(app.categories).map((categorie) => categorie.name).join(", ")
|
|
26
|
-
})));
|
|
27
|
-
} catch (err) {
|
|
28
|
-
console.error("\x1b[31m", err.message, "\x1b[0m");
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
await wappalyzer.destroy();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
module.exports = singleStack;
|
package/question.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
// module
|
|
2
|
-
const { textSync } = require("figlet")
|
|
3
|
-
const inquirer = require("inquirer")
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @param { string } result - result option anwser
|
|
7
|
-
* @return { void }
|
|
8
|
-
*/
|
|
9
|
-
const anwOption = (result) => {
|
|
10
|
-
// options conditional
|
|
11
|
-
switch (result) {
|
|
12
|
-
case "single":
|
|
13
|
-
console.clear()
|
|
14
|
-
inquirer
|
|
15
|
-
.prompt({
|
|
16
|
-
name: "url",
|
|
17
|
-
message: "enter url for analyze the tech stack",
|
|
18
|
-
})
|
|
19
|
-
.then((anw) => {
|
|
20
|
-
if (anw.url.indexOf("http" || "https") > -1) {
|
|
21
|
-
console.log(anw.url)
|
|
22
|
-
question()
|
|
23
|
-
} else {
|
|
24
|
-
console.error("\x1b[31mpor favor ingrese una direccion https o http valida")
|
|
25
|
-
question()
|
|
26
|
-
}
|
|
27
|
-
})
|
|
28
|
-
break
|
|
29
|
-
|
|
30
|
-
case "multiple":
|
|
31
|
-
console.clear()
|
|
32
|
-
inquirer
|
|
33
|
-
.prompt({
|
|
34
|
-
name: "urls",
|
|
35
|
-
message:
|
|
36
|
-
"enter urls for analyze the tech stacks with whitespace without quotes example. 'http://example.com https://nodejs.org/': \n",
|
|
37
|
-
})
|
|
38
|
-
.then((anw) => {
|
|
39
|
-
if (
|
|
40
|
-
anw.urls.match(/(https|http)/g) !== null &&
|
|
41
|
-
anw.urls.match(/(https|http)/g).length === 2
|
|
42
|
-
) {
|
|
43
|
-
console.log(anw.urls)
|
|
44
|
-
question()
|
|
45
|
-
} else {
|
|
46
|
-
console.error("\x1b[31mpor favor ingrese en cada una direccion https o http valida")
|
|
47
|
-
question()
|
|
48
|
-
}
|
|
49
|
-
})
|
|
50
|
-
break
|
|
51
|
-
|
|
52
|
-
default:
|
|
53
|
-
console.log("thanks for use stack analyze")
|
|
54
|
-
break
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* @return { Promise<void> } - return async/await question list
|
|
60
|
-
*/
|
|
61
|
-
async function question() {
|
|
62
|
-
const anw = await inquirer.prompt([
|
|
63
|
-
{
|
|
64
|
-
type: "list",
|
|
65
|
-
name: "analyze",
|
|
66
|
-
message: "what option do you want to analyze stack",
|
|
67
|
-
choices: ["single", "multiple", "about", "exit"],
|
|
68
|
-
},
|
|
69
|
-
])
|
|
70
|
-
anwOption(anw.analyze)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
console.clear()
|
|
74
|
-
console.log("\x1b[33m", textSync("stack-analyze"))
|
|
75
|
-
question()
|