@icarusmx/creta 1.3.4 → 1.3.5

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.
Files changed (38) hide show
  1. package/bin/creta.js +8 -1576
  2. package/codex-refactor.txt +13 -0
  3. package/lib/builders/LessonBuilder.js +228 -0
  4. package/lib/builders/MenuBuilder.js +154 -0
  5. package/lib/builders/ProjectBuilder.js +56 -0
  6. package/lib/cli/index.js +81 -0
  7. package/lib/commands/help.js +5 -0
  8. package/lib/constants/paths.js +9 -0
  9. package/lib/data/enunciados.js +44 -0
  10. package/lib/data/lessons/index.js +25 -0
  11. package/lib/data/lessons/lesson1-system-decomposition.js +312 -0
  12. package/lib/data/lessons/lesson2-object-requests.js +318 -0
  13. package/lib/data/lessons/lesson3-only-way.js +349 -0
  14. package/lib/data/lessons/lesson4-operation-signatures.js +332 -0
  15. package/lib/data/lessons/lesson5-interface-set.js +341 -0
  16. package/lib/data/lessons/lesson6-interface-design.js +407 -0
  17. package/lib/data/lessons/lesson7-object-definition.js +375 -0
  18. package/lib/data/lessons/sintaxis/terminal-basico.js +46 -0
  19. package/lib/data/menus.js +43 -0
  20. package/lib/data/messages.js +28 -0
  21. package/lib/executors/enunciados-executor.js +63 -0
  22. package/lib/executors/portfolio-executor.js +167 -0
  23. package/lib/executors/proyectos-executor.js +23 -0
  24. package/lib/executors/sintaxis-executor.js +7 -0
  25. package/lib/templates/LevelModifier.js +287 -0
  26. package/lib/utils/file-utils.js +18 -0
  27. package/lib/utils/input.js +15 -0
  28. package/lib/utils/output.js +4 -0
  29. package/package.json +4 -1
  30. package/refactor.txt +581 -0
  31. package/test/enunciados.test.js +72 -0
  32. package/lessons/lesson1-system-decomposition.js +0 -313
  33. package/lessons/lesson2-object-requests.js +0 -309
  34. package/lessons/lesson3-only-way.js +0 -324
  35. package/lessons/lesson4-operation-signatures.js +0 -319
  36. package/lessons/lesson5-interface-set.js +0 -326
  37. package/lessons/lesson6-interface-design.js +0 -391
  38. package/lessons/lesson7-object-definition.js +0 -300
@@ -0,0 +1,341 @@
1
+ export const LESSON_5_INTERFACE_SET = {
2
+ id: 5,
3
+ title: 'LECCIÓN 5: La interfaz de un objeto es el conjunto de todas sus firmas de operación',
4
+ subtitle: 'Enfoque práctico: Demostrar cómo las firmas individuales forman una interfaz coherente',
5
+ flow: [
6
+ {
7
+ lines: [
8
+ '\n💡 ¿Qué significa esto?',
9
+ '- Una interfaz NO es una sola operación',
10
+ '- Es el CONJUNTO COMPLETO de todas las firmas',
11
+ '- Define TODO lo que el objeto puede hacer',
12
+ "- Es el 'contrato público' del objeto"
13
+ ],
14
+ type: 'text'
15
+ },
16
+ {
17
+ message: '\nPresiona Enter para comenzar con ejemplos prácticos...',
18
+ type: 'pause'
19
+ },
20
+ {
21
+ type: 'clear'
22
+ },
23
+ {
24
+ lines: [
25
+ '🛠️ EJERCICIO PRÁCTICO: Reproductor de Música',
26
+ '==================================================',
27
+ '🎯 Vamos a construir una interfaz completa paso a paso',
28
+ '\nSistema: Reproductor de música digital',
29
+ 'Objeto: MusicPlayer'
30
+ ],
31
+ type: 'text'
32
+ },
33
+ {
34
+ message: '\nPresiona Enter para ver cómo NO diseñar una interfaz...',
35
+ type: 'pause'
36
+ },
37
+ {
38
+ type: 'clear'
39
+ },
40
+ {
41
+ lines: [
42
+ '❌ INTERFAZ INCOMPLETA',
43
+ '==============================',
44
+ 'Veamos un objeto con interfaz parcial:',
45
+ '\n🚫 PROBLEMA: Solo algunas operaciones definidas',
46
+ 'class MusicPlayer {\n' +
47
+ ' // ✅ Operación bien definida\n' +
48
+ ' play(songId: string): boolean {\n' +
49
+ ' // implementación...\n' +
50
+ ' }\n' +
51
+ '\n' +
52
+ ' // ❌ Otras operaciones sin firma clara\n' +
53
+ ' stop() {\n' +
54
+ ' // ¿Qué devuelve? ¿Puede fallar?\n' +
55
+ ' }\n' +
56
+ '\n' +
57
+ ' volume(level) {\n' +
58
+ ' // ¿Qué tipo es level? ¿Qué rango?\n' +
59
+ ' }\n' +
60
+ '\n' +
61
+ ' // ❌ Operaciones faltantes\n' +
62
+ ' // ¿Cómo pauso? ¿Cómo cambio de canción?\n' +
63
+ ' // ¿Cómo consulto qué está sonando?\n' +
64
+ '}',
65
+ '\n💥 Problemas de interfaz incompleta:',
66
+ '• Imposible predecir qué operaciones están disponibles',
67
+ '• Firmas inconsistentes entre operaciones',
68
+ '• Funcionalidad básica faltante',
69
+ '• Colaboración con otros objetos impredecible'
70
+ ],
71
+ type: 'text'
72
+ },
73
+ {
74
+ message: '\nPresiona Enter para ver otro problema...',
75
+ type: 'pause'
76
+ },
77
+ {
78
+ lines: [
79
+ '\n🚫 PROBLEMA: Firmas sin relación',
80
+ 'class BadMusicPlayer {\n' +
81
+ ' // ❌ Firmas que no forman un conjunto coherente\n' +
82
+ ' startMusic(file: string): void // Usa archivos\n' +
83
+ ' playTrack(id: number): boolean // Usa IDs numéricos\n' +
84
+ ' beginSong(song: object): string // Usa objetos\n' +
85
+ '\n' +
86
+ ' setVol(x: number): void // Volumen sin validación\n' +
87
+ ' adjustAudio(level: string): boolean // Volumen como string??\n' +
88
+ '\n' +
89
+ " getCurrentStatus(): any // Retorna 'any' (inútil)\n" +
90
+ ' getInfo(): string // Retorna string (ambiguo)\n' +
91
+ '}',
92
+ '\n📉 Resultado:',
93
+ 'No es una interfaz, es una colección caótica de operaciones',
94
+ 'sin relación ni coherencia entre sí.'
95
+ ],
96
+ type: 'text'
97
+ },
98
+ {
99
+ message: '\nPresiona Enter para ver cómo debe ser...',
100
+ type: 'pause'
101
+ },
102
+ {
103
+ type: 'clear'
104
+ },
105
+ {
106
+ lines: [
107
+ '✅ INTERFAZ COMPLETA Y COHERENTE',
108
+ '========================================',
109
+ 'Veamos una interfaz bien diseñada:',
110
+ '\n🎵 CONJUNTO COMPLETO de firmas de operación:',
111
+ 'interface MusicPlayerInterface {\n' +
112
+ ' // 🎮 GRUPO: Control de reproducción\n' +
113
+ ' play(songId: string): Promise<{success: boolean, message: string}>\n' +
114
+ ' pause(): Promise<{success: boolean, currentPosition: number}>\n' +
115
+ ' stop(): Promise<{success: boolean}>\n' +
116
+ ' resume(): Promise<{success: boolean, message: string}>\n' +
117
+ '\n' +
118
+ ' // 🔊 GRUPO: Control de audio\n' +
119
+ ' setVolume(level: number): {success: boolean, currentVolume: number} // 0-100\n' +
120
+ ' getVolume(): number\n' +
121
+ ' mute(): {success: boolean, previousVolume: number}\n' +
122
+ ' unmute(): {success: boolean, restoredVolume: number}\n' +
123
+ '\n' +
124
+ ' // 📋 GRUPO: Gestión de playlist\n' +
125
+ ' addSong(song: Song): {success: boolean, playlistLength: number}\n' +
126
+ ' removeSong(songId: string): {success: boolean, wasPlaying: boolean}\n' +
127
+ ' getPlaylist(): Song[]\n' +
128
+ ' shufflePlaylist(): {success: boolean, newOrder: string[]}\n' +
129
+ '\n' +
130
+ ' // 📊 GRUPO: Información de estado\n' +
131
+ ' getCurrentSong(): Song | null\n' +
132
+ ' getPlaybackStatus(): {\n' +
133
+ ' isPlaying: boolean,\n' +
134
+ ' isPaused: boolean,\n' +
135
+ ' currentTime: number,\n' +
136
+ ' totalTime: number,\n' +
137
+ ' volume: number\n' +
138
+ ' }\n' +
139
+ ' getDuration(songId: string): number | null\n' +
140
+ '\n' +
141
+ ' // ⚙️ GRUPO: Configuración\n' +
142
+ " setRepeatMode(mode: 'none' | 'one' | 'all'): boolean\n" +
143
+ " getRepeatMode(): 'none' | 'one' | 'all'\n" +
144
+ ' setShuffleMode(enabled: boolean): boolean\n' +
145
+ ' isShuffleEnabled(): boolean\n' +
146
+ '}'
147
+ ],
148
+ type: 'text'
149
+ },
150
+ {
151
+ message: '\nPresiona Enter para analizar esta interfaz...',
152
+ type: 'pause'
153
+ },
154
+ {
155
+ lines: [
156
+ '\n🔍 ANÁLISIS del conjunto:',
157
+ '\n1️⃣ COMPLETITUD:',
158
+ ' • Todas las operaciones necesarias están presentes',
159
+ ' • No hay funcionalidad faltante básica',
160
+ ' • Cubre todo el comportamiento esperado',
161
+ '\n2️⃣ COHERENCIA:',
162
+ ' • Todas las firmas usan tipos consistentes',
163
+ ' • Patrones de retorno consistentes',
164
+ ' • Nomenclatura uniforme',
165
+ '\n3️⃣ ORGANIZACIÓN:',
166
+ ' • Operaciones agrupadas por funcionalidad',
167
+ ' • Cada grupo tiene propósito claro',
168
+ ' • Fácil de entender y recordar'
169
+ ],
170
+ type: 'text'
171
+ },
172
+ {
173
+ message: '\nPresiona Enter para ver la implementación...',
174
+ type: 'pause'
175
+ },
176
+ {
177
+ type: 'clear'
178
+ },
179
+ {
180
+ lines: [
181
+ '🧩 COHERENCIA DE LA INTERFAZ',
182
+ '===================================',
183
+ 'Veamos cómo las firmas forman un conjunto coherente:',
184
+ '\n📏 CONSISTENCIA EN TIPOS:',
185
+ '// ✅ Todas las operaciones de canciones usan string\n' +
186
+ 'play(songId: string)\n' +
187
+ 'removeSong(songId: string)\n' +
188
+ 'getDuration(songId: string)\n' +
189
+ '\n' +
190
+ '// ✅ Todas las operaciones de volumen usan number (0-100)\n' +
191
+ 'setVolume(level: number) // 0-100\n' +
192
+ 'getVolume(): number // 0-100\n' +
193
+ 'mute(): {previousVolume: number} // 0-100',
194
+ '\n🔄 CONSISTENCIA EN PATRONES:',
195
+ '// ✅ Operaciones de configuración siguen patrón set/get\n' +
196
+ 'setRepeatMode(mode) / getRepeatMode()\n' +
197
+ 'setShuffleMode(enabled) / isShuffleEnabled()\n' +
198
+ 'setVolume(level) / getVolume()\n' +
199
+ '\n' +
200
+ '// ✅ Operaciones de estado siguen patrón de objeto estructurado\n' +
201
+ 'getPlaybackStatus(): {isPlaying, isPaused, currentTime, ...}\n' +
202
+ 'pause(): {success, currentPosition}\n' +
203
+ 'mute(): {success, previousVolume}',
204
+ '\n🎯 COMPLETITUD FUNCIONAL:',
205
+ '// ✅ Para cada acción, hay su contraparte\n' +
206
+ 'play() ↔ pause() ↔ stop() ↔ resume()\n' +
207
+ 'mute() ↔ unmute()\n' +
208
+ 'addSong() ↔ removeSong()\n' +
209
+ '\n' +
210
+ '// ✅ Para cada operación de cambio, hay consulta\n' +
211
+ 'setVolume() → getVolume()\n' +
212
+ 'setRepeatMode() → getRepeatMode()'
213
+ ],
214
+ type: 'text'
215
+ },
216
+ {
217
+ message: '\nPresiona Enter para ver cómo se usa...',
218
+ type: 'pause'
219
+ },
220
+ {
221
+ type: 'clear'
222
+ },
223
+ {
224
+ lines: [
225
+ '🎭 DEMOSTRACIÓN: Uso de Interfaz Completa',
226
+ '=============================================',
227
+ 'Veamos cómo se usa una interfaz bien diseñada:',
228
+ '\n// Crear reproductor',
229
+ 'const player = new MusicPlayer()',
230
+ '',
231
+ '// 🎵 Usar GRUPO de reproducción',
232
+ "const song = new Song('123', 'Bohemian Rhapsody', 'Queen')",
233
+ 'await player.addSong(song)',
234
+ '',
235
+ "const playResult = await player.play('123')",
236
+ 'if (playResult.success) {',
237
+ " console.log('Reproduciendo:', playResult.message)",
238
+ '}'
239
+ ],
240
+ type: 'text'
241
+ },
242
+ {
243
+ message: '\nPresiona Enter para ver más uso...',
244
+ type: 'pause'
245
+ },
246
+ {
247
+ lines: [
248
+ '\n// 🔊 Usar GRUPO de audio',
249
+ 'const volumeResult = player.setVolume(75)',
250
+ "console.log('Volumen actual:', volumeResult.currentVolume)",
251
+ '',
252
+ '// 📊 Usar GRUPO de información',
253
+ 'const status = player.getPlaybackStatus()',
254
+ 'console.log(`Reproduciendo: ${status.isPlaying}`)',
255
+ 'console.log(`Tiempo: ${status.currentTime}/${status.totalTime}`)',
256
+ 'console.log(`Volumen: ${status.volume}`)'
257
+ ],
258
+ type: 'text'
259
+ },
260
+ {
261
+ message: '\nPresiona Enter para ver uso avanzado...',
262
+ type: 'pause'
263
+ },
264
+ {
265
+ lines: [
266
+ '\n// 🎮 Combinando múltiples grupos',
267
+ 'async function createMusicSession() {',
268
+ ' // Configurar reproductor',
269
+ " player.setRepeatMode('all')",
270
+ ' player.setShuffleMode(true)',
271
+ ' player.setVolume(60)',
272
+ ' ',
273
+ ' // Agregar canciones',
274
+ " const songs = ['123', '456', '789']",
275
+ ' for (const songId of songs) {',
276
+ ' await player.addSong(getSong(songId))',
277
+ ' }',
278
+ ' ',
279
+ ' // Iniciar reproducción',
280
+ ' await player.play(songs[0])',
281
+ ' ',
282
+ ' // Monitorear estado cada segundo',
283
+ ' setInterval(() => {',
284
+ ' const status = player.getPlaybackStatus()',
285
+ ' updateUI(status)',
286
+ ' }, 1000)',
287
+ '}',
288
+ '\n🌟 Beneficios observados:',
289
+ '• Cada operación se complementa con las demás',
290
+ '• Podemos crear flujos complejos combinando firmas',
291
+ '• La interfaz completa permite cualquier funcionalidad',
292
+ '• El conjunto es mayor que la suma de sus partes'
293
+ ],
294
+ type: 'text'
295
+ },
296
+ {
297
+ message: '\nPresiona Enter para la conclusión...',
298
+ type: 'pause'
299
+ },
300
+ {
301
+ type: 'clear'
302
+ },
303
+ {
304
+ lines: [
305
+ '🎓 CONCLUSIÓN: Interfaz como Conjunto de Firmas',
306
+ '==================================================',
307
+ '🎯 Hemos demostrado que:',
308
+ '\n1️⃣ Una interfaz es el CONJUNTO COMPLETO de firmas',
309
+ '2️⃣ No es una operación individual, sino TODAS juntas',
310
+ '3️⃣ Las firmas deben ser coherentes entre sí',
311
+ '4️⃣ El conjunto debe cubrir toda la funcionalidad necesaria',
312
+ '\n🧩 Características de una buena interfaz:',
313
+ '• COMPLETITUD - todas las operaciones necesarias',
314
+ '• COHERENCIA - tipos y patrones consistentes',
315
+ '• ORGANIZACIÓN - agrupación lógica de funcionalidades',
316
+ '• PREDICTIBILIDAD - comportamiento uniforme',
317
+ '\n🎯 La interfaz como contrato:',
318
+ '• Define TODO lo que el objeto puede hacer',
319
+ '• Especifica exactamente cómo interactuar',
320
+ '• Garantiza comportamiento predecible',
321
+ '• Permite colaboración confiable',
322
+ '\n📚 Conexión con otras lecciones:',
323
+ '• Lección 1-3: Los objetos necesitan interfaces para interactuar',
324
+ '• Lección 4: Cada operación de la interfaz tiene firma completa',
325
+ '• Lección 5: ✅ La interfaz es el conjunto de TODAS las firmas',
326
+ '• Lección 6: El énfasis debe estar en diseñar este conjunto',
327
+ '\n💭 Reflexión:',
328
+ 'Imagina un control remoto que solo tuviera algunos botones:',
329
+ 'play pero no pause, volumen+ pero no volumen-. ¡Sería inútil!',
330
+ 'Las interfaces necesitan ser conjuntos completos y coherentes.',
331
+ '\n🏆 Ahora entiendes qué es realmente una interfaz:',
332
+ 'el conjunto completo de todas las firmas de operación.'
333
+ ],
334
+ type: 'text'
335
+ },
336
+ {
337
+ message: '\n✨ ¡Lección 5 completada! Presiona Enter para salir...',
338
+ type: 'pause'
339
+ }
340
+ ]
341
+ }