New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@raulingg/md-links

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@raulingg/md-links - npm Package Compare versions

Comparing version 0.4.0 to 0.5.0

45

dist/mdLinks.js

@@ -10,2 +10,17 @@ "use strict";

/**
* @typedef {Object} Link
* @property {String} path - Path to file where link was found
* @property {String} href - URL to website
* @property {String} text - Text descriptive used to attach url
* @property {String|undefined} status - Confirm wether href is valid or not. "Ok" | "fail"
* @property {number|undefined} statusCode - status code from server response when href is validated
*/
/**
* @typedef {Object} Stats
* @property {number} total - number of links found
* @property {number} unique - number of links with href unique
* @property {number|undefined} broken - number of links with status "fail"
*/
const onlyBroken = markdownLinks => markdownLinks.filter(item => item.status !== 'OK');

@@ -43,9 +58,21 @@

console.info(`${linkWithPath.path} ${linkWithPath.href} ${linkWithPath.text}`);
return linkWithPath;
return Promise.resolve(linkWithPath);
});
};
/**
* mdLinks find links either in markdown file or in all files inside a directory
* @param {String} path - Path to file or directory which contains markdown files
* @param {Object} options - Options that can be passed
* @param {boolean} options.validate - if it's true it validate all links
* @returns {Promise<{data: () => Link[] ,stats: () => Stats}, Error>}
* @example
* mdLinks('path/to/directory').then(mdlink => {
* const results = mdlink.data()
* const stats = mdlink.stats()
* })
*/
var _default = async (path, options = {
validate: false,
stats: false
var _default = (path, options = {
validate: false
}) => {

@@ -56,8 +83,6 @@ try {

const streamResultsPromised = markdownPaths.map(path => (0, _util.streamFile)(path, pipe(path, options.validate)));
const streamResults = await Promise.all(streamResultsPromised);
const markdownLinks = await Promise.all(streamResults.reduce((acc, streamResult) => acc.concat(streamResult), []));
return {
data: () => markdownLinks,
stats: () => stats(markdownLinks, options.validate)
};
return Promise.all(streamResultsPromised).then(streamResults => Promise.all(streamResults.reduce((acc, linkPromised) => acc.concat(linkPromised), []))).then(links => ({
data: () => links,
stats: () => stats(links, options.validate)
}));
} catch (err) {

@@ -64,0 +89,0 @@ return Promise.reject(err);

{
"name": "@raulingg/md-links",
"version": "0.4.0",
"version": "0.5.0",
"description": "This library allows you to find links within markdown files",

@@ -20,3 +20,3 @@ "author": "Raul Quispe <relaxedchild@gmail.com>",

],
"main": "./src/index.js",
"main": "./dist/mdLinks.js",
"scripts": {

@@ -23,0 +23,0 @@ "clean": "rm -rf dist",

# Markdown Links
## Índice
> This repository is an implementation of this [proposal](https://github.com/Laboratoria/LIM008-fe-md-links)
* [1. Preámbulo](#1-preámbulo)
* [2. Resumen del proyecto](#2-resumen-del-proyecto)
* [3. Objetivos de aprendizaje](#3-objetivos-de-aprendizaje)
* [4. Consideraciones generales](#4-consideraciones-generales)
* [5. Criterios de aceptación mínimos del proyecto](#5-criterios-de-aceptación-mínimos-del-proyecto)
* [6. Entregables](#6-entregables)
* [7. Hacker edition](#7-hacker-edition)
* [8. Evaluación](#8-evaluación)
* [9. Pistas, tips y lecturas complementarias](#9-pistas-tips-y-lecturas-complementarias)
* [10. Checklist](#10-checklist)
[![Build Status](https://travis-ci.org/raulingg/md-links.svg?branch=master)](https://travis-ci.org/raulingg/md-links)
[![Coverage Status](https://coveralls.io/repos/github/raulingg/md-links/badge.svg?branch=master)](https://coveralls.io/github/raulingg/md-links?branch=master)
***
Find all links included in a markdown file or in all markdown files inside a folder.
## 1. Preámbulo
## Installation
[Markdown](https://es.wikipedia.org/wiki/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`).
to install globally
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](https://nodejs.org/), que lea y analice archivos
en formato `Markdown`, para verificar los links que contengan y reportar
algunas estadísticas.
`npm install -g @raulingg/md-links`
![md-links](https://user-images.githubusercontent.com/110297/42118443-b7a5f1f0-7bc8-11e8-96ad-9cc5593715a6.jpg)
## 2. Resumen del proyecto
to install as a dependency in your project
[Node.js](https://nodejs.org/es/) es un entorno de ejecución para JavaScript
construido con el [motor de JavaScript V8 de Chrome](https://developers.google.com/v8/).
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, ...
`npm install @raulingg/md-links`
En este proyecto nos alejamos un poco del navegador para construir un programa
que se ejecute usando Node.js, donde aprenderemos sobre cómo interactuar con el
sistema archivos, con el entorno (_proceso_, _env_, _stdin/stdout/stderr_), ...
## 3. Objetivos de aprendizaje
## Usage
El objetivo práctico de este proyecto es que aprendas cómo crear tu propia
**librería** (o biblioteca - _library_) en JavaScript.
- Requiring dependency
Diseñar tu propia librería es una experiencia fundamental para cualquier
desarrollador porque que te obliga a pensar en la interfaz (API) de tus
_módulos_ y cómo será usado por otros developers. Debes tener especial
consideración en peculiaridades del lenguaje, convenciones y buenas prácticas.
```js
const mdLinks = require('@raulingg/md-links')
Tópicos: [Node.js](https://nodejs.org/en/),
[módulos (CommonJS)](https://nodejs.org/docs/latest-v0.10.x/api/modules.html),
[file system](https://nodejs.org/api/fs.html),
[path](https://nodejs.org/api/path.html),
[http.get](https://nodejs.org/api/http.html#http_http_get_options_callback),
parsing,
[markdown](https://daringfireball.net/projects/markdown/syntax), CLI,
[npm-scripts](https://docs.npmjs.com/misc/scripts),
[semver](https://semver.org/), ...
mdLinks('path/to/file.md')
.then(mdlink => {
// Return an object with two methods data and stats
## 4. Consideraciones generales
// data() return an array with results
mdlink.data().forEach(item => {
console.log(item.path, item.href, item.text)
})
});
Este proyecto se debe "resolver" de manera individual.
// find links in all markdown files inside a directory
mdLinks('path/to/directory').data().then(data => {});
```
La librería debe estar implementada en JavaScript para ser ejecutada con
Node.js. **Está permitido usar librerías externas**.
- Importing using ES6
## 5. Criterios de aceptación mínimos del proyecto
```js
import mdLinks from require('@raulingg/md-links')
Tu módulo debe ser instalable via `npm install <github-user>/md-links`. Este
módulo debe incluir tanto un _ejecutable_ que podamos invocar en la línea de
comando como una interfaz que podamos importar con `require` para usarlo
programáticamente.
const mdlink = await mdLinks('path/to/file.md')
const results = mdlink.data()
Los tests unitarios deben cubrir un mínimo del 70% de _statements_, _functions_,
_lines_ y _branches_. Te recomendamos explorar [Jest](https://jestjs.io/)
para tus pruebas unitarias.
// do whatever you want
```
Para comenzar este proyecto tendrás que hacer un _fork_ y _clonar_ este
repositorio.
- validate broken links
Antes de comenzar a codear, es necesario crear un plan de acción. Esto debería
quedar detallado en el `README.md` de tu repo y en una serie de _issues_
y _milestones_ para priorizar y organizar el trabajo, y para poder hacer
seguimiento de tu progreso.
```js
mdLinks('path/to/file.md', { validate: true}).then((mdlink) => {
mdlink.data().forEach((item) => {
console.log(item.path, item.text, item.href, item.status, item.statusCode)
})
});
```
Dentro de cada _milestone_ se crearán y asignarán los _issues_ que cada quien
considere necesarios.
- Get stats
### Archivos del proyecto
```js
/**
* Stats Object
* {
* total: <#linksFound>
* unique: <#LinksUnique>
* broken: <#LinksBroken>
* }
*/
mdLinks('path/to/file.md').then(mdlink => mdlink.stats());
* `README.md` con descripción del módulo, instrucciones de instalación/uso,
documentación del API y ejemplos. Todo lo relevante para que cualquier
developer que quiera usar tu librería pueda hacerlo sin inconvenientes.
* `index.js`: Desde este archivo debes exportar una función (`mdLinks`).
* `package.json` con nombre, versión, descripción, autores, licencia,
dependencias, scripts (pretest, test, ...)
* `.editorconfig` con configuración para editores de texto. Este archivo no se
debe cambiar.
* `.eslintrc` con configuración para linter. Este archivo no
se debe cambiar.
* `.gitignore` para ignorar `node_modules` u otras carpetas que no deban
incluirse en control de versiones (`git`).
* `test/md-links.spec.js` debe contener los tests unitarios para la función
`mdLinks()`. Tu inplementación debe pasar estos tets.
// get stats from broken links
mdLinks('path/to/file.md', { validate: true}).then(mdlink => mdlink.stats());
```
### JavaScript API
### CLI
El módulo debe poder importarse en otros scripts de Node.js y debe ofrecer la
siguiente interfaz:
- Basic usage
#### `mdLinks(path, options)`
```sh
# single file
md-links <path/to/file.md>
##### Argumentos
# scan all markdown files in directory
md-links <path/to/directory>
```
* `path`: Ruta absoluta o relativa al archivo o directorio. Si la ruta pasada es
relativa, debe resolverse como relativa al directorio desde donde se invoca
node - _current working directory_).
* `options`: Un objeto con las siguientes propiedades:
- `validate`: Booleano que determina si se desea validar los links
encontrados.
- Adding a validation option (--validate or -val)
##### Valor de retorno
```sh
md-links <path/to/directory> --validate
```
La función debe retornar una promesa (`Promise`) que resuelva a un arreglo
(`Array`) de objetos (`Object`), donde cada objeto representa un link y contiene
las siguientes propiedades:
- Get stats about how many links and broken links exist
* `href`: URL encontrada.
* `text`: Texto que aparecía dentro del link (`<a>`).
* `file`: Ruta del archivo donde se encontró el link.
```sh
md-links <path/to/directory> --stats
#### Ejemplo
# validate and return stats
md-links <path/to/directory> --validate --stats
```
```js
const mdLinks = require("md-links");
## Markdown file
mdLinks("./some/example.md")
.then(links => {
// => [{ href, text, file }]
})
.catch(console.error);
### Extensions supported
mdLinks("./some/example.md", { validate: true })
.then(links => {
// => [{ href, text, file, status, ok }]
})
.catch(console.error);
- .md
- .markdown
mdLinks("./some/dir")
.then(links => {
// => [{ href, text, file }]
})
.catch(console.error);
```
### Format supported
### CLI (Command Line Interface - Interfaz de Línea de Comando)
- Basic Cases
El ejecutable de nuestra aplicación debe poder ejecutarse de la siguiente
manera a través de la terminal:
```md
[valid link](http://test.com)
[test-link@test.com](http://test.com/test-link?djdjd&)
[title (parenthesis)](http://www.test.com)
[title with
linebreak](http://test.com)
```
`md-links <path-to-file> [options]`
- Extra Cases
Por ejemplo:
```md
[[extra sq bracket](https://test.com?g=154&fh=!445?)
```
```sh
$ md-links ./some/example.md
./some/example.md http://algo.com/2/3/ Link a algo
./some/example.md https://otra-cosa.net/algun-doc.html algún doc
./some/example.md http://google.com/ Google
```
- Video Case
El comportamiento por defecto no debe validar si las URLs responden ok o no,
solo debe identificar el archivo markdown (a partir de la ruta que recibe como
argumento), analizar el archivo Markdown e imprimir los links que vaya
encontrando, junto con la ruta del archivo donde aparece y el texto
que hay dentro del link (truncado a 50 caracteres).
Find image and video url
```md
[![Solution Temperature converter](https://i.ytimg.com/vi/Ix6VLiBcABw/0.jpg)](https://www.youtube.com/watch?v=Ix6VLiBcABw)
#### Options
```
- Unsupported Cases
##### `--validate`
```md
[extra sq bracket - invalid]](https://test.com)
Si pasamos la opción `--validate`, el módulo debe hacer una petición HTTP para
averiguar si el link funciona o no. Si el link resulta en una redirección a una
URL que responde ok, entonces consideraremos el link como ok.
Por ejemplo:
```sh
$ md-links ./some/example.md --validate
./some/example.md http://algo.com/2/3/ ok 200 Link a algo
./some/example.md https://otra-cosa.net/algun-doc.html fail 404 algún doc
./some/example.md http://google.com/ ok 301 Google
```
Vemos que el _output_ en este caso incluye la palabra `ok` o `fail` después de
la URL, así como el status de la respuesta recibida a la petición HTTP a dicha
URL.
##### `--stats`
Si pasamos la opción `--stats` el output (salida) será un texto con estadísticas
básicas sobre los links.
```sh
$ md-links ./some/example.md --stats
Total: 3
Unique: 3
```
También podemos combinar `--stats` y `--validate` para obtener estadísticas que
necesiten de los resultados de la validación.
```sh
$ md-links ./some/example.md --stats --validate
Total: 3
Unique: 3
Broken: 1
```
## 6. Entregables
Módulo instalable via `npm install <github-user>/md-links`. Este módulo debe
incluir tanto un ejecutable como una interfaz que podamos importar con `require`
para usarlo programáticamente.
## 7. Hacker edition
Las secciones llamadas _Hacker Edition_ son **opcionales**. Si **terminaste**
con todo lo anterior y te queda tiempo, intenta completarlas. Así podrás
profundizar y/o ejercitar más sobre los objetivos de aprendizaje del proyecto.
* Puedes agregar la propiedad `line` a cada objeto `link` indicando en qué línea
del archivo se encontró el link.
* Puedes agregar más estadísticas.
* Integración continua con Travis o Circle CI.
## 8. Evaluación
NOTA: Esta sección incluye una lista de habilidades que se podrán tener en
cuenta a la hora de evaluar el proyecto. Los niveles esperados son _sugerencias_
así como _guías_ en el diseño curricular, pero no reglas absolutas.
Te aconsejamos revisar [nuestra rúbrica](https://docs.google.com/spreadsheets/u/1/d/e/2PACX-1vRktPN4ilZtkRN5tUb3DVhgeihwlzk63_-JI3moA-bXpKDbHDioAK2H3qbrwWNb0Ql4wX22Tgv7-PDv/pubhtml)
para ver la descripción detallada de cada _habilidad_ y cada _nivel_. Te
recomendamos también que trates de aplicarte la rúbrica a tí misma y/o a los
proyectos de tus compañeras a lo largo del Bootcamp para ir viendo tu evolución.
### General
| Característica | Nivel esperado |
|----------------|----------------|
| Completitud | 4 |
### Habilidades Blandas
Para este proyecto esperamos que ya hayas alcanzado el nivel 4 en todas tus
habilidades blandas. Te aconsejamos revisar la rúbrica:
| Habilidad | Nivel esperado |
|------------------------------|----------------|
| Planificación y organización | 4 |
| Autoaprendizaje | 4 |
| Presentaciones | 4 |
| Adaptabilidad | 4 |
| Solución de problemas | 4 |
| Responsabilidad | 4 |
| Dar y recibir feedback | 4 |
| Comunicación eficaz | 4 |
### Tech
| Habilidad | Nivel esperado |
| ---------------------- | -------------- |
| **Computer Science** |
| Lógica | 2 |
| Arquitectura | 3 |
| **Source Control Management** |
| Git | 3 |
| GitHub | 3 |
| **JavaScript** |
| Estilo | 3 |
| Nomenclatura/semántica | 3 |
| Funciones/modularidad | 4 |
| Estructuras de datos | 3 |
| Tests | 3 |
## 9. Pistas, tips y lecturas complementarias
### FAQs
#### ¿Cómo hago para que mi módulo sea _instalable_ desde GitHub?
Para que el módulo sea instalable desde GitHub solo tiene que:
* Estar en un repo público de GitHub
* Contener un `package.json` válido
Con el comando `npm install githubname/reponame` podemos instalar directamente
desde GitHub. Ver [docs oficiales de `npm install` acá](https://docs.npmjs.com/cli/install).
Por ejemplo, el [`course-parser`](https://github.com/Laboratoria/course-parser)
que usamos para la currícula no está publicado en el registro público de NPM,
así que lo instalamos directamente desde GitHub con el comando `npm install
Laboratoria/course-parser`.
### Sugerencias de implementación
La implementación de este proyecto tiene varias partes: leer del sistema de
archivos, recibir argumentos a través de la línea de comando, analizar texto,
hacer consultas HTTP, ... y todas estas cosas pueden enfocarse de muchas formas,
tanto usando librerías como implementando en VanillaJS.
Por poner un ejemplo, el _parseado_ (análisis) del markdown para extraer los
links podría plantearse de las siguientes maneras (todas válidas):
* Usando un _módulo_ como [markdown-it](https://github.com/markdown-it/markdown-it),
que nos devuelve un arreglo de _tokens_ que podemos recorrer para identificar
los links.
* Siguiendo otro camino completamente, podríamos usar
[expresiones regulares (`RegExp`)](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Regular_Expressions).
* También podríamos usar una combinación de varios _módulos_ (podría ser válido
transformar el markdown a HTML usando algo como [marked](https://github.com/markedjs/marked)
y de ahí extraer los link con una librería de DOM como [JSDOM](https://github.com/jsdom/jsdom)
o [Cheerio](https://github.com/cheeriojs/cheerio) entre otras).
* Usando un _custom renderer_ de [marked](https://github.com/markedjs/marked)
(`new marked.Renderer()`).
No dudes en consultar a tus compañeras, coaches y/o el [foro de la comunidad](http://community.laboratoria.la/c/js)
si tienes dudas existenciales con respecto a estas decisiones. No existe una
"única" manera correcta :wink:
### Tutoriales / NodeSchool workshoppers
* [learnyounode](https://github.com/workshopper/learnyounode)
* [how-to-npm](https://github.com/workshopper/how-to-npm)
* [promise-it-wont-hurt](https://github.com/stevekane/promise-it-wont-hurt)
### Otros recursos
* [Acerca de Node.js - Documentación oficial](https://nodejs.org/es/about/)
* [Node.js file system - Documentación oficial](https://nodejs.org/api/fs.html)
* [Node.js http.get - Documentación oficial](https://nodejs.org/api/http.html#http_http_get_options_callback)
* [Node.js - Wikipedia](https://es.wikipedia.org/wiki/Node.js)
* [What exactly is Node.js? - freeCodeCamp](https://medium.freecodecamp.org/what-exactly-is-node-js-ae36e97449f5)
* [¿Qué es Node.js y para qué sirve? - drauta.com](https://www.drauta.com/que-es-nodejs-y-para-que-sirve)
* [¿Qué es Nodejs? Javascript en el Servidor - Fazt en YouTube](https://www.youtube.com/watch?v=WgSc1nv_4Gw)
* [¿Simplemente qué es Node.js? - IBM Developer Works, 2011](https://www.ibm.com/developerworks/ssa/opensource/library/os-nodejs/index.html)
* [Node.js y npm](https://www.genbeta.com/desarrollo/node-js-y-npm)
* [Módulos, librerías, paquetes, frameworks... ¿cuál es la diferencia?](http://community.laboratoria.la/t/modulos-librerias-paquetes-frameworks-cual-es-la-diferencia/175)
* [Asíncronía en js](https://carlosazaustre.com/manejando-la-asincronia-en-javascript/)
* [NPM](https://docs.npmjs.com/getting-started/what-is-npm)
* [Publicar packpage](https://docs.npmjs.com/getting-started/publishing-npm-packages)
* [Crear módulos en Node.js](https://docs.npmjs.com/getting-started/publishing-npm-packages)
* [Leer un archivo](https://nodejs.org/api/fs.html#fs_fs_readfile_path_options_callback)
* [Leer un directorio](https://nodejs.org/api/fs.html#fs_fs_readdir_path_options_callback)
* [Path](https://nodejs.org/api/path.html)
* [Linea de comando CLI](https://medium.com/netscape/a-guide-to-create-a-nodejs-command-line-package-c2166ad0452e)
## 10. Checklist
### General
* [ ] Puede instalarse via `npm install --global <github-user>/md-links`
### `README.md`
* [ ] Un board con el backlog para la implementación de la librería.
* [ ] Documentación técnica de la librería.
* [ ] Guía de uso e instalación de la librería
### API `mdLinks(path, opts)`
* [ ] El módulo exporta una función con la interfaz (API) esperada.
* [ ] Implementa soporte para archivo individual
* [ ] Implementa soporte para directorios
* [ ] Implementa `options.validate`
### CLI
* [ ] Expone ejecutable `md-links` en el path (configurado en `package.json`)
* [ ] Se ejecuta sin errores / output esperado
* [ ] Implementa `--validate`
* [ ] Implementa `--stats`
### Pruebas / tests
* [ ] Pruebas unitarias cubren un mínimo del 70% de statements, functions,
lines, y branches.
* [ ] Pasa tests (y linters) (`npm test`).
[link with linebreak - invalid](http:
//test.com)
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc