-
Notifications
You must be signed in to change notification settings - Fork 816
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'midudev:main' into prueba_gasperdev
- Loading branch information
Showing
51 changed files
with
5,837 additions
and
3,977 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
'pruebas': | ||
- pruebas/** | ||
|
||
'prueba-1': | ||
- pruebas/01-reading-list/** | ||
|
||
'prueba-2': | ||
- pruebas/02-bazar-universal/** | ||
|
||
'web': | ||
- web/** | ||
|
||
'chore': | ||
- .github/** | ||
- .gitignore | ||
- LICENSE | ||
- README.md | ||
- package.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
name: Check Folder Structure | ||
|
||
on: | ||
pull_request: | ||
types: opened | ||
|
||
jobs: | ||
check-folder-structure: | ||
runs-on: ubuntu-latest | ||
outputs: | ||
comment: ${{ steps.check.outputs.comment }} | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Get changed files | ||
id: changed_files | ||
uses: tj-actions/[email protected] | ||
- name: Check if folder structure is correct | ||
id: check | ||
run: | | ||
PR_USERNAME=$(echo "${{ github.event.pull_request.user.login }}") | ||
FILES="${{ steps.changed_files.outputs.all_modified_files }}" | ||
IFS=' ' read -r -a FILES_ARR <<< "$FILES" | ||
for FILE in "${FILES_ARR[@]}"; do | ||
if [[ ${FILE} == pruebas/* ]]; then | ||
TEST_FOLDER=$(echo ${FILE} | cut -d'/' -f2) | ||
if [[ ${FILE} != pruebas/${TEST_FOLDER}/${PR_USERNAME}/* ]]; then | ||
echo "Incorrect folder structure in file: ${FILE}. Requesting changes." | ||
echo "Asegúrese de que los cambios se realicen en 'pruebas/${TEST_FOLDER}/${PR_USERNAME}/'. :file_folder:" > message.txt | ||
echo "::set-output name=comment::$(cat message.txt)" | ||
break | ||
fi | ||
fi | ||
done | ||
- name: Comment PR | ||
if: steps.check.outputs.comment != '' | ||
uses: actions/github-script@v6 | ||
with: | ||
github-token: ${{secrets.GITHUB_TOKEN}} | ||
script: | | ||
github.rest.issues.createComment({ | ||
issue_number: context.issue.number, | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
body: "${{ steps.check.outputs.comment }}" | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
name: "Pull Request Labeler" | ||
on: | ||
- pull_request_target | ||
- workflow_dispatch | ||
|
||
jobs: | ||
triage: | ||
permissions: | ||
contents: read | ||
pull-requests: write | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/labeler@v4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
# Prueba Técnica JavaScript + Node.js | ||
|
||
Escribe las soluciones en el archivo `solutions/index.js` manteniendo el nombre de las funciones y sus `export`. Usa `ESModules` en tu proyecto de Node.js | ||
|
||
1 - Arregla esta función para que el código posterior funcione como se espera: | ||
|
||
```javascript | ||
import net from 'node:net' | ||
|
||
export const ping = (ip) => { | ||
const startTime = process.hrtime() | ||
|
||
const client = net.connect({ port: 80, host: ip }, () => { | ||
client.end() | ||
return { time: process.hrtime(startTime), ip } | ||
}) | ||
|
||
client.on('error', (err) => { | ||
throw err | ||
client.end() | ||
}) | ||
} | ||
|
||
ping('midu.dev', (err, info) => { | ||
if (err) console.error(err) | ||
console.log(info) | ||
}) | ||
``` | ||
|
||
2 - Transforma la siguiente función para que funcione con promesas en lugar de callbacks: | ||
|
||
```javascript | ||
export function obtenerDatosPromise(callback) { | ||
setTimeout(() => { | ||
callback(null, { data: 'datos importantes' }); | ||
}, 2000); | ||
} | ||
``` | ||
|
||
3 - Explica qué hace la funcion. Identifica y corrige los errores en el siguiente código. Si ves algo innecesario, elimínalo. Luego mejoralo para que siga funcionando con callback y luego haz lo que consideres para mejorar su legibilidad. | ||
|
||
```javascript | ||
export function procesarArchivo() { | ||
fs.readFile('input.txt', 'utf8', (error, contenido) => { | ||
if (error) { | ||
console.error('Error leyendo archivo:', error.message); | ||
return false; | ||
} | ||
|
||
setTimeout(() => { | ||
const textoProcesado = contenido.toUpperCase(); | ||
|
||
fs.writeFile('output.txt', textoProcesado, error => { | ||
if (error) { | ||
console.error('Error guardando archivo:', error.message); | ||
return false; | ||
} | ||
|
||
console.log('Archivo procesado y guardado con éxito'); | ||
return true | ||
}); | ||
|
||
}, 1000); | ||
}); | ||
} | ||
``` | ||
|
||
4 - ¿Cómo mejorarías el siguiente código y por qué? Arregla los tests si es necesario: | ||
|
||
```javascript | ||
import fs from 'node:fs'; | ||
|
||
export function leerArchivos() { | ||
const archivo1 = fs.readSync('archivo1.txt', 'utf8'); | ||
const archivo2 = fs.readSync('archivo2.txt', 'utf8'); | ||
const archivo3 = fs.readSync('archivo3.txt', 'utf8'); | ||
|
||
return `${archivo1} ${archivo2} ${archivo3}` | ||
} | ||
|
||
leerArchivos(); | ||
``` | ||
|
||
5 - Escribe una funcion `delay` que retorne una promesa que se resuelva después de `n` milisegundos. Por ejemplo: | ||
|
||
```javascript | ||
export async function delay () { | ||
// ... | ||
} | ||
|
||
delay(3000).then(() => console.log('Hola mundo')); | ||
// o.. | ||
await delay(3000) | ||
console.log('Hola mundo') | ||
``` | ||
|
||
6. Vamos a crear nuestra propia utilidad `dotenv` en el archivo `dotenv.js`. | ||
|
||
- La utilidad debe devolver un método `config` que lee el archivo `.env` y añade las variables de entorno que haya en el archivo al objeto `process.env`. | ||
|
||
- Por ejemplo si tu archivo `.env` contiene: | ||
|
||
```sh | ||
PORT=8080 | ||
TOKEN="123abc" | ||
``` | ||
|
||
Entonces podríamos hacer esto: | ||
|
||
```javascript | ||
const dotenv = require("./dotenv.js"); | ||
dotenv.config() | ||
|
||
console.log(process.env.PORT) // "8008" | ||
console.log(process.env.TOKEN) // "123abc" | ||
``` | ||
|
||
También se le puede pasar el path del archivo `.env` como parámetro: | ||
|
||
```javascript | ||
const dotenv = require("./dotenv.js"); | ||
dotenv.config("./config/.env.local") | ||
``` | ||
|
||
Cosas a tener en cuenta: | ||
|
||
- Sólo se permite usar el módulo `fs` para leer el archivo. | ||
- Si el archivo no existe, no debe dar error, simplemente no hace nada. | ||
- Si el archivo existe, pero no tiene ninguna variable de entorno, no debe hacer nada. | ||
- Sólo debe soportar el archivo `.env` o el que se le pasa como parametro, no hace falta que soporte `.env.local`, `.env.development` y similares de forma automática. | ||
- Las variables de entorno siempre son strings, por lo que si en el archivo `.env` hay un número, por ejemplo `PORT=8080`, al leerlo con `fs` y añadirlo a `process.env` debe ser un string, no un número. | ||
- `process.env` es un objeto y, por lo tanto, es mutable. Esto significa que podemos añadir propiedades nuevas sin problemas. | ||
|
||
|
||
7 - Diseña una API REST utilizando Express que permite a los usuarios crear, leer, modificar, actualizar y eliminar elementos de una lista. | ||
|
||
La lista tendrá objetos que tienen la siguiente forma: | ||
|
||
```javascript | ||
{ | ||
id: 1, | ||
content: 'Item 1' | ||
} | ||
``` | ||
|
||
Haz la solución en el archivo `solutions/server.js` y exporta el `app` y `server` creado. | ||
Instala Express con `npm install express`. No te preocupes por CORS. |
29 changes: 29 additions & 0 deletions
29
live-coding/01-node-callbacks-promises/already-solved/dotenv.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { readFileSync } from 'node:fs' | ||
|
||
function parseEnv(env) { | ||
const lines = env.split('\n') | ||
|
||
lines.forEach(line => { | ||
const [key, ...value] = line.split('=') | ||
const valueString = value.join('') | ||
const hasQuotes = valueString.startsWith('"') && valueString.endsWith('"') | ||
const valueToStore = hasQuotes ? valueString.slice(1, -1) : valueString | ||
process.env[key] = valueToStore | ||
}) | ||
|
||
} | ||
|
||
export function config({ path = '.env' } = {}) { | ||
try { | ||
const env = readFileSync(path, 'utf8') | ||
parseEnv(env) | ||
} catch (e) { | ||
console.error(e) | ||
} | ||
} | ||
|
||
const dotenv = { | ||
config | ||
} | ||
|
||
export default dotenv |
96 changes: 96 additions & 0 deletions
96
live-coding/01-node-callbacks-promises/already-solved/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import net from 'node:net' | ||
import fs from 'node:fs' | ||
|
||
export const ping = (ip, callback) => { | ||
const startTime = process.hrtime() | ||
|
||
const client = net.connect({ port: 80, host: ip }, () => { | ||
client.end() | ||
callback(null, { time: process.hrtime(startTime), ip }) | ||
}) | ||
|
||
client.on('error', (err) => { | ||
client.end() | ||
callback(err) | ||
}) | ||
} | ||
|
||
// ping('midu.dev', (err, info) => { | ||
// if (err) console.error(err) | ||
// console.log(info) | ||
// }) | ||
|
||
export function obtenerDatosPromise() { | ||
return new Promise((resolve) => { | ||
setTimeout(() => { | ||
resolve({ data: 'datos importantes' }); | ||
}, 2000); | ||
}) | ||
} | ||
|
||
export function procesarArchivo(callback) { | ||
const handleReadFile = (error, contenido) => { | ||
if (error) { | ||
console.error('Error leyendo archivo:', error.message); | ||
callback(error) | ||
} | ||
|
||
const textoProcesado = contenido.toUpperCase(); | ||
|
||
fs.writeFile('output.txt', textoProcesado, handleWriteFile); | ||
} | ||
|
||
const handleWriteFile = error => { | ||
if (error) { | ||
console.error('Error guardando archivo:', error.message); | ||
callback(error) | ||
} | ||
|
||
console.log('Archivo procesado y guardado con éxito'); | ||
callback(null) | ||
} | ||
|
||
fs.readFile('input.txt', 'utf8', handleReadFile); | ||
} | ||
|
||
export async function procesarArchivoPromise() { | ||
try { | ||
const file = await fs.promises.readFile('input.txt', 'utf8') | ||
const textoProcesado = file.toUpperCase() | ||
await fs.promises.writeFile('output.txt', textoProcesado) | ||
} catch (error) { | ||
console.error('Error procesando archivo:', error.message) | ||
throw error | ||
} | ||
} | ||
|
||
// export function leerArchivos() { | ||
// const archivo1 = fs.readSync('archivo1.txt', 'utf8'); | ||
// const archivo2 = fs.readSync('archivo2.txt', 'utf8'); | ||
// const archivo3 = fs.readSync('archivo3.txt', 'utf8'); | ||
|
||
// return `${archivo1} ${archivo2} ${archivo3}` | ||
// } | ||
|
||
// leerArchivos(); | ||
|
||
export async function leerArchivos() { | ||
console.time('leerArchivos') | ||
const [a, b, c] = await Promise.all([ | ||
fs.promises.readFile('archivo1.txt', 'utf8'), | ||
fs.promises.readFile('archivo2.txt', 'utf8'), | ||
fs.promises.readFile('archivo3.txt', 'utf8') | ||
]) | ||
console.timeEnd('leerArchivos') | ||
|
||
return `${a} ${b} ${c}` | ||
} | ||
|
||
|
||
export async function delay (ms) { | ||
return new Promise((resolve) => { | ||
setTimeout(() => { | ||
resolve() | ||
}, ms) | ||
}) | ||
} |
Oops, something went wrong.