smoonb 0.0.32 → 0.0.34
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 +1 -1
- package/src/commands/backup.js +91 -15
package/package.json
CHANGED
package/src/commands/backup.js
CHANGED
|
@@ -108,37 +108,47 @@ async function performFullBackup(config, options) {
|
|
|
108
108
|
};
|
|
109
109
|
|
|
110
110
|
// 1. Backup Database via pg_dumpall Docker (idêntico ao Dashboard)
|
|
111
|
-
console.log(chalk.blue('\n📊 1/
|
|
111
|
+
console.log(chalk.blue('\n📊 1/8 - Backup da Database PostgreSQL via pg_dumpall Docker...'));
|
|
112
112
|
const databaseResult = await backupDatabase(config.supabase.projectId, backupDir);
|
|
113
113
|
manifest.components.database = databaseResult;
|
|
114
114
|
|
|
115
|
+
// 1.5. Backup Database Separado (SQL files para troubleshooting)
|
|
116
|
+
console.log(chalk.blue('\n📊 1.5/8 - Backup da Database PostgreSQL (arquivos SQL separados)...'));
|
|
117
|
+
const dbSeparatedResult = await backupDatabaseSeparated(config.supabase.projectId, backupDir);
|
|
118
|
+
manifest.components.database_separated = {
|
|
119
|
+
success: dbSeparatedResult.success,
|
|
120
|
+
method: 'supabase-cli',
|
|
121
|
+
files: dbSeparatedResult.files || [],
|
|
122
|
+
total_size_kb: dbSeparatedResult.totalSizeKB || '0.0'
|
|
123
|
+
};
|
|
124
|
+
|
|
115
125
|
// 2. Backup Edge Functions via Docker
|
|
116
|
-
console.log(chalk.blue('\n⚡ 2/
|
|
126
|
+
console.log(chalk.blue('\n⚡ 2/8 - Backup das Edge Functions via Docker...'));
|
|
117
127
|
const functionsResult = await backupEdgeFunctionsWithDocker(config.supabase.projectId, config.supabase.accessToken, backupDir);
|
|
118
128
|
manifest.components.edge_functions = functionsResult;
|
|
119
129
|
|
|
120
130
|
// 3. Backup Auth Settings via API
|
|
121
|
-
console.log(chalk.blue('\n🔐 3/
|
|
131
|
+
console.log(chalk.blue('\n🔐 3/8 - Backup das Auth Settings via API...'));
|
|
122
132
|
const authResult = await backupAuthSettings(config.supabase.projectId, config.supabase.accessToken, backupDir);
|
|
123
133
|
manifest.components.auth_settings = authResult;
|
|
124
134
|
|
|
125
135
|
// 4. Backup Storage via API
|
|
126
|
-
console.log(chalk.blue('\n📦 4/
|
|
136
|
+
console.log(chalk.blue('\n📦 4/8 - Backup do Storage via API...'));
|
|
127
137
|
const storageResult = await backupStorage(config.supabase.projectId, config.supabase.accessToken, backupDir);
|
|
128
138
|
manifest.components.storage = storageResult;
|
|
129
139
|
|
|
130
140
|
// 5. Backup Custom Roles via SQL
|
|
131
|
-
console.log(chalk.blue('\n👥 5/
|
|
141
|
+
console.log(chalk.blue('\n👥 5/8 - Backup dos Custom Roles via SQL...'));
|
|
132
142
|
const rolesResult = await backupCustomRoles(config.supabase.databaseUrl, backupDir);
|
|
133
143
|
manifest.components.custom_roles = rolesResult;
|
|
134
144
|
|
|
135
145
|
// 6. Backup das Database Extensions and Settings via SQL
|
|
136
|
-
console.log(chalk.blue('\n🔧 6/
|
|
146
|
+
console.log(chalk.blue('\n🔧 6/8 - Backup das Database Extensions and Settings via SQL...'));
|
|
137
147
|
const databaseSettingsResult = await backupDatabaseSettings(config.supabase.projectId, backupDir);
|
|
138
148
|
manifest.components.database_settings = databaseSettingsResult;
|
|
139
149
|
|
|
140
150
|
// 7. Backup Realtime Settings via Captura Interativa
|
|
141
|
-
console.log(chalk.blue('\n🔄 7/
|
|
151
|
+
console.log(chalk.blue('\n🔄 7/8 - Backup das Realtime Settings via Captura Interativa...'));
|
|
142
152
|
const realtimeResult = await backupRealtimeSettings(config.supabase.projectId, backupDir, options.skipRealtime);
|
|
143
153
|
manifest.components.realtime = realtimeResult;
|
|
144
154
|
|
|
@@ -148,6 +158,7 @@ async function performFullBackup(config, options) {
|
|
|
148
158
|
console.log(chalk.green('\n🎉 BACKUP COMPLETO FINALIZADO VIA DOCKER!'));
|
|
149
159
|
console.log(chalk.blue(`📁 Localização: ${backupDir}`));
|
|
150
160
|
console.log(chalk.green(`📊 Database: ${databaseResult.fileName} (${databaseResult.size} KB) - Idêntico ao Dashboard`));
|
|
161
|
+
console.log(chalk.green(`📊 Database SQL: ${dbSeparatedResult.files?.length || 0} arquivos separados (${dbSeparatedResult.totalSizeKB} KB) - Para troubleshooting`));
|
|
151
162
|
console.log(chalk.green(`🔧 Database Settings: ${databaseSettingsResult.fileName} (${databaseSettingsResult.size} KB) - Extensions e Configurações`));
|
|
152
163
|
console.log(chalk.green(`⚡ Edge Functions: ${functionsResult.success_count || 0}/${functionsResult.functions_count || 0} functions baixadas via Docker`));
|
|
153
164
|
console.log(chalk.green(`🔐 Auth Settings: ${authResult.success ? 'Exportadas via API' : 'Falharam'}`));
|
|
@@ -297,6 +308,75 @@ async function backupDatabase(projectId, backupDir) {
|
|
|
297
308
|
}
|
|
298
309
|
}
|
|
299
310
|
|
|
311
|
+
// Backup da database usando arquivos SQL separados via Supabase CLI (para troubleshooting)
|
|
312
|
+
async function backupDatabaseSeparated(projectId, backupDir) {
|
|
313
|
+
try {
|
|
314
|
+
console.log(chalk.gray(' - Criando backups SQL separados via Supabase CLI...'));
|
|
315
|
+
|
|
316
|
+
const { execSync } = require('child_process');
|
|
317
|
+
const config = await readConfig();
|
|
318
|
+
|
|
319
|
+
const dbUrl = config.supabase.databaseUrl;
|
|
320
|
+
const files = [];
|
|
321
|
+
let totalSizeKB = 0;
|
|
322
|
+
|
|
323
|
+
// 1. Backup do Schema
|
|
324
|
+
console.log(chalk.gray(' - Exportando schema...'));
|
|
325
|
+
const schemaFile = path.join(backupDir, 'schema.sql');
|
|
326
|
+
|
|
327
|
+
try {
|
|
328
|
+
execSync(`supabase db dump --db-url "${dbUrl}" -f "${schemaFile}"`, { stdio: 'pipe' });
|
|
329
|
+
const stats = await fs.stat(schemaFile);
|
|
330
|
+
const sizeKB = (stats.size / 1024).toFixed(1);
|
|
331
|
+
files.push({ filename: 'schema.sql', sizeKB });
|
|
332
|
+
totalSizeKB += parseFloat(sizeKB);
|
|
333
|
+
console.log(chalk.green(` ✅ Schema: ${sizeKB} KB`));
|
|
334
|
+
} catch (error) {
|
|
335
|
+
console.log(chalk.yellow(` ⚠️ Erro no schema: ${error.message}`));
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// 2. Backup dos Dados
|
|
339
|
+
console.log(chalk.gray(' - Exportando dados...'));
|
|
340
|
+
const dataFile = path.join(backupDir, 'data.sql');
|
|
341
|
+
|
|
342
|
+
try {
|
|
343
|
+
execSync(`supabase db dump --db-url "${dbUrl}" --data-only -f "${dataFile}"`, { stdio: 'pipe' });
|
|
344
|
+
const stats = await fs.stat(dataFile);
|
|
345
|
+
const sizeKB = (stats.size / 1024).toFixed(1);
|
|
346
|
+
files.push({ filename: 'data.sql', sizeKB });
|
|
347
|
+
totalSizeKB += parseFloat(sizeKB);
|
|
348
|
+
console.log(chalk.green(` ✅ Data: ${sizeKB} KB`));
|
|
349
|
+
} catch (error) {
|
|
350
|
+
console.log(chalk.yellow(` ⚠️ Erro nos dados: ${error.message}`));
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// 3. Backup dos Roles
|
|
354
|
+
console.log(chalk.gray(' - Exportando roles...'));
|
|
355
|
+
const rolesFile = path.join(backupDir, 'roles.sql');
|
|
356
|
+
|
|
357
|
+
try {
|
|
358
|
+
execSync(`supabase db dump --db-url "${dbUrl}" --role-only -f "${rolesFile}"`, { stdio: 'pipe' });
|
|
359
|
+
const stats = await fs.stat(rolesFile);
|
|
360
|
+
const sizeKB = (stats.size / 1024).toFixed(1);
|
|
361
|
+
files.push({ filename: 'roles.sql', sizeKB });
|
|
362
|
+
totalSizeKB += parseFloat(sizeKB);
|
|
363
|
+
console.log(chalk.green(` ✅ Roles: ${sizeKB} KB`));
|
|
364
|
+
} catch (error) {
|
|
365
|
+
console.log(chalk.yellow(` ⚠️ Erro nos roles: ${error.message}`));
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return {
|
|
369
|
+
success: files.length > 0,
|
|
370
|
+
files,
|
|
371
|
+
totalSizeKB: totalSizeKB.toFixed(1)
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
} catch (error) {
|
|
375
|
+
console.log(chalk.yellow(` ⚠️ Erro nos backups SQL separados: ${error.message}`));
|
|
376
|
+
return { success: false, files: [], totalSizeKB: '0.0' };
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
300
380
|
// Backup das Edge Functions via Docker
|
|
301
381
|
async function backupEdgeFunctionsWithDocker(projectId, accessToken, backupDir) {
|
|
302
382
|
try {
|
|
@@ -584,8 +664,7 @@ SELECT json_agg(
|
|
|
584
664
|
'schema', extnamespace::regnamespace
|
|
585
665
|
)
|
|
586
666
|
) as extensions
|
|
587
|
-
FROM pg_extension
|
|
588
|
-
ORDER BY extname;
|
|
667
|
+
FROM pg_extension;
|
|
589
668
|
|
|
590
669
|
-- 2. Capturar configurações PostgreSQL importantes
|
|
591
670
|
SELECT json_agg(
|
|
@@ -617,8 +696,7 @@ WHERE name IN (
|
|
|
617
696
|
'wal_buffers',
|
|
618
697
|
'max_wal_size',
|
|
619
698
|
'min_wal_size'
|
|
620
|
-
)
|
|
621
|
-
ORDER BY name;
|
|
699
|
+
);
|
|
622
700
|
|
|
623
701
|
-- 3. Capturar configurações específicas dos roles Supabase
|
|
624
702
|
SELECT json_agg(
|
|
@@ -629,8 +707,7 @@ SELECT json_agg(
|
|
|
629
707
|
) as role_configurations
|
|
630
708
|
FROM pg_roles
|
|
631
709
|
WHERE rolname IN ('anon', 'authenticated', 'authenticator', 'postgres', 'service_role')
|
|
632
|
-
AND rolconfig IS NOT NULL
|
|
633
|
-
ORDER BY rolname;
|
|
710
|
+
AND rolconfig IS NOT NULL;
|
|
634
711
|
|
|
635
712
|
-- 4. Capturar configurações de PGAudit (se existir)
|
|
636
713
|
SELECT json_agg(
|
|
@@ -644,8 +721,7 @@ WHERE rolconfig IS NOT NULL
|
|
|
644
721
|
AND EXISTS (
|
|
645
722
|
SELECT 1 FROM unnest(rolconfig) AS config
|
|
646
723
|
WHERE config LIKE '%pgaudit%'
|
|
647
|
-
)
|
|
648
|
-
ORDER BY rolname;
|
|
724
|
+
);
|
|
649
725
|
`;
|
|
650
726
|
|
|
651
727
|
// Salvar script SQL temporário
|