@deinossrl/dgp-agent 1.5.26 → 1.5.28

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 +119 -1
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -2344,13 +2344,131 @@ async function executePgRestore(command) {
2344
2344
  let env = { ...process.env };
2345
2345
 
2346
2346
  if (target_environment.connection_type === 'supabase') {
2347
+ const cleanScript = `
2348
+ DO $$
2349
+ DECLARE
2350
+ r RECORD;
2351
+ BEGIN
2352
+ -- 1. Drop Views
2353
+ FOR r IN (SELECT table_name FROM information_schema.views WHERE table_schema = '${schema}') LOOP
2354
+ EXECUTE 'DROP VIEW IF EXISTS "' || '${schema}' || '"."' || r.table_name || '" CASCADE';
2355
+ END LOOP;
2356
+
2357
+ -- 2. Drop Tables
2358
+ FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = '${schema}') LOOP
2359
+ EXECUTE 'DROP TABLE IF EXISTS "' || '${schema}' || '"."' || r.tablename || '" CASCADE';
2360
+ END LOOP;
2361
+
2362
+ -- 3. Drop Routines (Functions/Procedures)
2363
+ FOR r IN (SELECT routine_name, routine_type FROM information_schema.routines WHERE routine_schema = '${schema}') LOOP
2364
+ -- Esto es más complejo por la firma, solemos necesitar OID.
2365
+ -- Simplificación: Drop Schema Cascade es mejor si se puede.
2366
+ -- Si no se puede, intentamos borrar funcion por nombre (peligroso si hay sobrecarga).
2367
+ -- Mejor estrategia para funciones: dejarlas? No, conflictos.
2368
+ -- Estrategia alternativa: DROP EXTENSION si aplica.
2369
+ NULL;
2370
+ END LOOP;
2371
+ END $$;
2372
+
2373
+ -- INTENTO 1: DROP SCHEMA (Ideal)
2374
+ -- INTENTO 2: Si falla, al menos borrar tablas (que es donde están los datos)
2375
+ BEGIN;
2376
+ DROP SCHEMA IF EXISTS "${schema}" CASCADE;
2377
+ CREATE SCHEMA "${schema}";
2378
+ EXCEPTION WHEN OTHERS THEN
2379
+ RAISE NOTICE 'No se pudo borrar schema % (posiblemente falta de permisos), intentando borrar contenido...', '${schema}';
2380
+ -- Borrar tablas manualmente
2381
+ FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = '${schema}') LOOP
2382
+ EXECUTE 'DROP TABLE IF EXISTS "' || '${schema}' || '"."' || r.tablename || '" CASCADE';
2383
+ END LOOP;
2384
+ -- Borrar vistas
2385
+ FOR r IN (SELECT table_name FROM information_schema.views WHERE table_schema = '${schema}') LOOP
2386
+ EXECUTE 'DROP VIEW IF EXISTS "' || '${schema}' || '"."' || r.table_name || '" CASCADE';
2387
+ END LOOP;
2388
+ END;
2389
+ `;
2390
+
2391
+ // SIMPLIFICACION: En lugar de script complejo, enviamos comando psql directo.
2392
+ // Como no podemos meter un bloque PL/pgSQL tan fácil en una línea de comando Windows sin líos de escaping,
2393
+ // vamos a usar una estrategia híbrida robusta.
2394
+
2395
+ // ESTRATEGIA:
2396
+ // 1. Intentar DROP SCHEMA.
2397
+ // 2. Si pg_restore da error de permisos, es "fatal".
2398
+ // Pero el agente puede intentar DROP SCHEMA y si falla, ignorar y confiar en pg_restore --clean? NO.
2399
+
2400
+ // MEJOR ESTRATEGIA (La que usan migraciones):
2401
+ // Generar sentencias SQL para borrar tablas y ejecutarlas una por una o en bloque.
2402
+ // Pero requiere query previo.
2403
+
2404
+ // SI EL USUARIO NO ES OWNER, NO PUEDE BORRAR EL SCHEMA.
2347
2405
  const projectRef = target_environment.supabase_project_ref;
2406
+ // PERO SÍ PUEDE BORRAR LAS TABLAS SI ES OWNER DE LAS TABLAS.
2407
+
2408
+ // Vamos a inyectar un comando SQL que haga el Loop de borrado de tablas.
2409
+ // Es lo más seguro para vaciar datos.
2410
+
2411
+ const tableCleanSQL = `
2412
+ DO $$
2413
+ DECLARE
2414
+ r RECORD;
2415
+ BEGIN
2416
+ -- 0. KILL CONNECTIONS (Critical to avoid locking issues causing "failing cascade")
2417
+ -- Intentamos terminar conexiones que no sean la nuestra
2418
+ BEGIN
2419
+ PERFORM pg_terminate_backend(pid)
2420
+ FROM pg_stat_activity
2421
+ WHERE datname = current_database()
2422
+ AND pid <> pg_backend_pid()
2423
+ AND leader_pid IS NULL; -- Solo sesiones principales
2424
+ EXCEPTION WHEN OTHERS THEN
2425
+ RAISE NOTICE 'No se pudieron terminar conexiones (posiblemente falta permisos), continuando...';
2426
+ END;
2427
+
2428
+ -- 1. Drop Materialized Views (Often missed)
2429
+ FOR r IN (SELECT matviewname FROM pg_matviews WHERE schemaname = '${schema}') LOOP
2430
+ EXECUTE 'DROP MATERIALIZED VIEW IF EXISTS "' || '${schema}' || '"."' || r.matviewname || '" CASCADE';
2431
+ END LOOP;
2432
+
2433
+ -- 2. Drop Views
2434
+ FOR r IN (SELECT table_name FROM information_schema.views WHERE table_schema = '${schema}') LOOP
2435
+ EXECUTE 'DROP VIEW IF EXISTS "' || '${schema}' || '"."' || r.table_name || '" CASCADE';
2436
+ END LOOP;
2437
+
2438
+ -- 3. Drop Tables (The Meat)
2439
+ FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = '${schema}') LOOP
2440
+ EXECUTE 'DROP TABLE IF EXISTS "' || '${schema}' || '"."' || r.tablename || '" CASCADE';
2441
+ END LOOP;
2442
+
2443
+ -- 4. Drop Types (Enums/Composites)
2444
+ -- Limpiar tipos propios del schema para evitar conflictos de "type already exists"
2445
+ FOR r IN (
2446
+ SELECT t.typname
2447
+ FROM pg_type t
2448
+ JOIN pg_namespace n ON t.typnamespace = n.oid
2449
+ WHERE n.nspname = '${schema}'
2450
+ AND t.typtype IN ('e', 'c') -- Enum, Composite
2451
+ ) LOOP
2452
+ EXECUTE 'DROP TYPE IF EXISTS "' || '${schema}' || '"."' || r.typname || '" CASCADE';
2453
+ END LOOP;
2454
+
2455
+ -- 5. Final Schema Attempt
2456
+ -- Intentar borrar schema si es posible (limpieza total)
2457
+ BEGIN
2458
+ EXECUTE 'DROP SCHEMA IF EXISTS "' || '${schema}' || '" CASCADE';
2459
+ EXECUTE 'CREATE SCHEMA IF NOT EXISTS "' || '${schema}' || '"';
2460
+ EXCEPTION WHEN OTHERS THEN
2461
+ RAISE NOTICE 'Schema % preservado (contenido borrado).', '${schema}';
2462
+ END;
2463
+ END $$;
2464
+ `;
2465
+
2348
2466
  psqlArgs = [
2349
2467
  `--host=db.${projectRef}.supabase.co`,
2350
2468
  '--port=5432',
2351
2469
  '--username=postgres',
2352
2470
  '--dbname=postgres',
2353
- '-c', `DROP SCHEMA IF EXISTS "${schema}" CASCADE; CREATE SCHEMA "${schema}";`
2471
+ '-c', tableCleanSQL
2354
2472
  ];
2355
2473
  if (params.password_encrypted) env.PGPASSWORD = params.password_encrypted;
2356
2474
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deinossrl/dgp-agent",
3
- "version": "1.5.26",
3
+ "version": "1.5.28",
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": {