@deinossrl/dgp-agent 1.4.43 → 1.4.44

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 (3) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/index.mjs +206 -2
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog - DGP Agent
2
2
 
3
+ ## [1.4.44] - 2026-01-12
4
+
5
+ ### Added
6
+ - Búsqueda automática de pg_dump en ubicaciones comunes de Windows
7
+ - Descarga e instalación automática de PostgreSQL binaries si no se encuentra pg_dump
8
+ - Los binarios se guardan en ~/.dgp-agent/bin/ para reutilización
9
+ - Soporte para instalación portable sin requerir PostgreSQL completo
10
+
11
+ ### Changed
12
+ - executePgDump ahora busca/instala pg_dump automáticamente antes de ejecutar
13
+ - Mejor experiencia de usuario: funciona sin configuración manual
14
+
15
+ ### Fixed
16
+ - Error "pg_dump not found" en Windows ahora se resuelve automáticamente
17
+
3
18
  ## [1.4.43] - 2026-01-12
4
19
 
5
20
  ### Fixed
package/index.mjs CHANGED
@@ -44,6 +44,7 @@ const AGENT_VERSION = packageJson.version;
44
44
  const CONFIG_DIR = join(homedir(), '.dgp-agent');
45
45
  const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
46
46
  const PID_FILE = join(CONFIG_DIR, 'agent.pid');
47
+ const BIN_DIR = join(CONFIG_DIR, 'bin');
47
48
 
48
49
  /**
49
50
  * Mata al agente anterior si existe
@@ -1421,6 +1422,205 @@ async function executeDeploy(command) {
1421
1422
  }
1422
1423
  }
1423
1424
 
1425
+ /**
1426
+ * Busca pg_dump en el sistema o lo descarga automáticamente
1427
+ * @returns {Promise<string>} Ruta al ejecutable pg_dump
1428
+ */
1429
+ async function findOrInstallPgDump() {
1430
+ const isWindows = process.platform === 'win32';
1431
+ const executableName = isWindows ? 'pg_dump.exe' : 'pg_dump';
1432
+
1433
+ // 1. Verificar si ya está en nuestro BIN_DIR
1434
+ const localPgDump = join(BIN_DIR, executableName);
1435
+ if (existsSync(localPgDump)) {
1436
+ return localPgDump;
1437
+ }
1438
+
1439
+ // 2. Buscar en PATH
1440
+ try {
1441
+ const checkCmd = isWindows ? 'where pg_dump' : 'which pg_dump';
1442
+ const output = execSync(checkCmd, { encoding: 'utf-8' }).trim();
1443
+ if (output) {
1444
+ logSuccess(`pg_dump encontrado en PATH: ${output}`);
1445
+ return output.split('\n')[0]; // Primera línea si hay múltiples
1446
+ }
1447
+ } catch (e) {
1448
+ // No está en PATH, continuar buscando
1449
+ }
1450
+
1451
+ // 3. Buscar en ubicaciones comunes de Windows
1452
+ if (isWindows) {
1453
+ const commonPaths = [
1454
+ 'C:\\Program Files\\PostgreSQL',
1455
+ 'C:\\Program Files (x86)\\PostgreSQL',
1456
+ ];
1457
+
1458
+ for (const basePath of commonPaths) {
1459
+ if (existsSync(basePath)) {
1460
+ // Buscar en todas las versiones (16, 15, 14, etc.)
1461
+ try {
1462
+ const versions = execSync(`dir "${basePath}" /b`, { encoding: 'utf-8' })
1463
+ .trim()
1464
+ .split('\n')
1465
+ .filter(v => /^\d+$/.test(v.trim()))
1466
+ .sort((a, b) => parseInt(b) - parseInt(a)); // Mayor a menor
1467
+
1468
+ for (const version of versions) {
1469
+ const pgDumpPath = join(basePath, version.trim(), 'bin', 'pg_dump.exe');
1470
+ if (existsSync(pgDumpPath)) {
1471
+ logSuccess(`pg_dump encontrado: ${pgDumpPath}`);
1472
+ return pgDumpPath;
1473
+ }
1474
+ }
1475
+ } catch (e) {
1476
+ // Ignorar errores de dir
1477
+ }
1478
+ }
1479
+ }
1480
+ }
1481
+
1482
+ // 4. Si no se encontró, descargar binarios portables
1483
+ logInfo('pg_dump no encontrado. Descargando binarios de PostgreSQL...');
1484
+
1485
+ if (!existsSync(BIN_DIR)) {
1486
+ mkdirSync(BIN_DIR, { recursive: true });
1487
+ }
1488
+
1489
+ const downloadPgDump = async () => {
1490
+ if (isWindows) {
1491
+ // Descargar binaries de PostgreSQL para Windows
1492
+ // Usamos la versión portable de PostgreSQL 16
1493
+ const zipUrl = 'https://get.enterprisedb.com/postgresql/postgresql-16.1-1-windows-x64-binaries.zip';
1494
+ const zipPath = join(BIN_DIR, 'postgresql-binaries.zip');
1495
+
1496
+ logInfo('Descargando PostgreSQL binaries...');
1497
+ logInfo('Esto puede tomar unos minutos (80 MB)...');
1498
+
1499
+ return new Promise((resolve, reject) => {
1500
+ const file = createWriteStream(zipPath);
1501
+ https.get(zipUrl, (response) => {
1502
+ if (response.statusCode === 302 || response.statusCode === 301) {
1503
+ // Seguir redirect
1504
+ https.get(response.headers.location, (redirectResponse) => {
1505
+ redirectResponse.pipe(file);
1506
+ file.on('finish', () => {
1507
+ file.close();
1508
+ logInfo('Descarga completada. Extrayendo...');
1509
+
1510
+ // Extraer solo pg_dump.exe y sus DLLs necesarias
1511
+ try {
1512
+ // Usar PowerShell para extraer el zip
1513
+ const extractCmd = `powershell -command "Expand-Archive -Path '${zipPath}' -DestinationPath '${BIN_DIR}' -Force"`;
1514
+ execSync(extractCmd);
1515
+
1516
+ // Los binarios estarán en BIN_DIR/pgsql/bin/
1517
+ const extractedPgDump = join(BIN_DIR, 'pgsql', 'bin', 'pg_dump.exe');
1518
+
1519
+ if (existsSync(extractedPgDump)) {
1520
+ // Copiar pg_dump.exe y DLLs necesarias al BIN_DIR raíz
1521
+ const binSrcDir = join(BIN_DIR, 'pgsql', 'bin');
1522
+ const essentialFiles = [
1523
+ 'pg_dump.exe',
1524
+ 'libpq.dll',
1525
+ 'libiconv-2.dll',
1526
+ 'libintl-9.dll',
1527
+ 'libssl-3-x64.dll',
1528
+ 'libcrypto-3-x64.dll',
1529
+ 'zlib1.dll',
1530
+ ];
1531
+
1532
+ for (const file of essentialFiles) {
1533
+ const src = join(binSrcDir, file);
1534
+ const dest = join(BIN_DIR, file);
1535
+ if (existsSync(src)) {
1536
+ execSync(`copy "${src}" "${dest}"`, { shell: 'cmd.exe' });
1537
+ }
1538
+ }
1539
+
1540
+ // Limpiar archivos temporales
1541
+ unlinkSync(zipPath);
1542
+ // Opcional: eliminar carpeta pgsql si queremos ahorrar espacio
1543
+ // execSync(`rmdir /s /q "${join(BIN_DIR, 'pgsql')}"`, { shell: 'cmd.exe' });
1544
+
1545
+ logSuccess('pg_dump instalado correctamente');
1546
+ resolve(localPgDump);
1547
+ } else {
1548
+ reject(new Error('No se pudo extraer pg_dump del archivo'));
1549
+ }
1550
+ } catch (extractError) {
1551
+ reject(new Error(`Error al extraer: ${extractError.message}`));
1552
+ }
1553
+ });
1554
+ }).on('error', reject);
1555
+ } else {
1556
+ response.pipe(file);
1557
+ file.on('finish', () => {
1558
+ file.close();
1559
+ logInfo('Descarga completada. Extrayendo...');
1560
+
1561
+ try {
1562
+ const extractCmd = `powershell -command "Expand-Archive -Path '${zipPath}' -DestinationPath '${BIN_DIR}' -Force"`;
1563
+ execSync(extractCmd);
1564
+
1565
+ const extractedPgDump = join(BIN_DIR, 'pgsql', 'bin', 'pg_dump.exe');
1566
+
1567
+ if (existsSync(extractedPgDump)) {
1568
+ const binSrcDir = join(BIN_DIR, 'pgsql', 'bin');
1569
+ const essentialFiles = [
1570
+ 'pg_dump.exe',
1571
+ 'libpq.dll',
1572
+ 'libiconv-2.dll',
1573
+ 'libintl-9.dll',
1574
+ 'libssl-3-x64.dll',
1575
+ 'libcrypto-3-x64.dll',
1576
+ 'zlib1.dll',
1577
+ ];
1578
+
1579
+ for (const file of essentialFiles) {
1580
+ const src = join(binSrcDir, file);
1581
+ const dest = join(BIN_DIR, file);
1582
+ if (existsSync(src)) {
1583
+ execSync(`copy "${src}" "${dest}"`, { shell: 'cmd.exe' });
1584
+ }
1585
+ }
1586
+
1587
+ unlinkSync(zipPath);
1588
+
1589
+ logSuccess('pg_dump instalado correctamente');
1590
+ resolve(localPgDump);
1591
+ } else {
1592
+ reject(new Error('No se pudo extraer pg_dump del archivo'));
1593
+ }
1594
+ } catch (extractError) {
1595
+ reject(new Error(`Error al extraer: ${extractError.message}`));
1596
+ }
1597
+ });
1598
+ }
1599
+ }).on('error', (err) => {
1600
+ unlinkSync(zipPath);
1601
+ reject(err);
1602
+ });
1603
+
1604
+ file.on('error', (err) => {
1605
+ unlinkSync(zipPath);
1606
+ reject(err);
1607
+ });
1608
+ });
1609
+ } else {
1610
+ // En Linux/Mac, intentar instalar via package manager
1611
+ throw new Error('pg_dump no encontrado. Por favor instala PostgreSQL: sudo apt-get install postgresql-client (Debian/Ubuntu) o brew install postgresql (Mac)');
1612
+ }
1613
+ };
1614
+
1615
+ await downloadPgDump();
1616
+
1617
+ if (existsSync(localPgDump)) {
1618
+ return localPgDump;
1619
+ } else {
1620
+ throw new Error('No se pudo instalar pg_dump automáticamente');
1621
+ }
1622
+ }
1623
+
1424
1624
  /**
1425
1625
  * Ejecuta pg_dump para crear backup de PostgreSQL
1426
1626
  */
@@ -1459,8 +1659,12 @@ async function executePgDump(command) {
1459
1659
  const fileName = `backup_${environmentId}_${timestamp}.${extension}`;
1460
1660
  localFilePath = join(backupsDir, fileName);
1461
1661
 
1462
- // Construir comando pg_dump
1463
- let pgDumpCmd = 'pg_dump';
1662
+ // Buscar o instalar pg_dump
1663
+ await addCommandLog('info', 'Buscando pg_dump...');
1664
+ const pgDumpCmd = await findOrInstallPgDump();
1665
+ await addCommandLog('success', `Usando pg_dump: ${pgDumpCmd}`);
1666
+
1667
+ // Construir argumentos
1464
1668
  const pgDumpArgs = [];
1465
1669
 
1466
1670
  // Configurar conexión según tipo
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deinossrl/dgp-agent",
3
- "version": "1.4.43",
3
+ "version": "1.4.44",
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": {