smoonb 0.0.21 → 0.0.23

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 CHANGED
@@ -25,25 +25,42 @@ O **smoonb** resolve o problema das ferramentas existentes que fazem backup apen
25
25
 
26
26
  ## 🚀 Instalação
27
27
 
28
+ **⚠️ IMPORTANTE: Instale APENAS localmente no projeto!**
29
+
28
30
  ```bash
29
- # Instalar localmente no projeto
31
+ # ✅ CORRETO - Instalar localmente no projeto
30
32
  npm install smoonb
31
33
 
32
- # Usar com npx
34
+ # ✅ CORRETO - Usar com npx
33
35
  npx smoonb --help
36
+
37
+ # ❌ ERRADO - NÃO instalar globalmente
38
+ npm install -g smoonb # ← Isso será bloqueado!
34
39
  ```
35
40
 
41
+ **💡 Por que apenas local?**
42
+ - **🔒 Segurança**: Evita conflitos de versão
43
+ - **📦 Isolamento**: Cada projeto usa sua versão
44
+ - **🔄 Atualizações**: Controle granular por projeto
45
+ - **🛡️ Estabilidade**: Evita quebras em outros projetos
46
+
36
47
  ## 📋 Pré-requisitos
37
48
 
38
- ### 1. Supabase CLI
49
+ ### 1. Docker Desktop
39
50
  ```bash
40
- npm install -g supabase
51
+ # Instalar Docker Desktop
52
+ # Windows/macOS: https://docs.docker.com/desktop/install/
53
+ # Linux: https://docs.docker.com/engine/install/
54
+
55
+ # Verificar se está rodando
56
+ docker --version
57
+ docker ps
41
58
  ```
42
59
 
43
- ### 2. PostgreSQL (psql)
44
- - **Windows**: https://www.postgresql.org/download/windows/
45
- - **macOS**: `brew install postgresql`
46
- - **Linux**: `sudo apt-get install postgresql-client`
60
+ ### 2. Supabase CLI
61
+ ```bash
62
+ npm install -g supabase
63
+ ```
47
64
 
48
65
  ## ⚙️ Configuração
49
66
 
package/package.json CHANGED
@@ -1,14 +1,18 @@
1
1
  {
2
2
  "name": "smoonb",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
4
4
  "description": "Complete Supabase backup and migration tool - EXPERIMENTAL VERSION - USE AT YOUR OWN RISK",
5
+ "preferGlobal": false,
6
+ "preventGlobalInstall": true,
5
7
  "main": "index.js",
6
8
  "bin": {
7
9
  "smoonb": "bin/smoonb.js"
8
10
  },
9
11
  "scripts": {
10
12
  "test": "echo \"Error: no test specified\" && exit 1",
11
- "start": "node bin/smoonb.js"
13
+ "start": "node bin/smoonb.js",
14
+ "preinstall": "node -e \"if(process.env.npm_config_global) { console.error('\\n❌ SMOONB NÃO DEVE SER INSTALADO GLOBALMENTE!\\n\\n📋 Para usar o smoonb, instale localmente no seu projeto:\\n npm install smoonb\\n\\n💡 Depois execute com:\\n npx smoonb backup\\n\\n🚫 Instalação global cancelada!\\n'); process.exit(1); }\"",
15
+ "postinstall": "echo '\\n✅ smoonb instalado com sucesso!\\n💡 Execute: npx smoonb backup\\n📖 Documentação: https://github.com/almmello/smoonb\\n'"
12
16
  },
13
17
  "keywords": [
14
18
  "supabase",
@@ -230,7 +230,7 @@ async function backupDatabaseWithDocker(databaseUrl, backupDir) {
230
230
  const schemaFile = path.join(backupDir, 'schema.sql');
231
231
 
232
232
  try {
233
- await execAsync(`supabase db dump --db-url "${databaseUrl}" --schema-only -f "${schemaFile}"`);
233
+ await execAsync(`supabase db dump --db-url "${databaseUrl}" -f "${schemaFile}"`);
234
234
 
235
235
  const schemaValidation = await validateSqlFile(schemaFile);
236
236
  if (schemaValidation.valid) {
@@ -524,102 +524,64 @@ async function backupStorage(projectId, accessToken, backupDir) {
524
524
  }
525
525
  }
526
526
 
527
- // Backup dos Custom Roles via SQL
527
+ // Backup dos Custom Roles via Docker
528
528
  async function backupCustomRoles(databaseUrl, backupDir) {
529
529
  try {
530
- console.log(chalk.gray(' - Exportando Custom Roles...'));
530
+ console.log(chalk.gray(' - Exportando Custom Roles via Docker...'));
531
531
 
532
532
  const customRolesFile = path.join(backupDir, 'custom-roles.sql');
533
533
 
534
- // Query para obter roles customizados com senhas
535
- const customRolesQuery = `
536
- -- Custom Roles Backup
537
- -- Roles customizados com senhas
538
-
539
- SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolconnlimit, rolpassword
540
- FROM pg_roles
541
- WHERE rolname NOT IN ('postgres', 'supabase_admin', 'supabase_auth_admin', 'supabase_storage_admin', 'supabase_read_only_user', 'authenticator', 'anon', 'authenticated', 'service_role')
542
- ORDER BY rolname;
543
- `;
544
-
545
- // Executar query e salvar resultado
546
- const { stdout } = await execAsync(
547
- `psql "${databaseUrl}" -t -c "${customRolesQuery}"`
548
- );
549
-
550
- const rolesContent = `-- Custom Roles Backup
551
- -- Generated at: ${new Date().toISOString()}
552
-
553
- ${customRolesQuery}
554
-
555
- -- Results:
556
- ${stdout}
557
- `;
558
-
559
- await fs.promises.writeFile(customRolesFile, rolesContent);
560
-
561
- const stats = fs.statSync(customRolesFile);
562
- const sizeKB = (stats.size / 1024).toFixed(1);
563
-
564
- console.log(chalk.green(` ✅ Custom Roles exportados: ${sizeKB} KB`));
565
-
566
- return { success: true, roles: [{ filename: 'custom-roles.sql', sizeKB }] };
534
+ try {
535
+ // Usar Supabase CLI via Docker para roles
536
+ await execAsync(`supabase db dump --db-url "${databaseUrl}" --role-only -f "${customRolesFile}"`);
537
+
538
+ const stats = fs.statSync(customRolesFile);
539
+ const sizeKB = (stats.size / 1024).toFixed(1);
540
+
541
+ console.log(chalk.green(` ✅ Custom Roles exportados via Docker: ${sizeKB} KB`));
542
+
543
+ return { success: true, roles: [{ filename: 'custom-roles.sql', sizeKB }] };
544
+ } catch (error) {
545
+ console.log(chalk.yellow(` ⚠️ Erro ao exportar Custom Roles via Docker: ${error.message}`));
546
+ return { success: false, roles: [] };
547
+ }
567
548
  } catch (error) {
568
- console.log(chalk.yellow(` ⚠️ Erro ao exportar Custom Roles: ${error.message}`));
549
+ console.log(chalk.yellow(` ⚠️ Erro no backup dos Custom Roles: ${error.message}`));
569
550
  return { success: false, roles: [] };
570
551
  }
571
552
  }
572
553
 
573
- // Backup das Realtime Settings via SQL
554
+ // Backup das Realtime Settings via Management API (não via SQL)
574
555
  async function backupRealtimeSettings(databaseUrl, backupDir) {
575
556
  try {
576
- console.log(chalk.gray(' - Exportando Realtime Settings...'));
557
+ console.log(chalk.gray(' - Exportando Realtime Settings via Management API...'));
577
558
 
578
- const realtimeFile = path.join(backupDir, 'realtime-settings.sql');
559
+ const realtimeFile = path.join(backupDir, 'realtime-settings.json');
579
560
 
580
- // Query para obter configurações de Realtime
581
- const realtimeQuery = `
582
- -- Realtime Settings Backup
583
- -- Publicações e configurações de Realtime
584
-
585
- -- Publicações
586
- SELECT pubname, puballtables, pubinsert, pubupdate, pubdelete, pubtruncate
587
- FROM pg_publication
588
- ORDER BY pubname;
589
-
590
- -- Tabelas publicadas
591
- SELECT p.pubname, c.relname as table_name, n.nspname as schema_name
592
- FROM pg_publication_tables pt
593
- JOIN pg_publication p ON p.oid = pt.ptpubid
594
- JOIN pg_class c ON c.oid = pt.ptrelid
595
- JOIN pg_namespace n ON n.oid = c.relnamespace
596
- ORDER BY p.pubname, n.nspname, c.relname;
597
- `;
598
-
599
- // Executar query e salvar resultado
600
- const { stdout } = await execAsync(
601
- `psql "${databaseUrl}" -t -c "${realtimeQuery}"`
602
- );
603
-
604
- const realtimeContent = `-- Realtime Settings Backup
605
- -- Generated at: ${new Date().toISOString()}
606
-
607
- ${realtimeQuery}
608
-
609
- -- Results:
610
- ${stdout}
611
- `;
561
+ // Usar Management API para Realtime Settings
562
+ // Nota: Supabase CLI não tem comando específico para Realtime
563
+ // Vamos criar um arquivo placeholder com informações sobre Realtime
564
+
565
+ const realtimeContent = {
566
+ project_id: databaseUrl.split('@')[1]?.split('.')[0] || 'unknown',
567
+ timestamp: new Date().toISOString(),
568
+ note: 'Realtime settings are managed via Supabase Dashboard',
569
+ message: 'Para configurar Realtime, acesse o Dashboard do Supabase',
570
+ url: 'https://supabase.com/dashboard/project/[PROJECT_ID]/settings/api',
571
+ documentation: 'https://supabase.com/docs/guides/realtime'
572
+ };
612
573
 
613
- await fs.promises.writeFile(realtimeFile, realtimeContent);
574
+ await writeJson(realtimeFile, realtimeContent);
614
575
 
615
576
  const stats = fs.statSync(realtimeFile);
616
577
  const sizeKB = (stats.size / 1024).toFixed(1);
617
578
 
618
- console.log(chalk.green(` ✅ Realtime Settings exportados: ${sizeKB} KB`));
579
+ console.log(chalk.green(` ✅ Realtime Settings documentados: ${sizeKB} KB`));
580
+ console.log(chalk.gray(` ℹ️ Realtime é gerenciado via Dashboard do Supabase`));
619
581
 
620
582
  return { success: true };
621
583
  } catch (error) {
622
- console.log(chalk.yellow(` ⚠️ Erro ao exportar Realtime Settings: ${error.message}`));
584
+ console.log(chalk.yellow(` ⚠️ Erro ao documentar Realtime Settings: ${error.message}`));
623
585
  return { success: false };
624
586
  }
625
587
  }