@icarusmx/creta 1.5.14 → 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 +11 -1
- package/lib/data/command-help/lz.js +40 -30
- package/lib/exercises/13-shell-aliases.md +183 -38
- package/lib/exercises/14-gh-fundamentals.md +976 -0
- package/lib/exercises/API_CHANGES.md +193 -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()
|
|
@@ -691,7 +699,9 @@ function showHelp() {
|
|
|
691
699
|
console.log(" creta - Menú principal interactivo")
|
|
692
700
|
console.log(" creta sintaxis - Aprende comandos de terminal y Git")
|
|
693
701
|
console.log(" creta enunciados - Explora los 7 enunciados fundamentales de OOP")
|
|
694
|
-
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")
|
|
695
705
|
|
|
696
706
|
console.log("🛠️ Proyectos:")
|
|
697
707
|
console.log(" creta portafolio - Crea tu portafolio personal")
|
|
@@ -1,57 +1,67 @@
|
|
|
1
1
|
export const lz = {
|
|
2
2
|
command: 'lz',
|
|
3
|
-
description: 'Localiza
|
|
3
|
+
description: 'Localiza recursos web con manejo automático de API keys',
|
|
4
4
|
usage: 'lz [url]',
|
|
5
|
-
|
|
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: [
|
|
6
12
|
{
|
|
7
|
-
|
|
8
|
-
description: '
|
|
13
|
+
pattern: 'lz icarus.mx/api/endpoint',
|
|
14
|
+
description: 'Request GET con autenticación automática (si $key está definida)'
|
|
9
15
|
},
|
|
10
16
|
{
|
|
11
|
-
|
|
12
|
-
description: '
|
|
17
|
+
pattern: 'export key="sk_test_123"',
|
|
18
|
+
description: 'Define tu API key para la sesión actual'
|
|
13
19
|
},
|
|
14
20
|
{
|
|
15
|
-
|
|
16
|
-
description: '
|
|
21
|
+
pattern: 'unset key',
|
|
22
|
+
description: 'Elimina la API key de la sesión (seguridad)'
|
|
17
23
|
},
|
|
18
24
|
{
|
|
19
|
-
|
|
20
|
-
description: '
|
|
25
|
+
pattern: 'headers icarus.mx/api',
|
|
26
|
+
description: 'Ver headers de un endpoint (función helper)'
|
|
21
27
|
},
|
|
22
28
|
{
|
|
23
|
-
|
|
24
|
-
description: '
|
|
29
|
+
pattern: 'post icarus.mx/api \'{"name":"Memo"}\'',
|
|
30
|
+
description: 'POST request con JSON (función helper)'
|
|
25
31
|
}
|
|
26
32
|
],
|
|
27
33
|
examples: [
|
|
28
34
|
{
|
|
29
|
-
command: 'lz icarus.mx
|
|
30
|
-
description: '
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
command: 'lz -O icarus.mx/logo.png',
|
|
34
|
-
description: 'Descarga logo.png con su nombre original'
|
|
35
|
+
command: 'lz icarus.mx',
|
|
36
|
+
description: 'Request normal (sin autenticación)'
|
|
35
37
|
},
|
|
36
38
|
{
|
|
37
|
-
command: '
|
|
38
|
-
description: '
|
|
39
|
+
command: 'export key="sk_test_4eC39HqLyjWDarjtT1zdp7dc" && lz icarus.mx/api/creta',
|
|
40
|
+
description: 'Request con API key (header automático)'
|
|
39
41
|
},
|
|
40
42
|
{
|
|
41
|
-
command: 'lz
|
|
42
|
-
description: '
|
|
43
|
+
command: 'switch_key dev && lz icarus.mx/api/users',
|
|
44
|
+
description: 'Cambiar a key de desarrollo y hacer request'
|
|
43
45
|
},
|
|
44
46
|
{
|
|
45
|
-
command: 'lz
|
|
46
|
-
description: '
|
|
47
|
+
command: 'lz icarus.mx/api/data | jq \'.results\'',
|
|
48
|
+
description: 'Request autenticado + parsear JSON con jq'
|
|
47
49
|
}
|
|
48
50
|
],
|
|
49
|
-
relatedLesson: '
|
|
51
|
+
relatedLesson: 'Shell Functions: API Querying Simplificado',
|
|
50
52
|
tips: [
|
|
51
|
-
'
|
|
52
|
-
'
|
|
53
|
-
'
|
|
54
|
-
'
|
|
55
|
-
'
|
|
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'
|
|
56
66
|
]
|
|
57
67
|
}
|
|
@@ -1,21 +1,38 @@
|
|
|
1
|
-
# Shell
|
|
1
|
+
# Shell Functions: API Querying Simplificado
|
|
2
2
|
|
|
3
3
|
## Objetivo
|
|
4
4
|
|
|
5
|
-
Aprende a crear
|
|
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
6
|
|
|
7
|
-
## ¿
|
|
7
|
+
## ¿Por qué una Función y no un Alias?
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
- Escribes `lz https://icarus.mx`
|
|
9
|
+
**Alias**: Atajo simple para un comando
|
|
10
|
+
- `alias lz='curl'` → reemplaza lz con curl
|
|
12
11
|
|
|
13
|
-
|
|
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`
|
|
14
31
|
|
|
15
32
|
**curl** = Client URL (Cliente de URL)
|
|
16
33
|
- **Cliente**: localiza recursos para ti
|
|
17
34
|
- **Universal**: usa HTTP (HyperText Transfer Protocol)
|
|
18
|
-
- **lz**: "localiza recurso" -
|
|
35
|
+
- **lz**: "localiza recurso" - wrapper inteligente de curl
|
|
19
36
|
|
|
20
37
|
## Paso 1: Identificar tu Shell
|
|
21
38
|
|
|
@@ -42,15 +59,36 @@ O si prefieres VS Code:
|
|
|
42
59
|
code ~/.zshrc
|
|
43
60
|
```
|
|
44
61
|
|
|
45
|
-
## Paso 3: Agregar
|
|
62
|
+
## Paso 3: Agregar la Función `lz`
|
|
46
63
|
|
|
47
|
-
Al final del archivo, agrega:
|
|
64
|
+
Al final del archivo, agrega esta función:
|
|
48
65
|
|
|
49
66
|
```bash
|
|
50
|
-
#
|
|
51
|
-
|
|
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
|
+
}
|
|
52
83
|
```
|
|
53
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
|
+
|
|
54
92
|
Guarda el archivo:
|
|
55
93
|
- En nvim: presiona `ESC`, luego escribe `:wq` y `ENTER`
|
|
56
94
|
- En VS Code: `Cmd + S`
|
|
@@ -66,48 +104,132 @@ source ~/.zshrc
|
|
|
66
104
|
|
|
67
105
|
**Opción 2: Cerrar y abrir una nueva terminal**
|
|
68
106
|
|
|
69
|
-
## Paso 5: Probar
|
|
107
|
+
## Paso 5: Probar la Función
|
|
70
108
|
|
|
109
|
+
**Sin API key (request normal):**
|
|
71
110
|
```bash
|
|
72
111
|
lz icarus.mx
|
|
73
112
|
```
|
|
74
113
|
|
|
75
114
|
Deberías ver el HTML del sitio de Icarus.
|
|
76
115
|
|
|
77
|
-
|
|
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
|
|
78
164
|
|
|
79
165
|
Mientras estás editando `~/.zshrc`, considera agregar:
|
|
80
166
|
|
|
81
167
|
```bash
|
|
82
|
-
#
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
+
}
|
|
96
204
|
```
|
|
97
205
|
|
|
98
206
|
## Verificar que Funciona
|
|
99
207
|
|
|
100
208
|
```bash
|
|
101
|
-
#
|
|
102
|
-
lz
|
|
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"
|
|
103
216
|
|
|
104
|
-
#
|
|
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
|
|
105
226
|
```
|
|
106
227
|
|
|
107
228
|
## Troubleshooting
|
|
108
229
|
|
|
109
230
|
**Problema: "command not found: lz"**
|
|
110
231
|
- Solución: Verifica que ejecutaste `source ~/.zshrc`
|
|
232
|
+
- Verifica que la función está correctamente definida (sin errores de sintaxis)
|
|
111
233
|
|
|
112
234
|
**Problema: "No such file or directory: ~/.zshrc"**
|
|
113
235
|
- Solución: Crea el archivo primero: `touch ~/.zshrc`
|
|
@@ -115,20 +237,43 @@ lz -I icarus.mx
|
|
|
115
237
|
**Problema: Sigo usando bash en vez de zsh**
|
|
116
238
|
- Solución: Edita `~/.bashrc` en vez de `~/.zshrc`
|
|
117
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
|
+
|
|
118
262
|
## Siguiente Nivel
|
|
119
263
|
|
|
120
|
-
Una vez que domines
|
|
121
|
-
- **
|
|
264
|
+
Una vez que domines funciones básicas, aprende sobre:
|
|
265
|
+
- **jq**: parsear JSON en la terminal
|
|
266
|
+
- **Scripts de shell**: automatizar workflows completos
|
|
122
267
|
- **Dotfiles**: versionar tu configuración con Git
|
|
123
|
-
- **
|
|
268
|
+
- **Environment managers**: direnv para keys por proyecto
|
|
124
269
|
|
|
125
270
|
## Recursos
|
|
126
271
|
|
|
127
272
|
- `man zsh` - Manual de zsh
|
|
128
|
-
- `man
|
|
129
|
-
- `
|
|
130
|
-
- `
|
|
273
|
+
- `man curl` - Manual de curl
|
|
274
|
+
- `printenv` - Ver todas tus variables de entorno
|
|
275
|
+
- `unset key` - Eliminar variable temporal
|
|
131
276
|
|
|
132
277
|
---
|
|
133
278
|
|
|
134
|
-
**Pro tip**:
|
|
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.
|