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