@icarusmx/creta 1.5.13 → 1.5.15
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/README.md +476 -74
- package/bin/creta.js +13 -2
- package/lib/data/command-help/grep.js +4 -0
- package/lib/data/command-help/index.js +2 -0
- package/lib/data/command-help/lz.js +67 -0
- package/lib/exercises/13-shell-aliases.md +279 -0
- package/lib/exercises/14-gh-fundamentals.md +976 -0
- package/lib/exercises/API_CHANGES.md +193 -0
- package/lib/exercises/README.md +7 -0
- package/lib/exercises/utils/README.md +114 -0
- package/lib/exercises/utils/lz-functions.sh +240 -0
- package/lib/readers/exercise-reader.js +197 -0
- package/package.json +1 -1
package/bin/creta.js
CHANGED
|
@@ -10,6 +10,7 @@ import { PullRequestTutorial } from '../lib/pr-tutorial.js'
|
|
|
10
10
|
import { VimSetupTutorial } from '../lib/vim-setup-tutorial.js'
|
|
11
11
|
import { AWSGuideViewer } from '../lib/aws-guide-viewer.js'
|
|
12
12
|
import { CommandHelpExecutor } from '../lib/executors/CommandHelpExecutor.js'
|
|
13
|
+
import { readExercise, listExercises } from '../lib/readers/exercise-reader.js'
|
|
13
14
|
import { PapersExecutor } from '../lib/papers/PapersExecutor.js'
|
|
14
15
|
import { ExercisesExecutor } from '../lib/executors/ExercisesExecutor.js'
|
|
15
16
|
import { executeSintaxis } from '../lib/executors/sintaxis-executor.js'
|
|
@@ -185,6 +186,13 @@ if (command.startsWith('portafolio')) {
|
|
|
185
186
|
} else if (command === 'privacy' || command === 'privacidad') {
|
|
186
187
|
// Show privacy information
|
|
187
188
|
showPrivacyInfo()
|
|
189
|
+
} else if (command === 'read' || command === 'leer') {
|
|
190
|
+
// Read exercise/lesson
|
|
191
|
+
const query = args.slice(1).join(' ')
|
|
192
|
+
await readExercise(query)
|
|
193
|
+
} else if (command === 'exercises' || command === 'ejercicios') {
|
|
194
|
+
// List all exercises
|
|
195
|
+
await listExercises()
|
|
188
196
|
} else if (command === 'help' || command === 'ayuda') {
|
|
189
197
|
// Show available commands
|
|
190
198
|
showHelp()
|
|
@@ -681,6 +689,7 @@ function showHelp() {
|
|
|
681
689
|
console.log("📖 Documentación de comandos:")
|
|
682
690
|
console.log(" creta ls - Documentación en español del comando ls")
|
|
683
691
|
console.log(" creta grep - Documentación en español del comando grep")
|
|
692
|
+
console.log(" creta lz - Localiza recursos (alias de curl)")
|
|
684
693
|
console.log(" creta cd - Documentación en español del comando cd")
|
|
685
694
|
console.log(" creta curl - Documentación en español del comando curl")
|
|
686
695
|
console.log(" creta git status - Documentación en español de git status")
|
|
@@ -690,7 +699,9 @@ function showHelp() {
|
|
|
690
699
|
console.log(" creta - Menú principal interactivo")
|
|
691
700
|
console.log(" creta sintaxis - Aprende comandos de terminal y Git")
|
|
692
701
|
console.log(" creta enunciados - Explora los 7 enunciados fundamentales de OOP")
|
|
693
|
-
console.log(" creta papers - Recrea papers clásicos de Computer Science
|
|
702
|
+
console.log(" creta papers - Recrea papers clásicos de Computer Science")
|
|
703
|
+
console.log(" creta exercises - Lista todos los ejercicios disponibles")
|
|
704
|
+
console.log(" creta read <nombre> - Lee un ejercicio específico (ej: creta read 14)\n")
|
|
694
705
|
|
|
695
706
|
console.log("🛠️ Proyectos:")
|
|
696
707
|
console.log(" creta portafolio - Crea tu portafolio personal")
|
|
@@ -1904,7 +1915,7 @@ async function startVimSetupTutorial() {
|
|
|
1904
1915
|
// Helper function to detect command help requests
|
|
1905
1916
|
function isCommandHelpRequest(args) {
|
|
1906
1917
|
// List of supported commands for help
|
|
1907
|
-
const basicCommands = ['ls', 'cd', 'mkdir', 'touch', 'wc', 'curl', 'grep']
|
|
1918
|
+
const basicCommands = ['ls', 'cd', 'mkdir', 'touch', 'wc', 'curl', 'grep', 'lz']
|
|
1908
1919
|
const gitCommands = ['git status', 'git add', 'git commit', 'git push', 'git log']
|
|
1909
1920
|
|
|
1910
1921
|
const commandString = args.join(' ')
|
|
@@ -23,6 +23,10 @@ export const grep = {
|
|
|
23
23
|
flag: '-c',
|
|
24
24
|
description: 'Cuenta líneas que coinciden'
|
|
25
25
|
},
|
|
26
|
+
{
|
|
27
|
+
flag: '-q',
|
|
28
|
+
description: 'Modo silencioso (no imprime nada, solo devuelve código de salida)'
|
|
29
|
+
},
|
|
26
30
|
{
|
|
27
31
|
flag: '-l',
|
|
28
32
|
description: 'Solo muestra nombres de archivos con coincidencias'
|
|
@@ -6,6 +6,7 @@ export { touch } from './touch.js'
|
|
|
6
6
|
export { wc } from './wc.js'
|
|
7
7
|
export { curl } from './curl.js'
|
|
8
8
|
export { grep } from './grep.js'
|
|
9
|
+
export { lz } from './lz.js'
|
|
9
10
|
|
|
10
11
|
// Git commands
|
|
11
12
|
export { gitStatus } from './git-status.js'
|
|
@@ -27,6 +28,7 @@ export const commandMap = {
|
|
|
27
28
|
'wc': 'wc',
|
|
28
29
|
'curl': 'curl',
|
|
29
30
|
'grep': 'grep',
|
|
31
|
+
'lz': 'lz',
|
|
30
32
|
|
|
31
33
|
// Git
|
|
32
34
|
'git status': 'gitStatus',
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export const lz = {
|
|
2
|
+
command: 'lz',
|
|
3
|
+
description: 'Localiza recursos web con manejo automático de API keys',
|
|
4
|
+
usage: 'lz [url]',
|
|
5
|
+
setup: [
|
|
6
|
+
'1. Agrega la función lz a tu ~/.zshrc (ver lección Shell Functions)',
|
|
7
|
+
'2. Crea ~/.api_keys con permisos 600 para guardar tus keys',
|
|
8
|
+
'3. Exporta tu API key: export key="tu_api_key"',
|
|
9
|
+
'4. Usa lz normalmente - incluye la key automáticamente'
|
|
10
|
+
],
|
|
11
|
+
commonPatterns: [
|
|
12
|
+
{
|
|
13
|
+
pattern: 'lz icarus.mx/api/endpoint',
|
|
14
|
+
description: 'Request GET con autenticación automática (si $key está definida)'
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
pattern: 'export key="sk_test_123"',
|
|
18
|
+
description: 'Define tu API key para la sesión actual'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
pattern: 'unset key',
|
|
22
|
+
description: 'Elimina la API key de la sesión (seguridad)'
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
pattern: 'headers icarus.mx/api',
|
|
26
|
+
description: 'Ver headers de un endpoint (función helper)'
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
pattern: 'post icarus.mx/api \'{"name":"Memo"}\'',
|
|
30
|
+
description: 'POST request con JSON (función helper)'
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
examples: [
|
|
34
|
+
{
|
|
35
|
+
command: 'lz icarus.mx',
|
|
36
|
+
description: 'Request normal (sin autenticación)'
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
command: 'export key="sk_test_4eC39HqLyjWDarjtT1zdp7dc" && lz icarus.mx/api/creta',
|
|
40
|
+
description: 'Request con API key (header automático)'
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
command: 'switch_key dev && lz icarus.mx/api/users',
|
|
44
|
+
description: 'Cambiar a key de desarrollo y hacer request'
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
command: 'lz icarus.mx/api/data | jq \'.results\'',
|
|
48
|
+
description: 'Request autenticado + parsear JSON con jq'
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
relatedLesson: 'Shell Functions: API Querying Simplificado',
|
|
52
|
+
tips: [
|
|
53
|
+
'🔑 lz detecta automáticamente si $key está definida y agrega el header',
|
|
54
|
+
'⚡ Combina lz con jq para parsear JSON: lz api.com | jq',
|
|
55
|
+
'🔒 Usa chmod 600 ~/.api_keys para proteger tus keys',
|
|
56
|
+
'🔄 switch_key te permite cambiar entre dev/prod fácilmente',
|
|
57
|
+
'🧹 Siempre usa unset key cuando termines con APIs sensibles',
|
|
58
|
+
'📖 lz = "localiza recurso" - wrapper inteligente de curl'
|
|
59
|
+
],
|
|
60
|
+
securityNotes: [
|
|
61
|
+
'❌ NUNCA pongas API keys directamente en ~/.zshrc',
|
|
62
|
+
'✅ Usa ~/.api_keys con permisos 600 (solo tú puedes leer)',
|
|
63
|
+
'✅ Agrega ~/.api_keys a tu .gitignore',
|
|
64
|
+
'✅ Usa unset key después de trabajar con APIs sensibles',
|
|
65
|
+
'✅ Considera usar direnv para keys por proyecto'
|
|
66
|
+
]
|
|
67
|
+
}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# Shell Functions: API Querying Simplificado
|
|
2
|
+
|
|
3
|
+
## Objetivo
|
|
4
|
+
|
|
5
|
+
Aprende a crear funciones de shell para hacer peticiones a APIs más fáciles. Crearemos `lz` (localiza recurso) - una función que maneja API keys automáticamente.
|
|
6
|
+
|
|
7
|
+
## ¿Por qué una Función y no un Alias?
|
|
8
|
+
|
|
9
|
+
**Alias**: Atajo simple para un comando
|
|
10
|
+
- `alias lz='curl'` → reemplaza lz con curl
|
|
11
|
+
|
|
12
|
+
**Función**: Lógica programable con argumentos
|
|
13
|
+
- Puede verificar variables (`$key`)
|
|
14
|
+
- Puede construir requests dinámicamente
|
|
15
|
+
- Puede manejar errores
|
|
16
|
+
|
|
17
|
+
## El Problema que Resuelve `lz`
|
|
18
|
+
|
|
19
|
+
Sin `lz`:
|
|
20
|
+
```bash
|
|
21
|
+
curl -H "Authorization: Bearer tu_api_key_super_larga_aqui" https://icarus.mx/api/creta
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Con `lz`:
|
|
25
|
+
```bash
|
|
26
|
+
export key="tu_api_key_super_larga_aqui"
|
|
27
|
+
lz icarus.mx/api/creta
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Por qué `lz`
|
|
31
|
+
|
|
32
|
+
**curl** = Client URL (Cliente de URL)
|
|
33
|
+
- **Cliente**: localiza recursos para ti
|
|
34
|
+
- **Universal**: usa HTTP (HyperText Transfer Protocol)
|
|
35
|
+
- **lz**: "localiza recurso" - wrapper inteligente de curl
|
|
36
|
+
|
|
37
|
+
## Paso 1: Identificar tu Shell
|
|
38
|
+
|
|
39
|
+
En macOS Catalina+ se usa `zsh` por defecto:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
echo $SHELL
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Si ves `/bin/zsh` → usas zsh (archivo: `~/.zshrc`)
|
|
46
|
+
Si ves `/bin/bash` → usas bash (archivo: `~/.bashrc`)
|
|
47
|
+
|
|
48
|
+
## Paso 2: Abrir el Archivo de Configuración
|
|
49
|
+
|
|
50
|
+
Para zsh (más común en Mac):
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
nvim ~/.zshrc
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
O si prefieres VS Code:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
code ~/.zshrc
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Paso 3: Agregar la Función `lz`
|
|
63
|
+
|
|
64
|
+
Al final del archivo, agrega esta función:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Función lz - API querying con API key automático
|
|
68
|
+
lz() {
|
|
69
|
+
local url="$1"
|
|
70
|
+
|
|
71
|
+
# Si la URL no tiene protocolo, agregar https://
|
|
72
|
+
if [[ ! "$url" =~ ^https?:// ]]; then
|
|
73
|
+
url="https://$url"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# Si hay API key exportada, incluirla en el header
|
|
77
|
+
if [ -n "$key" ]; then
|
|
78
|
+
curl -H "Authorization: Bearer $key" "$url"
|
|
79
|
+
else
|
|
80
|
+
curl "$url"
|
|
81
|
+
fi
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**¿Qué hace esta función?**
|
|
86
|
+
1. Toma la URL como argumento (`$1`)
|
|
87
|
+
2. Agrega `https://` si no tiene protocolo
|
|
88
|
+
3. Verifica si existe la variable `$key`
|
|
89
|
+
4. Si existe, incluye el header de autorización
|
|
90
|
+
5. Si no, hace un curl normal
|
|
91
|
+
|
|
92
|
+
Guarda el archivo:
|
|
93
|
+
- En nvim: presiona `ESC`, luego escribe `:wq` y `ENTER`
|
|
94
|
+
- En VS Code: `Cmd + S`
|
|
95
|
+
|
|
96
|
+
## Paso 4: Recargar la Configuración
|
|
97
|
+
|
|
98
|
+
Tienes dos opciones:
|
|
99
|
+
|
|
100
|
+
**Opción 1: Recargar el archivo**
|
|
101
|
+
```bash
|
|
102
|
+
source ~/.zshrc
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Opción 2: Cerrar y abrir una nueva terminal**
|
|
106
|
+
|
|
107
|
+
## Paso 5: Probar la Función
|
|
108
|
+
|
|
109
|
+
**Sin API key (request normal):**
|
|
110
|
+
```bash
|
|
111
|
+
lz icarus.mx
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Deberías ver el HTML del sitio de Icarus.
|
|
115
|
+
|
|
116
|
+
**Con API key (request autenticado):**
|
|
117
|
+
```bash
|
|
118
|
+
# Exportar tu API key (poético, ¿no?)
|
|
119
|
+
export key="es un secreto"
|
|
120
|
+
|
|
121
|
+
# Hacer request con autenticación automática
|
|
122
|
+
lz icarus.mx/api/creta/testeo
|
|
123
|
+
|
|
124
|
+
# La función automáticamente incluye:
|
|
125
|
+
# -H "Authorization: Bearer es un secreto"
|
|
126
|
+
|
|
127
|
+
# El API responde:
|
|
128
|
+
# "que a tu mirada y la mía la separa el abismo"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Ventajas:**
|
|
132
|
+
- No tener que escribir headers largos cada vez
|
|
133
|
+
- Cambiar de API key con un solo `export`
|
|
134
|
+
- Código más limpio y legible
|
|
135
|
+
|
|
136
|
+
## Paso 6: Guardar el API Key de Forma Segura
|
|
137
|
+
|
|
138
|
+
**❌ Nunca hagas esto:**
|
|
139
|
+
```bash
|
|
140
|
+
# NO pongas tu key directo en ~/.zshrc
|
|
141
|
+
export key="sk_live_SUPER_SECRETA" # ¡MAL!
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**✅ Mejor práctica:**
|
|
145
|
+
```bash
|
|
146
|
+
# En ~/.zshrc agrega:
|
|
147
|
+
if [ -f ~/.api_keys ]; then
|
|
148
|
+
source ~/.api_keys
|
|
149
|
+
fi
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Crea ~/.api_keys con permisos restrictivos
|
|
154
|
+
touch ~/.api_keys
|
|
155
|
+
chmod 600 ~/.api_keys
|
|
156
|
+
|
|
157
|
+
# Edita ~/.api_keys y agrega:
|
|
158
|
+
export key="tu_api_key_aqui"
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Ahora tu key está separada y con permisos seguros (solo tú puedes leerla).
|
|
162
|
+
|
|
163
|
+
## Funciones Adicionales Útiles
|
|
164
|
+
|
|
165
|
+
Mientras estás editando `~/.zshrc`, considera agregar:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Función para cambiar entre diferentes API keys
|
|
169
|
+
switch_key() {
|
|
170
|
+
case "$1" in
|
|
171
|
+
dev)
|
|
172
|
+
export key="sk_test_desarrollo"
|
|
173
|
+
echo "✅ API key: desarrollo"
|
|
174
|
+
;;
|
|
175
|
+
prod)
|
|
176
|
+
export key="sk_live_produccion"
|
|
177
|
+
echo "✅ API key: producción"
|
|
178
|
+
;;
|
|
179
|
+
*)
|
|
180
|
+
echo "Uso: switch_key [dev|prod]"
|
|
181
|
+
;;
|
|
182
|
+
esac
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
# Ver headers de una API
|
|
186
|
+
headers() {
|
|
187
|
+
lz "$1" -I
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
# POST request con lz
|
|
191
|
+
post() {
|
|
192
|
+
local url="$1"
|
|
193
|
+
local data="$2"
|
|
194
|
+
|
|
195
|
+
if [ -n "$key" ]; then
|
|
196
|
+
curl -X POST -H "Authorization: Bearer $key" \
|
|
197
|
+
-H "Content-Type: application/json" \
|
|
198
|
+
-d "$data" "https://$url"
|
|
199
|
+
else
|
|
200
|
+
curl -X POST -H "Content-Type: application/json" \
|
|
201
|
+
-d "$data" "https://$url"
|
|
202
|
+
fi
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Verificar que Funciona
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
# Request normal
|
|
210
|
+
lz icarus.mx
|
|
211
|
+
|
|
212
|
+
# Request con autenticación poética
|
|
213
|
+
export key="es un secreto"
|
|
214
|
+
lz icarus.mx/api/creta/testeo
|
|
215
|
+
# Responde: "que a tu mirada y la mía la separa el abismo"
|
|
216
|
+
|
|
217
|
+
# Ver headers
|
|
218
|
+
headers icarus.mx
|
|
219
|
+
|
|
220
|
+
# POST con data
|
|
221
|
+
post icarus.mx/api/users '{"name":"Guillermo"}'
|
|
222
|
+
|
|
223
|
+
# Cambiar entre keys
|
|
224
|
+
switch_key dev
|
|
225
|
+
switch_key prod
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Troubleshooting
|
|
229
|
+
|
|
230
|
+
**Problema: "command not found: lz"**
|
|
231
|
+
- Solución: Verifica que ejecutaste `source ~/.zshrc`
|
|
232
|
+
- Verifica que la función está correctamente definida (sin errores de sintaxis)
|
|
233
|
+
|
|
234
|
+
**Problema: "No such file or directory: ~/.zshrc"**
|
|
235
|
+
- Solución: Crea el archivo primero: `touch ~/.zshrc`
|
|
236
|
+
|
|
237
|
+
**Problema: Sigo usando bash en vez de zsh**
|
|
238
|
+
- Solución: Edita `~/.bashrc` en vez de `~/.zshrc`
|
|
239
|
+
|
|
240
|
+
**Problema: La API responde 401 Unauthorized**
|
|
241
|
+
- Verifica que exportaste la key: `echo $key`
|
|
242
|
+
- Verifica que la key es válida
|
|
243
|
+
- Prueba el request completo con curl para debug
|
|
244
|
+
|
|
245
|
+
**Problema: ~/.api_keys no se carga**
|
|
246
|
+
- Verifica que agregaste el `source` en ~/.zshrc
|
|
247
|
+
- Recarga la configuración: `source ~/.zshrc`
|
|
248
|
+
|
|
249
|
+
## Seguridad: ¿Por qué `chmod 600`?
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
chmod 600 ~/.api_keys
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Permisos en formato numérico:
|
|
256
|
+
- **6** (rw-): El dueño puede leer y escribir
|
|
257
|
+
- **0** (---): El grupo no tiene permisos
|
|
258
|
+
- **0** (---): Otros no tienen permisos
|
|
259
|
+
|
|
260
|
+
Resultado: Solo TÚ puedes leer tus API keys.
|
|
261
|
+
|
|
262
|
+
## Siguiente Nivel
|
|
263
|
+
|
|
264
|
+
Una vez que domines funciones básicas, aprende sobre:
|
|
265
|
+
- **jq**: parsear JSON en la terminal
|
|
266
|
+
- **Scripts de shell**: automatizar workflows completos
|
|
267
|
+
- **Dotfiles**: versionar tu configuración con Git
|
|
268
|
+
- **Environment managers**: direnv para keys por proyecto
|
|
269
|
+
|
|
270
|
+
## Recursos
|
|
271
|
+
|
|
272
|
+
- `man zsh` - Manual de zsh
|
|
273
|
+
- `man curl` - Manual de curl
|
|
274
|
+
- `printenv` - Ver todas tus variables de entorno
|
|
275
|
+
- `unset key` - Eliminar variable temporal
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
**Pro tip**: Usa `unset key` cuando termines de trabajar con APIs sensibles. Las variables exportadas persisten en toda la sesión de la terminal.
|