smoonb 0.0.51 → 0.0.54
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 +69 -28
- package/src/commands/restore/index.js +71 -11
- package/src/commands/restore/steps/01-components-selection.js +11 -11
- package/src/commands/restore/steps/02-confirmation.js +1 -1
- package/src/commands/restore/steps/03-database.js +0 -2
- package/src/commands/restore/steps/04-edge-functions.js +11 -4
- package/src/commands/restore/steps/05-auth-settings.js +0 -1
- package/src/commands/restore/steps/06-storage.js +8 -3
- package/src/commands/restore/steps/07-database-settings.js +4 -3
- package/src/commands/restore/steps/08-realtime-settings.js +0 -1
- package/src/interactive/envMapper.js +32 -11
package/package.json
CHANGED
|
@@ -140,12 +140,20 @@ module.exports = async (options) => {
|
|
|
140
140
|
// Mostrar resumo e pedir confirmação final
|
|
141
141
|
console.log(chalk.cyan('\n📋 RESUMO DAS CONFIGURAÇÕES:\n'));
|
|
142
142
|
console.log(chalk.gray(` ✅ Edge Functions: ${flags.includeFunctions ? 'Sim' : 'Não'}`));
|
|
143
|
+
if (flags.includeFunctions) {
|
|
144
|
+
console.log(chalk.gray(` 🗑️ Limpar após backup: ${flags.cleanFunctions ? 'Sim' : 'Não'}`));
|
|
145
|
+
}
|
|
146
|
+
console.log(chalk.gray(` ✅ Supabase .temp: ${flags.includeTemp ? 'Sim' : 'Não'}`));
|
|
147
|
+
if (flags.includeTemp) {
|
|
148
|
+
console.log(chalk.gray(` 🗑️ Apagar após backup: ${flags.cleanTemp ? 'Sim' : 'Não'}`));
|
|
149
|
+
}
|
|
150
|
+
console.log(chalk.gray(` ✅ Migrations: ${flags.includeMigrations ? 'Sim' : 'Não'}`));
|
|
151
|
+
if (flags.includeMigrations) {
|
|
152
|
+
console.log(chalk.gray(` 🗑️ Apagar após backup: ${flags.cleanMigrations ? 'Sim' : 'Não'}`));
|
|
153
|
+
}
|
|
143
154
|
console.log(chalk.gray(` ✅ Storage: ${flags.includeStorage ? 'Sim' : 'Não'}`));
|
|
144
155
|
console.log(chalk.gray(` ✅ Auth: ${flags.includeAuth ? 'Sim' : 'Não'}`));
|
|
145
156
|
console.log(chalk.gray(` ✅ Realtime: ${flags.includeRealtime ? 'Sim' : 'Não'}`));
|
|
146
|
-
console.log(chalk.gray(` 🗑️ Limpar supabase/functions após backup: ${flags.cleanFunctions ? 'Sim' : 'Não'}`));
|
|
147
|
-
console.log(chalk.gray(` 🗑️ Apagar supabase/.temp após backup: ${flags.cleanTemp ? 'Sim' : 'Não'}`));
|
|
148
|
-
console.log(chalk.gray(` 🗑️ Apagar supabase/migrations após backup: ${flags.cleanMigrations ? 'Sim' : 'Não'}`));
|
|
149
157
|
console.log(chalk.gray(` 📁 Diretório de backup: ${finalBackupDir}\n`));
|
|
150
158
|
|
|
151
159
|
const finalOk = await confirm('Deseja iniciar o backup com estas configurações?', true);
|
|
@@ -187,13 +195,19 @@ module.exports = async (options) => {
|
|
|
187
195
|
console.log(chalk.blue(`📁 Diretório: ${finalBackupDir}`));
|
|
188
196
|
console.log(chalk.gray(`🐳 Backup via Docker Desktop`));
|
|
189
197
|
|
|
198
|
+
// Contar etapas totais para numeração
|
|
199
|
+
let stepNumber = 0;
|
|
200
|
+
const totalSteps = 7 + (flags?.includeAuth ? 1 : 0) + (flags?.includeRealtime ? 1 : 0) + (flags?.includeStorage ? 1 : 0) + (flags?.includeFunctions ? 1 : 0) + (flags?.includeTemp ? 1 : 0) + (flags?.includeMigrations ? 1 : 0);
|
|
201
|
+
|
|
190
202
|
// 1. Backup Database via pg_dumpall Docker
|
|
191
|
-
|
|
203
|
+
stepNumber++;
|
|
204
|
+
console.log(chalk.blue(`\n📊 ${stepNumber}/${totalSteps} - Backup da Database PostgreSQL via pg_dumpall Docker...`));
|
|
192
205
|
const databaseResult = await step01Database(context);
|
|
193
206
|
manifest.components.database = databaseResult;
|
|
194
207
|
|
|
195
208
|
// 2. Backup Database Separado
|
|
196
|
-
|
|
209
|
+
stepNumber++;
|
|
210
|
+
console.log(chalk.blue(`\n📊 ${stepNumber}/${totalSteps} - Backup da Database PostgreSQL (arquivos SQL separados)...`));
|
|
197
211
|
const dbSeparatedResult = await step02DatabaseSeparated(context);
|
|
198
212
|
manifest.components.database_separated = {
|
|
199
213
|
success: dbSeparatedResult.success,
|
|
@@ -203,76 +217,79 @@ module.exports = async (options) => {
|
|
|
203
217
|
};
|
|
204
218
|
|
|
205
219
|
// 3. Backup Database Settings
|
|
206
|
-
|
|
220
|
+
stepNumber++;
|
|
221
|
+
console.log(chalk.blue(`\n🔧 ${stepNumber}/${totalSteps} - Backup das Database Extensions and Settings via SQL...`));
|
|
207
222
|
const databaseSettingsResult = await step03DatabaseSettings(context);
|
|
208
223
|
manifest.components.database_settings = databaseSettingsResult;
|
|
209
224
|
|
|
210
225
|
// 4. Backup Auth Settings
|
|
211
226
|
if (flags?.includeAuth) {
|
|
212
|
-
|
|
227
|
+
stepNumber++;
|
|
228
|
+
console.log(chalk.blue(`\n🔐 ${stepNumber}/${totalSteps} - Backup das Auth Settings via API...`));
|
|
213
229
|
const authResult = await step04AuthSettings(context);
|
|
214
230
|
manifest.components.auth_settings = authResult;
|
|
215
231
|
}
|
|
216
232
|
|
|
217
233
|
// 5. Backup Realtime Settings
|
|
218
234
|
if (flags?.includeRealtime) {
|
|
219
|
-
|
|
235
|
+
stepNumber++;
|
|
236
|
+
console.log(chalk.blue(`\n🔄 ${stepNumber}/${totalSteps} - Backup das Realtime Settings via Captura Interativa...`));
|
|
220
237
|
const realtimeResult = await step05RealtimeSettings(context);
|
|
221
238
|
manifest.components.realtime = realtimeResult;
|
|
222
239
|
}
|
|
223
240
|
|
|
224
241
|
// 6. Backup Storage
|
|
225
242
|
if (flags?.includeStorage) {
|
|
226
|
-
|
|
243
|
+
stepNumber++;
|
|
244
|
+
console.log(chalk.blue(`\n📦 ${stepNumber}/${totalSteps} - Backup do Storage via API...`));
|
|
227
245
|
const storageResult = await step06Storage(context);
|
|
228
246
|
manifest.components.storage = storageResult;
|
|
229
247
|
}
|
|
230
248
|
|
|
231
249
|
// 7. Backup Custom Roles
|
|
232
|
-
|
|
250
|
+
stepNumber++;
|
|
251
|
+
console.log(chalk.blue(`\n👥 ${stepNumber}/${totalSteps} - Backup dos Custom Roles via SQL...`));
|
|
233
252
|
const rolesResult = await step07CustomRoles(context);
|
|
234
253
|
manifest.components.custom_roles = rolesResult;
|
|
235
254
|
|
|
236
255
|
// 8. Backup Edge Functions
|
|
237
256
|
if (flags?.includeFunctions) {
|
|
238
|
-
|
|
257
|
+
stepNumber++;
|
|
258
|
+
console.log(chalk.blue(`\n⚡ ${stepNumber}/${totalSteps} - Backup das Edge Functions via Docker...`));
|
|
239
259
|
const functionsResult = await step08EdgeFunctions(context);
|
|
240
260
|
manifest.components.edge_functions = functionsResult;
|
|
241
261
|
}
|
|
242
262
|
|
|
243
263
|
// 9. Backup Supabase .temp
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
264
|
+
if (flags?.includeTemp) {
|
|
265
|
+
stepNumber++;
|
|
266
|
+
console.log(chalk.blue(`\n📁 ${stepNumber}/${totalSteps} - Backup do Supabase .temp...`));
|
|
267
|
+
const supabaseTempResult = await step09SupabaseTemp(context);
|
|
268
|
+
manifest.components.supabase_temp = supabaseTempResult;
|
|
269
|
+
}
|
|
247
270
|
|
|
248
271
|
// 10. Backup Migrations
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
272
|
+
if (flags?.includeMigrations) {
|
|
273
|
+
stepNumber++;
|
|
274
|
+
console.log(chalk.blue(`\n📋 ${stepNumber}/${totalSteps} - Backup das Migrations...`));
|
|
275
|
+
const migrationsResult = await step10Migrations(context);
|
|
276
|
+
manifest.components.migrations = migrationsResult;
|
|
277
|
+
}
|
|
252
278
|
|
|
253
279
|
// Salvar manifest
|
|
254
280
|
await writeJson(path.join(finalBackupDir, 'backup-manifest.json'), manifest);
|
|
255
281
|
|
|
256
|
-
// Exibir resumo final
|
|
282
|
+
// Exibir resumo final (na ordem de captura)
|
|
257
283
|
console.log(chalk.green('\n🎉 BACKUP COMPLETO FINALIZADO VIA DOCKER!'));
|
|
258
284
|
console.log(chalk.blue(`📁 Localização: ${finalBackupDir}`));
|
|
259
285
|
console.log(chalk.green(`📊 Database: ${databaseResult.fileName} (${databaseResult.size} KB) - Idêntico ao Dashboard`));
|
|
260
286
|
console.log(chalk.green(`📊 Database SQL: ${dbSeparatedResult.files?.length || 0} arquivos separados (${dbSeparatedResult.totalSizeKB} KB) - Para troubleshooting`));
|
|
261
287
|
console.log(chalk.green(`🔧 Database Settings: ${databaseSettingsResult.fileName} (${databaseSettingsResult.size} KB) - Extensions e Configurações`));
|
|
262
288
|
|
|
263
|
-
if (flags?.includeFunctions && manifest.components.edge_functions) {
|
|
264
|
-
const functionsResult = manifest.components.edge_functions;
|
|
265
|
-
console.log(chalk.green(`⚡ Edge Functions: ${functionsResult.success_count || 0}/${functionsResult.functions_count || 0} functions baixadas via Docker`));
|
|
266
|
-
}
|
|
267
289
|
if (flags?.includeAuth && manifest.components.auth_settings) {
|
|
268
290
|
const authResult = manifest.components.auth_settings;
|
|
269
291
|
console.log(chalk.green(`🔐 Auth Settings: ${authResult.success ? 'Exportadas via API' : 'Falharam'}`));
|
|
270
292
|
}
|
|
271
|
-
if (flags?.includeStorage && manifest.components.storage) {
|
|
272
|
-
const storageResult = manifest.components.storage;
|
|
273
|
-
console.log(chalk.green(`📦 Storage: ${storageResult.buckets?.length || 0} buckets verificados via API`));
|
|
274
|
-
}
|
|
275
|
-
console.log(chalk.green(`👥 Custom Roles: ${rolesResult.roles?.length || 0} roles exportados via SQL`));
|
|
276
293
|
|
|
277
294
|
// Determinar mensagem correta baseada no método usado
|
|
278
295
|
if (flags?.includeRealtime && manifest.components.realtime) {
|
|
@@ -287,6 +304,28 @@ module.exports = async (options) => {
|
|
|
287
304
|
}
|
|
288
305
|
console.log(chalk.green(`🔄 Realtime: ${realtimeMessage}`));
|
|
289
306
|
}
|
|
307
|
+
|
|
308
|
+
if (flags?.includeStorage && manifest.components.storage) {
|
|
309
|
+
const storageResult = manifest.components.storage;
|
|
310
|
+
console.log(chalk.green(`📦 Storage: ${storageResult.buckets?.length || 0} buckets verificados via API`));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
console.log(chalk.green(`👥 Custom Roles: ${rolesResult.roles?.length || 0} roles exportados via SQL`));
|
|
314
|
+
|
|
315
|
+
if (flags?.includeFunctions && manifest.components.edge_functions) {
|
|
316
|
+
const functionsResult = manifest.components.edge_functions;
|
|
317
|
+
console.log(chalk.green(`⚡ Edge Functions: ${functionsResult.success_count || 0}/${functionsResult.functions_count || 0} functions baixadas via Docker`));
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (flags?.includeTemp && manifest.components.supabase_temp) {
|
|
321
|
+
const tempResult = manifest.components.supabase_temp;
|
|
322
|
+
console.log(chalk.green(`📁 Supabase .temp: ${tempResult.file_count || 0} arquivo(s) copiado(s)`));
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (flags?.includeMigrations && manifest.components.migrations) {
|
|
326
|
+
const migrationsResult = manifest.components.migrations;
|
|
327
|
+
console.log(chalk.green(`📋 Migrations: ${migrationsResult.file_count || 0} migration(s) copiada(s)`));
|
|
328
|
+
}
|
|
290
329
|
|
|
291
330
|
// report.json
|
|
292
331
|
await writeJson(path.join(finalBackupDir, 'report.json'), {
|
|
@@ -302,7 +341,9 @@ module.exports = async (options) => {
|
|
|
302
341
|
includeFunctions: !!flags?.includeFunctions,
|
|
303
342
|
includeStorage: !!flags?.includeStorage,
|
|
304
343
|
includeAuth: !!flags?.includeAuth,
|
|
305
|
-
includeRealtime: !!flags?.includeRealtime
|
|
344
|
+
includeRealtime: !!flags?.includeRealtime,
|
|
345
|
+
includeTemp: !!flags?.includeTemp,
|
|
346
|
+
includeMigrations: !!flags?.includeMigrations
|
|
306
347
|
}
|
|
307
348
|
});
|
|
308
349
|
|
|
@@ -107,14 +107,14 @@ module.exports = async (_options) => {
|
|
|
107
107
|
|
|
108
108
|
// 4. Mostrar resumo detalhado
|
|
109
109
|
console.log(chalk.cyan('\n📋 RESUMO DA RESTAURAÇÃO:\n'));
|
|
110
|
-
console.log(chalk.
|
|
111
|
-
console.log(chalk.
|
|
112
|
-
console.log(chalk.
|
|
113
|
-
console.log(chalk.
|
|
114
|
-
console.log(chalk.
|
|
115
|
-
console.log(chalk.
|
|
116
|
-
console.log(chalk.
|
|
117
|
-
console.log(chalk.
|
|
110
|
+
console.log(chalk.white(` 📁 Backup selecionado: ${path.basename(selectedBackup.path)}`));
|
|
111
|
+
console.log(chalk.white(` 🎯 Projeto destino: ${targetProject.targetProjectId || '(não configurado)'}`));
|
|
112
|
+
console.log(chalk.white(` 📊 Database: ${components.database ? 'Sim' : 'Não'}`));
|
|
113
|
+
console.log(chalk.white(` ⚡ Edge Functions: ${components.edgeFunctions ? 'Sim' : 'Não'}`));
|
|
114
|
+
console.log(chalk.white(` 🔐 Auth Settings: ${components.authSettings ? 'Sim' : 'Não'}`));
|
|
115
|
+
console.log(chalk.white(` 📦 Storage: ${components.storage ? 'Sim' : 'Não'}`));
|
|
116
|
+
console.log(chalk.white(` 🔧 Database Settings: ${components.databaseSettings ? 'Sim' : 'Não'}`));
|
|
117
|
+
console.log(chalk.white(` 🔄 Realtime Settings: ${components.realtimeSettings ? 'Sim' : 'Não'}\n`));
|
|
118
118
|
|
|
119
119
|
// Mostrar resumo técnico adicional
|
|
120
120
|
showRestoreSummary(selectedBackup, components, targetProject);
|
|
@@ -129,51 +129,81 @@ module.exports = async (_options) => {
|
|
|
129
129
|
// 6. Executar restauração
|
|
130
130
|
console.log(chalk.blue('\n🚀 Iniciando restauração...'));
|
|
131
131
|
|
|
132
|
+
// Contar etapas totais para numeração dinâmica
|
|
133
|
+
let stepNumber = 0;
|
|
134
|
+
const totalSteps = (components.database ? 1 : 0) +
|
|
135
|
+
(components.edgeFunctions ? 1 : 0) +
|
|
136
|
+
(components.authSettings ? 1 : 0) +
|
|
137
|
+
(components.storage ? 1 : 0) +
|
|
138
|
+
(components.databaseSettings ? 1 : 0) +
|
|
139
|
+
(components.realtimeSettings ? 1 : 0);
|
|
140
|
+
|
|
141
|
+
// Armazenar resultados para o resumo final
|
|
142
|
+
const restoreResults = {};
|
|
143
|
+
|
|
132
144
|
// 6.1 Database (se selecionado)
|
|
133
145
|
if (components.database) {
|
|
146
|
+
stepNumber++;
|
|
147
|
+
console.log(chalk.blue(`\n📊 ${stepNumber}/${totalSteps} - Restaurando Database...`));
|
|
134
148
|
await step03Database({
|
|
135
149
|
backupFilePath: path.join(selectedBackup.path, selectedBackup.backupFile),
|
|
136
150
|
targetDatabaseUrl: targetProject.targetDatabaseUrl
|
|
137
151
|
});
|
|
152
|
+
restoreResults.database = { success: true };
|
|
138
153
|
}
|
|
139
154
|
|
|
140
155
|
// 6.2 Edge Functions (se selecionado)
|
|
141
156
|
if (components.edgeFunctions) {
|
|
142
|
-
|
|
157
|
+
stepNumber++;
|
|
158
|
+
console.log(chalk.blue(`\n⚡ ${stepNumber}/${totalSteps} - Restaurando Edge Functions...`));
|
|
159
|
+
const edgeFunctionsResult = await step04EdgeFunctions({
|
|
143
160
|
backupPath: selectedBackup.path,
|
|
144
161
|
targetProject
|
|
145
162
|
});
|
|
163
|
+
restoreResults.edgeFunctions = edgeFunctionsResult || { success: true };
|
|
146
164
|
}
|
|
147
165
|
|
|
148
166
|
// 6.3 Auth Settings (se selecionado)
|
|
149
167
|
if (components.authSettings) {
|
|
168
|
+
stepNumber++;
|
|
169
|
+
console.log(chalk.blue(`\n🔐 ${stepNumber}/${totalSteps} - Restaurando Auth Settings...`));
|
|
150
170
|
await step05AuthSettings({
|
|
151
171
|
backupPath: selectedBackup.path,
|
|
152
172
|
targetProject
|
|
153
173
|
});
|
|
174
|
+
restoreResults.authSettings = { success: true };
|
|
154
175
|
}
|
|
155
176
|
|
|
156
177
|
// 6.4 Storage Buckets (se selecionado)
|
|
157
178
|
if (components.storage) {
|
|
158
|
-
|
|
179
|
+
stepNumber++;
|
|
180
|
+
console.log(chalk.blue(`\n📦 ${stepNumber}/${totalSteps} - Restaurando Storage Buckets...`));
|
|
181
|
+
const storageResult = await step06Storage({
|
|
159
182
|
backupPath: selectedBackup.path
|
|
160
183
|
});
|
|
184
|
+
restoreResults.storage = storageResult || { success: true };
|
|
161
185
|
}
|
|
162
186
|
|
|
163
187
|
// 6.5 Database Settings (se selecionado)
|
|
164
188
|
if (components.databaseSettings) {
|
|
189
|
+
stepNumber++;
|
|
190
|
+
console.log(chalk.blue(`\n🔧 ${stepNumber}/${totalSteps} - Restaurando Database Settings...`));
|
|
165
191
|
await step07DatabaseSettings({
|
|
166
192
|
backupPath: selectedBackup.path,
|
|
167
193
|
targetProject
|
|
168
194
|
});
|
|
195
|
+
restoreResults.databaseSettings = { success: true };
|
|
169
196
|
}
|
|
170
197
|
|
|
171
198
|
// 6.6 Realtime Settings (se selecionado)
|
|
172
199
|
if (components.realtimeSettings) {
|
|
200
|
+
stepNumber++;
|
|
201
|
+
console.log(chalk.blue(`\n🔄 ${stepNumber}/${totalSteps} - Restaurando Realtime Settings...`));
|
|
173
202
|
await step08RealtimeSettings({
|
|
174
203
|
backupPath: selectedBackup.path,
|
|
175
204
|
targetProject
|
|
176
205
|
});
|
|
206
|
+
restoreResults.realtimeSettings = { success: true };
|
|
177
207
|
}
|
|
178
208
|
|
|
179
209
|
// report.json de restauração
|
|
@@ -186,6 +216,7 @@ module.exports = async (_options) => {
|
|
|
186
216
|
env_map: path.join(processDir, 'env', 'env-map.json')
|
|
187
217
|
},
|
|
188
218
|
components: components,
|
|
219
|
+
results: restoreResults,
|
|
189
220
|
notes: [
|
|
190
221
|
'supabase/functions limpo antes e depois do deploy (se Edge Functions selecionado)'
|
|
191
222
|
]
|
|
@@ -196,7 +227,36 @@ module.exports = async (_options) => {
|
|
|
196
227
|
// silencioso
|
|
197
228
|
}
|
|
198
229
|
|
|
199
|
-
|
|
230
|
+
// Exibir resumo final
|
|
231
|
+
console.log(chalk.green('\n🎉 RESTAURAÇÃO COMPLETA FINALIZADA!'));
|
|
232
|
+
console.log(chalk.blue(`🎯 Projeto destino: ${targetProject.targetProjectId || '(não configurado)'}`));
|
|
233
|
+
|
|
234
|
+
if (restoreResults.database) {
|
|
235
|
+
console.log(chalk.green(`📊 Database: Restaurada com sucesso via Docker`));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (restoreResults.edgeFunctions) {
|
|
239
|
+
const funcCount = restoreResults.edgeFunctions.functions_count || 0;
|
|
240
|
+
const successCount = restoreResults.edgeFunctions.success_count || 0;
|
|
241
|
+
console.log(chalk.green(`⚡ Edge Functions: ${successCount}/${funcCount} functions restauradas`));
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (restoreResults.authSettings) {
|
|
245
|
+
console.log(chalk.green(`🔐 Auth Settings: Configurações exibidas para configuração manual`));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (restoreResults.storage) {
|
|
249
|
+
const bucketCount = restoreResults.storage.buckets_count || 0;
|
|
250
|
+
console.log(chalk.green(`📦 Storage: ${bucketCount} bucket(s) encontrado(s) - migração manual necessária`));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (restoreResults.databaseSettings) {
|
|
254
|
+
console.log(chalk.green(`🔧 Database Settings: Extensões e configurações restauradas via SQL`));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (restoreResults.realtimeSettings) {
|
|
258
|
+
console.log(chalk.green(`🔄 Realtime Settings: Configurações exibidas para configuração manual`));
|
|
259
|
+
}
|
|
200
260
|
|
|
201
261
|
} catch (error) {
|
|
202
262
|
console.error(chalk.red(`❌ Erro na restauração: ${error.message}`));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
|
-
const { confirm } = require('
|
|
4
|
+
const { confirm } = require('../../../utils/prompt');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Etapa 1: Perguntar quais componentes restaurar
|
|
@@ -15,8 +15,8 @@ module.exports = async (backupPath) => {
|
|
|
15
15
|
let restoreEdgeFunctions = false;
|
|
16
16
|
if (fs.existsSync(edgeFunctionsDir) && fs.readdirSync(edgeFunctionsDir).length > 0) {
|
|
17
17
|
console.log(chalk.cyan('\n⚡ Edge Functions:'));
|
|
18
|
-
console.log(chalk.
|
|
19
|
-
console.log(chalk.
|
|
18
|
+
console.log(chalk.white(' As Edge Functions serão copiadas para supabase/functions e implantadas no projeto destino.'));
|
|
19
|
+
console.log(chalk.white(' A pasta supabase/functions será limpa antes do processo.\n'));
|
|
20
20
|
restoreEdgeFunctions = await confirm('Deseja restaurar Edge Functions', true);
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -24,8 +24,8 @@ module.exports = async (backupPath) => {
|
|
|
24
24
|
let restoreAuthSettings = false;
|
|
25
25
|
if (fs.existsSync(path.join(backupPath, 'auth-settings.json'))) {
|
|
26
26
|
console.log(chalk.cyan('\n🔐 Auth Settings:'));
|
|
27
|
-
console.log(chalk.
|
|
28
|
-
console.log(chalk.
|
|
27
|
+
console.log(chalk.white(' As configurações de Auth serão exibidas para configuração manual no Dashboard.'));
|
|
28
|
+
console.log(chalk.white(' Algumas configurações não podem ser aplicadas automaticamente por questões de segurança.\n'));
|
|
29
29
|
restoreAuthSettings = await confirm('Deseja ver as configurações de Auth Settings', true);
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -34,8 +34,8 @@ module.exports = async (backupPath) => {
|
|
|
34
34
|
let restoreStorage = false;
|
|
35
35
|
if (fs.existsSync(storageDir) && fs.readdirSync(storageDir).length > 0) {
|
|
36
36
|
console.log(chalk.cyan('\n📦 Storage:'));
|
|
37
|
-
console.log(chalk.
|
|
38
|
-
console.log(chalk.
|
|
37
|
+
console.log(chalk.white(' As informações dos buckets de Storage serão exibidas para migração manual.'));
|
|
38
|
+
console.log(chalk.white(' Os arquivos precisam ser migrados manualmente usando as ferramentas do Supabase.\n'));
|
|
39
39
|
restoreStorage = await confirm('Deseja ver informações de Storage Buckets', true);
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -45,8 +45,8 @@ module.exports = async (backupPath) => {
|
|
|
45
45
|
let restoreDatabaseSettings = false;
|
|
46
46
|
if (dbSettingsFiles.length > 0) {
|
|
47
47
|
console.log(chalk.cyan('\n🔧 Database Extensions and Settings:'));
|
|
48
|
-
console.log(chalk.
|
|
49
|
-
console.log(chalk.
|
|
48
|
+
console.log(chalk.white(' As extensões e configurações do banco de dados serão restauradas via SQL.'));
|
|
49
|
+
console.log(chalk.white(' Isso inclui extensões PostgreSQL e configurações específicas do projeto.\n'));
|
|
50
50
|
restoreDatabaseSettings = await confirm('Deseja restaurar Database Extensions and Settings', true);
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -54,8 +54,8 @@ module.exports = async (backupPath) => {
|
|
|
54
54
|
let restoreRealtimeSettings = false;
|
|
55
55
|
if (fs.existsSync(path.join(backupPath, 'realtime-settings.json'))) {
|
|
56
56
|
console.log(chalk.cyan('\n🔄 Realtime Settings:'));
|
|
57
|
-
console.log(chalk.
|
|
58
|
-
console.log(chalk.
|
|
57
|
+
console.log(chalk.white(' As configurações de Realtime serão exibidas para configuração manual no Dashboard.'));
|
|
58
|
+
console.log(chalk.white(' Algumas configurações precisam ser aplicadas manualmente.\n'));
|
|
59
59
|
restoreRealtimeSettings = await confirm('Deseja ver as configurações de Realtime Settings', true);
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// A confirmação agora é feita no index.js com resumo detalhado
|
|
3
3
|
// Mantido para compatibilidade, mas pode ser removido no futuro
|
|
4
4
|
|
|
5
|
-
const { confirm } = require('
|
|
5
|
+
const { confirm } = require('../../../utils/prompt');
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Etapa 2: Confirmar execução (LEGACY - não usado mais)
|
|
@@ -6,8 +6,6 @@ const { execSync } = require('child_process');
|
|
|
6
6
|
* Etapa 3: Restaurar Database via psql
|
|
7
7
|
*/
|
|
8
8
|
module.exports = async ({ backupFilePath, targetDatabaseUrl }) => {
|
|
9
|
-
console.log(chalk.blue('📊 Restaurando Database...'));
|
|
10
|
-
|
|
11
9
|
try {
|
|
12
10
|
const backupDirAbs = path.resolve(path.dirname(backupFilePath));
|
|
13
11
|
const fileName = path.basename(backupFilePath);
|
|
@@ -8,14 +8,12 @@ const { copyDirectoryRecursive } = require('../utils');
|
|
|
8
8
|
* Etapa 4: Restaurar Edge Functions via supabase functions deploy
|
|
9
9
|
*/
|
|
10
10
|
module.exports = async ({ backupPath, targetProject }) => {
|
|
11
|
-
console.log(chalk.blue('\n⚡ Restaurando Edge Functions...'));
|
|
12
|
-
|
|
13
11
|
try {
|
|
14
12
|
const edgeFunctionsDir = path.join(backupPath, 'edge-functions');
|
|
15
13
|
|
|
16
14
|
if (!await fs.access(edgeFunctionsDir).then(() => true).catch(() => false)) {
|
|
17
15
|
console.log(chalk.yellow(' ⚠️ Nenhuma Edge Function encontrada no backup'));
|
|
18
|
-
return;
|
|
16
|
+
return { success: false, functions_count: 0, success_count: 0 };
|
|
19
17
|
}
|
|
20
18
|
|
|
21
19
|
const items = await fs.readdir(edgeFunctionsDir);
|
|
@@ -31,7 +29,7 @@ module.exports = async ({ backupPath, targetProject }) => {
|
|
|
31
29
|
|
|
32
30
|
if (functions.length === 0) {
|
|
33
31
|
console.log(chalk.yellow(' ⚠️ Nenhuma Edge Function encontrada no backup'));
|
|
34
|
-
return;
|
|
32
|
+
return { success: false, functions_count: 0, success_count: 0 };
|
|
35
33
|
}
|
|
36
34
|
|
|
37
35
|
console.log(chalk.gray(` - Encontradas ${functions.length} Edge Function(s)`));
|
|
@@ -77,6 +75,7 @@ module.exports = async ({ backupPath, targetProject }) => {
|
|
|
77
75
|
}
|
|
78
76
|
|
|
79
77
|
// Deploy das Edge Functions
|
|
78
|
+
let successCount = 0;
|
|
80
79
|
for (const funcName of functions) {
|
|
81
80
|
console.log(chalk.gray(` - Deployando ${funcName}...`));
|
|
82
81
|
|
|
@@ -90,6 +89,7 @@ module.exports = async ({ backupPath, targetProject }) => {
|
|
|
90
89
|
});
|
|
91
90
|
|
|
92
91
|
console.log(chalk.green(` ✅ ${funcName} deployada com sucesso!`));
|
|
92
|
+
successCount++;
|
|
93
93
|
} catch (deployError) {
|
|
94
94
|
console.log(chalk.yellow(` ⚠️ ${funcName} - deploy falhou: ${deployError.message}`));
|
|
95
95
|
}
|
|
@@ -105,8 +105,15 @@ module.exports = async ({ backupPath, targetProject }) => {
|
|
|
105
105
|
|
|
106
106
|
console.log(chalk.green(' ✅ Edge Functions restauradas com sucesso!'));
|
|
107
107
|
|
|
108
|
+
return {
|
|
109
|
+
success: true,
|
|
110
|
+
functions_count: functions.length,
|
|
111
|
+
success_count: successCount
|
|
112
|
+
};
|
|
113
|
+
|
|
108
114
|
} catch (error) {
|
|
109
115
|
console.error(chalk.red(` ❌ Erro ao restaurar Edge Functions: ${error.message}`));
|
|
116
|
+
throw error;
|
|
110
117
|
}
|
|
111
118
|
};
|
|
112
119
|
|
|
@@ -7,7 +7,6 @@ const inquirer = require('inquirer');
|
|
|
7
7
|
* Etapa 5: Restaurar Auth Settings (interativo - exibir URL e valores)
|
|
8
8
|
*/
|
|
9
9
|
module.exports = async ({ backupPath, targetProject }) => {
|
|
10
|
-
console.log(chalk.blue('\n🔐 Restaurando Auth Settings...'));
|
|
11
10
|
|
|
12
11
|
try {
|
|
13
12
|
const authSettingsPath = path.join(backupPath, 'auth-settings.json');
|
|
@@ -7,14 +7,13 @@ const inquirer = require('inquirer');
|
|
|
7
7
|
* Etapa 6: Restaurar Storage Buckets (interativo - exibir informações)
|
|
8
8
|
*/
|
|
9
9
|
module.exports = async ({ backupPath }) => {
|
|
10
|
-
console.log(chalk.blue('\n📦 Restaurando Storage Buckets...'));
|
|
11
10
|
|
|
12
11
|
try {
|
|
13
12
|
const storageDir = path.join(backupPath, 'storage');
|
|
14
13
|
|
|
15
14
|
if (!fs.existsSync(storageDir)) {
|
|
16
15
|
console.log(chalk.yellow(' ⚠️ Nenhum bucket de Storage encontrado no backup'));
|
|
17
|
-
return;
|
|
16
|
+
return { success: false, buckets_count: 0 };
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
const manifestPath = path.join(backupPath, 'backup-manifest.json');
|
|
@@ -28,7 +27,7 @@ module.exports = async ({ backupPath }) => {
|
|
|
28
27
|
|
|
29
28
|
if (buckets.length === 0) {
|
|
30
29
|
console.log(chalk.gray(' ℹ️ Nenhum bucket para restaurar'));
|
|
31
|
-
return;
|
|
30
|
+
return { success: false, buckets_count: 0 };
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
console.log(chalk.green(`\n ✅ ${buckets.length} bucket(s) encontrado(s) no backup`));
|
|
@@ -51,8 +50,14 @@ module.exports = async ({ backupPath }) => {
|
|
|
51
50
|
message: 'Pressione Enter para continuar'
|
|
52
51
|
}]);
|
|
53
52
|
|
|
53
|
+
return {
|
|
54
|
+
success: true,
|
|
55
|
+
buckets_count: buckets.length
|
|
56
|
+
};
|
|
57
|
+
|
|
54
58
|
} catch (error) {
|
|
55
59
|
console.error(chalk.red(` ❌ Erro ao processar Storage: ${error.message}`));
|
|
60
|
+
throw error;
|
|
56
61
|
}
|
|
57
62
|
};
|
|
58
63
|
|
|
@@ -7,15 +7,13 @@ const { execSync } = require('child_process');
|
|
|
7
7
|
* Etapa 7: Restaurar Database Settings (via SQL)
|
|
8
8
|
*/
|
|
9
9
|
module.exports = async ({ backupPath, targetProject }) => {
|
|
10
|
-
console.log(chalk.blue('\n🔧 Restaurando Database Settings...'));
|
|
11
|
-
|
|
12
10
|
try {
|
|
13
11
|
const files = fs.readdirSync(backupPath);
|
|
14
12
|
const dbSettingsFile = files.find(f => f.startsWith('database-settings-') && f.endsWith('.json'));
|
|
15
13
|
|
|
16
14
|
if (!dbSettingsFile) {
|
|
17
15
|
console.log(chalk.yellow(' ⚠️ Nenhuma configuração de Database encontrada no backup'));
|
|
18
|
-
return;
|
|
16
|
+
return { success: false };
|
|
19
17
|
}
|
|
20
18
|
|
|
21
19
|
const dbSettingsData = JSON.parse(fs.readFileSync(path.join(backupPath, dbSettingsFile), 'utf8'));
|
|
@@ -58,8 +56,11 @@ module.exports = async ({ backupPath, targetProject }) => {
|
|
|
58
56
|
|
|
59
57
|
console.log(chalk.green(' ✅ Database Settings restaurados com sucesso!'));
|
|
60
58
|
|
|
59
|
+
return { success: true, extensions_count: extensions.length };
|
|
60
|
+
|
|
61
61
|
} catch (error) {
|
|
62
62
|
console.error(chalk.red(` ❌ Erro ao restaurar Database Settings: ${error.message}`));
|
|
63
|
+
throw error;
|
|
63
64
|
}
|
|
64
65
|
};
|
|
65
66
|
|
|
@@ -7,7 +7,6 @@ const inquirer = require('inquirer');
|
|
|
7
7
|
* Etapa 8: Restaurar Realtime Settings (interativo - exibir URL e valores)
|
|
8
8
|
*/
|
|
9
9
|
module.exports = async ({ backupPath, targetProject }) => {
|
|
10
|
-
console.log(chalk.blue('\n🔄 Restaurando Realtime Settings...'));
|
|
11
10
|
|
|
12
11
|
try {
|
|
13
12
|
const realtimeSettingsPath = path.join(backupPath, 'realtime-settings.json');
|
|
@@ -84,36 +84,57 @@ async function mapEnvVariablesInteractively(env, expectedKeys) {
|
|
|
84
84
|
async function askComponentsFlags() {
|
|
85
85
|
// Explicação sobre Edge Functions
|
|
86
86
|
console.log(chalk.cyan('\n⚡ Edge Functions:'));
|
|
87
|
-
console.log(chalk.
|
|
88
|
-
console.log(chalk.
|
|
89
|
-
console.log(chalk.
|
|
87
|
+
console.log(chalk.white(' Vamos apagar as funções existentes na pasta supabase/functions, fazer um reset no link'));
|
|
88
|
+
console.log(chalk.white(' entre a ferramenta e o projeto, e baixar novamente as funções do servidor.'));
|
|
89
|
+
console.log(chalk.white(' Você terá a opção de manter ou apagar as funções na pasta após o backup.\n'));
|
|
90
90
|
|
|
91
91
|
const includeFunctions = await confirm('Deseja incluir Edge Functions', true);
|
|
92
|
+
|
|
93
|
+
// Pergunta de limpeza de functions imediatamente após
|
|
94
|
+
let cleanFunctions = false;
|
|
95
|
+
if (includeFunctions) {
|
|
96
|
+
cleanFunctions = await confirm('Deseja limpar supabase/functions após o backup', false);
|
|
97
|
+
}
|
|
92
98
|
|
|
93
99
|
// Explicação sobre .temp
|
|
94
100
|
console.log(chalk.cyan('\n📁 Supabase .temp:'));
|
|
95
|
-
console.log(chalk.
|
|
96
|
-
console.log(chalk.
|
|
101
|
+
console.log(chalk.white(' Vamos copiar os arquivos existentes (se existirem) na pasta supabase/.temp.'));
|
|
102
|
+
console.log(chalk.white(' Você terá a opção de manter ou apagar os arquivos nesta pasta após o backup.\n'));
|
|
103
|
+
|
|
104
|
+
const includeTemp = await confirm('Deseja incluir Supabase .temp', true);
|
|
105
|
+
|
|
106
|
+
// Pergunta de limpeza de .temp imediatamente após
|
|
107
|
+
let cleanTemp = false;
|
|
108
|
+
if (includeTemp) {
|
|
109
|
+
cleanTemp = await confirm('Deseja apagar supabase/.temp após o backup', false);
|
|
110
|
+
}
|
|
97
111
|
|
|
98
112
|
// Explicação sobre Migrations
|
|
99
113
|
console.log(chalk.cyan('\n📋 Migrations:'));
|
|
100
|
-
console.log(chalk.
|
|
101
|
-
console.log(chalk.
|
|
102
|
-
console.log(chalk.
|
|
114
|
+
console.log(chalk.white(' Vamos apagar as migrations existentes (se existirem) na pasta supabase/migrations,'));
|
|
115
|
+
console.log(chalk.white(' fazer um reset no link entre a ferramenta e o projeto, e baixar novamente as migrations'));
|
|
116
|
+
console.log(chalk.white(' do servidor. Você terá a opção de manter ou apagar as migrations na pasta após o backup.\n'));
|
|
117
|
+
|
|
118
|
+
const includeMigrations = await confirm('Deseja incluir Migrations', true);
|
|
119
|
+
|
|
120
|
+
// Pergunta de limpeza de migrations imediatamente após
|
|
121
|
+
let cleanMigrations = false;
|
|
122
|
+
if (includeMigrations) {
|
|
123
|
+
cleanMigrations = await confirm('Deseja apagar supabase/migrations após o backup', false);
|
|
124
|
+
}
|
|
103
125
|
|
|
104
126
|
// Continuar com outras perguntas
|
|
105
127
|
const includeStorage = await confirm('Deseja incluir Storage', true);
|
|
106
128
|
const includeAuth = await confirm('Deseja incluir Auth', true);
|
|
107
129
|
const includeRealtime = await confirm('Deseja incluir Realtime', true);
|
|
108
|
-
const cleanFunctions = await confirm('Deseja limpar supabase/functions após o backup', false);
|
|
109
|
-
const cleanTemp = await confirm('Deseja apagar supabase/.temp após o backup', false);
|
|
110
|
-
const cleanMigrations = await confirm('Deseja apagar supabase/migrations após o backup', false);
|
|
111
130
|
|
|
112
131
|
return {
|
|
113
132
|
includeFunctions,
|
|
114
133
|
includeStorage,
|
|
115
134
|
includeAuth,
|
|
116
135
|
includeRealtime,
|
|
136
|
+
includeTemp,
|
|
137
|
+
includeMigrations,
|
|
117
138
|
cleanFunctions,
|
|
118
139
|
cleanTemp,
|
|
119
140
|
cleanMigrations
|