@deinossrl/dgp-agent 1.5.6 → 1.5.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.
Files changed (2) hide show
  1. package/index.mjs +152 -17
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -1770,24 +1770,93 @@ async function executePgDump(command) {
1770
1770
  // Archivo de salida
1771
1771
  pgDumpArgs.push(`--file=${localFilePath}`);
1772
1772
 
1773
- // Ejecutar pg_dump usando spawnSync directamente (evita problemas con espacios en rutas)
1773
+ // Agregar --verbose para obtener información de progreso
1774
+ pgDumpArgs.push('--verbose');
1775
+
1776
+ // Ejecutar pg_dump usando spawn para capturar progreso en tiempo real
1774
1777
  logCommand(`Ejecutando: pg_dump [conexión oculta]`);
1775
1778
  await addCommandLog('command', 'Ejecutando pg_dump...');
1776
1779
 
1777
- const result = spawnSync(pgDumpCmd, pgDumpArgs, {
1778
- env: process.env,
1779
- encoding: 'utf-8',
1780
- stdio: 'pipe',
1781
- });
1780
+ // Usar spawn asíncrono para capturar progreso
1781
+ await new Promise((resolve, reject) => {
1782
+ const pgDumpProcess = spawn(pgDumpCmd, pgDumpArgs, {
1783
+ env: process.env,
1784
+ stdio: ['ignore', 'pipe', 'pipe'],
1785
+ });
1782
1786
 
1783
- if (result.error) {
1784
- throw new Error(`Error ejecutando pg_dump: ${result.error.message}`);
1785
- }
1787
+ let stderrBuffer = '';
1788
+ let stdoutBuffer = '';
1789
+ let lastLogTime = Date.now();
1790
+ let objectCount = 0;
1791
+ let totalEstimated = 0;
1792
+
1793
+ // Estimar total de objetos si se especificaron schemas/tables
1794
+ if (params.tables && params.tables.length > 0) {
1795
+ totalEstimated = params.tables.length;
1796
+ } else if (params.schemas && params.schemas.length > 0) {
1797
+ // Aproximado: ~20 objetos por schema (tablas, índices, secuencias, etc.)
1798
+ totalEstimated = params.schemas.length * 20;
1799
+ }
1786
1800
 
1787
- if (result.status !== 0) {
1788
- const errorMsg = result.stderr || result.stdout || 'Unknown error';
1789
- throw new Error(`pg_dump failed with code ${result.status}: ${errorMsg}`);
1790
- }
1801
+ // Capturar stderr (pg_dump envía progreso aquí con --verbose)
1802
+ pgDumpProcess.stderr.on('data', (data) => {
1803
+ const message = data.toString();
1804
+ stderrBuffer += message;
1805
+
1806
+ // Contar objetos procesados
1807
+ const lines = message.split('\n');
1808
+ for (const line of lines) {
1809
+ if (line.includes('processing') || line.includes('dumping data for table') || line.includes('creating') || line.includes('setting owner')) {
1810
+ objectCount++;
1811
+ }
1812
+ }
1813
+
1814
+ // Enviar log cada 2 segundos para no saturar
1815
+ const now = Date.now();
1816
+ if (now - lastLogTime > 2000) {
1817
+ const relevantLine = lines[lines.length - 1].trim();
1818
+ if (relevantLine && (relevantLine.includes('processing') || relevantLine.includes('dumping') || relevantLine.includes('table') || relevantLine.includes('creating'))) {
1819
+ let progressMsg = '';
1820
+
1821
+ // Si tenemos estimación, mostrar porcentaje
1822
+ if (totalEstimated > 0 && objectCount > 0) {
1823
+ const percentage = Math.min(Math.round((objectCount / totalEstimated) * 100), 100);
1824
+ progressMsg = `Progreso: ${percentage}% (${objectCount}/${totalEstimated}) - `;
1825
+ } else if (objectCount > 0) {
1826
+ progressMsg = `Objetos procesados: ${objectCount} - `;
1827
+ }
1828
+
1829
+ progressMsg += relevantLine.substring(0, 80);
1830
+ addCommandLog('info', progressMsg).catch(() => {});
1831
+ lastLogTime = now;
1832
+ }
1833
+ }
1834
+ });
1835
+
1836
+ // Capturar stdout (por si acaso)
1837
+ pgDumpProcess.stdout.on('data', (data) => {
1838
+ stdoutBuffer += data.toString();
1839
+ });
1840
+
1841
+ // Manejar errores del proceso
1842
+ pgDumpProcess.on('error', (error) => {
1843
+ reject(new Error(`Error ejecutando pg_dump: ${error.message}`));
1844
+ });
1845
+
1846
+ // Manejar finalización
1847
+ pgDumpProcess.on('close', (code) => {
1848
+ if (code !== 0) {
1849
+ const errorMsg = stderrBuffer || stdoutBuffer || 'Unknown error';
1850
+ reject(new Error(`pg_dump failed with code ${code}: ${errorMsg}`));
1851
+ } else {
1852
+ // Log final con total de objetos procesados
1853
+ if (objectCount > 0) {
1854
+ addCommandLog('success', `Backup completado: ${objectCount} objetos exportados`).catch(() => {});
1855
+ }
1856
+ resolve();
1857
+ }
1858
+ });
1859
+ });
1791
1860
 
1792
1861
  // Verificar que el archivo se creó
1793
1862
  if (!existsSync(localFilePath)) {
@@ -2177,9 +2246,35 @@ async function executePgRestore(command) {
2177
2246
  pgRestoreArgs.push('--no-owner');
2178
2247
  pgRestoreArgs.push('--no-privileges');
2179
2248
 
2249
+ // Agregar --verbose para obtener información de progreso
2250
+ pgRestoreArgs.push('--verbose');
2251
+
2180
2252
  // Archivo de entrada
2181
2253
  pgRestoreArgs.push(localFilePath);
2182
2254
 
2255
+ // CALCULAR TOTAL DE OBJETOS para el porcentaje
2256
+ let totalObjects = 0;
2257
+ try {
2258
+ const listResult = spawnSync(pgRestorePath, ['--list', localFilePath], {
2259
+ env: process.env,
2260
+ encoding: 'utf-8',
2261
+ stdio: 'pipe',
2262
+ });
2263
+
2264
+ if (listResult.status === 0 && listResult.stdout) {
2265
+ // Contar líneas que representan objetos (excluir comentarios y líneas vacías)
2266
+ const lines = listResult.stdout.split('\n').filter(line => {
2267
+ const trimmed = line.trim();
2268
+ return trimmed && !trimmed.startsWith(';') && /^\d+;/.test(trimmed);
2269
+ });
2270
+ totalObjects = lines.length;
2271
+ logInfo(`Total de objetos a restaurar: ${totalObjects}`);
2272
+ await addCommandLog('info', `Objetos a procesar: ${totalObjects}`);
2273
+ }
2274
+ } catch (e) {
2275
+ logInfo('No se pudo contar objetos, continuando sin porcentaje...');
2276
+ }
2277
+
2183
2278
  // Ejecutar pg_restore con progreso en tiempo real
2184
2279
  logCommand(`Ejecutando: pg_restore [conexión oculta]`);
2185
2280
  await addCommandLog('command', 'Ejecutando pg_restore...');
@@ -2190,24 +2285,64 @@ async function executePgRestore(command) {
2190
2285
  const result = await new Promise((resolve, reject) => {
2191
2286
  const child = spawn(pgRestorePath, pgRestoreArgs, {
2192
2287
  env: process.env,
2193
- stdio: 'pipe',
2288
+ stdio: ['ignore', 'pipe', 'pipe'],
2194
2289
  });
2195
2290
 
2196
2291
  let stdout = '';
2197
2292
  let stderr = '';
2293
+ let processedObjects = 0;
2294
+ let lastLogTime = Date.now();
2198
2295
 
2199
2296
  child.stdout.on('data', (data) => {
2200
2297
  stdout += data.toString();
2201
2298
  });
2202
2299
 
2203
2300
  child.stderr.on('data', (data) => {
2204
- stderr += data.toString();
2301
+ const message = data.toString();
2302
+ stderr += message;
2303
+
2304
+ // Contar objetos procesados buscando patrones como "processing item" o nombres de tablas
2305
+ const lines = message.split('\n');
2306
+ for (const line of lines) {
2307
+ if (line.includes('processing') || line.includes('creating') || line.includes('restoring')) {
2308
+ processedObjects++;
2309
+
2310
+ // Enviar log cada 2 segundos para no saturar
2311
+ const now = Date.now();
2312
+ if (now - lastLogTime > 2000) {
2313
+ let progressMsg = '';
2314
+
2315
+ if (totalObjects > 0) {
2316
+ const percentage = Math.min(Math.round((processedObjects / totalObjects) * 100), 100);
2317
+ progressMsg = `Progreso: ${percentage}% (${processedObjects}/${totalObjects})`;
2318
+ } else {
2319
+ progressMsg = `Objetos procesados: ${processedObjects}`;
2320
+ }
2321
+
2322
+ // Agregar detalle de lo que se está procesando
2323
+ const relevantLine = line.substring(0, 100).trim();
2324
+ if (relevantLine) {
2325
+ progressMsg += ` - ${relevantLine}`;
2326
+ }
2327
+
2328
+ addCommandLog('info', progressMsg).catch(() => {});
2329
+ lastLogTime = now;
2330
+ }
2331
+ }
2332
+ }
2205
2333
  });
2206
2334
 
2207
- // Mostrar progreso cada 10 segundos
2335
+ // Mostrar progreso por tiempo cada 10 segundos como respaldo
2208
2336
  progressInterval = setInterval(() => {
2209
2337
  const elapsed = Math.floor((Date.now() - startTime) / 1000);
2210
- logInfo(`Restaurando... (${elapsed}s transcurridos)`);
2338
+ if (Date.now() - lastLogTime > 10000) { // Solo si no se ha logueado recientemente
2339
+ let msg = `Restaurando... (${elapsed}s transcurridos)`;
2340
+ if (totalObjects > 0 && processedObjects > 0) {
2341
+ const percentage = Math.min(Math.round((processedObjects / totalObjects) * 100), 100);
2342
+ msg += ` - ${percentage}%`;
2343
+ }
2344
+ logInfo(msg);
2345
+ }
2211
2346
  }, 10000);
2212
2347
 
2213
2348
  child.on('error', (error) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deinossrl/dgp-agent",
3
- "version": "1.5.6",
3
+ "version": "1.5.8",
4
4
  "description": "Agente local para Despliegue-GPT - Reporta el estado del repositorio Git a la plataforma TenMinute IA",
5
5
  "main": "index.mjs",
6
6
  "bin": {