smoonb 0.0.7 → 0.0.9
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/README.md +166 -169
- package/bin/smoonb.js +7 -24
- package/package.json +3 -3
- package/src/commands/backup.js +140 -249
- package/src/commands/check.js +210 -349
- package/src/commands/functions.js +123 -349
- package/src/commands/restore.js +203 -281
- package/src/index.js +12 -21
- package/src/services/introspect.js +299 -0
- package/src/utils/cli.js +87 -0
- package/src/utils/config.js +140 -0
- package/src/utils/fsx.js +110 -0
- package/src/utils/hash.js +40 -0
- package/src/commands/secrets.js +0 -361
package/src/commands/check.js
CHANGED
|
@@ -1,412 +1,273 @@
|
|
|
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
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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 } = require('../utils/config');
|
|
7
|
+
const { writeJson } = require('../utils/fsx');
|
|
8
|
+
const { IntrospectionService } = require('../services/introspect');
|
|
9
|
+
const { showBetaBanner } = require('../index');
|
|
23
10
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
11
|
+
const checkCommand = new Command('check')
|
|
12
|
+
.description('Verificar integridade do projeto Supabase após restauração')
|
|
13
|
+
.option('-o, --output <file>', 'Arquivo de saída do relatório', 'check-report.json')
|
|
14
|
+
.action(async (options) => {
|
|
15
|
+
showBetaBanner();
|
|
27
16
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
17
|
+
try {
|
|
18
|
+
// Verificar se psql está disponível
|
|
19
|
+
const psqlPath = await ensureBin('psql');
|
|
20
|
+
if (!psqlPath) {
|
|
21
|
+
console.error(chalk.red('❌ psql não encontrado'));
|
|
22
|
+
console.log(chalk.yellow('💡 Instale PostgreSQL:'));
|
|
23
|
+
console.log(chalk.yellow(' https://www.postgresql.org/download/'));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Carregar configuração
|
|
28
|
+
const config = await readConfig();
|
|
29
|
+
validateFor(config, 'backup'); // Usar mesma validação do backup
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
const databaseUrl = config.supabase.databaseUrl;
|
|
32
|
+
if (!databaseUrl) {
|
|
33
|
+
console.error(chalk.red('❌ databaseUrl não configurada'));
|
|
34
|
+
console.log(chalk.yellow('💡 Configure databaseUrl no .smoonbrc'));
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
41
37
|
|
|
42
|
-
|
|
43
|
-
const results = await runPostRestoreChecks(projectId, options.verbose);
|
|
38
|
+
console.log(chalk.blue(`🔍 Verificando integridade do projeto: ${config.supabase.projectId}`));
|
|
44
39
|
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
// Executar verificações
|
|
41
|
+
const report = await performChecks(config, databaseUrl);
|
|
47
42
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
}
|
|
43
|
+
// Salvar relatório
|
|
44
|
+
const reportPath = path.resolve(options.output);
|
|
45
|
+
await writeJson(reportPath, report);
|
|
53
46
|
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
];
|
|
47
|
+
// Mostrar resumo
|
|
48
|
+
showCheckSummary(report);
|
|
70
49
|
|
|
71
|
-
|
|
50
|
+
console.log(chalk.green('\n🎉 Verificação concluída!'));
|
|
51
|
+
console.log(chalk.blue(`📋 Relatório salvo em: ${reportPath}`));
|
|
72
52
|
|
|
73
|
-
// Executar verificações por categoria
|
|
74
|
-
for (const check of checks) {
|
|
75
|
-
try {
|
|
76
|
-
await performCheck(check, projectId, verbose);
|
|
77
53
|
} catch (error) {
|
|
78
|
-
|
|
79
|
-
|
|
54
|
+
console.error(chalk.red(`❌ Erro na verificação: ${error.message}`));
|
|
55
|
+
process.exit(1);
|
|
80
56
|
}
|
|
81
|
-
}
|
|
57
|
+
});
|
|
82
58
|
|
|
83
|
-
|
|
84
|
-
|
|
59
|
+
// Executar todas as verificações
|
|
60
|
+
async function performChecks(config, databaseUrl) {
|
|
61
|
+
const report = {
|
|
62
|
+
timestamp: new Date().toISOString(),
|
|
63
|
+
project_id: config.supabase.projectId,
|
|
64
|
+
checks: {}
|
|
65
|
+
};
|
|
85
66
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
async function performCheck(check, projectId, verbose) {
|
|
90
|
-
if (verbose) {
|
|
91
|
-
console.log(chalk.gray(` - Verificando ${check.name}...`));
|
|
92
|
-
}
|
|
67
|
+
// 1. Verificar conexão com database
|
|
68
|
+
console.log(chalk.blue('\n🔌 1/6 - Verificando conexão com database...'));
|
|
69
|
+
report.checks.database_connection = await checkDatabaseConnection(databaseUrl);
|
|
93
70
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
}
|
|
71
|
+
// 2. Verificar extensões
|
|
72
|
+
console.log(chalk.blue('\n🔧 2/6 - Verificando extensões...'));
|
|
73
|
+
report.checks.extensions = await checkExtensions(databaseUrl);
|
|
74
|
+
|
|
75
|
+
// 3. Verificar tabelas
|
|
76
|
+
console.log(chalk.blue('\n📊 3/6 - Verificando tabelas...'));
|
|
77
|
+
report.checks.tables = await checkTables(databaseUrl);
|
|
78
|
+
|
|
79
|
+
// 4. Verificar políticas RLS
|
|
80
|
+
console.log(chalk.blue('\n🔒 4/6 - Verificando políticas RLS...'));
|
|
81
|
+
report.checks.rls_policies = await checkRLSPolicies(databaseUrl);
|
|
82
|
+
|
|
83
|
+
// 5. Verificar Realtime
|
|
84
|
+
console.log(chalk.blue('\n🔄 5/6 - Verificando Realtime...'));
|
|
85
|
+
report.checks.realtime = await checkRealtime(databaseUrl);
|
|
86
|
+
|
|
87
|
+
// 6. Verificar Storage
|
|
88
|
+
console.log(chalk.blue('\n📦 6/6 - Verificando Storage...'));
|
|
89
|
+
report.checks.storage = await checkStorage(config);
|
|
90
|
+
|
|
91
|
+
return report;
|
|
126
92
|
}
|
|
127
93
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
*/
|
|
131
|
-
async function checkDatabaseConnection(check, projectId, verbose) {
|
|
94
|
+
// Verificar conexão com database
|
|
95
|
+
async function checkDatabaseConnection(databaseUrl) {
|
|
132
96
|
try {
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const testCmd = `psql "${dbUrl}" -c "SELECT 1;"`;
|
|
137
|
-
execSync(testCmd, { stdio: 'pipe' });
|
|
97
|
+
const { stdout } = await runCommand(
|
|
98
|
+
`psql "${databaseUrl}" -t -c "SELECT 1 as test_connection;"`
|
|
99
|
+
);
|
|
138
100
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
console.log(chalk.gray(' ✅ Conexão com database OK'));
|
|
101
|
+
if (stdout.trim() === '1') {
|
|
102
|
+
return { status: 'ok', message: 'Conexão estabelecida com sucesso' };
|
|
103
|
+
} else {
|
|
104
|
+
return { status: 'error', message: 'Resposta inesperada da database' };
|
|
144
105
|
}
|
|
145
106
|
} catch (error) {
|
|
146
|
-
|
|
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
|
-
}
|
|
107
|
+
return { status: 'error', message: `Falha na conexão: ${error.message}` };
|
|
152
108
|
}
|
|
153
109
|
}
|
|
154
110
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
*/
|
|
158
|
-
async function checkDatabaseSchema(check, projectId, verbose) {
|
|
111
|
+
// Verificar extensões
|
|
112
|
+
async function checkExtensions(databaseUrl) {
|
|
159
113
|
try {
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
114
|
+
const query = `
|
|
115
|
+
SELECT extname, extversion
|
|
116
|
+
FROM pg_extension
|
|
117
|
+
ORDER BY extname;
|
|
118
|
+
`;
|
|
165
119
|
|
|
166
|
-
const
|
|
167
|
-
|
|
120
|
+
const { stdout } = await runCommand(
|
|
121
|
+
`psql "${databaseUrl}" -t -c "${query}"`
|
|
122
|
+
);
|
|
168
123
|
|
|
169
|
-
|
|
170
|
-
|
|
124
|
+
const extensions = stdout.trim().split('\n')
|
|
125
|
+
.filter(line => line.trim())
|
|
126
|
+
.map(line => {
|
|
127
|
+
const [name, version] = line.trim().split('|');
|
|
128
|
+
return { name: name?.trim(), version: version?.trim() };
|
|
129
|
+
});
|
|
171
130
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
131
|
+
return {
|
|
132
|
+
status: 'ok',
|
|
133
|
+
message: `${extensions.length} extensões encontradas`,
|
|
134
|
+
data: extensions
|
|
135
|
+
};
|
|
175
136
|
} catch (error) {
|
|
176
|
-
|
|
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
|
-
}
|
|
137
|
+
return { status: 'error', message: `Erro ao verificar extensões: ${error.message}` };
|
|
182
138
|
}
|
|
183
139
|
}
|
|
184
140
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
*/
|
|
188
|
-
async function checkDatabaseExtensions(check, projectId, verbose) {
|
|
141
|
+
// Verificar tabelas
|
|
142
|
+
async function checkTables(databaseUrl) {
|
|
189
143
|
try {
|
|
190
|
-
const
|
|
144
|
+
const query = `
|
|
145
|
+
SELECT schemaname, tablename, tableowner
|
|
146
|
+
FROM pg_tables
|
|
147
|
+
WHERE schemaname IN ('public', 'auth', 'storage')
|
|
148
|
+
ORDER BY schemaname, tablename;
|
|
149
|
+
`;
|
|
191
150
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
151
|
+
const { stdout } = await runCommand(
|
|
152
|
+
`psql "${databaseUrl}" -t -c "${query}"`
|
|
153
|
+
);
|
|
195
154
|
|
|
196
|
-
const
|
|
197
|
-
|
|
155
|
+
const tables = stdout.trim().split('\n')
|
|
156
|
+
.filter(line => line.trim())
|
|
157
|
+
.map(line => {
|
|
158
|
+
const [schema, table, owner] = line.trim().split('|');
|
|
159
|
+
return {
|
|
160
|
+
schema: schema?.trim(),
|
|
161
|
+
table: table?.trim(),
|
|
162
|
+
owner: owner?.trim()
|
|
163
|
+
};
|
|
164
|
+
});
|
|
198
165
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
166
|
+
return {
|
|
167
|
+
status: 'ok',
|
|
168
|
+
message: `${tables.length} tabelas encontradas`,
|
|
169
|
+
data: tables
|
|
170
|
+
};
|
|
205
171
|
} catch (error) {
|
|
206
|
-
|
|
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
|
-
}
|
|
172
|
+
return { status: 'error', message: `Erro ao verificar tabelas: ${error.message}` };
|
|
212
173
|
}
|
|
213
174
|
}
|
|
214
175
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
*/
|
|
218
|
-
async function checkEdgeFunctions(check, projectId, verbose) {
|
|
176
|
+
// Verificar políticas RLS
|
|
177
|
+
async function checkRLSPolicies(databaseUrl) {
|
|
219
178
|
try {
|
|
220
|
-
|
|
221
|
-
|
|
179
|
+
const query = `
|
|
180
|
+
SELECT COUNT(*) as policy_count
|
|
181
|
+
FROM pg_policies;
|
|
182
|
+
`;
|
|
222
183
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
184
|
+
const { stdout } = await runCommand(
|
|
185
|
+
`psql "${databaseUrl}" -t -c "${query}"`
|
|
186
|
+
);
|
|
226
187
|
|
|
227
|
-
|
|
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');
|
|
188
|
+
const policyCount = parseInt(stdout.trim());
|
|
248
189
|
|
|
249
|
-
|
|
250
|
-
|
|
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'));
|
|
190
|
+
return {
|
|
191
|
+
status: 'ok',
|
|
192
|
+
message: `${policyCount} políticas RLS encontradas`,
|
|
193
|
+
data: { policy_count: policyCount }
|
|
194
|
+
};
|
|
195
|
+
} catch (error) {
|
|
196
|
+
return { status: 'error', message: `Erro ao verificar políticas RLS: ${error.message}` };
|
|
304
197
|
}
|
|
305
198
|
}
|
|
306
199
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
200
|
+
// Verificar Realtime
|
|
201
|
+
async function checkRealtime(databaseUrl) {
|
|
202
|
+
try {
|
|
203
|
+
const query = `
|
|
204
|
+
SELECT pubname
|
|
205
|
+
FROM pg_publication
|
|
206
|
+
ORDER BY pubname;
|
|
207
|
+
`;
|
|
208
|
+
|
|
209
|
+
const { stdout } = await runCommand(
|
|
210
|
+
`psql "${databaseUrl}" -t -c "${query}"`
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
const publications = stdout.trim().split('\n')
|
|
214
|
+
.filter(line => line.trim())
|
|
215
|
+
.map(line => line.trim());
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
status: 'ok',
|
|
219
|
+
message: `${publications.length} publicações Realtime encontradas`,
|
|
220
|
+
data: { publications }
|
|
221
|
+
};
|
|
222
|
+
} catch (error) {
|
|
223
|
+
return { status: 'error', message: `Erro ao verificar Realtime: ${error.message}` };
|
|
317
224
|
}
|
|
318
225
|
}
|
|
319
226
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
*/
|
|
323
|
-
async function checkAPIEndpoints(check, projectId, verbose) {
|
|
227
|
+
// Verificar Storage
|
|
228
|
+
async function checkStorage(config) {
|
|
324
229
|
try {
|
|
325
|
-
const
|
|
230
|
+
const introspection = new IntrospectionService(config);
|
|
231
|
+
const storageInventory = await introspection.getStorageInventory();
|
|
326
232
|
|
|
327
|
-
|
|
328
|
-
const
|
|
233
|
+
const bucketCount = storageInventory.buckets?.length || 0;
|
|
234
|
+
const totalObjects = storageInventory.buckets?.reduce(
|
|
235
|
+
(total, bucket) => total + (bucket.objects?.length || 0), 0
|
|
236
|
+
) || 0;
|
|
329
237
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
console.log(chalk.gray(' ✅ API endpoints OK'));
|
|
336
|
-
}
|
|
238
|
+
return {
|
|
239
|
+
status: 'ok',
|
|
240
|
+
message: `${bucketCount} buckets e ${totalObjects} objetos encontrados`,
|
|
241
|
+
data: storageInventory
|
|
242
|
+
};
|
|
337
243
|
} catch (error) {
|
|
338
|
-
|
|
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
|
-
}
|
|
244
|
+
return { status: 'error', message: `Erro ao verificar Storage: ${error.message}` };
|
|
344
245
|
}
|
|
345
246
|
}
|
|
346
247
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
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}:`));
|
|
248
|
+
// Mostrar resumo das verificações
|
|
249
|
+
function showCheckSummary(report) {
|
|
250
|
+
console.log(chalk.blue('\n📋 RESUMO DAS VERIFICAÇÕES:'));
|
|
251
|
+
console.log(chalk.blue('═'.repeat(50)));
|
|
252
|
+
|
|
253
|
+
for (const [checkName, result] of Object.entries(report.checks)) {
|
|
254
|
+
const icon = result.status === 'ok' ? '✅' : '❌';
|
|
255
|
+
const color = result.status === 'ok' ? chalk.green : chalk.red;
|
|
366
256
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
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'));
|
|
257
|
+
console.log(`${icon} ${color(checkName.replace(/_/g, ' ').toUpperCase())}: ${result.message}`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const okCount = Object.values(report.checks).filter(c => c.status === 'ok').length;
|
|
261
|
+
const totalCount = Object.keys(report.checks).length;
|
|
262
|
+
|
|
263
|
+
console.log(chalk.blue('═'.repeat(50)));
|
|
264
|
+
console.log(chalk.blue(`📊 Resultado: ${okCount}/${totalCount} verificações passaram`));
|
|
265
|
+
|
|
266
|
+
if (okCount === totalCount) {
|
|
267
|
+
console.log(chalk.green('🎉 Todas as verificações passaram!'));
|
|
401
268
|
} else {
|
|
402
|
-
console.log(chalk.
|
|
403
|
-
console.log(chalk.gray(' - Alguns componentes podem não estar funcionando corretamente'));
|
|
269
|
+
console.log(chalk.yellow('⚠️ Algumas verificações falharam. Verifique o relatório completo.'));
|
|
404
270
|
}
|
|
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
271
|
}
|
|
411
272
|
|
|
412
|
-
module.exports = checkCommand;
|
|
273
|
+
module.exports = checkCommand;
|