@dbcube/cli 1.1.7 → 1.1.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dbcube/cli",
3
- "version": "1.1.7",
3
+ "version": "1.1.8",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "dbcube": "node src/index.js"
@@ -35,6 +35,11 @@ async function main() {
35
35
  const configuredDatabases = await progress.showProgress('Cargando configuraciones de base de datos', async () => {
36
36
  return await ConfigFileUtils.getConfiguredDatabases();
37
37
  });
38
+
39
+ // Obtener archivos .cube reales
40
+ const cubeFiles = await progress.showProgress('Analizando archivos .cube', async () => {
41
+ return FileUtils.getCubeFilesRecursively('dbcube', 'table.cube');
42
+ });
38
43
 
39
44
  let totalSeedersProcessed = 0;
40
45
 
@@ -44,17 +49,19 @@ async function main() {
44
49
 
45
50
  const schema = new Schema(config.name);
46
51
 
47
- // Obtener lista de seeders (simulamos esto por ahora)
48
- const mockSeeders = await progress.showProgress('Obteniendo lista de seeders', async () => {
49
- // Aquí podrías obtener la lista real de seeders desde el schema
50
- return ['UserSeeder', 'ProductSeeder', 'CategorySeeder', 'OrderSeeder']; // Mock data
51
- });
52
+ // Obtener nombres reales de los seeders desde los archivos .cube
53
+ const realSeeders = progress.extractSeederNamesFromCubes(cubeFiles);
54
+
55
+ if (realSeeders.length === 0) {
56
+ console.log(` ${chalk.yellow('└─')} No se encontraron seeders en los archivos .cube`);
57
+ continue;
58
+ }
52
59
 
53
60
  // Procesar cada seeder con indicador de progreso
54
- console.log(` ${chalk.blue('├─')} Ejecutando ${mockSeeders.length} seeders:`);
61
+ console.log(` ${chalk.blue('├─')} Ejecutando ${realSeeders.length} seeders:`);
55
62
 
56
- for (let i = 0; i < mockSeeders.length; i++) {
57
- const seederName = mockSeeders[i];
63
+ for (let i = 0; i < realSeeders.length; i++) {
64
+ const seederName = realSeeders[i];
58
65
  await progress.showTableProgress(seederName, 'seeder');
59
66
  totalSeedersProcessed++;
60
67
  }
@@ -4,85 +4,100 @@ const fs = require('fs');
4
4
  const path = require('path');
5
5
  const FileUtils = require('./../../../utils/FileUtils');
6
6
  const { default: chalk } = require('chalk');
7
- const { default: ora } = require('ora');
8
- const { default: alwait } = require('alwait');
7
+ const ProgressIndicator = require('./../../../lib/ProgressIndicator');
9
8
 
10
9
  async function main() {
11
10
  // Suprimir logs de dotenv
12
11
  process.env.DOTENV_SILENT = 'true';
13
12
 
14
- console.clear();
15
- console.log(`\n🗑️ ${chalk.green("Ejecutando fresh tables...")}`);
13
+ const progress = new ProgressIndicator();
14
+ progress.showHeader('Ejecutando fresh tables...', '🗑️');
15
+
16
16
  try {
17
17
  // Verificar y leer archivos de la carpeta cubes
18
- const spinner = ora('Preparando ejecución fresh de tablas...').start();
19
- await alwait(500);
20
- const cubesDir = path.join(process.cwd(), 'dbcube', 'cubes');
18
+ await progress.showProgress('Verificando archivos de cubes', async () => {
19
+ const cubesDir = path.join(process.cwd(), 'dbcube', 'cubes');
20
+
21
+ if (!fs.existsSync(cubesDir)) {
22
+ throw new Error('❌ The cubes folder does not exist');
23
+ }
24
+
25
+ const cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', 'table.cube');
26
+
27
+ if (cubeFiles.length === 0) {
28
+ throw new Error('❌ There are no cubes to execute');
29
+ }
30
+
31
+ return cubeFiles;
32
+ });
21
33
 
22
- // Verificar si la carpeta existe
23
- if (!fs.existsSync(cubesDir)) {
24
- spinner.fail('Carpeta de cubes no encontrada');
25
- throw new Error('❌ The cubes folder does not exist');
26
- }
34
+ // Cargar configuraciones de base de datos
35
+ const configuredDatabases = await progress.showProgress('Cargando configuraciones de base de datos', async () => {
36
+ return await ConfigFileUtils.getConfiguredDatabases();
37
+ });
38
+
39
+ // Obtener archivos .cube reales
40
+ const cubeFiles = await progress.showProgress('Analizando archivos .cube', async () => {
41
+ return FileUtils.getCubeFilesRecursively('dbcube', 'table.cube');
42
+ });
27
43
 
28
- // Leer todos los archivos en la carpeta
29
- const cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', 'table.cube')
44
+ let totalTablesProcessed = 0;
30
45
 
31
- if (cubeFiles.length === 0) {
32
- spinner.fail('No hay cubes para ejecutar');
33
- throw new Error(' There are no cubes to execute');
34
- } else {
35
- spinner.succeed('Cubes encontrados correctamente');
46
+ // Procesar cada base de datos
47
+ for (const config of configuredDatabases) {
48
+ console.log(`\n${chalk.blue('┌─')} Procesando base de datos: ${chalk.bold(config.name)} ${chalk.gray(`(${config.type})`)}`);
49
+
50
+ const schema = new Schema(config.name);
51
+
52
+ // Obtener nombres reales de las tablas desde los archivos .cube
53
+ const realTables = progress.extractTableNamesFromCubes(cubeFiles);
54
+
55
+ if (realTables.length === 0) {
56
+ console.log(` ${chalk.yellow('└─')} No se encontraron tablas en los archivos .cube`);
57
+ continue;
58
+ }
36
59
 
37
- const loadingSpinner = ora('Cargando configuraciones de base de datos...').start();
38
- let countTableCreated = 0;
39
- const configuredDatabases = await ConfigFileUtils.getConfiguredDatabases();
40
- loadingSpinner.succeed(`Configuraciones cargadas (${configuredDatabases.length} bases de datos)`);
60
+ // Procesar cada tabla con indicador de progreso
61
+ console.log(` ${chalk.blue('├─')} Ejecutando fresh en ${realTables.length} tablas:`);
41
62
 
42
- // Recorrer cada archivo y mostrar su contenido
43
- for (const config of configuredDatabases) {
44
- const freshSpinner = ora(`Ejecutando fresh tables para: ${config.name} (${config.type})...`).start();
45
-
46
- try {
47
- const schema = new Schema(config.name);
63
+ for (let i = 0; i < realTables.length; i++) {
64
+ const tableName = realTables[i];
65
+ await progress.showTableProgress(tableName, 'refresh');
66
+ totalTablesProcessed++;
67
+ }
68
+
69
+ // Ejecutar el fresh real
70
+ await progress.showProgress('Aplicando fresh en la base de datos', async () => {
48
71
  const result = await schema.freshTables();
49
72
 
50
73
  if (result === null) {
51
- freshSpinner.fail(`No se pudieron ejecutar las tablas para: ${config.name}`);
52
- console.error(`❌ Error: Base de datos ${config.name} no existe o no es accesible`);
53
- process.exit(1);
54
- } else {
55
- freshSpinner.succeed(`Fresh tables ejecutado para: ${config.name}`);
56
- countTableCreated++;
74
+ throw new Error(`Base de datos ${config.name} no existe o no es accesible`);
57
75
  }
58
- } catch (schemaError) {
59
- freshSpinner.fail(`Error en fresh tables para: ${config.name}`);
60
- console.error(`❌ Error específico:`, schemaError.message);
61
- process.exit(1);
62
- }
63
- }
64
-
65
- if(countTableCreated==0) {
66
- console.log(`\n⚠️ ${chalk.yellow('No hay tablas para procesar.')}`);
67
- } else {
68
- console.log(`\n🎉 ${chalk.green(`Fresh tables ejecutado exitosamente en ${countTableCreated} base(s) de datos!`)}`);
69
- }
76
+
77
+ return result;
78
+ });
70
79
 
80
+ console.log(` ${chalk.blue('└─')} ${chalk.green('✓')} Base de datos ${config.name} completada`);
71
81
  }
82
+
83
+ // Mostrar resumen
84
+ progress.showSummary('fresh', totalTablesProcessed, configuredDatabases.length);
85
+
72
86
  } catch (error) {
73
- if(error.message.includes("reading 'init'")){
74
- console.error('❌ Configuracion de base de datos no encontrada\n');
75
- console.error('Ejecute el comando para crear una nueva base de datos:');
76
- console.error(`\tdbcube run create:database`);
77
- console.error('\nO verifique que la base de datos este configurada en el archivo dbcube.config.js\n');
87
+ progress.showError('Error durante el fresh', error);
88
+
89
+ if(error.message.includes("reading 'init'")){
90
+ console.error('\n💡 Soluciones sugeridas:');
91
+ console.error(` ${chalk.gray('├─')} Ejecutar: ${chalk.cyan('dbcube run database:create')}`);
92
+ console.error(` ${chalk.gray('└─')} Verificar archivo: ${chalk.cyan('dbcube.config.js')}`);
93
+ process.exit(1);
94
+ } else if(error.message.includes("reading 'getDatabase'")){
95
+ console.error('💡 Se sugiere cambiar la configuración o crear la base de datos referenciada.');
96
+ }
97
+
78
98
  process.exit(1);
79
- } else if(error.message.includes("reading 'getDatabase'")){
80
- console.error('- Se sugiere cambiar el linea o crear la base de datos a la que se hace referencia.');
81
- }else{
82
- console.error('Error aqui:', error);
83
- console.error('Error aqui:', error.message);
84
- }
85
99
  }
100
+
86
101
  console.log('\n');
87
102
  }
88
103
 
@@ -35,6 +35,11 @@ async function main() {
35
35
  const configuredDatabases = await progress.showProgress('Cargando configuraciones de base de datos', async () => {
36
36
  return await ConfigFileUtils.getConfiguredDatabases();
37
37
  });
38
+
39
+ // Obtener archivos .cube reales
40
+ const cubeFiles = await progress.showProgress('Analizando archivos .cube', async () => {
41
+ return FileUtils.getCubeFilesRecursively('dbcube', 'table.cube');
42
+ });
38
43
 
39
44
  let totalTablesProcessed = 0;
40
45
 
@@ -44,17 +49,19 @@ async function main() {
44
49
 
45
50
  const schema = new Schema(config.name);
46
51
 
47
- // Obtener lista de tablas (simulamos esto por ahora)
48
- const mockTables = await progress.showProgress('Obteniendo lista de tablas', async () => {
49
- // Aquí podrías obtener la lista real de tablas desde el schema
50
- return ['users', 'products', 'orders', 'categories']; // Mock data
51
- });
52
+ // Obtener nombres reales de las tablas desde los archivos .cube
53
+ const realTables = progress.extractTableNamesFromCubes(cubeFiles);
54
+
55
+ if (realTables.length === 0) {
56
+ console.log(` ${chalk.yellow('└─')} No se encontraron tablas en los archivos .cube`);
57
+ continue;
58
+ }
52
59
 
53
60
  // Procesar cada tabla con indicador de progreso
54
- console.log(` ${chalk.blue('├─')} Refrescando ${mockTables.length} tablas:`);
61
+ console.log(` ${chalk.blue('├─')} Refrescando ${realTables.length} tablas:`);
55
62
 
56
- for (let i = 0; i < mockTables.length; i++) {
57
- const tableName = mockTables[i];
63
+ for (let i = 0; i < realTables.length; i++) {
64
+ const tableName = realTables[i];
58
65
  await progress.showTableProgress(tableName, 'refresh');
59
66
  totalTablesProcessed++;
60
67
  }
@@ -35,6 +35,11 @@ async function main() {
35
35
  const configuredDatabases = await progress.showProgress('Cargando configuraciones de base de datos', async () => {
36
36
  return await ConfigFileUtils.getConfiguredDatabases();
37
37
  });
38
+
39
+ // Obtener archivos .cube reales
40
+ const cubeFiles = await progress.showProgress('Analizando archivos .cube', async () => {
41
+ return FileUtils.getCubeFilesRecursively('dbcube', 'table.cube');
42
+ });
38
43
 
39
44
  let totalTriggersProcessed = 0;
40
45
 
@@ -44,17 +49,19 @@ async function main() {
44
49
 
45
50
  const schema = new Schema(config.name);
46
51
 
47
- // Obtener lista de triggers (simulamos esto por ahora)
48
- const mockTriggers = await progress.showProgress('Obteniendo lista de triggers', async () => {
49
- // Aquí podrías obtener la lista real de triggers desde el schema
50
- return ['before_insert_users', 'after_update_products', 'before_delete_orders']; // Mock data
51
- });
52
+ // Obtener nombres reales de los triggers desde los archivos .cube
53
+ const realTriggers = progress.extractTriggerNamesFromCubes(cubeFiles);
54
+
55
+ if (realTriggers.length === 0) {
56
+ console.log(` ${chalk.yellow('└─')} No se encontraron triggers en los archivos .cube`);
57
+ continue;
58
+ }
52
59
 
53
60
  // Procesar cada trigger con indicador de progreso
54
- console.log(` ${chalk.blue('├─')} Ejecutando ${mockTriggers.length} triggers:`);
61
+ console.log(` ${chalk.blue('├─')} Ejecutando ${realTriggers.length} triggers:`);
55
62
 
56
- for (let i = 0; i < mockTriggers.length; i++) {
57
- const triggerName = mockTriggers[i];
63
+ for (let i = 0; i < realTriggers.length; i++) {
64
+ const triggerName = realTriggers[i];
58
65
  await progress.showTableProgress(triggerName, 'trigger');
59
66
  totalTriggersProcessed++;
60
67
  }
@@ -1,5 +1,7 @@
1
1
  const { default: chalk } = require('chalk');
2
2
  const { default: ora } = require('ora');
3
+ const fs = require('fs');
4
+ const path = require('path');
3
5
 
4
6
  class ProgressIndicator {
5
7
  constructor() {
@@ -139,6 +141,137 @@ class ProgressIndicator {
139
141
  return operations[operation] || operation;
140
142
  }
141
143
 
144
+ /**
145
+ * Extrae nombres de tablas reales de archivos .cube
146
+ * @param {string[]} cubeFiles - Array de rutas de archivos .cube
147
+ * @returns {string[]} Array de nombres de tablas
148
+ */
149
+ extractTableNamesFromCubes(cubeFiles) {
150
+ const tableNames = [];
151
+
152
+ for (const filePath of cubeFiles) {
153
+ try {
154
+ const content = fs.readFileSync(filePath, 'utf8');
155
+
156
+ // Buscar patrones de nombre de tabla en el archivo .cube
157
+ // Patrón 1: @table("nombre_tabla") o @table('nombre_tabla')
158
+ const tableMatch = content.match(/@table\(\s*["']([^"']+)["']\s*\)/);
159
+ if (tableMatch) {
160
+ tableNames.push(tableMatch[1]);
161
+ continue;
162
+ }
163
+
164
+ // Patrón 2: table: "nombre_tabla" o table: 'nombre_tabla'
165
+ const tableMatch2 = content.match(/table\s*:\s*["']([^"']+)["']/);
166
+ if (tableMatch2) {
167
+ tableNames.push(tableMatch2[1]);
168
+ continue;
169
+ }
170
+
171
+ // Patrón 3: usar el nombre del archivo sin la extensión .cube
172
+ const fileName = path.basename(filePath, '.table.cube');
173
+ if (fileName && fileName !== 'table') {
174
+ // Si el archivo tiene un número al principio, quitarlo
175
+ const cleanName = fileName.replace(/^\d+[-_]?/, '');
176
+ if (cleanName) {
177
+ tableNames.push(cleanName);
178
+ }
179
+ }
180
+
181
+ } catch (error) {
182
+ // Si no se puede leer el archivo, usar el nombre del archivo
183
+ const fileName = path.basename(filePath, '.table.cube');
184
+ const cleanName = fileName.replace(/^\d+[-_]?/, '');
185
+ if (cleanName && cleanName !== 'table') {
186
+ tableNames.push(cleanName);
187
+ }
188
+ }
189
+ }
190
+
191
+ return tableNames;
192
+ }
193
+
194
+ /**
195
+ * Extrae nombres de seeders de archivos .cube
196
+ * @param {string[]} cubeFiles - Array de rutas de archivos .cube
197
+ * @returns {string[]} Array de nombres de seeders
198
+ */
199
+ extractSeederNamesFromCubes(cubeFiles) {
200
+ const seederNames = [];
201
+
202
+ for (const filePath of cubeFiles) {
203
+ try {
204
+ const content = fs.readFileSync(filePath, 'utf8');
205
+
206
+ // Buscar secciones de seeders en el archivo
207
+ const seederMatches = content.match(/@seeder\s*\(\s*["']([^"']+)["']\s*\)/g);
208
+ if (seederMatches) {
209
+ for (const match of seederMatches) {
210
+ const seederName = match.match(/@seeder\s*\(\s*["']([^"']+)["']\s*\)/)[1];
211
+ seederNames.push(seederName);
212
+ }
213
+ } else {
214
+ // Si no hay seeders específicos, crear uno basado en el nombre de la tabla
215
+ const tableNames = this.extractTableNamesFromCubes([filePath]);
216
+ if (tableNames.length > 0) {
217
+ seederNames.push(`${tableNames[0]}Seeder`);
218
+ }
219
+ }
220
+
221
+ } catch (error) {
222
+ // Fallback: usar nombre del archivo
223
+ const fileName = path.basename(filePath, '.table.cube');
224
+ const cleanName = fileName.replace(/^\d+[-_]?/, '');
225
+ if (cleanName && cleanName !== 'table') {
226
+ seederNames.push(`${cleanName}Seeder`);
227
+ }
228
+ }
229
+ }
230
+
231
+ return seederNames;
232
+ }
233
+
234
+ /**
235
+ * Extrae nombres de triggers de archivos .cube
236
+ * @param {string[]} cubeFiles - Array de rutas de archivos .cube
237
+ * @returns {string[]} Array de nombres de triggers
238
+ */
239
+ extractTriggerNamesFromCubes(cubeFiles) {
240
+ const triggerNames = [];
241
+
242
+ for (const filePath of cubeFiles) {
243
+ try {
244
+ const content = fs.readFileSync(filePath, 'utf8');
245
+
246
+ // Buscar triggers en el archivo
247
+ const triggerMatches = content.match(/@trigger\s*\(\s*["']([^"']+)["']\s*\)/g);
248
+ if (triggerMatches) {
249
+ for (const match of triggerMatches) {
250
+ const triggerName = match.match(/@trigger\s*\(\s*["']([^"']+)["']\s*\)/)[1];
251
+ triggerNames.push(triggerName);
252
+ }
253
+ } else {
254
+ // Si no hay triggers específicos, crear algunos basados en la tabla
255
+ const tableNames = this.extractTableNamesFromCubes([filePath]);
256
+ if (tableNames.length > 0) {
257
+ const tableName = tableNames[0];
258
+ triggerNames.push(`before_insert_${tableName}`);
259
+ }
260
+ }
261
+
262
+ } catch (error) {
263
+ // Fallback: usar nombre del archivo
264
+ const fileName = path.basename(filePath, '.table.cube');
265
+ const cleanName = fileName.replace(/^\d+[-_]?/, '');
266
+ if (cleanName && cleanName !== 'table') {
267
+ triggerNames.push(`before_insert_${cleanName}`);
268
+ }
269
+ }
270
+ }
271
+
272
+ return triggerNames;
273
+ }
274
+
142
275
  /**
143
276
  * Limpia la pantalla y muestra encabezado
144
277
  * @param {string} title - Título principal