smoonb 0.0.6 → 0.0.8

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 (35) hide show
  1. package/.smoonbrc +7 -6
  2. package/.smoonbrc.example +2 -1
  3. package/README.md +164 -164
  4. package/backups/backup-2025-10-17T19-52-20-211Z/auth-config.json +7 -0
  5. package/backups/backup-2025-10-17T19-52-20-211Z/backup-manifest.json +19 -0
  6. package/backups/backup-2025-10-17T19-52-20-211Z/database-2025-10-17T19-52-20-215Z.dump +0 -0
  7. package/backups/backup-2025-10-17T19-52-20-211Z/functions/README.md +4 -0
  8. package/backups/backup-2025-10-17T19-52-20-211Z/realtime-config.json +7 -0
  9. package/backups/backup-2025-10-17T19-52-20-211Z/storage/storage-config.json +6 -0
  10. package/backups/backup-2025-10-17T20-38-13-188Z/auth-config.json +7 -0
  11. package/backups/backup-2025-10-17T20-38-13-188Z/backup-manifest.json +19 -0
  12. package/backups/backup-2025-10-17T20-38-13-188Z/database-2025-10-17T20-38-13-194Z.dump +0 -0
  13. package/backups/backup-2025-10-17T20-38-13-188Z/functions/README.md +4 -0
  14. package/backups/backup-2025-10-17T20-38-13-188Z/realtime-config.json +7 -0
  15. package/backups/backup-2025-10-17T20-38-13-188Z/storage/storage-config.json +6 -0
  16. package/bin/smoonb.js +16 -32
  17. package/package.json +1 -1
  18. package/src/commands/backup.js +140 -239
  19. package/src/commands/check.js +209 -349
  20. package/src/commands/config.js +78 -77
  21. package/src/commands/functions.js +123 -349
  22. package/src/commands/restore.js +122 -294
  23. package/src/index.js +12 -21
  24. package/src/services/introspect.js +299 -0
  25. package/src/utils/cli.js +87 -0
  26. package/src/utils/config.js +140 -0
  27. package/src/utils/fsx.js +110 -0
  28. package/src/utils/hash.js +40 -0
  29. package/src/utils/supabase.js +447 -387
  30. package/src/commands/secrets.js +0 -361
  31. /package/{backup → backups}/backup-2025-10-17T19-18-58-539Z/auth-config.json +0 -0
  32. /package/{backup → backups}/backup-2025-10-17T19-18-58-539Z/backup-manifest.json +0 -0
  33. /package/{backup → backups}/backup-2025-10-17T19-18-58-539Z/functions/README.md +0 -0
  34. /package/{backup → backups}/backup-2025-10-17T19-18-58-539Z/realtime-config.json +0 -0
  35. /package/{backup → backups}/backup-2025-10-17T19-18-58-539Z/storage/storage-config.json +0 -0
@@ -1,412 +1,272 @@
1
- /**
2
- * Comando de checklist pós-restore
3
- * Verificação de integridade completa
4
- */
5
-
1
+ const { Command } = require('commander');
6
2
  const chalk = require('chalk');
7
- const { execSync } = require('child_process');
8
- const fs = require('fs');
9
3
  const path = require('path');
10
- const { getProjectId } = require('../utils/supabase');
11
-
12
- /**
13
- * Checklist pós-restore - Verificação de integridade
14
- * Resolve o problema: garantir que restauração foi bem-sucedida
15
- */
16
- async function checkCommand(options) {
17
- console.log(chalk.red.bold('🚀 smoonb - EXPERIMENTAL VERSION'));
18
- console.log(chalk.red.bold('⚠️ VERSÃO EXPERIMENTAL - NUNCA TESTADA EM PRODUÇÃO!'));
19
- console.log(chalk.red.bold('🚨 USE POR SUA CONTA E RISCO - Pode causar perda de dados!'));
20
- console.log(chalk.red.bold('❌ NÃO NOS RESPONSABILIZAMOS por qualquer perda de dados!\n'));
21
-
22
- console.log(chalk.cyan.bold('🔍 Checklist pós-restore - Verificação de integridade...\n'));
4
+ const fs = require('fs');
5
+ const { ensureBin, runCommand } = require('../utils/cli');
6
+ const { readConfig, validateFor, writeJson } = require('../utils/config');
7
+ const { IntrospectionService } = require('../services/introspect');
8
+ const { showBetaBanner } = require('../index');
23
9
 
24
- try {
25
- // Obter projectId (da opção ou da configuração)
26
- const projectId = options.projectId || getProjectId();
10
+ const checkCommand = new Command('check')
11
+ .description('Verificar integridade do projeto Supabase após restauração')
12
+ .option('-o, --output <file>', 'Arquivo de saída do relatório', 'check-report.json')
13
+ .action(async (options) => {
14
+ showBetaBanner();
27
15
 
28
- if (!projectId) {
29
- console.error(chalk.red.bold('❌ Erro: Project ID não encontrado'));
30
- console.log(chalk.yellow('💡 Opções:'));
31
- console.log(chalk.gray(' 1. Use: smoonb check --project-id <seu-project-id>'));
32
- console.log(chalk.gray(' 2. Configure: smoonb config --init'));
33
- console.log(chalk.gray(' 3. Ou defina SUPABASE_PROJECT_ID no ambiente'));
34
- console.log(chalk.gray(' 4. Ou edite ~/.smoonbrc e configure o projectId'));
35
- process.exit(1);
36
- }
16
+ try {
17
+ // Verificar se psql está disponível
18
+ const psqlPath = await ensureBin('psql');
19
+ if (!psqlPath) {
20
+ console.error(chalk.red(' psql não encontrado'));
21
+ console.log(chalk.yellow('💡 Instale PostgreSQL:'));
22
+ console.log(chalk.yellow(' https://www.postgresql.org/download/'));
23
+ process.exit(1);
24
+ }
25
+
26
+ // Carregar configuração
27
+ const config = await readConfig();
28
+ validateFor(config, 'backup'); // Usar mesma validação do backup
37
29
 
38
- console.log(chalk.blue('🆔 Project ID:'), projectId);
39
- console.log(chalk.blue('📊 Modo verbose:'), options.verbose ? 'Ativado' : 'Desativado');
40
- console.log();
30
+ const databaseUrl = config.supabase.databaseUrl;
31
+ if (!databaseUrl) {
32
+ console.error(chalk.red('❌ databaseUrl não configurada'));
33
+ console.log(chalk.yellow('💡 Configure databaseUrl no .smoonbrc'));
34
+ process.exit(1);
35
+ }
41
36
 
42
- // Executar verificações
43
- const results = await runPostRestoreChecks(projectId, options.verbose);
37
+ console.log(chalk.blue(`🔍 Verificando integridade do projeto: ${config.supabase.projectId}`));
44
38
 
45
- // Mostrar resumo
46
- showCheckSummary(results);
39
+ // Executar verificações
40
+ const report = await performChecks(config, databaseUrl);
47
41
 
48
- } catch (error) {
49
- console.error(chalk.red.bold('❌ Erro durante o checklist:'), error.message);
50
- process.exit(1);
51
- }
52
- }
42
+ // Salvar relatório
43
+ const reportPath = path.resolve(options.output);
44
+ await writeJson(reportPath, report);
53
45
 
54
- /**
55
- * Executar todas as verificações pós-restore
56
- */
57
- async function runPostRestoreChecks(projectId, verbose = false) {
58
- const checks = [
59
- { name: 'Database Connection', category: 'database', status: 'pending', details: [] },
60
- { name: 'Database Schema', category: 'database', status: 'pending', details: [] },
61
- { name: 'Database Extensions', category: 'database', status: 'pending', details: [] },
62
- { name: 'Edge Functions', category: 'functions', status: 'pending', details: [] },
63
- { name: 'Auth Providers', category: 'auth', status: 'pending', details: [] },
64
- { name: 'Auth Policies', category: 'auth', status: 'pending', details: [] },
65
- { name: 'Storage Buckets', category: 'storage', status: 'pending', details: [] },
66
- { name: 'Storage Objects', category: 'storage', status: 'pending', details: [] },
67
- { name: 'Realtime Settings', category: 'realtime', status: 'pending', details: [] },
68
- { name: 'API Endpoints', category: 'api', status: 'pending', details: [] }
69
- ];
46
+ // Mostrar resumo
47
+ showCheckSummary(report);
70
48
 
71
- console.log(chalk.blue.bold('🔍 Executando verificações...\n'));
49
+ console.log(chalk.green('\n🎉 Verificação concluída!'));
50
+ console.log(chalk.blue(`📋 Relatório salvo em: ${reportPath}`));
72
51
 
73
- // Executar verificações por categoria
74
- for (const check of checks) {
75
- try {
76
- await performCheck(check, projectId, verbose);
77
52
  } catch (error) {
78
- check.status = 'error';
79
- check.details.push(`Erro: ${error.message}`);
53
+ console.error(chalk.red(`❌ Erro na verificação: ${error.message}`));
54
+ process.exit(1);
80
55
  }
81
- }
56
+ });
82
57
 
83
- return checks;
84
- }
58
+ // Executar todas as verificações
59
+ async function performChecks(config, databaseUrl) {
60
+ const report = {
61
+ timestamp: new Date().toISOString(),
62
+ project_id: config.supabase.projectId,
63
+ checks: {}
64
+ };
85
65
 
86
- /**
87
- * Executar verificação individual
88
- */
89
- async function performCheck(check, projectId, verbose) {
90
- if (verbose) {
91
- console.log(chalk.gray(` - Verificando ${check.name}...`));
92
- }
66
+ // 1. Verificar conexão com database
67
+ console.log(chalk.blue('\n🔌 1/6 - Verificando conexão com database...'));
68
+ report.checks.database_connection = await checkDatabaseConnection(databaseUrl);
93
69
 
94
- switch (check.name) {
95
- case 'Database Connection':
96
- await checkDatabaseConnection(check, projectId, verbose);
97
- break;
98
- case 'Database Schema':
99
- await checkDatabaseSchema(check, projectId, verbose);
100
- break;
101
- case 'Database Extensions':
102
- await checkDatabaseExtensions(check, projectId, verbose);
103
- break;
104
- case 'Edge Functions':
105
- await checkEdgeFunctions(check, projectId, verbose);
106
- break;
107
- case 'Auth Providers':
108
- await checkAuthProviders(check, projectId, verbose);
109
- break;
110
- case 'Auth Policies':
111
- await checkAuthPolicies(check, projectId, verbose);
112
- break;
113
- case 'Storage Buckets':
114
- await checkStorageBuckets(check, projectId, verbose);
115
- break;
116
- case 'Storage Objects':
117
- await checkStorageObjects(check, projectId, verbose);
118
- break;
119
- case 'Realtime Settings':
120
- await checkRealtimeSettings(check, projectId, verbose);
121
- break;
122
- case 'API Endpoints':
123
- await checkAPIEndpoints(check, projectId, verbose);
124
- break;
125
- }
70
+ // 2. Verificar extensões
71
+ console.log(chalk.blue('\n🔧 2/6 - Verificando extensões...'));
72
+ report.checks.extensions = await checkExtensions(databaseUrl);
73
+
74
+ // 3. Verificar tabelas
75
+ console.log(chalk.blue('\n📊 3/6 - Verificando tabelas...'));
76
+ report.checks.tables = await checkTables(databaseUrl);
77
+
78
+ // 4. Verificar políticas RLS
79
+ console.log(chalk.blue('\n🔒 4/6 - Verificando políticas RLS...'));
80
+ report.checks.rls_policies = await checkRLSPolicies(databaseUrl);
81
+
82
+ // 5. Verificar Realtime
83
+ console.log(chalk.blue('\n🔄 5/6 - Verificando Realtime...'));
84
+ report.checks.realtime = await checkRealtime(databaseUrl);
85
+
86
+ // 6. Verificar Storage
87
+ console.log(chalk.blue('\n📦 6/6 - Verificando Storage...'));
88
+ report.checks.storage = await checkStorage(config);
89
+
90
+ return report;
126
91
  }
127
92
 
128
- /**
129
- * Verificar conexão com database
130
- */
131
- async function checkDatabaseConnection(check, projectId, verbose) {
93
+ // Verificar conexão com database
94
+ async function checkDatabaseConnection(databaseUrl) {
132
95
  try {
133
- const dbUrl = process.env.DATABASE_URL || `postgresql://postgres:[password]@db.${projectId}.supabase.co:5432/postgres`;
134
-
135
- // Tentar conectar via psql
136
- const testCmd = `psql "${dbUrl}" -c "SELECT 1;"`;
137
- execSync(testCmd, { stdio: 'pipe' });
96
+ const { stdout } = await runCommand(
97
+ `psql "${databaseUrl}" -t -c "SELECT 1 as test_connection;"`
98
+ );
138
99
 
139
- check.status = 'ok';
140
- check.details.push('Conexão estabelecida com sucesso');
141
-
142
- if (verbose) {
143
- console.log(chalk.gray(' ✅ Conexão com database OK'));
100
+ if (stdout.trim() === '1') {
101
+ return { status: 'ok', message: 'Conexão estabelecida com sucesso' };
102
+ } else {
103
+ return { status: 'error', message: 'Resposta inesperada da database' };
144
104
  }
145
105
  } catch (error) {
146
- check.status = 'warning';
147
- check.details.push('Conexão falhou (credenciais não configuradas)');
148
-
149
- if (verbose) {
150
- console.log(chalk.gray(' ⚠️ Conexão com database falhou'));
151
- }
106
+ return { status: 'error', message: `Falha na conexão: ${error.message}` };
152
107
  }
153
108
  }
154
109
 
155
- /**
156
- * Verificar schema da database
157
- */
158
- async function checkDatabaseSchema(check, projectId, verbose) {
110
+ // Verificar extensões
111
+ async function checkExtensions(databaseUrl) {
159
112
  try {
160
- const dbUrl = process.env.DATABASE_URL || `postgresql://postgres:[password]@db.${projectId}.supabase.co:5432/postgres`;
161
-
162
- // Verificar tabelas principais
163
- const schemaCmd = `psql "${dbUrl}" -c "SELECT schemaname, tablename FROM pg_tables WHERE schemaname = 'public';"`;
164
- const output = execSync(schemaCmd, { encoding: 'utf8', stdio: 'pipe' });
113
+ const query = `
114
+ SELECT extname, extversion
115
+ FROM pg_extension
116
+ ORDER BY extname;
117
+ `;
165
118
 
166
- const lines = output.split('\n').filter(line => line.trim() && !line.includes('schemaname'));
167
- const tableCount = lines.length;
119
+ const { stdout } = await runCommand(
120
+ `psql "${databaseUrl}" -t -c "${query}"`
121
+ );
168
122
 
169
- check.status = 'ok';
170
- check.details.push(`${tableCount} tabelas encontradas no schema public`);
123
+ const extensions = stdout.trim().split('\n')
124
+ .filter(line => line.trim())
125
+ .map(line => {
126
+ const [name, version] = line.trim().split('|');
127
+ return { name: name?.trim(), version: version?.trim() };
128
+ });
171
129
 
172
- if (verbose) {
173
- console.log(chalk.gray(` ✅ Schema OK (${tableCount} tabelas)`));
174
- }
130
+ return {
131
+ status: 'ok',
132
+ message: `${extensions.length} extensões encontradas`,
133
+ data: extensions
134
+ };
175
135
  } catch (error) {
176
- check.status = 'warning';
177
- check.details.push('Não foi possível verificar schema (credenciais não configuradas)');
178
-
179
- if (verbose) {
180
- console.log(chalk.gray(' ⚠️ Verificação de schema falhou'));
181
- }
136
+ return { status: 'error', message: `Erro ao verificar extensões: ${error.message}` };
182
137
  }
183
138
  }
184
139
 
185
- /**
186
- * Verificar extensões da database
187
- */
188
- async function checkDatabaseExtensions(check, projectId, verbose) {
140
+ // Verificar tabelas
141
+ async function checkTables(databaseUrl) {
189
142
  try {
190
- const dbUrl = process.env.DATABASE_URL || `postgresql://postgres:[password]@db.${projectId}.supabase.co:5432/postgres`;
143
+ const query = `
144
+ SELECT schemaname, tablename, tableowner
145
+ FROM pg_tables
146
+ WHERE schemaname IN ('public', 'auth', 'storage')
147
+ ORDER BY schemaname, tablename;
148
+ `;
191
149
 
192
- // Verificar extensões instaladas
193
- const extensionsCmd = `psql "${dbUrl}" -c "SELECT extname FROM pg_extension;"`;
194
- const output = execSync(extensionsCmd, { encoding: 'utf8', stdio: 'pipe' });
150
+ const { stdout } = await runCommand(
151
+ `psql "${databaseUrl}" -t -c "${query}"`
152
+ );
195
153
 
196
- const lines = output.split('\n').filter(line => line.trim() && !line.includes('extname'));
197
- const extensionCount = lines.length;
154
+ const tables = stdout.trim().split('\n')
155
+ .filter(line => line.trim())
156
+ .map(line => {
157
+ const [schema, table, owner] = line.trim().split('|');
158
+ return {
159
+ schema: schema?.trim(),
160
+ table: table?.trim(),
161
+ owner: owner?.trim()
162
+ };
163
+ });
198
164
 
199
- check.status = 'ok';
200
- check.details.push(`${extensionCount} extensões instaladas`);
201
-
202
- if (verbose) {
203
- console.log(chalk.gray(` ✅ Extensões OK (${extensionCount} instaladas)`));
204
- }
165
+ return {
166
+ status: 'ok',
167
+ message: `${tables.length} tabelas encontradas`,
168
+ data: tables
169
+ };
205
170
  } catch (error) {
206
- check.status = 'warning';
207
- check.details.push('Não foi possível verificar extensões (credenciais não configuradas)');
208
-
209
- if (verbose) {
210
- console.log(chalk.gray(' ⚠️ Verificação de extensões falhou'));
211
- }
171
+ return { status: 'error', message: `Erro ao verificar tabelas: ${error.message}` };
212
172
  }
213
173
  }
214
174
 
215
- /**
216
- * Verificar Edge Functions
217
- */
218
- async function checkEdgeFunctions(check, projectId, verbose) {
175
+ // Verificar políticas RLS
176
+ async function checkRLSPolicies(databaseUrl) {
219
177
  try {
220
- // Verificar se Supabase CLI está disponível
221
- execSync('supabase --version', { stdio: 'pipe' });
178
+ const query = `
179
+ SELECT COUNT(*) as policy_count
180
+ FROM pg_policies;
181
+ `;
222
182
 
223
- // Listar functions remotas
224
- const listCmd = 'supabase functions list';
225
- const output = execSync(listCmd, { encoding: 'utf8', stdio: 'pipe' });
183
+ const { stdout } = await runCommand(
184
+ `psql "${databaseUrl}" -t -c "${query}"`
185
+ );
226
186
 
227
- if (output.trim()) {
228
- const lines = output.split('\n').filter(line => line.trim());
229
- const functionCount = lines.length;
230
-
231
- check.status = 'ok';
232
- check.details.push(`${functionCount} Edge Functions encontradas`);
233
-
234
- if (verbose) {
235
- console.log(chalk.gray(` ✅ Edge Functions OK (${functionCount} encontradas)`));
236
- }
237
- } else {
238
- check.status = 'warning';
239
- check.details.push('Nenhuma Edge Function encontrada');
240
-
241
- if (verbose) {
242
- console.log(chalk.gray(' ⚠️ Nenhuma Edge Function encontrada'));
243
- }
244
- }
245
- } catch (error) {
246
- check.status = 'warning';
247
- check.details.push('Supabase CLI não encontrado ou projeto não configurado');
187
+ const policyCount = parseInt(stdout.trim());
248
188
 
249
- if (verbose) {
250
- console.log(chalk.gray(' ⚠️ Verificação de Edge Functions falhou'));
251
- }
252
- }
253
- }
254
-
255
- /**
256
- * Verificar Auth Providers
257
- */
258
- async function checkAuthProviders(check, projectId, verbose) {
259
- // TODO: Implementar verificação real via Supabase API
260
- check.status = 'warning';
261
- check.details.push('Verificação de Auth Providers em desenvolvimento');
262
-
263
- if (verbose) {
264
- console.log(chalk.gray(' ⚠️ Verificação de Auth Providers em desenvolvimento'));
265
- }
266
- }
267
-
268
- /**
269
- * Verificar Auth Policies
270
- */
271
- async function checkAuthPolicies(check, projectId, verbose) {
272
- // TODO: Implementar verificação real via Supabase API
273
- check.status = 'warning';
274
- check.details.push('Verificação de Auth Policies em desenvolvimento');
275
-
276
- if (verbose) {
277
- console.log(chalk.gray(' ⚠️ Verificação de Auth Policies em desenvolvimento'));
278
- }
279
- }
280
-
281
- /**
282
- * Verificar Storage Buckets
283
- */
284
- async function checkStorageBuckets(check, projectId, verbose) {
285
- // TODO: Implementar verificação real via Supabase API
286
- check.status = 'warning';
287
- check.details.push('Verificação de Storage Buckets em desenvolvimento');
288
-
289
- if (verbose) {
290
- console.log(chalk.gray(' ⚠️ Verificação de Storage Buckets em desenvolvimento'));
291
- }
292
- }
293
-
294
- /**
295
- * Verificar Storage Objects
296
- */
297
- async function checkStorageObjects(check, projectId, verbose) {
298
- // TODO: Implementar verificação real via Supabase API
299
- check.status = 'warning';
300
- check.details.push('Verificação de Storage Objects em desenvolvimento');
301
-
302
- if (verbose) {
303
- console.log(chalk.gray(' ⚠️ Verificação de Storage Objects em desenvolvimento'));
189
+ return {
190
+ status: 'ok',
191
+ message: `${policyCount} políticas RLS encontradas`,
192
+ data: { policy_count: policyCount }
193
+ };
194
+ } catch (error) {
195
+ return { status: 'error', message: `Erro ao verificar políticas RLS: ${error.message}` };
304
196
  }
305
197
  }
306
198
 
307
- /**
308
- * Verificar Realtime Settings
309
- */
310
- async function checkRealtimeSettings(check, projectId, verbose) {
311
- // TODO: Implementar verificação real via Supabase API
312
- check.status = 'warning';
313
- check.details.push('Verificação de Realtime Settings em desenvolvimento');
314
-
315
- if (verbose) {
316
- console.log(chalk.gray(' ⚠️ Verificação de Realtime Settings em desenvolvimento'));
199
+ // Verificar Realtime
200
+ async function checkRealtime(databaseUrl) {
201
+ try {
202
+ const query = `
203
+ SELECT pubname
204
+ FROM pg_publication
205
+ ORDER BY pubname;
206
+ `;
207
+
208
+ const { stdout } = await runCommand(
209
+ `psql "${databaseUrl}" -t -c "${query}"`
210
+ );
211
+
212
+ const publications = stdout.trim().split('\n')
213
+ .filter(line => line.trim())
214
+ .map(line => line.trim());
215
+
216
+ return {
217
+ status: 'ok',
218
+ message: `${publications.length} publicações Realtime encontradas`,
219
+ data: { publications }
220
+ };
221
+ } catch (error) {
222
+ return { status: 'error', message: `Erro ao verificar Realtime: ${error.message}` };
317
223
  }
318
224
  }
319
225
 
320
- /**
321
- * Verificar API Endpoints
322
- */
323
- async function checkAPIEndpoints(check, projectId, verbose) {
226
+ // Verificar Storage
227
+ async function checkStorage(config) {
324
228
  try {
325
- const supabaseUrl = process.env.SUPABASE_URL || `https://${projectId}.supabase.co`;
229
+ const introspection = new IntrospectionService(config);
230
+ const storageInventory = await introspection.getStorageInventory();
326
231
 
327
- // Verificar endpoint de health
328
- const healthUrl = `${supabaseUrl}/rest/v1/`;
232
+ const bucketCount = storageInventory.buckets?.length || 0;
233
+ const totalObjects = storageInventory.buckets?.reduce(
234
+ (total, bucket) => total + (bucket.objects?.length || 0), 0
235
+ ) || 0;
329
236
 
330
- // Simular verificação (TODO: implementar verificação real)
331
- check.status = 'ok';
332
- check.details.push('API endpoints respondendo');
333
-
334
- if (verbose) {
335
- console.log(chalk.gray(' ✅ API endpoints OK'));
336
- }
237
+ return {
238
+ status: 'ok',
239
+ message: `${bucketCount} buckets e ${totalObjects} objetos encontrados`,
240
+ data: storageInventory
241
+ };
337
242
  } catch (error) {
338
- check.status = 'warning';
339
- check.details.push('Não foi possível verificar API endpoints');
340
-
341
- if (verbose) {
342
- console.log(chalk.gray(' ⚠️ Verificação de API endpoints falhou'));
343
- }
243
+ return { status: 'error', message: `Erro ao verificar Storage: ${error.message}` };
344
244
  }
345
245
  }
346
246
 
347
- /**
348
- * Mostrar resumo das verificações
349
- */
350
- function showCheckSummary(results) {
351
- console.log(chalk.blue.bold('\n📊 Resumo das Verificações:\n'));
352
-
353
- // Agrupar por categoria
354
- const categories = {};
355
- results.forEach(check => {
356
- if (!categories[check.category]) {
357
- categories[check.category] = [];
358
- }
359
- categories[check.category].push(check);
360
- });
361
-
362
- // Mostrar por categoria
363
- Object.entries(categories).forEach(([category, checks]) => {
364
- const categoryName = category.charAt(0).toUpperCase() + category.slice(1);
365
- console.log(chalk.cyan.bold(`📁 ${categoryName}:`));
247
+ // Mostrar resumo das verificações
248
+ function showCheckSummary(report) {
249
+ console.log(chalk.blue('\n📋 RESUMO DAS VERIFICAÇÕES:'));
250
+ console.log(chalk.blue('═'.repeat(50)));
251
+
252
+ for (const [checkName, result] of Object.entries(report.checks)) {
253
+ const icon = result.status === 'ok' ? '✅' : '❌';
254
+ const color = result.status === 'ok' ? chalk.green : chalk.red;
366
255
 
367
- checks.forEach(check => {
368
- const icon = check.status === 'ok' ? '✅' :
369
- check.status === 'warning' ? '⚠️' : '❌';
370
- const statusColor = check.status === 'ok' ? chalk.green :
371
- check.status === 'warning' ? chalk.yellow : chalk.red;
372
-
373
- console.log(` ${icon} ${statusColor(check.name)}`);
374
-
375
- if (check.details.length > 0) {
376
- check.details.forEach(detail => {
377
- console.log(chalk.gray(` - ${detail}`));
378
- });
379
- }
380
- });
381
- console.log();
382
- });
383
-
384
- // Estatísticas gerais
385
- const totalChecks = results.length;
386
- const okChecks = results.filter(c => c.status === 'ok').length;
387
- const warningChecks = results.filter(c => c.status === 'warning').length;
388
- const errorChecks = results.filter(c => c.status === 'error').length;
389
-
390
- console.log(chalk.blue.bold('📈 Estatísticas:'));
391
- console.log(chalk.green(`✅ OK: ${okChecks}/${totalChecks}`));
392
- console.log(chalk.yellow(`⚠️ Avisos: ${warningChecks}/${totalChecks}`));
393
- console.log(chalk.red(`❌ Erros: ${errorChecks}/${totalChecks}`));
394
-
395
- // Status geral
396
- if (errorChecks === 0 && warningChecks === 0) {
397
- console.log(chalk.green.bold('\n🎉 Todas as verificações passaram com sucesso!'));
398
- } else if (errorChecks === 0) {
399
- console.log(chalk.yellow.bold('\n⚠️ Verificações concluídas com avisos'));
400
- console.log(chalk.gray(' - Projeto funcional, mas algumas verificações precisam de atenção'));
256
+ console.log(`${icon} ${color(checkName.replace(/_/g, ' ').toUpperCase())}: ${result.message}`);
257
+ }
258
+
259
+ const okCount = Object.values(report.checks).filter(c => c.status === 'ok').length;
260
+ const totalCount = Object.keys(report.checks).length;
261
+
262
+ console.log(chalk.blue('═'.repeat(50)));
263
+ console.log(chalk.blue(`📊 Resultado: ${okCount}/${totalCount} verificações passaram`));
264
+
265
+ if (okCount === totalCount) {
266
+ console.log(chalk.green('🎉 Todas as verificações passaram!'));
401
267
  } else {
402
- console.log(chalk.red.bold('\n❌ Verificações encontraram problemas críticos'));
403
- console.log(chalk.gray(' - Alguns componentes podem não estar funcionando corretamente'));
268
+ console.log(chalk.yellow('⚠️ Algumas verificações falharam. Verifique o relatório completo.'));
404
269
  }
405
-
406
- console.log(chalk.yellow('\n💡 Dicas:'));
407
- console.log(chalk.gray(' - Configure credenciais: smoonb config --init'));
408
- console.log(chalk.gray(' - Instale Supabase CLI: npm install -g supabase'));
409
- console.log(chalk.gray(' - Execute verificações detalhadas: smoonb check --verbose'));
410
270
  }
411
271
 
412
- module.exports = checkCommand;
272
+ module.exports = checkCommand;