forked from Laboratoria/DEV007-md-links
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctions.js
269 lines (238 loc) · 7.12 KB
/
functions.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/* eslint-disable no-unused-vars */
/* eslint-disable no-shadow */
/* eslint-disable import/no-extraneous-dependencies */
import chalk from 'chalk';
import fs from 'fs';
import marked from 'marked';
import { JSDOM } from 'jsdom';
import path from 'path';
import axios from 'axios';
// ---------- FUNCIONES PURAS
// PATH ABSOLUTA
export function convertAbsolute(pathUser) {
if (path.isAbsolute(pathUser)) {
return pathUser;
}
return path.resolve(pathUser);
}
// ES UN ARCHIVO
export function isFile(pathUser) {
const infoFile = fs.statSync(pathUser);
return infoFile.isFile();
}
// ES UN ARCHIVO .md
export function isMd(file) {
return (path.extname(file) === '.md');
}
// NO ES UN ARCHIVO .md
export function isNotMd(file) {
return (path.extname(file) !== '.md');
}
// ES UN DIRECTORIO
export function isDirectory(pathUser) {
const infoDir = fs.statSync(pathUser);
return infoDir.isDirectory();
}
// ARCHIVOS DENTRO DIRECTORIO
export function filesDir(directory) {
const files = fs.readdirSync(directory, 'utf-8');
return files;
}
// UNIR PATHS ARCHIVOS DIRECTORIO
export function unionPaths(directory, pathUser) {
const filePathComplete = path.join(directory, pathUser);
return filePathComplete;
}
// .md A HTML
export function convertToHtml(markdownContent) {
const html = marked(markdownContent, { headerIds: false, mangle: false }); // convierte HTML
const dom = new JSDOM(html); // creación de instancia DOM del HTML
const { document } = dom.window; // se ingresa al objeto DOM
return document;
}
// LINKS VALID FALSE
export function getLinksFalse(dom, file) {
const linksFalse = Array.from(dom.querySelectorAll('a')).map((element) => ({
href: element.href,
text: element.textContent.trim(),
file,
}));
if (linksFalse.length === 0) {
console.log('');
console.log(chalk.bold('Links found in: '), chalk.underline(file));
console.log(chalk.bold.red('This file has no links'));
console.log('');
}
return linksFalse;
}
// LINKS VALID TRUE
export function getLinksTrue(dom, file) {
const linksTrue = Array.from(dom.querySelectorAll('a')).map((element) => ({
href: element.href,
text: element.textContent.trim(),
file,
status: 10,
ok: '',
}));
if (linksTrue.length === 0) {
console.log('');
console.log(chalk.bold('Links found in: '), chalk.underline(file));
console.log(chalk.bold.red('This file has no links'));
console.log('');
}
return linksTrue;
}
// HTTP REQUEST
export function getStatusCode(url) {
return axios.get(url)
.then((response) => response.status) // status OK
.catch((error) => {
if (error.response) { // status Fail
return error.response.status;
}
throw error; // si no es un error por el status, manda el error
});
}
// OBTENER ARCHIVOS RECURSIVAMENTE
export function getFilesRecursively(pathUser) {
const absolutePath = convertAbsolute(pathUser);
const filesArray = [];
function getFilesRecurs(dir) {
const files = filesDir(dir);
files.forEach((file) => {
const filePath = unionPaths(dir, file);
if (isFile(filePath) && isMd(file)) {
filesArray.push(filePath);
} else if (isDirectory(filePath)) {
getFilesRecurs(filePath);
}
});
}
if (isFile(absolutePath) && isMd(absolutePath)) {
filesArray.push(absolutePath);
}
if (isDirectory(absolutePath)) {
getFilesRecurs(absolutePath);
}
return filesArray;
}
// LEER .md Y OBTENER LINKS
export function processMarkdownFile(filePath) {
return new Promise((resolve, reject) => { // se crea promesa
fs.readFile(filePath, 'utf-8', (error, markdownContent) => { // leer archivo
if (error) { // en caso de error
reject(chalk.bgRedBright.bold(error));
return;
}
const document = convertToHtml(markdownContent);
const linksFalse = getLinksFalse(document, filePath);
resolve(linksFalse);
});
});
}
// LEER .md Y OBTENER LINKS CON SU STATUS
export function processMarkdownFileWithStatus(filePath) {
return new Promise((resolve, reject) => { // promesa principal
fs.readFile(filePath, 'utf-8', (error, markdownContent) => { // leer archivo
if (error) { // si hay error al leer archivo
reject(chalk.bgRedBright.bold(error));
return;
}
// si se lee bien el archivo...
const document = convertToHtml(markdownContent);
const links = getLinksTrue(document, filePath); // array de links
const promises = links.map((link) => { // declara array de promesas de la obtención de status
const objectLink = { ...link };// Crear copia de c/objeto link
return getStatusCode(link.href) // devuelve las promesas de obtener status
.then((statusCode) => {
objectLink.status = statusCode;
// condicionales segun el status del link
if (statusCode >= 100 && statusCode < 200) {
objectLink.ok = 'Informational';
} else if (statusCode >= 200 && statusCode < 300) {
objectLink.ok = 'OK ✔';
} else if (statusCode >= 300 && statusCode < 400) {
objectLink.ok = 'Redirect';
} else if (statusCode >= 400 && statusCode < 500) {
objectLink.ok = 'Fail ✘';
} else if (statusCode >= 500 && statusCode < 600) {
objectLink.ok = 'Fail ✘';
} else {
objectLink.ok = 'Unknown';
}
return objectLink;
})
.catch((error) => {
objectLink.status = 'Error';
objectLink.ok = 'Fail ✘';
return objectLink;
});
});
Promise.all(promises) // se espera que las promesas de status se resuelvan
.then((objectLinks) => {
resolve(objectLinks); // resuelve promesa principal
})
.catch((error) => { // error de promesa principal
reject(error);
});
});
});
}
// TRUNCAR TEXTO 50 CARACTERES
export function truncateText(text) {
if (text.length <= 50) {
return text;
}
return `${text.slice(0, 50)}...`;
}
// CONTAR LINKS
export function countLinks(links) {
return links.length;
}
// CONTAR LINKS ROTOS
export function countBroken(links) {
let broken = 0;
links.forEach(
(link) => {
if (link.ok === 'Fail ✘') {
broken += 1;
}
},
);
return broken;
}
// CONTAR LINKS EXITOSOS
export function countSuccessfull(links) {
let successfull = 0;
links.forEach(
(link) => {
if (link.ok === 'OK ✔') {
successfull += 1;
}
},
);
return successfull;
}
// CONTAR LINKS UNICOS
export function countUniques(links) {
const uniqueLinks = new Set(links.map((link) => link.href)); // conjunto url unicas
return uniqueLinks.size; // tamaño del conjunto
}
// STATS
export function getStats(links) {
const statsTrue = {
Total: countLinks(links),
Unique: countUniques(links),
};
return statsTrue;
}
// STATS Y VALIDATE
export function getStatsValidate(links) {
const statsValidateTrue = {
Total: countLinks(links),
Unique: countUniques(links),
Broken: countBroken(links),
Successfull: countSuccessfull(links),
};
return statsValidateTrue;
}