smoonb 0.0.55 → 0.0.56
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/index.js +11 -11
- package/src/commands/backup/steps/00-docker-validation.js +1 -1
- package/src/commands/backup/steps/01-database.js +2 -2
- package/src/commands/backup/steps/02-database-separated.js +4 -4
- package/src/commands/backup/steps/03-database-settings.js +2 -2
- package/src/commands/backup/steps/04-auth-settings.js +1 -1
- package/src/commands/backup/steps/05-realtime-settings.js +1 -1
- package/src/commands/backup/steps/06-storage.js +4 -4
- package/src/commands/backup/steps/07-custom-roles.js +1 -1
- package/src/commands/backup/steps/08-edge-functions.js +9 -9
- package/src/commands/backup/steps/09-supabase-temp.js +3 -3
- package/src/commands/backup/steps/10-migrations.js +4 -4
- package/src/commands/restore/steps/03-database.js +5 -5
- package/src/commands/restore/steps/04-edge-functions.js +4 -4
- package/src/commands/restore/steps/05-auth-settings.js +2 -2
- package/src/commands/restore/steps/06-storage.js +6 -6
- package/src/commands/restore/steps/07-database-settings.js +2 -2
- package/src/commands/restore/steps/08-realtime-settings.js +2 -2
- package/src/utils/supabaseLink.js +2 -2
package/package.json
CHANGED
|
@@ -139,22 +139,22 @@ module.exports = async (options) => {
|
|
|
139
139
|
|
|
140
140
|
// Mostrar resumo e pedir confirmação final
|
|
141
141
|
console.log(chalk.cyan('\n📋 RESUMO DAS CONFIGURAÇÕES:\n'));
|
|
142
|
-
console.log(chalk.
|
|
142
|
+
console.log(chalk.white(` ✅ Edge Functions: ${flags.includeFunctions ? 'Sim' : 'Não'}`));
|
|
143
143
|
if (flags.includeFunctions) {
|
|
144
|
-
console.log(chalk.
|
|
144
|
+
console.log(chalk.white(` 🗑️ Limpar após backup: ${flags.cleanFunctions ? 'Sim' : 'Não'}`));
|
|
145
145
|
}
|
|
146
|
-
console.log(chalk.
|
|
146
|
+
console.log(chalk.white(` ✅ Supabase .temp: ${flags.includeTemp ? 'Sim' : 'Não'}`));
|
|
147
147
|
if (flags.includeTemp) {
|
|
148
|
-
console.log(chalk.
|
|
148
|
+
console.log(chalk.white(` 🗑️ Apagar após backup: ${flags.cleanTemp ? 'Sim' : 'Não'}`));
|
|
149
149
|
}
|
|
150
|
-
console.log(chalk.
|
|
150
|
+
console.log(chalk.white(` ✅ Migrations: ${flags.includeMigrations ? 'Sim' : 'Não'}`));
|
|
151
151
|
if (flags.includeMigrations) {
|
|
152
|
-
console.log(chalk.
|
|
152
|
+
console.log(chalk.white(` 🗑️ Apagar após backup: ${flags.cleanMigrations ? 'Sim' : 'Não'}`));
|
|
153
153
|
}
|
|
154
|
-
console.log(chalk.
|
|
155
|
-
console.log(chalk.
|
|
156
|
-
console.log(chalk.
|
|
157
|
-
console.log(chalk.
|
|
154
|
+
console.log(chalk.white(` ✅ Storage: ${flags.includeStorage ? 'Sim' : 'Não'}`));
|
|
155
|
+
console.log(chalk.white(` ✅ Auth: ${flags.includeAuth ? 'Sim' : 'Não'}`));
|
|
156
|
+
console.log(chalk.white(` ✅ Realtime: ${flags.includeRealtime ? 'Sim' : 'Não'}`));
|
|
157
|
+
console.log(chalk.white(` 📁 Diretório de backup: ${finalBackupDir}\n`));
|
|
158
158
|
|
|
159
159
|
const finalOk = await confirm('Deseja iniciar o backup com estas configurações?', true);
|
|
160
160
|
|
|
@@ -193,7 +193,7 @@ module.exports = async (options) => {
|
|
|
193
193
|
|
|
194
194
|
// Executar todas as etapas na ordem
|
|
195
195
|
console.log(chalk.blue(`📁 Diretório: ${finalBackupDir}`));
|
|
196
|
-
console.log(chalk.
|
|
196
|
+
console.log(chalk.white(`🐳 Backup via Docker Desktop`));
|
|
197
197
|
|
|
198
198
|
// Contar etapas totais para numeração
|
|
199
199
|
// Etapas fixas: Database, Database Separado, Database Settings, Custom Roles (4)
|
|
@@ -17,7 +17,7 @@ module.exports = async () => {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
console.log(chalk.green('✅ Docker Desktop detectado e funcionando'));
|
|
20
|
-
console.log(chalk.
|
|
20
|
+
console.log(chalk.white(`🐳 Versão: ${backupCapability.dockerStatus.version}`));
|
|
21
21
|
|
|
22
22
|
return { success: true };
|
|
23
23
|
};
|
|
@@ -8,7 +8,7 @@ const { execSync } = require('child_process');
|
|
|
8
8
|
*/
|
|
9
9
|
module.exports = async ({ databaseUrl, backupDir }) => {
|
|
10
10
|
try {
|
|
11
|
-
console.log(chalk.
|
|
11
|
+
console.log(chalk.white(' - Criando backup completo via pg_dumpall...'));
|
|
12
12
|
|
|
13
13
|
// Extrair credenciais da databaseUrl
|
|
14
14
|
const urlMatch = databaseUrl.match(/postgresql:\/\/([^:]+):([^@]+)@([^:]+):(\d+)\/(.+)/);
|
|
@@ -45,7 +45,7 @@ module.exports = async ({ databaseUrl, backupDir }) => {
|
|
|
45
45
|
`-f /host/${fileName}`
|
|
46
46
|
].join(' ');
|
|
47
47
|
|
|
48
|
-
console.log(chalk.
|
|
48
|
+
console.log(chalk.white(' - Executando pg_dumpall via Docker...'));
|
|
49
49
|
execSync(dockerCmd, { stdio: 'pipe' });
|
|
50
50
|
|
|
51
51
|
// Compactar igual ao Supabase Dashboard
|
|
@@ -8,14 +8,14 @@ const { execSync } = require('child_process');
|
|
|
8
8
|
*/
|
|
9
9
|
module.exports = async ({ databaseUrl, backupDir, accessToken }) => {
|
|
10
10
|
try {
|
|
11
|
-
console.log(chalk.
|
|
11
|
+
console.log(chalk.white(' - Criando backups SQL separados via Supabase CLI...'));
|
|
12
12
|
|
|
13
13
|
const dbUrl = databaseUrl;
|
|
14
14
|
const files = [];
|
|
15
15
|
let totalSizeKB = 0;
|
|
16
16
|
|
|
17
17
|
// 1. Backup do Schema
|
|
18
|
-
console.log(chalk.
|
|
18
|
+
console.log(chalk.white(' - Exportando schema...'));
|
|
19
19
|
const schemaFile = path.join(backupDir, 'schema.sql');
|
|
20
20
|
|
|
21
21
|
try {
|
|
@@ -33,7 +33,7 @@ module.exports = async ({ databaseUrl, backupDir, accessToken }) => {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
// 2. Backup dos Dados
|
|
36
|
-
console.log(chalk.
|
|
36
|
+
console.log(chalk.white(' - Exportando dados...'));
|
|
37
37
|
const dataFile = path.join(backupDir, 'data.sql');
|
|
38
38
|
|
|
39
39
|
try {
|
|
@@ -51,7 +51,7 @@ module.exports = async ({ databaseUrl, backupDir, accessToken }) => {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// 3. Backup dos Roles
|
|
54
|
-
console.log(chalk.
|
|
54
|
+
console.log(chalk.white(' - Exportando roles...'));
|
|
55
55
|
const rolesFile = path.join(backupDir, 'roles.sql');
|
|
56
56
|
|
|
57
57
|
try {
|
|
@@ -8,7 +8,7 @@ const { execSync } = require('child_process');
|
|
|
8
8
|
*/
|
|
9
9
|
module.exports = async ({ databaseUrl, projectId, backupDir }) => {
|
|
10
10
|
try {
|
|
11
|
-
console.log(chalk.
|
|
11
|
+
console.log(chalk.white(' - Capturando Database Extensions and Settings...'));
|
|
12
12
|
|
|
13
13
|
// Extrair credenciais da databaseUrl
|
|
14
14
|
const urlMatch = databaseUrl.match(/postgresql:\/\/([^:]+):([^@]+)@([^:]+):(\d+)\/(.+)/);
|
|
@@ -125,7 +125,7 @@ AND EXISTS (
|
|
|
125
125
|
'-A' // Unaligned output
|
|
126
126
|
].join(' ');
|
|
127
127
|
|
|
128
|
-
console.log(chalk.
|
|
128
|
+
console.log(chalk.white(' - Executando queries de configurações via Docker...'));
|
|
129
129
|
const output = execSync(dockerCmd, { stdio: 'pipe', encoding: 'utf8' });
|
|
130
130
|
|
|
131
131
|
// Processar output e criar JSON estruturado
|
|
@@ -7,7 +7,7 @@ const { writeJson } = require('../../../utils/fsx');
|
|
|
7
7
|
*/
|
|
8
8
|
module.exports = async ({ projectId, accessToken, backupDir }) => {
|
|
9
9
|
try {
|
|
10
|
-
console.log(chalk.
|
|
10
|
+
console.log(chalk.white(' - Exportando configurações de Auth via Management API...'));
|
|
11
11
|
|
|
12
12
|
// Usar fetch direto para Management API com Personal Access Token
|
|
13
13
|
const authResponse = await fetch(`https://api.supabase.com/v1/projects/${projectId}/config/auth`, {
|
|
@@ -8,7 +8,7 @@ const { captureRealtimeSettings } = require('../../../utils/realtime-settings');
|
|
|
8
8
|
*/
|
|
9
9
|
module.exports = async ({ projectId, backupDir, options }) => {
|
|
10
10
|
try {
|
|
11
|
-
console.log(chalk.
|
|
11
|
+
console.log(chalk.white(' - Capturando Realtime Settings interativamente...'));
|
|
12
12
|
|
|
13
13
|
const result = await captureRealtimeSettings(projectId, backupDir, options?.skipRealtime);
|
|
14
14
|
|
|
@@ -10,7 +10,7 @@ module.exports = async ({ projectId, accessToken, backupDir }) => {
|
|
|
10
10
|
const storageDir = path.join(backupDir, 'storage');
|
|
11
11
|
await ensureDir(storageDir);
|
|
12
12
|
|
|
13
|
-
console.log(chalk.
|
|
13
|
+
console.log(chalk.white(' - Listando buckets de Storage via Management API...'));
|
|
14
14
|
|
|
15
15
|
// Usar fetch direto para Management API com Personal Access Token
|
|
16
16
|
const storageResponse = await fetch(`https://api.supabase.com/v1/projects/${projectId}/storage/buckets`, {
|
|
@@ -28,20 +28,20 @@ module.exports = async ({ projectId, accessToken, backupDir }) => {
|
|
|
28
28
|
const buckets = await storageResponse.json();
|
|
29
29
|
|
|
30
30
|
if (!buckets || buckets.length === 0) {
|
|
31
|
-
console.log(chalk.
|
|
31
|
+
console.log(chalk.white(' - Nenhum bucket encontrado'));
|
|
32
32
|
await writeJson(path.join(storageDir, 'README.md'), {
|
|
33
33
|
message: 'Nenhum bucket de Storage encontrado neste projeto'
|
|
34
34
|
});
|
|
35
35
|
return { success: true, buckets: [] };
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
console.log(chalk.
|
|
38
|
+
console.log(chalk.white(` - Encontrados ${buckets.length} buckets`));
|
|
39
39
|
|
|
40
40
|
const processedBuckets = [];
|
|
41
41
|
|
|
42
42
|
for (const bucket of buckets || []) {
|
|
43
43
|
try {
|
|
44
|
-
console.log(chalk.
|
|
44
|
+
console.log(chalk.white(` - Processando bucket: ${bucket.name}`));
|
|
45
45
|
|
|
46
46
|
// Listar objetos do bucket via Management API com Personal Access Token
|
|
47
47
|
const objectsResponse = await fetch(`https://api.supabase.com/v1/projects/${projectId}/storage/buckets/${bucket.name}/objects`, {
|
|
@@ -11,7 +11,7 @@ const execAsync = promisify(exec);
|
|
|
11
11
|
*/
|
|
12
12
|
module.exports = async ({ databaseUrl, backupDir, accessToken }) => {
|
|
13
13
|
try {
|
|
14
|
-
console.log(chalk.
|
|
14
|
+
console.log(chalk.white(' - Exportando Custom Roles via Docker...'));
|
|
15
15
|
|
|
16
16
|
const customRolesFile = path.join(backupDir, 'custom-roles.sql');
|
|
17
17
|
|
|
@@ -45,18 +45,18 @@ module.exports = async (context) => {
|
|
|
45
45
|
if (shouldCleanAfter) {
|
|
46
46
|
// Limpar antes se o usuário escolheu limpar após (garante ambiente limpo)
|
|
47
47
|
await cleanDir(supabaseFunctionsDir);
|
|
48
|
-
console.log(chalk.
|
|
48
|
+
console.log(chalk.white(' - Pasta supabase/functions limpa antes do backup.'));
|
|
49
49
|
} else {
|
|
50
50
|
// Apenas garantir que o diretório existe
|
|
51
51
|
await fs.mkdir(supabaseFunctionsDir, { recursive: true });
|
|
52
52
|
if (existingFunctionsBefore.length > 0) {
|
|
53
|
-
console.log(chalk.
|
|
53
|
+
console.log(chalk.white(` - Preservando ${existingFunctionsBefore.length} função(ões) existente(s) na pasta supabase/functions.`));
|
|
54
54
|
} else {
|
|
55
|
-
console.log(chalk.
|
|
55
|
+
console.log(chalk.white(' - Pasta supabase/functions preparada (será preservada após backup).'));
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
console.log(chalk.
|
|
59
|
+
console.log(chalk.white(' - Listando Edge Functions via Management API...'));
|
|
60
60
|
|
|
61
61
|
// Usar fetch direto para Management API com Personal Access Token
|
|
62
62
|
const functionsResponse = await fetch(`https://api.supabase.com/v1/projects/${projectId}/functions`, {
|
|
@@ -74,14 +74,14 @@ module.exports = async (context) => {
|
|
|
74
74
|
const functions = await functionsResponse.json();
|
|
75
75
|
|
|
76
76
|
if (!functions || functions.length === 0) {
|
|
77
|
-
console.log(chalk.
|
|
77
|
+
console.log(chalk.white(' - Nenhuma Edge Function encontrada'));
|
|
78
78
|
await writeJson(path.join(functionsDir, 'README.md'), {
|
|
79
79
|
message: 'Nenhuma Edge Function encontrada neste projeto'
|
|
80
80
|
});
|
|
81
81
|
return { success: true, reason: 'no_functions', functions: [] };
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
console.log(chalk.
|
|
84
|
+
console.log(chalk.white(` - Encontradas ${functions.length} Edge Function(s)`));
|
|
85
85
|
|
|
86
86
|
const downloadedFunctions = [];
|
|
87
87
|
let successCount = 0;
|
|
@@ -91,7 +91,7 @@ module.exports = async (context) => {
|
|
|
91
91
|
// Nota: O CLI ignora o cwd e sempre baixa para supabase/functions
|
|
92
92
|
for (const func of functions) {
|
|
93
93
|
try {
|
|
94
|
-
console.log(chalk.
|
|
94
|
+
console.log(chalk.white(` - Baixando: ${func.name}...`));
|
|
95
95
|
|
|
96
96
|
// Criar diretório da função NO BACKUP
|
|
97
97
|
const functionTargetDir = path.join(functionsDir, func.name);
|
|
@@ -167,11 +167,11 @@ module.exports = async (context) => {
|
|
|
167
167
|
// Nota: shouldCleanAfter já foi definido acima
|
|
168
168
|
if (shouldCleanAfter) {
|
|
169
169
|
await cleanDir(supabaseFunctionsDir);
|
|
170
|
-
console.log(chalk.
|
|
170
|
+
console.log(chalk.white(' - supabase/functions limpo após o backup.'));
|
|
171
171
|
} else {
|
|
172
172
|
// Preservar tudo: tanto as funções que já existiam quanto as que foram baixadas
|
|
173
173
|
// As funções baixadas não foram removidas individualmente (linha acima foi ajustada)
|
|
174
|
-
console.log(chalk.
|
|
174
|
+
console.log(chalk.white(' - supabase/functions preservada conforme solicitado.'));
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
return {
|
|
@@ -14,10 +14,10 @@ module.exports = async (context) => {
|
|
|
14
14
|
|
|
15
15
|
const fileCount = await copyDirSafe(tempDir, backupTempDir);
|
|
16
16
|
|
|
17
|
-
console.log(chalk.
|
|
17
|
+
console.log(chalk.white(` - Copiando supabase/.temp → backups/backup-${path.basename(backupDir)}/supabase-temp (${fileCount} arquivos)...`));
|
|
18
18
|
|
|
19
19
|
if (fileCount === 0) {
|
|
20
|
-
console.log(chalk.
|
|
20
|
+
console.log(chalk.white(' - Nenhum arquivo encontrado em supabase/.temp'));
|
|
21
21
|
} else {
|
|
22
22
|
console.log(chalk.green(` ✅ ${fileCount} arquivo(s) copiado(s)`));
|
|
23
23
|
}
|
|
@@ -27,7 +27,7 @@ module.exports = async (context) => {
|
|
|
27
27
|
|
|
28
28
|
if (shouldClean) {
|
|
29
29
|
await cleanDir(tempDir);
|
|
30
|
-
console.log(chalk.
|
|
30
|
+
console.log(chalk.white(' - supabase/.temp apagado.'));
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
return {
|
|
@@ -17,10 +17,10 @@ module.exports = async (context) => {
|
|
|
17
17
|
// Limpar migrations local (opcional, mas recomendado para garantir servidor como fonte da verdade)
|
|
18
18
|
const migrationsDir = path.join(process.cwd(), 'supabase', 'migrations');
|
|
19
19
|
await cleanDir(migrationsDir);
|
|
20
|
-
console.log(chalk.
|
|
20
|
+
console.log(chalk.white(' - Limpando supabase/migrations...'));
|
|
21
21
|
|
|
22
22
|
// Baixar todas as migrations do servidor usando migration fetch
|
|
23
|
-
console.log(chalk.
|
|
23
|
+
console.log(chalk.white(' - Baixando todas as migrations do servidor usando migration fetch...'));
|
|
24
24
|
|
|
25
25
|
const env = {
|
|
26
26
|
...process.env,
|
|
@@ -43,12 +43,12 @@ module.exports = async (context) => {
|
|
|
43
43
|
|
|
44
44
|
// Contar arquivos baixados
|
|
45
45
|
const fileCount = await countFiles(migrationsDir);
|
|
46
|
-
console.log(chalk.
|
|
46
|
+
console.log(chalk.white(` - Arquivos baixados: ${fileCount} migrations`));
|
|
47
47
|
|
|
48
48
|
// Copiar migrations para o backup
|
|
49
49
|
const backupMigrationsDir = path.join(backupDir, 'migrations');
|
|
50
50
|
const copiedCount = await copyDirSafe(migrationsDir, backupMigrationsDir);
|
|
51
|
-
console.log(chalk.
|
|
51
|
+
console.log(chalk.white(` - Copiando supabase/migrations → backups/backup-${path.basename(backupDir)}/migrations (${copiedCount} arquivos)...`));
|
|
52
52
|
|
|
53
53
|
if (copiedCount > 0) {
|
|
54
54
|
console.log(chalk.green(` ✅ ${copiedCount} migration(s) copiada(s)`));
|
|
@@ -13,8 +13,8 @@ module.exports = async ({ backupFilePath, targetDatabaseUrl }) => {
|
|
|
13
13
|
|
|
14
14
|
// Verificar se é arquivo .backup.gz (compactado) ou .backup (descompactado)
|
|
15
15
|
if (fileName.endsWith('.backup.gz')) {
|
|
16
|
-
console.log(chalk.
|
|
17
|
-
console.log(chalk.
|
|
16
|
+
console.log(chalk.white(' - Arquivo .backup.gz detectado'));
|
|
17
|
+
console.log(chalk.white(' - Extraindo arquivo .gz...'));
|
|
18
18
|
|
|
19
19
|
const unzipCmd = [
|
|
20
20
|
'docker run --rm',
|
|
@@ -24,10 +24,10 @@ module.exports = async ({ backupFilePath, targetDatabaseUrl }) => {
|
|
|
24
24
|
|
|
25
25
|
execSync(unzipCmd, { stdio: 'pipe' });
|
|
26
26
|
uncompressedFile = fileName.replace('.gz', '');
|
|
27
|
-
console.log(chalk.
|
|
27
|
+
console.log(chalk.white(' - Arquivo descompactado: ' + uncompressedFile));
|
|
28
28
|
} else if (fileName.endsWith('.backup')) {
|
|
29
|
-
console.log(chalk.
|
|
30
|
-
console.log(chalk.
|
|
29
|
+
console.log(chalk.white(' - Arquivo .backup detectado (já descompactado)'));
|
|
30
|
+
console.log(chalk.white(' - Prosseguindo com restauração direta'));
|
|
31
31
|
} else {
|
|
32
32
|
throw new Error(`Formato de arquivo inválido. Esperado .backup.gz ou .backup, recebido: ${fileName}`);
|
|
33
33
|
}
|
|
@@ -32,7 +32,7 @@ module.exports = async ({ backupPath, targetProject }) => {
|
|
|
32
32
|
return { success: false, functions_count: 0, success_count: 0 };
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
console.log(chalk.
|
|
35
|
+
console.log(chalk.white(` - Encontradas ${functions.length} Edge Function(s)`));
|
|
36
36
|
|
|
37
37
|
// COPIAR Edge Functions de backups/backup-XXX/edge-functions para supabase/functions
|
|
38
38
|
const supabaseFunctionsDir = path.join(process.cwd(), 'supabase', 'functions');
|
|
@@ -54,13 +54,13 @@ module.exports = async ({ backupPath, targetProject }) => {
|
|
|
54
54
|
const backupFuncPath = path.join(edgeFunctionsDir, funcName);
|
|
55
55
|
const targetFuncPath = path.join(supabaseFunctionsDir, funcName);
|
|
56
56
|
|
|
57
|
-
console.log(chalk.
|
|
57
|
+
console.log(chalk.white(` - Copiando ${funcName} para supabase/functions...`));
|
|
58
58
|
|
|
59
59
|
// Copiar recursivamente
|
|
60
60
|
await copyDirectoryRecursive(backupFuncPath, targetFuncPath);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
console.log(chalk.
|
|
63
|
+
console.log(chalk.white(` - Linkando com projeto ${targetProject.targetProjectId}...`));
|
|
64
64
|
|
|
65
65
|
// Linkar com o projeto destino
|
|
66
66
|
try {
|
|
@@ -77,7 +77,7 @@ module.exports = async ({ backupPath, targetProject }) => {
|
|
|
77
77
|
// Deploy das Edge Functions
|
|
78
78
|
let successCount = 0;
|
|
79
79
|
for (const funcName of functions) {
|
|
80
|
-
console.log(chalk.
|
|
80
|
+
console.log(chalk.white(` - Deployando ${funcName}...`));
|
|
81
81
|
|
|
82
82
|
try {
|
|
83
83
|
execSync(`supabase functions deploy ${funcName}`, {
|
|
@@ -25,11 +25,11 @@ module.exports = async ({ backupPath, targetProject }) => {
|
|
|
25
25
|
|
|
26
26
|
if (authSettings.settings?.auth_url_config) {
|
|
27
27
|
Object.entries(authSettings.settings.auth_url_config).forEach(([key, value]) => {
|
|
28
|
-
console.log(chalk.
|
|
28
|
+
console.log(chalk.white(` - ${key}: ${value}`));
|
|
29
29
|
});
|
|
30
30
|
} else if (authSettings.auth_url_config) {
|
|
31
31
|
Object.entries(authSettings.auth_url_config).forEach(([key, value]) => {
|
|
32
|
-
console.log(chalk.
|
|
32
|
+
console.log(chalk.white(` - ${key}: ${value}`));
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -26,23 +26,23 @@ module.exports = async ({ backupPath }) => {
|
|
|
26
26
|
const buckets = manifest?.components?.storage?.buckets || [];
|
|
27
27
|
|
|
28
28
|
if (buckets.length === 0) {
|
|
29
|
-
console.log(chalk.
|
|
29
|
+
console.log(chalk.white(' ℹ️ Nenhum bucket para restaurar'));
|
|
30
30
|
return { success: false, buckets_count: 0 };
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
console.log(chalk.green(`\n ✅ ${buckets.length} bucket(s) encontrado(s) no backup`));
|
|
34
34
|
buckets.forEach(bucket => {
|
|
35
|
-
console.log(chalk.
|
|
35
|
+
console.log(chalk.white(` - ${bucket.name} (${bucket.public ? 'público' : 'privado'})`));
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
const colabUrl = 'https://colab.research.google.com/github/PLyn/supabase-storage-migrate/blob/main/Supabase_Storage_migration.ipynb';
|
|
39
39
|
|
|
40
40
|
console.log(chalk.yellow('\n ⚠️ Migração de objetos de Storage requer processo manual'));
|
|
41
41
|
console.log(chalk.cyan(` ℹ️ Use o script do Google Colab: ${colabUrl}`));
|
|
42
|
-
console.log(chalk.
|
|
43
|
-
console.log(chalk.
|
|
44
|
-
console.log(chalk.
|
|
45
|
-
console.log(chalk.
|
|
42
|
+
console.log(chalk.white('\n 📋 Instruções:'));
|
|
43
|
+
console.log(chalk.white(' 1. Execute o script no Google Colab'));
|
|
44
|
+
console.log(chalk.white(' 2. Configure as credenciais dos projetos (origem e destino)'));
|
|
45
|
+
console.log(chalk.white(' 3. Execute a migração'));
|
|
46
46
|
|
|
47
47
|
await inquirer.prompt([{
|
|
48
48
|
type: 'input',
|
|
@@ -22,11 +22,11 @@ module.exports = async ({ backupPath, targetProject }) => {
|
|
|
22
22
|
const extensions = dbSettings.extensions || [];
|
|
23
23
|
|
|
24
24
|
if (extensions.length > 0) {
|
|
25
|
-
console.log(chalk.
|
|
25
|
+
console.log(chalk.white(` - Habilitando ${extensions.length} extension(s)...`));
|
|
26
26
|
|
|
27
27
|
for (const ext of extensions) {
|
|
28
28
|
const extName = typeof ext === 'string' ? ext : ext.name;
|
|
29
|
-
console.log(chalk.
|
|
29
|
+
console.log(chalk.white(` - ${extName}`));
|
|
30
30
|
|
|
31
31
|
const sqlCommand = `CREATE EXTENSION IF NOT EXISTS ${extName};`;
|
|
32
32
|
|
|
@@ -25,9 +25,9 @@ module.exports = async ({ backupPath, targetProject }) => {
|
|
|
25
25
|
|
|
26
26
|
if (realtimeSettings.realtime_settings?.settings) {
|
|
27
27
|
Object.values(realtimeSettings.realtime_settings.settings).forEach((setting) => {
|
|
28
|
-
console.log(chalk.
|
|
28
|
+
console.log(chalk.white(` - ${setting.label}: ${setting.value}`));
|
|
29
29
|
if (setting.description) {
|
|
30
|
-
console.log(chalk.
|
|
30
|
+
console.log(chalk.white(` ${setting.description}`));
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
}
|
|
@@ -28,7 +28,7 @@ async function ensureCleanLink(projectRef, accessToken, dbPassword) {
|
|
|
28
28
|
const tempDir = path.join(process.cwd(), 'supabase', '.temp');
|
|
29
29
|
|
|
30
30
|
// Remover supabase/.temp completamente
|
|
31
|
-
console.log(chalk.
|
|
31
|
+
console.log(chalk.white(` - Zerando vínculo e linkando projeto: ${projectRef}...`));
|
|
32
32
|
|
|
33
33
|
try {
|
|
34
34
|
await fs.rm(tempDir, { recursive: true, force: true });
|
|
@@ -66,7 +66,7 @@ async function ensureCleanLink(projectRef, accessToken, dbPassword) {
|
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
console.log(chalk.
|
|
69
|
+
console.log(chalk.white(` - Validação: linked-ref = ${linkedRefTrimmed} (esperado = ${projectRef})`));
|
|
70
70
|
} catch (error) {
|
|
71
71
|
if (error.message.includes('Validação falhou')) {
|
|
72
72
|
throw error;
|