Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Final #14

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
760 changes: 307 additions & 453 deletions README.md

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env node

const mdLinks = require('./mdLinks'); // se importa la función mdLinks
const process = require("process");
const colors = require("colors");

const path2 = process.argv[2];
const pathOptions1 = process.argv[3];
const pathOptions2 = process.argv[4];
const arOptions = [pathOptions1, pathOptions2]; //Se crea un arreglo que contiene las opciones que se van a aplicar al análisis

mdLinks(path2, arOptions);

module.exports = mdLinks;

// console.log(colors.bgYellow('Probando...'));
// console.log(colors.rainbow('MdLinks'));
// console.log(colors.magenta('trabajando con Node.js'));
// console.log(colors.bgCyan('<3'));


3 changes: 3 additions & 0 deletions examplesFiles/prueba2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
motor de JavaScript V8 de Chrome. Esto nos va a permitir ejecutar JavaScript en el entorno del sistema operativo, ya sea tu máquina o un servidor, lo cual nos abre las puertas para poder interactuar con el sistema en sí, archivos, redes, ...

Dentro de una comunidad de código abierto, nos han propuesto crear una herramienta usando Node.js, que lea y analice archivos en formato Markdown, para verificar los links que contengan y reportar algunas estadísticas. https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing12345/Client-side_JavaScript_frameworks
8 changes: 8 additions & 0 deletions examplesFiles/pruebas/ejemplos/prueba1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
1. Preámbulo
Markdown es un lenguaje de marcado ligero muy popular entre developers. Es usado en muchísimas plataformas que manejan texto plano (GitHub, foros, blogs, ...), y es muy común encontrar varios archivos en ese formato en cualquier tipo de repositorio (empezando por el tradicional README.md).

Estos archivos Markdown normalmente contienen links (vínculos/ligas) que muchas veces están rotos o ya no son válidos y eso perjudica mucho el valor de la información que se quiere compartir.

Dentro de una comunidad de código abierto, nos han propuesto crear una herramienta usando Node.js, que lea y analice archivos en formato Markdown, para verificar los links que contengan y reportar algunas estadísticas.

Módulos, librerías, paquetes, frameworks... ¿cuál es la diferencia?
7 changes: 7 additions & 0 deletions examplesFiles/pruebas/prueba0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[Markdown](https://es.wikipedia.org/wiki/Markdown)
[motor de JavaScript V8 de Chrome](https://developers.google.com/v8/)
[Arreglos](https://curriculum.laboratoria.la/es/topics/javascript/04-arrays)
[Objetos en JavaScript](https://curriculum.laboratoria.la/es/topics/javascript/05-objects/01-objects)
[JSDOM](https://github.com/jsdom/jsdom/gy)
[NPM](https://docs.npmjs.com/getting-started/what-is-npm)
[Leer un directorio](https://nodejs.org/api/fs.html#fs_fs_readdir_path_options_callback)
213 changes: 213 additions & 0 deletions functions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
const fs = require("fs");
const path = require("path");
const process = require("process");
const axios = require("axios");
const colors = require("colors");
// console.log(fs);

//FUNCIONES A UTILIZAR

//¿La ruta existe?
// console.log(fs.existsSync('./pruebas'));
const validPath = (route) => fs.existsSync(route);

//¿La ruta es absoluta?
// console.log(path.isAbsolute('./pruebas'));
const absolutePath = (route) => path.isAbsolute(route);

//convierte la ruta de relativa en absoluta
// console.log(process.cwd("./pruebas"));
// ruta transformada: C:\Users\tania\OneDrive\Escritorio\Proyectos Laboratoria\mdLinks\DEV002-md-links

const transformAbs = (route) => {
const validDir = process.cwd(); //verifica si el arcivo existe en el local
return path.resolve(validDir, route); //si es directorio, devuelve una ruta absoluta
};

//¿Es un directorio?

const validDir = (route) => {
//devuelve 'true' si la ruta especificada es una carpeta válida, y 'false' si no lo es.
const stats = fs.statSync(route);
return stats.isDirectory();
};

//lee los archivos del directorio
//console.log(fs.readdirSync('./pruebas')); debería devolver un array con el contenido de ese directorio
const readFile = (route) => fs.readdirSync(route);

//validar que la función sea md devuelve la ext se un arch
const mdFile = (route) => (path.extname(route) === ".md" ? true : false);

//recursividad
const recursive = (route) => {
let arrReadMd = [];
if (mdFile(route)) {
arrReadMd.push(route); //se llena si la ruta tiene ext md si no es un directorio
} else if (validDir(route)) {
const contentRoute = readFile(route); //leer las rutas del directorio e itera el contenido que tiene
contentRoute.forEach((pathRoute) => {
//route es el elemt que se esta iterando del arr de string que me devolv contenRoute

arrReadMd = arrReadMd.concat(recursive(`${route}/${pathRoute}`));
})
}
return arrReadMd;
};

//lee directorios y retorna archivos md

const readFileMd = (route) => {
return new Promise((res, rej) => {
fs.readFile(route, "utf-8", (error, data) => {
error ? rej("Ocurrió un error") : res(data);

});
});
};
// const readFileMd = (route) => {
// return new Promise((res, rej) => {
// fs.readFile(route, "utf-8", (error, data) => {
// error ? rej("ocurrió un error") : res(data);
// });
// });
// };

//Validar todo tipo de ruta 'false'
const routeFalse = (route) => {
return new Promise((res, rej) => {
const allLinks = []; //usar este array para crear un objeto
readFileMd(route) //promesa(lento) probar con readme readContentMd
.then((data) => {
const regExp =
/\[([\w\s\d]+)\]\(((?:\/|https?:\/\/)[\w\d./?=#]+[a-zA-Z0-9!-_$]+)\)/gi;

//regExp.exec(data)//devuelve array con link que cumplan con la regEx...

let resultRegEx = regExp.exec(data); //devuelve array iterado
while (resultRegEx !== null) {
// evitar que me devuelva null

allLinks.push({
href: resultRegEx[2],
text: resultRegEx[1],
file: route, //probar con readme
});
resultRegEx = regExp.exec(data);
}
res(allLinks);
})
.catch((error) => {
rej(error);
});
});
};

// routeFalse('README.md')
// .then((data) => {
// console.log(data)
// })
// .catch((error) => {
// console.log(error);
// });

//validar ruta (true) devolver un array de objeto

const trueRoute = (allLinks) => {
// simulando parameter
return Promise.all(
allLinks.map((content) => {
//cada objeto es una promesa y all me dev un array de promesa
return axios //peticiones http a un serv
.get(content.href) //hace peticion para obtener datos obtener inf de esa url
.then((data) => {
//axios
const objs = {
...content,
status: data.status, //se presenta con num
statusText: data.statusText, //string
};
return (objs);
})
.catch((error) => {
const failObject = {
...content,
status: error.data ? 404 : 404,
statusText: "FAIL",
};
return(failObject);
});
})
);
};
// trueRoute([
// {
// href: "https://es.wikipedia.org/wiki/Markdown/tania",
// text: "Markdown",
// file: "README.md",
// },
// ]);

// estadística de archivos repetidos (en caso de que hayan) console.log(new Set([50,90,30,'veinte', 'ocho', 90,30,'quince'])) //instancia de un modelo existente // set no funciona con lengh si no con size
const statsRep = (allLinks) => {
// me va a devolver un arr de links
const linksAr = allLinks.map((content) => content.href);
const linksU = new Set(linksAr); // me va a dar linsk unicos
return {
total: linksAr.length,
unique: linksU.size,
};
};
// console.log(statsRep([
// {
// href: "https://es.wikipedia.org/wiki/Markdown/tania",
// text: "Markdown",
// file: "README.md",
// },
// {
// href: "https://es.wikipedia.org/wiki/Markdown/tania",
// text: "Markdown",
// file: "README.md",
// },
// ]));
//validar links rotos
const brokenLinks = (allLinks) => {
const brokenAr = allLinks.filter((content) => content.statusText === "FAIL"); //filtrar de acuerdo a una condición //devuelve un arr con los rotos
return {
total: allLinks.length,
unique: statsRep(allLinks).unique,
broken: brokenAr.length,
};
};
// console.log(brokenLinks([
// {
// href: "https://es.wikipedia.org/wiki/Markdown/tania",
// text: "Markdown",
// file: "README.md",
// statusText:"FAIL",
// },
// {
// href: "https://es.wikipedia.org/wiki/Markdown/tania",
// text: "Markdown",
// file: "README.md",
// statusText: "FAIL",
// },
// ]))

//obtener archivos md //usar ejemplo readme.md
const addFileMd = (route) => {
if (validPath(route)) {
absolutePath(route);
transformAbs(route);
}
return recursive(route); // devuelve un array con archivos md
};

// addFileMd();
module.exports = {
addFileMd, //obtiene archivos md
routeFalse, //valida ruta false
trueRoute, //valida ruta true
brokenLinks, //valida los links rotos
statsRep, //devuelve stats
};
Binary file added imgdrawio/drawio1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgdrawio/drawio2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgdrawio/drawio3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 0 additions & 3 deletions index.js

This file was deleted.

66 changes: 66 additions & 0 deletions mdLinks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const {
addFileMd,
routeFalse,
trueRoute,
brokenLinks,
statsRep
} = require("./function"); //use destructuración para importar funciones
const colors = require('colors');

const mdLinks = (path, options) => {
return new Promise((res, rej) => {
if (options[0] === undefined && options[1] === undefined) {
const inputPath = addFileMd(path);
inputPath.map((content) => {

//map recibe una funct y la funct recibe un elemento a iterar
routeFalse(content)
.then((data) => {
console.log(data);
return res(data);
})
.catch((error) => {
rej("La ruta ingresada no es válida", error);
});
});
} else {
if (
(options[0] === "--validate" && options[1] === "--stats") ||
(options[0] === "--stats" && options[1] === "--validate")
) {
const inputPath = addFileMd(path);
inputPath.map((content) => {
routeFalse(content).then((data) => {
console.log(brokenLinks(data))
return res (brokenLinks(data));
});
});

} else if (options[0] === "--validate") {
const arrMd = addFileMd(path);
arrMd.map((element) => {
routeFalse(element)
.then((data) => {
trueRoute(data).then((data)=> {
console.log(data)
return resolve(data)
}
);
})
.catch((error) => {
return reject("La ruta ingresada es válida", error);
});
});
} else if (options[0] === "--stats") {
const arrMdStast = obtenerArchivosMd(path);
arrMdStast.map((element) => {
invalidateAllRoutes(element).then((data) => {
console.log(statsFunction(data));
return resolve(statsFunction(data));
});
});
}
}
});
};
module.exports = mdLinks;
Loading