smoonb 0.0.2 → 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 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smoonb",
3
- "version": "0.0.2",
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": {
@@ -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
- // Validar opções
26
- if (!options.projectId) {
27
- console.error(chalk.red.bold('❌ Erro: Project ID é obrigatório'));
28
- console.log(chalk.yellow('💡 Use: smoonb backup --project-id <seu-project-id>'));
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(options.projectId, backupDir);
42
- console.log(chalk.green('✅ Database backupado:'), path.basename(dbBackupFile));
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(options.projectId, backupDir);
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(options.projectId, backupDir);
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(options.projectId, backupDir);
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(options.projectId, backupDir);
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: options.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
- // Construir URL de conexão (assumindo que está configurada)
117
- const dbUrl = process.env.DATABASE_URL || `postgresql://postgres:[password]@db.${projectId}.supabase.co:5432/postgres`;
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`;
@@ -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
- // Validar opções
25
- if (!options.projectId) {
26
- console.error(chalk.red.bold('❌ Erro: Project ID é obrigatório'));
27
- console.log(chalk.yellow('💡 Use: smoonb check --project-id <seu-project-id>'));
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:'), options.projectId);
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(options.projectId, options.verbose);
42
+ const results = await runPostRestoreChecks(projectId, options.verbose);
37
43
 
38
44
  // Mostrar resumo
39
45
  showCheckSummary(results);
@@ -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,
@@ -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
- // Validar opções
25
- if (!options.projectId) {
26
- console.error(chalk.red.bold('❌ Erro: Project ID é obrigatório'));
27
- console.log(chalk.yellow('💡 Use: smoonb restore --project-id <seu-project-id> --backup-dir <diretorio-backup>'));
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 --project-id <project-id>
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 --project-id <project-id> --backup-dir <backup-dir>
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 --project-id <project-id>
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
 
@@ -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
- // URL padrão (requer configuração de senha)
93
- return `postgresql://postgres:[password]@db.${projectId}.supabase.co:5432/postgres`;
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,