smoonb 0.0.1 → 0.0.3
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/.smoonbrc.example +3 -1
- package/README.md +1 -1
- package/package.json +3 -3
- package/src/commands/backup.js +31 -13
- package/src/commands/check.js +12 -6
- package/src/commands/config.js +3 -1
- package/src/commands/restore.js +12 -4
- package/src/index.js +29 -4
- package/src/utils/supabase.js +26 -3
package/.smoonbrc.example
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"supabase": {
|
|
3
|
+
"projectId": "your-project-id-here",
|
|
3
4
|
"url": "https://your-project.supabase.co",
|
|
4
5
|
"serviceKey": "your-service-key-here",
|
|
5
|
-
"anonKey": "your-anon-key-here"
|
|
6
|
+
"anonKey": "your-anon-key-here",
|
|
7
|
+
"databaseUrl": "postgresql://postgres:[password]@db.your-project.supabase.co:5432/postgres"
|
|
6
8
|
},
|
|
7
9
|
"backup": {
|
|
8
10
|
"includeFunctions": true,
|
package/README.md
CHANGED
|
@@ -202,7 +202,7 @@ Encontrou um bug? [Abra uma issue](https://github.com/almmello/smoonb/issues) co
|
|
|
202
202
|
|
|
203
203
|
Se este projeto te ajudou e você gostaria de apoiar o desenvolvimento:
|
|
204
204
|
|
|
205
|
-
- ☕ **Compre um café**: [Link de pagamento](https://
|
|
205
|
+
- ☕ **Compre um café**: [Link de pagamento](https://buy.stripe.com/aFadR99XtbTNb18egpbfO02)
|
|
206
206
|
- ⭐ **Dê uma estrela** no GitHub
|
|
207
207
|
- 🐛 **Reporte bugs** e contribua com melhorias
|
|
208
208
|
- 📢 **Compartilhe** com outros desenvolvedores
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smoonb",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Complete Supabase backup and migration tool - EXPERIMENTAL VERSION - USE AT YOUR OWN RISK",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"smoonb": "
|
|
7
|
+
"smoonb": "bin/smoonb.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"type": "commonjs",
|
|
35
35
|
"repository": {
|
|
36
36
|
"type": "git",
|
|
37
|
-
"url": "https://github.com/almmello/smoonb.git"
|
|
37
|
+
"url": "git+https://github.com/almmello/smoonb.git"
|
|
38
38
|
},
|
|
39
39
|
"bugs": {
|
|
40
40
|
"url": "https://github.com/almmello/smoonb/issues"
|
package/src/commands/backup.js
CHANGED
|
@@ -8,6 +8,7 @@ const { execSync } = require('child_process');
|
|
|
8
8
|
const fs = require('fs');
|
|
9
9
|
const path = require('path');
|
|
10
10
|
const { createClient } = require('@supabase/supabase-js');
|
|
11
|
+
const { getProjectId, getDatabaseUrl } = require('../utils/supabase');
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Backup completo do projeto Supabase
|
|
@@ -22,13 +23,20 @@ async function backupCommand(options) {
|
|
|
22
23
|
console.log(chalk.cyan.bold('🚀 Iniciando backup COMPLETO do projeto Supabase...\n'));
|
|
23
24
|
|
|
24
25
|
try {
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
// Obter projectId (da opção ou da configuração)
|
|
27
|
+
const projectId = options.projectId || getProjectId();
|
|
28
|
+
|
|
29
|
+
if (!projectId) {
|
|
30
|
+
console.error(chalk.red.bold('❌ Erro: Project ID não encontrado'));
|
|
31
|
+
console.log(chalk.yellow('💡 Opções:'));
|
|
32
|
+
console.log(chalk.gray(' 1. Use: smoonb backup --project-id <seu-project-id>'));
|
|
33
|
+
console.log(chalk.gray(' 2. Configure: smoonb config --init'));
|
|
34
|
+
console.log(chalk.gray(' 3. Ou defina SUPABASE_PROJECT_ID no ambiente'));
|
|
29
35
|
process.exit(1);
|
|
30
36
|
}
|
|
31
37
|
|
|
38
|
+
console.log(chalk.blue('🆔 Project ID:'), projectId);
|
|
39
|
+
|
|
32
40
|
// Criar diretório de backup com timestamp
|
|
33
41
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
34
42
|
const backupDir = path.resolve(options.output, `backup-${timestamp}`);
|
|
@@ -38,41 +46,45 @@ async function backupCommand(options) {
|
|
|
38
46
|
|
|
39
47
|
// 1. BACKUP DA DATABASE (formato Custom - mais confiável)
|
|
40
48
|
console.log(chalk.blue.bold('\n📊 1/5 - Backup da Database PostgreSQL...'));
|
|
41
|
-
const dbBackupFile = await backupDatabase(
|
|
42
|
-
|
|
49
|
+
const dbBackupFile = await backupDatabase(projectId, backupDir);
|
|
50
|
+
if (dbBackupFile) {
|
|
51
|
+
console.log(chalk.green('✅ Database backupado:'), path.basename(dbBackupFile));
|
|
52
|
+
} else {
|
|
53
|
+
console.log(chalk.yellow('⚠️ Database não foi backupada (credenciais não configuradas)'));
|
|
54
|
+
}
|
|
43
55
|
|
|
44
56
|
// 2. BACKUP DAS EDGE FUNCTIONS
|
|
45
57
|
if (options.includeFunctions) {
|
|
46
58
|
console.log(chalk.blue.bold('\n⚡ 2/5 - Backup das Edge Functions...'));
|
|
47
|
-
const functionsDir = await backupEdgeFunctions(
|
|
59
|
+
const functionsDir = await backupEdgeFunctions(projectId, backupDir);
|
|
48
60
|
console.log(chalk.green('✅ Edge Functions backupadas:'), functionsDir);
|
|
49
61
|
}
|
|
50
62
|
|
|
51
63
|
// 3. BACKUP DAS CONFIGURAÇÕES DE AUTH
|
|
52
64
|
if (options.includeAuth) {
|
|
53
65
|
console.log(chalk.blue.bold('\n🔐 3/5 - Backup das configurações de Auth...'));
|
|
54
|
-
const authConfig = await backupAuthSettings(
|
|
66
|
+
const authConfig = await backupAuthSettings(projectId, backupDir);
|
|
55
67
|
console.log(chalk.green('✅ Auth settings backupadas:'), authConfig);
|
|
56
68
|
}
|
|
57
69
|
|
|
58
70
|
// 4. BACKUP DOS STORAGE OBJECTS
|
|
59
71
|
if (options.includeStorage) {
|
|
60
72
|
console.log(chalk.blue.bold('\n📁 4/5 - Backup dos Storage Objects...'));
|
|
61
|
-
const storageBackup = await backupStorageObjects(
|
|
73
|
+
const storageBackup = await backupStorageObjects(projectId, backupDir);
|
|
62
74
|
console.log(chalk.green('✅ Storage Objects backupados:'), storageBackup);
|
|
63
75
|
}
|
|
64
76
|
|
|
65
77
|
// 5. BACKUP DAS CONFIGURAÇÕES DE REALTIME
|
|
66
78
|
if (options.includeRealtime) {
|
|
67
79
|
console.log(chalk.blue.bold('\n🔄 5/5 - Backup das configurações de Realtime...'));
|
|
68
|
-
const realtimeConfig = await backupRealtimeSettings(
|
|
80
|
+
const realtimeConfig = await backupRealtimeSettings(projectId, backupDir);
|
|
69
81
|
console.log(chalk.green('✅ Realtime settings backupadas:'), realtimeConfig);
|
|
70
82
|
}
|
|
71
83
|
|
|
72
84
|
// Criar arquivo de manifesto do backup
|
|
73
85
|
const manifest = {
|
|
74
86
|
timestamp: new Date().toISOString(),
|
|
75
|
-
projectId:
|
|
87
|
+
projectId: projectId,
|
|
76
88
|
version: '0.1.0-beta',
|
|
77
89
|
components: {
|
|
78
90
|
database: !!dbBackupFile,
|
|
@@ -113,8 +125,14 @@ async function backupCommand(options) {
|
|
|
113
125
|
*/
|
|
114
126
|
async function backupDatabase(projectId, outputDir) {
|
|
115
127
|
try {
|
|
116
|
-
//
|
|
117
|
-
const dbUrl =
|
|
128
|
+
// Obter URL de conexão da configuração
|
|
129
|
+
const dbUrl = getDatabaseUrl(projectId);
|
|
130
|
+
|
|
131
|
+
if (!dbUrl) {
|
|
132
|
+
console.log(chalk.yellow('⚠️ Database URL não configurada'));
|
|
133
|
+
console.log(chalk.gray(' - Configure DATABASE_URL ou use smoonb config --init'));
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
118
136
|
|
|
119
137
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
120
138
|
const filename = `database-${timestamp}.dump`;
|
package/src/commands/check.js
CHANGED
|
@@ -7,6 +7,7 @@ const chalk = require('chalk');
|
|
|
7
7
|
const { execSync } = require('child_process');
|
|
8
8
|
const fs = require('fs');
|
|
9
9
|
const path = require('path');
|
|
10
|
+
const { getProjectId } = require('../utils/supabase');
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Checklist pós-restore - Verificação de integridade
|
|
@@ -21,19 +22,24 @@ async function checkCommand(options) {
|
|
|
21
22
|
console.log(chalk.cyan.bold('🔍 Checklist pós-restore - Verificação de integridade...\n'));
|
|
22
23
|
|
|
23
24
|
try {
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
// Obter projectId (da opção ou da configuração)
|
|
26
|
+
const projectId = options.projectId || getProjectId();
|
|
27
|
+
|
|
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'));
|
|
28
34
|
process.exit(1);
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
console.log(chalk.blue('🆔 Project ID:'),
|
|
37
|
+
console.log(chalk.blue('🆔 Project ID:'), projectId);
|
|
32
38
|
console.log(chalk.blue('📊 Modo verbose:'), options.verbose ? 'Ativado' : 'Desativado');
|
|
33
39
|
console.log();
|
|
34
40
|
|
|
35
41
|
// Executar verificações
|
|
36
|
-
const results = await runPostRestoreChecks(
|
|
42
|
+
const results = await runPostRestoreChecks(projectId, options.verbose);
|
|
37
43
|
|
|
38
44
|
// Mostrar resumo
|
|
39
45
|
showCheckSummary(results);
|
package/src/commands/config.js
CHANGED
|
@@ -22,9 +22,11 @@ async function configCommand(options) {
|
|
|
22
22
|
// Inicializar configuração
|
|
23
23
|
const defaultConfig = {
|
|
24
24
|
supabase: {
|
|
25
|
+
projectId: '',
|
|
25
26
|
url: '',
|
|
26
27
|
serviceKey: '',
|
|
27
|
-
anonKey: ''
|
|
28
|
+
anonKey: '',
|
|
29
|
+
databaseUrl: ''
|
|
28
30
|
},
|
|
29
31
|
backup: {
|
|
30
32
|
includeFunctions: true,
|
package/src/commands/restore.js
CHANGED
|
@@ -7,6 +7,7 @@ const chalk = require('chalk');
|
|
|
7
7
|
const { execSync } = require('child_process');
|
|
8
8
|
const fs = require('fs');
|
|
9
9
|
const path = require('path');
|
|
10
|
+
const { getProjectId } = require('../utils/supabase');
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Restauração completa do projeto Supabase
|
|
@@ -21,13 +22,20 @@ async function restoreCommand(options) {
|
|
|
21
22
|
console.log(chalk.cyan.bold('🔄 Iniciando restauração COMPLETA do projeto Supabase...\n'));
|
|
22
23
|
|
|
23
24
|
try {
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
// Obter projectId (da opção ou da configuração)
|
|
26
|
+
const projectId = options.projectId || getProjectId();
|
|
27
|
+
|
|
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 restore --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'));
|
|
28
34
|
process.exit(1);
|
|
29
35
|
}
|
|
30
36
|
|
|
37
|
+
console.log(chalk.blue('🆔 Project ID:'), projectId);
|
|
38
|
+
|
|
31
39
|
if (!options.backupDir) {
|
|
32
40
|
console.error(chalk.red.bold('❌ Erro: Diretório de backup é obrigatório'));
|
|
33
41
|
console.log(chalk.yellow('💡 Use: smoonb restore --project-id <seu-project-id> --backup-dir <diretorio-backup>'));
|
package/src/index.js
CHANGED
|
@@ -92,10 +92,12 @@ function showQuickHelp() {
|
|
|
92
92
|
🚀 COMANDOS PRINCIPAIS:
|
|
93
93
|
|
|
94
94
|
📊 Backup completo:
|
|
95
|
-
smoonb backup
|
|
95
|
+
smoonb backup # Usa projectId da configuração
|
|
96
|
+
smoonb backup --project-id <id> # Especifica projectId
|
|
96
97
|
|
|
97
98
|
🔄 Restauração completa:
|
|
98
|
-
smoonb restore --
|
|
99
|
+
smoonb restore --backup-dir <dir> # Usa projectId da configuração
|
|
100
|
+
smoonb restore --project-id <id> --backup-dir <dir> # Especifica projectId
|
|
99
101
|
|
|
100
102
|
🔐 Gerenciamento de secrets:
|
|
101
103
|
smoonb secrets export
|
|
@@ -106,10 +108,33 @@ function showQuickHelp() {
|
|
|
106
108
|
smoonb functions list
|
|
107
109
|
|
|
108
110
|
🔍 Verificação pós-restore:
|
|
109
|
-
smoonb check
|
|
111
|
+
smoonb check # Usa projectId da configuração
|
|
112
|
+
smoonb check --project-id <id> # Especifica projectId
|
|
110
113
|
|
|
111
114
|
⚙️ Configuração:
|
|
112
|
-
smoonb config --init
|
|
115
|
+
smoonb config --init # Criar arquivo de configuração
|
|
116
|
+
smoonb config --show # Mostrar configuração atual
|
|
117
|
+
|
|
118
|
+
📋 CONFIGURAÇÃO AUTOMÁTICA:
|
|
119
|
+
smoonb config --init # Cria ~/.smoonbrc com projectId, URLs, etc.
|
|
120
|
+
# Edite o arquivo com suas credenciais Supabase
|
|
121
|
+
smoonb backup # Funciona sem --project-id!
|
|
122
|
+
|
|
123
|
+
📝 EXEMPLO DE CONFIGURAÇÃO (.smoonbrc):
|
|
124
|
+
{
|
|
125
|
+
"supabase": {
|
|
126
|
+
"projectId": "abc123def456",
|
|
127
|
+
"url": "https://abc123def456.supabase.co",
|
|
128
|
+
"serviceKey": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
129
|
+
"anonKey": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
130
|
+
"databaseUrl": "postgresql://postgres:[senha]@db.abc123def456.supabase.co:5432/postgres"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
🔧 COMO CONFIGURAR:
|
|
135
|
+
1. smoonb config --init
|
|
136
|
+
2. Edite ~/.smoonbrc com suas credenciais
|
|
137
|
+
3. smoonb backup (funciona automaticamente!)
|
|
113
138
|
`));
|
|
114
139
|
}
|
|
115
140
|
|
package/src/utils/supabase.js
CHANGED
|
@@ -74,10 +74,28 @@ function saveConfig(config) {
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Obter Project ID do Supabase
|
|
79
|
+
*/
|
|
80
|
+
function getProjectId() {
|
|
81
|
+
// Tentar variável de ambiente primeiro
|
|
82
|
+
if (process.env.SUPABASE_PROJECT_ID) {
|
|
83
|
+
return process.env.SUPABASE_PROJECT_ID;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Tentar configuração
|
|
87
|
+
const config = loadConfig();
|
|
88
|
+
if (config?.supabase?.projectId) {
|
|
89
|
+
return config.supabase.projectId;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
77
95
|
/**
|
|
78
96
|
* Obter URL de conexão da database
|
|
79
97
|
*/
|
|
80
|
-
function getDatabaseUrl(projectId) {
|
|
98
|
+
function getDatabaseUrl(projectId = null) {
|
|
81
99
|
// Tentar variável de ambiente primeiro
|
|
82
100
|
if (process.env.DATABASE_URL) {
|
|
83
101
|
return process.env.DATABASE_URL;
|
|
@@ -89,8 +107,12 @@ function getDatabaseUrl(projectId) {
|
|
|
89
107
|
return config.supabase.databaseUrl;
|
|
90
108
|
}
|
|
91
109
|
|
|
92
|
-
//
|
|
93
|
-
|
|
110
|
+
// Se projectId foi fornecido, usar URL padrão
|
|
111
|
+
if (projectId) {
|
|
112
|
+
return `postgresql://postgres:[password]@db.${projectId}.supabase.co:5432/postgres`;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return null;
|
|
94
116
|
}
|
|
95
117
|
|
|
96
118
|
/**
|
|
@@ -349,6 +371,7 @@ module.exports = {
|
|
|
349
371
|
getSupabaseClient,
|
|
350
372
|
loadConfig,
|
|
351
373
|
saveConfig,
|
|
374
|
+
getProjectId,
|
|
352
375
|
getDatabaseUrl,
|
|
353
376
|
getSupabaseUrl,
|
|
354
377
|
getServiceKey,
|