smoonb 0.0.102 → 1.0.0

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.

Potentially problematic release.


This version of smoonb might be problematic. Click here for more details.

package/CHANGELOG.md ADDED
@@ -0,0 +1,30 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
+
7
+ ## [1.0.0] - 2025-01-29
8
+
9
+ ### Added
10
+
11
+ - Commercial release. Use requires an active license and valid subscription (or trial). See https://www.smoonb.com/#price
12
+ - License validation (step 00) at the start of backup and restore; CLI aborts if validation fails
13
+ - Restore disclaimer before execution: expected errors during DB restore, link to Supabase docs, wait for completion and test result
14
+ - Environment variables: `SMOONB_LICENSE_KEY` (required), `SMOONB_TELEMETRY_ENABLED` (optional), `SUPABASE_POSTGRES_MAJOR` (required for backup and restore)
15
+ - i18n (en, pt-BR) for all user-facing messages and help
16
+
17
+ ### Changed
18
+
19
+ - Backup flow: terms → license validation → Docker → consent → variable mapping (license not in wizard) → component selection → summary → execution
20
+ - Restore flow: terms → license validation → Docker → consent → mapping (includes `SUPABASE_POSTGRES_MAJOR`) → backup selection → component selection → summary → disclaimer → execution
21
+ - Help and README aligned with commercial product; legal disclaimers unchanged
22
+ - Documentation and links point to https://www.smoonb.com (terms, privacy, #price, #faq)
23
+
24
+ ### Fixed
25
+
26
+ - `instructions` used before definition in interactive env mapper; blocks moved after `getVariableInstructions()`
27
+
28
+ ---
29
+
30
+ [1.0.0]: https://github.com/almmello/smoonb/releases/tag/v1.0.0
package/LICENSE.md CHANGED
@@ -1,64 +1,33 @@
1
- # Licença Comercial smoonb
1
+ # Licença smoonb
2
2
 
3
- ## Versão Experimental Gratuita (Versões 0.x.x)
3
+ ## Uso comercial em vigor
4
4
 
5
- **IMPORTANTE**: Durante a versão experimental, todas as versões 0.x.x do smoonb são **COMPLETAMENTE GRATUITAS** para qualquer uso, incluindo uso comercial.
5
+ O smoonb é um **produto comercial**. Para usar o smoonb é necessário:
6
6
 
7
- ### Termos da Versão Experimental
7
+ - **Licença ativa** (gerada no app desktop em [smoonb.com](https://smoonb.com))
8
+ - **Assinatura válida** ou estar em **período de trial**
8
9
 
9
- - **Uso gratuito**: Pode usar em projetos pessoais e comerciais
10
- - ✅ **Sem restrições**: Sem limitações de funcionalidades
11
- - ❌ **SEM SUPORTE**: Não oferecemos suporte técnico neste estágio
12
- - ⚠️ **USE POR SUA CONTA E RISCO**: Software nunca testado em produção
13
- - ⚠️ **NÃO NOS RESPONSABILIZAMOS**: Por qualquer perda de dados
14
- - ✅ **Transparência total**: Mudanças de licença serão anunciadas com antecedência
10
+ [smoonb.com/#price](https://www.smoonb.com/#price). O uso é regido pelos [Termos de Serviço](https://www.smoonb.com/terms) e pela [Política de Privacidade](https://www.smoonb.com/privacy).
15
11
 
16
- ## Licença Comercial (Versões 1.0.0+)
12
+ ### Código (MIT)
17
13
 
18
- **AVISO**: A partir da versão 1.0.0, o smoonb será licenciado comercialmente.
14
+ O código-fonte é disponibilizado sob licença MIT (ver LICENSE). Isso não substitui a necessidade de licença e assinatura para uso operacional do CLI, conforme Termos de Serviço.
19
15
 
20
- ### Termos da Licença Comercial
16
+ [smoonb.com/#price](https://www.smoonb.com/#price).
21
17
 
22
- Copyright (c) 2024 Goalmoon Tecnologia LTDA. Todos os direitos reservados.
18
+ ## Disclaimer (avisos legais)
23
19
 
24
- **Proibido sem licença válida:**
25
- - Uso em produção
26
- - Distribuição ou redistribuição
27
- - Modificação do código-fonte
28
- - Engenharia reversa
20
+ Este software é fornecido "como está" ("AS IS"), sem garantias de qualquer tipo, expressas ou implícitas. O uso é por sua própria conta e risco.
29
21
 
30
- ### Licenças Disponíveis (a partir da v1.0.0)
22
+ **Limitação de responsabilidade**: Não nos responsabilizamos por qualquer perda de dados, danos diretos ou indiretos, interrupção de negócios ou prejuízos decorrentes do uso ou da incapacidade de uso do smoonb, ou das operações de backup/restore por ele realizadas. Os avisos legais completos constam nos [Termos de Serviço](https://www.smoonb.com/terms).
31
23
 
32
- 1. **Licença Individual**: Uso pessoal e projetos pequenos
33
- 2. **Licença Empresarial**: Uso corporativo e equipes
34
- 3. **Licença OEM**: Integração em produtos comerciais
24
+ ## Empresa desenvolvedora
35
25
 
36
- ### Política de Transição
37
-
38
- - **Aviso prévio**: Mudanças serão anunciadas 90 dias antes
39
- - **Migração suave**: Usuários beta terão desconto especial
40
- - **Transparência**: Todos os termos serão claramente comunicados
41
-
42
- ## Disclaimer
43
-
44
- Este software é fornecido "como está", sem garantias de qualquer tipo, expressas ou implícitas. O uso é por sua própria conta e risco.
45
-
46
- **IMPORTANTE**: Este software está em desenvolvimento inicial e NUNCA foi testado em produção. Os resultados podem ser imprevisíveis e podem causar perdas irreparáveis de dados. Não nos responsabilizamos por qualquer perda de dados ou danos causados pelo uso deste software.
47
-
48
- ## Empresa Desenvolvedora
49
-
50
- **smoonb** é desenvolvido pela **Goalmoon Tecnologia LTDA**
51
- - Website: https://goalmoon.com
52
- - Empresa brasileira especializada em soluções tecnológicas
26
+ **smoonb** é desenvolvido pela **Goalmoon Tecnologia LTDA**
27
+ Website: [smoonb.com](https://smoonb.com)
53
28
 
54
29
  ## Contato
55
30
 
56
- Para questões sobre licenciamento comercial:
57
- - Email: suporte@goalmoon.com
58
- - GitHub Issues: Para contribuições e bugs (sem suporte técnico)
59
- - Empresa: https://goalmoon.com
60
-
61
- ---
62
-
63
- **Última atualização**: Dezembro 2024
64
- **Próxima revisão**: Antes da versão 1.0.0
31
+ - [smoonb.com/#price](https://www.smoonb.com/#price)
32
+ - Termos: [www.smoonb.com/terms](https://www.smoonb.com/terms)
33
+ - Privacidade: [www.smoonb.com/privacy](https://www.smoonb.com/privacy)
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Backup and restore: complete and simple, as it should be
6
6
 
7
- > **Note on commercial access:** Supa Moonbase will require account validation before executing operations (login + subscription verification) in a future phase. In this version, there is no authentication implemented — this README only presents the legal/commercial basis. Operational use will be governed by the [Terms of Service](https://smoonb.com/terms) and [Privacy Policy](https://smoonb.com/privacy).
7
+ > **Commercial product.** You need an **active license** and a **valid subscription** (or be on a trial period) to use smoonb. [smoonb.com/#price](https://www.smoonb.com/#price). Use is governed by the [Terms of Service](https://www.smoonb.com/terms) and [Privacy Policy](https://www.smoonb.com/privacy). We do not assume any liability for damage caused by smoonb; the legal disclaimers below remain in effect.
8
8
 
9
9
  **Read this in other languages:** [Português (Brasil)](README.pt-BR.md)
10
10
 
@@ -101,6 +101,13 @@ You need to obtain a Supabase personal access token to use the Management API:
101
101
  3. Copy the token (format: `sbp_...`)
102
102
  4. Add to `.env.local` as `SUPABASE_ACCESS_TOKEN`
103
103
 
104
+ ### 4. License Key (REQUIRED for backup and restore)
105
+ **smoonb** requires a valid license to run backup and restore:
106
+
107
+ 1. Get your license from the desktop app at https://www.smoonb.com
108
+ 2. Set in environment or `.env.local`: `SMOONB_LICENSE_KEY=[your-license-key]`
109
+ 3. License is validated at the start of each run (step 00); no caching. If validation fails (network/server), the CLI aborts. The license is **not** shown in the interactive variable-mapping wizard (it is already validated before that).
110
+
104
111
  ## ⚙️ Configuration
105
112
 
106
113
  ### Modern Method: `.env.local` (RECOMMENDED)
@@ -117,6 +124,9 @@ touch .env.local
117
124
  #### 2. Add required environment variables
118
125
 
119
126
  ```env
127
+ # License (REQUIRED – from https://www.smoonb.com desktop app)
128
+ SMOONB_LICENSE_KEY=[your-license-key]
129
+
120
130
  # Supabase URLs and Keys
121
131
  NEXT_PUBLIC_SUPABASE_URL=[your-supabase-url]
122
132
  NEXT_PUBLIC_SUPABASE_ANON_KEY=[your-anon-key]
@@ -131,9 +141,11 @@ SUPABASE_PROJECT_ID=[your-project-id]
131
141
  # Personal Access Token (REQUIRED for Management API)
132
142
  SUPABASE_ACCESS_TOKEN=[your-access-token]
133
143
 
134
- # Postgres major version (REQUIRED for backup). Check in Dashboard: Project Settings -> Infrastructure -> Service Versions (Postgres line).
144
+ # Postgres major version (REQUIRED for backup and restore). Check in Dashboard: Project Settings -> Infrastructure -> Service Versions (Postgres line).
135
145
  SUPABASE_POSTGRES_MAJOR=17
136
146
 
147
+ # Optional
148
+ SMOONB_TELEMETRY_ENABLED=true
137
149
  # Backup Directory (optional, default: ./backups)
138
150
  SMOONB_OUTPUT_DIR=./backups
139
151
  ```
@@ -246,19 +258,21 @@ npx smoonb backup
246
258
 
247
259
  **Interactive backup flow:**
248
260
 
249
- 1. **Docker Validation** - Verifies if Docker is running
250
- 2. **Consent** - Asks permission to read/write `.env.local`
251
- 3. **Variable Mapping** - Maps your environment variables (first time)
252
- 4. **.env.local Backup** - Creates automatic backup before changes
253
- 5. **Component Selection** - Asks which components to include:
261
+ 1. **Terms of use** - Displays and requests acceptance of terms
262
+ 2. **License validation** - Validates `SMOONB_LICENSE_KEY` (env or prompt); no cache; aborts if validation fails
263
+ 3. **Docker validation** - Verifies if Docker is running
264
+ 4. **Consent** - Asks permission to read/write `.env.local`
265
+ 5. **Variable mapping** - Maps your environment variables (first time; license is not in the wizard—already validated)
266
+ 6. **.env.local backup** - Creates automatic backup before changes
267
+ 7. **Component selection** - Asks which components to include:
254
268
  - ⚡ Edge Functions (explanation about link reset and download)
255
269
  - 📦 Storage (explanation about full backup: file download + ZIP in Dashboard format)
256
270
  - 🔐 Auth Settings (explanation about configurations)
257
271
  - 🔄 Realtime Settings (explanation about interactive capture of 7 parameters)
258
272
  - 🗑️ Cleanup options (functions, .temp, migrations after backup)
259
- 6. **Configuration Summary** - Shows everything that will be done
260
- 7. **Final Confirmation** - Confirms before starting
261
- 8. **Step Execution:**
273
+ 8. **Configuration summary** - Shows everything that will be done
274
+ 9. **Final confirmation** - Confirms before starting
275
+ 10. **Step execution:**
262
276
  - 📊 1/10 - Database Backup via `pg_dumpall` (Docker)
263
277
  - 📊 2/10 - Separate Database SQL (schema, data, roles)
264
278
  - 🔧 3/10 - Database Extensions and Settings Backup
@@ -314,24 +328,26 @@ npx smoonb restore --file "backup.backup.gz" --storage "my-project.storage.zip"
314
328
 
315
329
  **Interactive restore flow:**
316
330
 
317
- 1. **Docker Validation** - Verifies if Docker is running
318
- 2. **Terms of Use** - Displays and requests acceptance of terms
319
- 3. **Consent** - Asks permission to read/write `.env.local`
320
- 4. **Variable Mapping** - Maps variables to target project
321
- 5. **.env.local Backup** - Creates automatic backup
322
- 6. **Backup Selection** - Lists and allows choosing which backup to restore (skips if `--file` provided)
331
+ 1. **Terms of use** - Displays and requests acceptance of terms
332
+ 2. **License validation** - Validates `SMOONB_LICENSE_KEY` (env or prompt); aborts if validation fails
333
+ 3. **Docker validation** - Verifies if Docker is running
334
+ 4. **Consent** - Asks permission to read/write `.env.local`
335
+ 5. **Variable mapping** - Maps variables to target project (includes `SUPABASE_POSTGRES_MAJOR`)
336
+ 6. **.env.local backup** - Creates automatic backup
337
+ 7. **Backup selection** - Lists and allows choosing which backup to restore (skips if `--file` provided)
323
338
  - If `--file` is provided: automatically imports and auto-selects the backup
324
339
  - If `--storage` is provided along with `--file`: also imports the storage file
325
- 7. **Component Selection** - Asks which components to restore:
340
+ 8. **Component selection** - Asks which components to restore:
326
341
  - 📊 Database (always available)
327
342
  - ⚡ Edge Functions (if available in backup)
328
343
  - 🔐 Auth Settings (if available in backup)
329
344
  - 📦 Storage (if available in backup)
330
345
  - 🔧 Database Extensions and Settings (if available in backup)
331
346
  - 🔄 Realtime Settings (if available in backup)
332
- 8. **Detailed Summary** - Shows selected backup, target project and components
333
- 9. **Final Confirmation** - Confirms before starting
334
- 10. **Restore Execution:**
347
+ 9. **Detailed summary** - Shows selected backup, target project and components
348
+ 10. **Final confirmation** - Confirms before starting
349
+ 11. **Disclaimer** - Explains that errors during restore are expected; link to [Supabase Dashboard Restore docs](https://supabase.com/docs/guides/platform/migrating-within-supabase/dashboard-restore); you should wait for the process to finish and then test the result before accepting to proceed
350
+ 12. **Restore execution:**
335
351
  - 📊 Database - Restores via `psql` (supports `.backup.gz` and `.backup`)
336
352
  - ⚡ Edge Functions - Copies and deploys to target project
337
353
  - 🔐 Auth Settings - Displays configurations for manual application
@@ -469,6 +485,7 @@ backup/
469
485
  ├── index.js # Orquestrador principal
470
486
  ├── utils.js # Utilitários específicos
471
487
  └── steps/
488
+ ├── 00-license.js # Validação de licença (SMOONB_LICENSE_KEY)
472
489
  ├── 01-docker-validation.js # Validação Docker
473
490
  ├── 02-database.js # Backup via pg_dumpall
474
491
  ├── 03-database-separated.js # SQL separado
@@ -483,6 +500,7 @@ backup/
483
500
  ```
484
501
 
485
502
  #### Restore (`src/commands/restore/`)
503
+ License validation (same as backup, `00-license.js` from backup steps) runs at start. Then:
486
504
  ```
487
505
  restore/
488
506
  ├── index.js # Orquestrador principal
@@ -685,39 +703,23 @@ If there are problems:
685
703
  - **No Sensitive Data**: No sensitive data is sent outside your environment
686
704
  - **Isolated Docker**: Database operations via Docker (isolation)
687
705
 
688
- ## 💼 Access Model and Subscription
689
-
690
- Supa Moonbase code is provided under MIT license (see `LICENSE`). In a future phase, CLI execution will be linked to a per-account subscription, allowing use associated with a valid account. Account validation will occur before any sensitive operations (e.g., backup and restore).
691
-
692
- Until validation is active, the tool can be used without login.
693
-
694
- Learn more at [Pricing](https://smoonb.com/pricing) and [Commercial FAQ](https://smoonb.com/faq).
706
+ ## 💼 Access and subscription
695
707
 
696
- ## 🎁 Grandfathering (concept)
708
+ Supa Moonbase code is provided under MIT license (see `LICENSE`). To use smoonb you must have an **active license** and a **valid subscription**, or be within a **trial period**. License validation runs at the start of backup and restore; without a valid license and subscription (or trial), the CLI will not run those operations.
697
709
 
698
- Accounts created during the initial commercial availability period may maintain differentiated access conditions while they remain active. The goal is to recognize early users. Specific details will be in the [Terms of Service](https://smoonb.com/terms) and [Pricing](https://smoonb.com/pricing).
710
+ [smoonb.com/#price](https://www.smoonb.com/#price).
699
711
 
700
712
  ## 🔒 Privacy and LGPD (summary)
701
713
 
702
- Supa Moonbase adopts the data minimization principle. When account validation is active, we will only process information strictly necessary for access control and billing (e.g., account identifier and contact). Purposes, legal bases and data subject rights will be described in the [Privacy Policy](https://smoonb.com/privacy).
703
-
704
- ## 📋 Terms of Service and Brand Usage
705
-
706
- The code license (MIT) does not replace the Terms of Service that will govern per-account operational access and subscription validation.
707
-
708
- "Supa Moonbase" and visual identity elements are trademarks of Goalmoon Tecnologia Ltda.; brand and branding assets usage is restricted, as per [Terms of Service](https://smoonb.com/terms).
709
-
710
- ## ❓ Commercial FAQ
711
-
712
- **Why subscription if the code is MIT?**
713
-
714
- > The code remains open for audit and contributions. Operational access will be conditioned to account validation, as per Terms of Service.
714
+ Supa Moonbase adopts the data minimization principle. We process only the information strictly necessary for access control and billing (e.g., account identifier and contact). Purposes, legal bases and data subject rights are described in the [Privacy Policy](https://www.smoonb.com/privacy).
715
715
 
716
- **What does grandfathering mean?**
716
+ ## 📋 Terms of Service and brand usage
717
717
 
718
- > Accounts from the initial period may maintain differentiated conditions while active; details will be in the Terms.
718
+ The code license (MIT) does not replace the [Terms of Service](https://www.smoonb.com/terms) that govern operational access and subscription validation.
719
719
 
720
+ "Supa Moonbase" and visual identity elements are trademarks of Goalmoon Tecnologia Ltda.; use of brand and branding assets is restricted as per [Terms of Service](https://www.smoonb.com/terms).
720
721
 
722
+ [FAQ](https://www.smoonb.com/#faq).
721
723
 
722
724
  ## 📝 License
723
725
 
@@ -725,7 +727,7 @@ Supa Moonbase code is provided under MIT license. See [LICENSE](LICENSE) for the
725
727
 
726
728
  ## 🤝 Contributing
727
729
 
728
- Contributions are welcome! This is an experimental project and we need community feedback.
730
+ Contributions are welcome. [smoonb.com/#price](https://www.smoonb.com/#price).
729
731
 
730
732
 
731
733
  ---
package/README.pt-BR.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Backup e restauração: completo e simples, como deveria ser
6
6
 
7
- > **Nota sobre acesso comercial:** o Supa Moonbase passará a exigir validação de conta antes de executar operações (login + verificação de assinatura) em fase futura. Nesta versão, não há autenticação implementada — este README apenas apresenta a base legal/comercial. O uso operacional será regido pelos [Termos de Serviço](https://smoonb.com/terms) e pela [Política de Privacidade](https://smoonb.com/privacy).
7
+ > **Produto comercial.** É necessário ter **licença ativa** e **assinatura válida** (ou estar em período de trial) para usar o smoonb. [smoonb.com/#price](https://www.smoonb.com/#price). O uso é regido pelos [Termos de Serviço](https://www.smoonb.com/terms) e pela [Política de Privacidade](https://www.smoonb.com/privacy). Não assumimos responsabilidade por danos causados pelo smoonb; os avisos legais abaixo permanecem válidos.
8
8
 
9
9
  **Leia em outro idioma:** [English](README.md)
10
10
 
@@ -101,6 +101,13 @@ Recomendamos **Supabase CLI v2.72 ou mais recente** para novos recursos e corre
101
101
  3. Copie o token (formato: `sbp_...`)
102
102
  4. Adicione ao `.env.local` como `SUPABASE_ACCESS_TOKEN`
103
103
 
104
+ ### 4. Chave de licença (OBRIGATÓRIA para backup e restore)
105
+ O **smoonb** exige uma licença válida para executar backup e restore:
106
+
107
+ 1. Obtenha sua licença no app desktop em https://www.smoonb.com
108
+ 2. Defina no ambiente ou no `.env.local`: `SMOONB_LICENSE_KEY=[sua-chave-de-licença]`
109
+ 3. A licença é validada no início de cada execução (step 00); não há cache. Se a validação falhar (rede/servidor), o CLI aborta. A licença **não** aparece no wizard de mapeamento de variáveis (já foi validada antes).
110
+
104
111
  ## ⚙️ Configuração
105
112
 
106
113
  ### Método Moderno: `.env.local` (RECOMENDADO)
@@ -117,6 +124,9 @@ touch .env.local
117
124
  #### 2. Adicionar as variáveis de ambiente necessárias
118
125
 
119
126
  ```env
127
+ # Licença (OBRIGATÓRIA – do app desktop em https://www.smoonb.com)
128
+ SMOONB_LICENSE_KEY=[sua-chave-de-licença]
129
+
120
130
  # URLs e Chaves do Supabase
121
131
  NEXT_PUBLIC_SUPABASE_URL=[sua-supabase-url]
122
132
  NEXT_PUBLIC_SUPABASE_ANON_KEY=[sua-anon-key]
@@ -131,9 +141,11 @@ SUPABASE_PROJECT_ID=[seu-project-id]
131
141
  # Personal Access Token (OBRIGATÓRIO para Management API)
132
142
  SUPABASE_ACCESS_TOKEN=[seu-access-token]
133
143
 
134
- # Versão major do Postgres (OBRIGATÓRIO para backup). Conferir no Dashboard: Project Settings -> Infrastructure -> Service Versions (linha Postgres).
144
+ # Versão major do Postgres (OBRIGATÓRIA para backup e restore). Conferir no Dashboard: Project Settings -> Infrastructure -> Service Versions (linha do Postgres).
135
145
  SUPABASE_POSTGRES_MAJOR=17
136
146
 
147
+ # Opcional
148
+ SMOONB_TELEMETRY_ENABLED=true
137
149
  # Diretório de Backups (opcional, padrão: ./backups)
138
150
  SMOONB_OUTPUT_DIR=./backups
139
151
  ```
@@ -246,19 +258,21 @@ npx smoonb backup
246
258
 
247
259
  **Fluxo interativo do backup:**
248
260
 
249
- 1. **Validação Docker** - Verifica se o Docker está rodando
250
- 2. **Consentimento** - Pede permissão para ler/escrever `.env.local`
251
- 3. **Mapeamento de Variáveis** - Mapeia suas variáveis de ambiente (primeira vez)
252
- 4. **Backup do .env.local** - Cria backup automático antes de alterações
253
- 5. **Seleção de Componentes** - Pergunta quais componentes incluir:
261
+ 1. **Termo de uso** - Exibe e solicita aceitação dos termos
262
+ 2. **Validação de licença** - Valida `SMOONB_LICENSE_KEY` (env ou prompt); sem cache; aborta se a validação falhar
263
+ 3. **Validação Docker** - Verifica se o Docker está rodando
264
+ 4. **Consentimento** - Pede permissão para ler/escrever `.env.local`
265
+ 5. **Mapeamento de variáveis** - Mapeia suas variáveis de ambiente (primeira vez; a licença não entra no wizard—já validada)
266
+ 6. **Backup do .env.local** - Cria backup automático antes de alterações
267
+ 7. **Seleção de componentes** - Pergunta quais componentes incluir:
254
268
  - ⚡ Edge Functions (explicação sobre reset de link e download)
255
269
  - 📦 Storage (explicação sobre backup completo: download de arquivos + ZIP no padrão do Dashboard)
256
270
  - 🔐 Auth Settings (explicação sobre configurações)
257
271
  - 🔄 Realtime Settings (explicação sobre captura interativa de 7 parâmetros)
258
272
  - 🗑️ Opções de limpeza (functions, .temp, migrations após backup)
259
- 6. **Resumo de Configurações** - Mostra tudo que será feito
260
- 7. **Confirmação Final** - Confirma antes de iniciar
261
- 8. **Execução das Etapas:**
273
+ 8. **Resumo de configurações** - Mostra tudo que será feito
274
+ 9. **Confirmação final** - Confirma antes de iniciar
275
+ 10. **Execução das etapas:**
262
276
  - 📊 1/10 - Backup Database via `pg_dumpall` (Docker)
263
277
  - 📊 2/10 - Backup Database SQL separado (schema, dados, roles)
264
278
  - 🔧 3/10 - Backup Database Extensions and Settings
@@ -314,24 +328,26 @@ npx smoonb restore --file "backup.backup.gz" --storage "meu-projeto.storage.zip"
314
328
 
315
329
  **Fluxo interativo do restore:**
316
330
 
317
- 1. **Validação Docker** - Verifica se o Docker está rodando
318
- 2. **Termo de Uso** - Exibe e solicita aceitação dos termos
319
- 3. **Consentimento** - Pede permissão para ler/escrever `.env.local`
320
- 4. **Mapeamento de Variáveis** - Mapeia variáveis para o projeto de destino
321
- 5. **Backup do .env.local** - Cria backup automático
322
- 6. **Seleção de Backup** - Lista e permite escolher qual backup restaurar (pula se `--file` fornecido)
331
+ 1. **Termo de uso** - Exibe e solicita aceitação dos termos
332
+ 2. **Validação de licença** - Valida `SMOONB_LICENSE_KEY` (env ou prompt); aborta se a validação falhar
333
+ 3. **Validação Docker** - Verifica se o Docker está rodando
334
+ 4. **Consentimento** - Pede permissão para ler/escrever `.env.local`
335
+ 5. **Mapeamento de variáveis** - Mapeia variáveis para o projeto de destino (inclui `SUPABASE_POSTGRES_MAJOR`)
336
+ 6. **Backup do .env.local** - Cria backup automático
337
+ 7. **Seleção de backup** - Lista e permite escolher qual backup restaurar (pula se `--file` fornecido)
323
338
  - Se `--file` for fornecido: importa automaticamente e auto-seleciona o backup
324
339
  - Se `--storage` for fornecido junto com `--file`: importa também o arquivo de storage
325
- 7. **Seleção de Componentes** - Pergunta quais componentes restaurar:
340
+ 8. **Seleção de componentes** - Pergunta quais componentes restaurar:
326
341
  - 📊 Database (sempre disponível)
327
342
  - ⚡ Edge Functions (se disponível no backup)
328
343
  - 🔐 Auth Settings (se disponível no backup)
329
344
  - 📦 Storage (se disponível no backup)
330
345
  - 🔧 Database Extensions and Settings (se disponível no backup)
331
346
  - 🔄 Realtime Settings (se disponível no backup)
332
- 8. **Resumo Detalhado** - Mostra backup selecionado, projeto destino e componentes
333
- 9. **Confirmação Final** - Confirma antes de iniciar
334
- 10. **Execução da Restauração:**
347
+ 9. **Resumo detalhado** - Mostra backup selecionado, projeto destino e componentes
348
+ 10. **Confirmação final** - Confirma antes de iniciar
349
+ 11. **Aviso** - Explica que erros durante a restauração são esperados; link para [documentação de restore do Dashboard Supabase](https://supabase.com/docs/guides/platform/migrating-within-supabase/dashboard-restore); aguardar o fim do processo e testar o resultado antes de aceitar para prosseguir
350
+ 12. **Execução da restauração:**
335
351
  - 📊 Database - Restaura via `psql` (suporta `.backup.gz` e `.backup`)
336
352
  - ⚡ Edge Functions - Copia e faz deploy no projeto destino
337
353
  - 🔐 Auth Settings - Exibe configurações para aplicação manual
@@ -469,6 +485,7 @@ backup/
469
485
  ├── index.js # Orquestrador principal
470
486
  ├── utils.js # Utilitários específicos
471
487
  └── steps/
488
+ ├── 00-license.js # Validação de licença (SMOONB_LICENSE_KEY)
472
489
  ├── 01-docker-validation.js # Validação Docker
473
490
  ├── 02-database.js # Backup via pg_dumpall
474
491
  ├── 03-database-separated.js # SQL separado
@@ -483,6 +500,7 @@ backup/
483
500
  ```
484
501
 
485
502
  #### Restore (`src/commands/restore/`)
503
+ A validação de licença (mesmo step do backup, `00-license.js` em backup/steps) roda no início. Em seguida:
486
504
  ```
487
505
  restore/
488
506
  ├── index.js # Orquestrador principal
@@ -685,39 +703,23 @@ Se houver problemas:
685
703
  - **Sem Dados Sensíveis**: Nenhum dado sensível é enviado para fora do seu ambiente
686
704
  - **Docker Isolado**: Operações de database via Docker (isolamento)
687
705
 
688
- ## 💼 Modelo de Acesso e Assinatura
689
-
690
- O código do Supa Moonbase é disponibilizado sob licença MIT (ver `LICENSE`). Em fase futura, a execução do CLI será vinculada a uma assinatura por conta, permitindo uso associado a uma conta válida. A validação de conta ocorrerá antes de qualquer operação sensível (ex.: backup e restore).
691
-
692
- Até que a validação esteja ativa, a ferramenta pode ser utilizada sem login.
693
-
694
- Saiba mais em [Pricing](https://smoonb.com/pricing) e [FAQ Comercial](https://smoonb.com/faq).
706
+ ## 💼 Acesso e assinatura
695
707
 
696
- ## 🎁 Grandfathering (conceito)
708
+ O código do Supa Moonbase é disponibilizado sob licença MIT (ver `LICENSE`). Para usar o smoonb é obrigatório ter **licença ativa** e **assinatura válida**, ou estar em **período de trial**. A validação da licença ocorre no início do backup e do restore; sem licença e assinatura válidas (ou trial), o CLI não executa essas operações.
697
709
 
698
- Contas criadas durante o período inicial de disponibilização comercial poderão manter condições de acesso diferenciadas enquanto permanecerem ativas. O objetivo é reconhecer os primeiros usuários. Detalhes específicos constarão nos [Termos de Serviço](https://smoonb.com/terms) e no [Pricing](https://smoonb.com/pricing).
710
+ [smoonb.com/#price](https://www.smoonb.com/#price).
699
711
 
700
712
  ## 🔒 Privacidade e LGPD (resumo)
701
713
 
702
- O Supa Moonbase adota o princípio de minimização de dados. Quando a validação de conta estiver ativa, trataremos apenas informações estritamente necessárias para controle de acesso e faturamento (por exemplo, identificador de conta e contato). Os propósitos, bases legais e direitos do titular serão descritos na [Política de Privacidade](https://smoonb.com/privacy).
703
-
704
- ## 📋 Termos de Serviço e Uso de Marca
705
-
706
- A licença de código (MIT) não substitui os Termos de Serviço que regerão o acesso operacional por conta e a validação de assinatura.
707
-
708
- "Supa Moonbase" e elementos de identidade visual são marcas da Goalmoon Tecnologia Ltda.; o uso de marca e assets de branding é restrito, conforme os [Termos de Serviço](https://smoonb.com/terms).
709
-
710
- ## ❓ FAQ Comercial
711
-
712
- **Por que assinatura se o código é MIT?**
713
-
714
- > O código permanece aberto para auditoria e contribuições. O acesso operacional será condicionado à validação de conta, conforme Termos de Serviço.
714
+ O Supa Moonbase adota o princípio de minimização de dados. Tratamos apenas as informações estritamente necessárias para controle de acesso e faturamento (por exemplo, identificador de conta e contato). Os propósitos, bases legais e direitos do titular estão descritos na [Política de Privacidade](https://www.smoonb.com/privacy).
715
715
 
716
- **O que significa grandfathering?**
716
+ ## 📋 Termos de Serviço e uso de marca
717
717
 
718
- > Contas do período inicial poderão manter condições diferenciadas enquanto ativas; detalhes estarão nos Termos.
718
+ A licença de código (MIT) não substitui os [Termos de Serviço](https://www.smoonb.com/terms) que regem o acesso operacional e a validação de assinatura.
719
719
 
720
+ "Supa Moonbase" e elementos de identidade visual são marcas da Goalmoon Tecnologia Ltda.; o uso de marca e assets de branding é restrito, conforme os [Termos de Serviço](https://www.smoonb.com/terms).
720
721
 
722
+ [FAQ](https://www.smoonb.com/#faq).
721
723
 
722
724
  ## 📝 Licença
723
725
 
@@ -725,7 +727,7 @@ O código do Supa Moonbase é disponibilizado sob licença MIT. Veja [LICENSE](L
725
727
 
726
728
  ## 🤝 Contribuição
727
729
 
728
- Contribuições são bem-vindas! Este é um projeto experimental e precisamos de feedback da comunidade.
730
+ Contribuições são bem-vindas. [smoonb.com/#price](https://www.smoonb.com/#price).
729
731
 
730
732
 
731
733
  ---
package/bin/smoonb.js CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  /**
4
4
  * smoonb - Complete Supabase backup and migration tool
5
- *
6
- * CLI principal para backup e migração de projetos Supabase
7
- * EXPERIMENTAL VERSION - USE AT YOUR OWN RISK
8
- *
5
+ *
6
+ * CLI principal para backup e migração de projetos Supabase.
7
+ * Produto comercial: licença ativa e assinatura válida (ou trial) necessárias. https://www.smoonb.com/#price
8
+ *
9
9
  * Desenvolvido por: Goalmoon Tecnologia LTDA
10
- * Website: https://goalmoon.com
10
+ * Website: https://smoonb.com
11
11
  */
12
12
 
13
13
  const { Command } = require('commander');
@@ -52,31 +52,31 @@ program
52
52
 
53
53
  ${chalk.yellow.bold(getT('help.backupTitle'))}
54
54
  ${chalk.white(getT('help.backupExample1'))}
55
- ${chalk.gray(getT('help.backupExample1Desc'))}
55
+ ${chalk.white(getT('help.backupExample1Desc'))}
56
56
 
57
57
  ${chalk.white(getT('help.backupExample2'))}
58
- ${chalk.gray(getT('help.backupExample2Desc'))}
58
+ ${chalk.white(getT('help.backupExample2Desc'))}
59
59
 
60
60
  ${chalk.yellow.bold(getT('help.restoreTitle'))}
61
61
  ${chalk.white(getT('help.restoreExample1'))}
62
- ${chalk.gray(getT('help.restoreExample1Desc'))}
62
+ ${chalk.white(getT('help.restoreExample1Desc'))}
63
63
 
64
64
  ${chalk.white(getT('help.restoreExample2'))}
65
- ${chalk.gray(getT('help.restoreExample2Desc'))}
65
+ ${chalk.white(getT('help.restoreExample2Desc'))}
66
66
 
67
67
  ${chalk.white(getT('help.restoreExample3'))}
68
- ${chalk.gray(getT('help.restoreExample3Desc'))}
68
+ ${chalk.white(getT('help.restoreExample3Desc'))}
69
69
 
70
70
  ${chalk.yellow.bold(getT('help.importTitle'))}
71
71
  ${chalk.white(getT('help.importExample1'))}
72
- ${chalk.gray(getT('help.importExample1Desc'))}
72
+ ${chalk.white(getT('help.importExample1Desc'))}
73
73
 
74
74
  ${chalk.white(getT('help.importExample2'))}
75
- ${chalk.gray(getT('help.importExample2Desc'))}
75
+ ${chalk.white(getT('help.importExample2Desc'))}
76
76
 
77
77
  ${chalk.yellow.bold(getT('help.checkTitle'))}
78
78
  ${chalk.white(getT('help.checkExample1'))}
79
- ${chalk.gray(getT('help.checkExample1Desc'))}
79
+ ${chalk.white(getT('help.checkExample1Desc'))}
80
80
 
81
81
  ${chalk.yellow.bold(getT('help.tipsTitle'))}
82
82
  ${chalk.white(getT('help.tip1'))}
@@ -103,10 +103,20 @@ program
103
103
  return `
104
104
  ${chalk.yellow.bold(getT('help.commands.backupExamples'))}
105
105
  ${chalk.white(getT('help.commands.backupExample1'))}
106
- ${chalk.gray(getT('help.commands.backupExample1Desc'))}
106
+ ${chalk.white(getT('help.commands.backupExample1Desc'))}
107
107
 
108
108
  ${chalk.white(getT('help.commands.backupExample2'))}
109
- ${chalk.gray(getT('help.commands.backupExample2Desc'))}
109
+ ${chalk.white(getT('help.commands.backupExample2Desc'))}
110
+
111
+ ${chalk.yellow.bold(getT('help.commands.backupFlow'))}
112
+ ${getT('help.commands.backupFlow1')}
113
+ ${getT('help.commands.backupFlow2')}
114
+ ${getT('help.commands.backupFlow3')}
115
+ ${getT('help.commands.backupFlow4')}
116
+ ${getT('help.commands.backupFlow5')}
117
+ ${getT('help.commands.backupFlow6')}
118
+ ${getT('help.commands.backupFlow7')}
119
+ ${getT('help.commands.backupFlow8')}
110
120
 
111
121
  ${chalk.yellow.bold(getT('help.commands.backupWhat'))}
112
122
  ${getT('help.commands.backupWhat1')}
@@ -161,6 +171,9 @@ ${chalk.yellow.bold(getT('help.commands.restoreFlow'))}
161
171
  ${getT('help.commands.restoreFlow5')}
162
172
  ${getT('help.commands.restoreFlow6')}
163
173
  ${getT('help.commands.restoreFlow7')}
174
+ ${getT('help.commands.restoreFlow8')}
175
+ ${getT('help.commands.restoreFlow9')}
176
+ ${getT('help.commands.restoreFlow10')}
164
177
 
165
178
  ${chalk.yellow.bold(getT('help.commands.restoreWhenFile'))}
166
179
  ${getT('help.commands.restoreWhenFile1')}
@@ -260,7 +273,7 @@ process.on('unhandledRejection', (reason, _promise) => {
260
273
  process.exit(1);
261
274
  });
262
275
 
263
- // Exibir informações do período beta quando nenhum comando é fornecido
276
+ // Exibir banner quando nenhum comando é fornecido
264
277
  if (process.argv.length === 2) {
265
278
  showBetaBanner();
266
279
  showQuickHelp();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "smoonb",
3
- "version": "0.0.102",
4
- "description": "Complete Supabase backup and migration tool - EXPERIMENTAL VERSION - USE AT YOUR OWN RISK",
3
+ "version": "1.0.0",
4
+ "description": "Complete Supabase backup and migration tool. https://www.smoonb.com/#price",
5
5
  "preferGlobal": false,
6
6
  "preventGlobalInstall": true,
7
7
  "main": "index.js",
@@ -16,7 +16,8 @@
16
16
  "lint": "eslint . --ext .js",
17
17
  "lint:fix": "eslint . --ext .js --fix",
18
18
  "build": "node scripts/build.js",
19
- "build:check": "node scripts/build.js"
19
+ "build:check": "node scripts/build.js",
20
+ "prepublishOnly": "node scripts/build.js"
20
21
  },
21
22
  "keywords": [
22
23
  "supabase",
@@ -28,7 +29,7 @@
28
29
  "cli",
29
30
  "tool"
30
31
  ],
31
- "author": "Goalmoon Tecnologia LTDA <https://goalmoon.com>",
32
+ "author": "Goalmoon Tecnologia LTDA <https://www.smoonb.com>",
32
33
  "license": "SEE LICENSE IN LICENSE.md",
33
34
  "engines": {
34
35
  "node": ">=16.0.0"
@@ -51,13 +52,15 @@
51
52
  "bugs": {
52
53
  "url": "https://github.com/almmello/smoonb/issues"
53
54
  },
54
- "homepage": "https://github.com/almmello/smoonb#readme",
55
+ "homepage": "https://www.smoonb.com",
55
56
  "files": [
56
57
  "bin/",
57
58
  "src/",
58
59
  "README.md",
59
60
  "README.pt-BR.md",
60
61
  "LICENSE",
61
- "LICENSE.pt-BR.md"
62
+ "LICENSE.md",
63
+ "LICENSE.pt-BR.md",
64
+ "CHANGELOG.md"
62
65
  ]
63
66
  }
@@ -1,17 +1,20 @@
1
- const chalk = require('chalk');
2
1
  const path = require('path');
3
2
  const fs = require('fs');
4
3
  const fsPromises = require('fs').promises;
5
4
  const { readEnvFile, writeEnvFile, backupEnvFile } = require('../../utils/env');
6
5
  const { saveEnvMap } = require('../../utils/envMap');
7
- const { mapEnvVariablesInteractively } = require('../../interactive/envMapper');
6
+ const { mapEnvVariablesInteractively, printSupabasePostgresMajorHintOnce } = require('../../interactive/envMapper');
8
7
  const { showBetaBanner } = require('../../utils/banner');
9
8
  const { listValidBackups, showRestoreSummary } = require('./utils');
10
9
  const { confirm } = require('../../utils/prompt');
11
10
  const { ensureDir } = require('../../utils/fsx');
11
+ const ui = require('../../utils/cliUi');
12
+ const { isPostgresMajorSupported } = require('../backup/utils');
12
13
  const step00License = require('../backup/steps/00-license');
13
14
  const step01DockerValidation = require('../backup/steps/01-docker-validation');
14
15
 
16
+ const SUPABASE_RESTORE_DOC_URL = 'https://supabase.com/docs/guides/platform/migrating-within-supabase/dashboard-restore';
17
+
15
18
  // Importar todas as etapas
16
19
  const step00BackupSelection = require('./steps/00-backup-selection');
17
20
  const step01ComponentsSelection = require('./steps/01-components-selection');
@@ -73,7 +76,7 @@ async function importBackupFile(sourceFile, sourceStorageFile, outputDir) {
73
76
 
74
77
  // Criar diretório de backup
75
78
  await ensureDir(backupDir);
76
- console.log(chalk.blue(`📁 ${getT('restore.import.importing', { name: backupDirName })}`));
79
+ ui.step(`📁 ${getT('restore.import.importing', { name: backupDirName })}`);
77
80
 
78
81
  // Copiar arquivo de backup para o diretório de backup
79
82
  const destFile = path.join(backupDir, fileName);
@@ -83,7 +86,7 @@ async function importBackupFile(sourceFile, sourceStorageFile, outputDir) {
83
86
  const stats = await fsPromises.stat(destFile);
84
87
  const sizeMB = (stats.size / (1024 * 1024)).toFixed(2);
85
88
 
86
- console.log(chalk.green(`✅ ${getT('restore.import.backupImported', { fileName, size: sizeMB })}`));
89
+ ui.success(`✅ ${getT('restore.import.backupImported', { fileName, size: sizeMB })}`);
87
90
 
88
91
  // Copiar arquivo de storage se fornecido
89
92
  if (sourceStorageFile) {
@@ -94,7 +97,7 @@ async function importBackupFile(sourceFile, sourceStorageFile, outputDir) {
94
97
  const storageStats = await fsPromises.stat(destStorageFile);
95
98
  const storageSizeMB = (storageStats.size / (1024 * 1024)).toFixed(2);
96
99
 
97
- console.log(chalk.green(`✅ ${getT('restore.import.storageImported', { fileName: storageFileName, size: storageSizeMB })}`));
100
+ ui.success(`✅ ${getT('restore.import.storageImported', { fileName: storageFileName, size: storageSizeMB })}`);
98
101
  }
99
102
 
100
103
  return backupDir;
@@ -110,13 +113,13 @@ module.exports = async (options) => {
110
113
  const getT = global.smoonbI18n?.t || t;
111
114
 
112
115
  // Termo de uso e aviso de risco
113
- console.log(chalk.yellow.bold(`\n⚠️ ${getT('disclaimer.title')}\n`));
114
- console.log(chalk.white(`${getT('disclaimer.text')}\n`));
115
- console.log(chalk.white(`${getT('disclaimer.limitation')}\n`));
116
-
116
+ ui.warn(`\n⚠️ ${getT('disclaimer.title')}\n`);
117
+ ui.info(`${getT('disclaimer.text')}\n`);
118
+ ui.info(`${getT('disclaimer.limitation')}\n`);
119
+
117
120
  const termsAccepted = await confirm(getT('disclaimer.acceptRestore'), true);
118
121
  if (!termsAccepted) {
119
- console.log(chalk.red(`🚫 ${getT('disclaimer.operationCancelled')}`));
122
+ ui.error(`🚫 ${getT('disclaimer.operationCancelled')}`);
120
123
  process.exit(1);
121
124
  }
122
125
 
@@ -127,12 +130,12 @@ module.exports = async (options) => {
127
130
  await step01DockerValidation();
128
131
 
129
132
  // Consentimento para leitura e escrita do .env.local
130
- console.log(chalk.yellow(`\n⚠️ ${getT('consent.title')}`));
131
- console.log(chalk.yellow(` ${getT('consent.backup')}`));
132
- console.log(chalk.yellow(` ${getT('consent.mapping')}`));
133
+ ui.warn(`\n⚠️ ${getT('consent.title')}`);
134
+ ui.warn(` ${getT('consent.backup')}`);
135
+ ui.warn(` ${getT('consent.mapping')}`);
133
136
  const consentOk = await confirm(getT('consent.proceed'), true);
134
137
  if (!consentOk) {
135
- console.log(chalk.red(`🚫 ${getT('disclaimer.operationCancelled')}`));
138
+ ui.error(`🚫 ${getT('disclaimer.operationCancelled')}`);
136
139
  process.exit(1);
137
140
  }
138
141
 
@@ -151,10 +154,9 @@ module.exports = async (options) => {
151
154
  try {
152
155
  await fsPromises.access(envPath);
153
156
  await backupEnvFile(envPath, envBackupPath);
154
- console.log(chalk.blue(`📁 ${getT('restore.import.envBackup', { path: path.relative(process.cwd(), envBackupPath) })}`));
157
+ ui.step(`📁 ${getT('restore.import.envBackup', { path: path.relative(process.cwd(), envBackupPath) })}`);
155
158
  } catch {
156
- // Arquivo não existe, não fazer backup
157
- console.log(chalk.yellow(getT('restore.import.envNotFound')));
159
+ ui.warn(getT('restore.import.envNotFound'));
158
160
  }
159
161
 
160
162
  // Leitura e mapeamento interativo
@@ -166,13 +168,14 @@ module.exports = async (options) => {
166
168
  'SUPABASE_SERVICE_ROLE_KEY',
167
169
  'SUPABASE_DB_URL',
168
170
  'SUPABASE_ACCESS_TOKEN',
171
+ 'SUPABASE_POSTGRES_MAJOR',
169
172
  'SMOONB_OUTPUT_DIR',
170
173
  'SMOONB_TELEMETRY_ENABLED'
171
174
  ];
172
175
  const { finalEnv, dePara } = await mapEnvVariablesInteractively(currentEnv, expectedKeys);
173
176
  await writeEnvFile(envPath, finalEnv);
174
177
  await saveEnvMap(dePara, path.join(processDir, 'env', 'env-map.json'));
175
- console.log(chalk.green(`✅ ${getT('restore.index.envUpdated')}`));
178
+ ui.success(`✅ ${getT('restore.index.envUpdated')}`);
176
179
 
177
180
  // Resolver valores esperados a partir do de-para
178
181
  function getValue(expectedKey) {
@@ -181,6 +184,22 @@ module.exports = async (options) => {
181
184
  }
182
185
  telemetryEnabled = (getValue('SMOONB_TELEMETRY_ENABLED') || 'true') !== 'false';
183
186
 
187
+ // Validar SUPABASE_POSTGRES_MAJOR (alinhado ao backup)
188
+ const postgresMajorRaw = (getValue('SUPABASE_POSTGRES_MAJOR') || process.env.SUPABASE_POSTGRES_MAJOR || '').toString().trim();
189
+ if (!postgresMajorRaw) {
190
+ ui.error(`❌ ${getT('backup.error.postgresMajorNotSet')}`);
191
+ ui.info(` ${getT('backup.error.postgresMajorInstructions')}`);
192
+ printSupabasePostgresMajorHintOnce(getT);
193
+ process.exit(1);
194
+ }
195
+ const parsedMajor = parseInt(postgresMajorRaw, 10);
196
+ if (Number.isNaN(parsedMajor) || !isPostgresMajorSupported(parsedMajor, true)) {
197
+ ui.error(`❌ ${getT('backup.error.postgresMajorInvalid')}`);
198
+ ui.info(` ${getT('backup.error.postgresMajorInstructions')}`);
199
+ printSupabasePostgresMajorHintOnce(getT);
200
+ process.exit(1);
201
+ }
202
+
184
203
  // Construir targetProject a partir do .env.local mapeado
185
204
  const targetProject = {
186
205
  targetProjectId: getValue('SUPABASE_PROJECT_ID'),
@@ -199,7 +218,7 @@ module.exports = async (options) => {
199
218
  const sourceFile = path.resolve(options.file);
200
219
  const sourceStorageFile = options.storage ? path.resolve(options.storage) : null;
201
220
 
202
- console.log(chalk.blue(`📁 ${getT('restore.import.importingFile')}`));
221
+ ui.step(`📁 ${getT('restore.import.importingFile')}`);
203
222
  const importedBackupDir = await importBackupFile(sourceFile, sourceStorageFile, outputDir);
204
223
 
205
224
  // Listar backups válidos para encontrar o backup importado
@@ -210,17 +229,17 @@ module.exports = async (options) => {
210
229
  throw new Error(getT('restore.import.cannotFind'));
211
230
  }
212
231
 
213
- console.log(chalk.green(`✅ ${getT('restore.import.importedSelected', { name: path.basename(selectedBackup.path) })}`));
232
+ ui.success(`✅ ${getT('restore.import.importedSelected', { name: path.basename(selectedBackup.path) })}`);
214
233
  } else {
215
234
  // Fluxo normal: listar e selecionar backup interativamente
216
- console.log(chalk.blue(`📁 ${getT('restore.index.searchingBackups', { path: outputDir })}`));
235
+ ui.step(`📁 ${getT('restore.index.searchingBackups', { path: outputDir })}`);
217
236
 
218
237
  // 1. Listar backups válidos (.backup.gz)
219
238
  const validBackups = await listValidBackups(outputDir);
220
239
 
221
240
  if (validBackups.length === 0) {
222
- console.error(chalk.red(`❌ ${getT('restore.index.noBackupsFound')}`));
223
- console.log(chalk.yellow(`💡 ${getT('restore.index.runBackupFirst')}`));
241
+ ui.error(`❌ ${getT('restore.index.noBackupsFound')}`);
242
+ ui.warn(`💡 ${getT('restore.index.runBackupFirst')}`);
224
243
  process.exit(1);
225
244
  }
226
245
 
@@ -233,20 +252,20 @@ module.exports = async (options) => {
233
252
 
234
253
  // Validar que pelo menos um componente foi selecionado
235
254
  if (!Object.values(components).some(Boolean)) {
236
- console.error(chalk.red(getT('restore.import.noComponents')));
255
+ ui.error(getT('restore.import.noComponents'));
237
256
  process.exit(1);
238
257
  }
239
258
 
240
259
  // 4. Mostrar resumo detalhado
241
- console.log(chalk.cyan(`\n📋 ${getT('restore.index.summaryTitle')}\n`));
242
- console.log(chalk.white(` 📁 ${getT('restore.index.selectedBackup', { name: path.basename(selectedBackup.path) })}`));
243
- console.log(chalk.white(` 🎯 ${getT('restore.index.targetProject', { projectId: targetProject.targetProjectId || getT('restore.index.notConfigured') })}`));
244
- console.log(chalk.white(` 📊 ${getT('restore.index.database', { value: components.database ? getT('restore.index.yes') : getT('restore.index.no') })}`));
245
- console.log(chalk.white(` ⚡ ${getT('restore.index.edgeFunctions', { value: components.edgeFunctions ? getT('restore.index.yes') : getT('restore.index.no') })}`));
246
- console.log(chalk.white(` 🔐 ${getT('restore.index.authSettings', { value: components.authSettings ? getT('restore.index.yes') : getT('restore.index.no') })}`));
247
- console.log(chalk.white(` 📦 ${getT('restore.index.storage', { value: components.storage ? getT('restore.index.yes') : getT('restore.index.no') })}`));
248
- console.log(chalk.white(` 🔧 ${getT('restore.index.databaseSettings', { value: components.databaseSettings ? getT('restore.index.yes') : getT('restore.index.no') })}`));
249
- console.log(chalk.white(` 🔄 ${getT('restore.index.realtimeSettings', { value: components.realtimeSettings ? getT('restore.index.yes') : getT('restore.index.no') })}\n`));
260
+ ui.title(`\n📋 ${getT('restore.index.summaryTitle')}\n`);
261
+ ui.info(` 📁 ${getT('restore.index.selectedBackup', { name: path.basename(selectedBackup.path) })}`);
262
+ ui.info(` 🎯 ${getT('restore.index.targetProject', { projectId: targetProject.targetProjectId || getT('restore.index.notConfigured') })}`);
263
+ ui.info(` 📊 ${getT('restore.index.database', { value: components.database ? getT('restore.index.yes') : getT('restore.index.no') })}`);
264
+ ui.info(` ⚡ ${getT('restore.index.edgeFunctions', { value: components.edgeFunctions ? getT('restore.index.yes') : getT('restore.index.no') })}`);
265
+ ui.info(` 🔐 ${getT('restore.index.authSettings', { value: components.authSettings ? getT('restore.index.yes') : getT('restore.index.no') })}`);
266
+ ui.info(` 📦 ${getT('restore.index.storage', { value: components.storage ? getT('restore.index.yes') : getT('restore.index.no') })}`);
267
+ ui.info(` 🔧 ${getT('restore.index.databaseSettings', { value: components.databaseSettings ? getT('restore.index.yes') : getT('restore.index.no') })}`);
268
+ ui.info(` 🔄 ${getT('restore.index.realtimeSettings', { value: components.realtimeSettings ? getT('restore.index.yes') : getT('restore.index.no') })}\n`);
250
269
 
251
270
  // Mostrar resumo técnico adicional
252
271
  showRestoreSummary(selectedBackup, components, targetProject);
@@ -254,12 +273,29 @@ module.exports = async (options) => {
254
273
  // 5. Confirmar execução
255
274
  const finalOk = await confirm(getT('restore.index.confirmRestore'), true);
256
275
  if (!finalOk) {
257
- console.log(chalk.yellow(`🚫 ${getT('restore.index.restoreCancelled')}`));
276
+ ui.warn(`🚫 ${getT('restore.index.restoreCancelled')}`);
258
277
  process.exit(0);
259
278
  }
260
-
279
+
280
+ // 5.1 Disclaimer: erros esperados durante restore (destacado)
281
+ ui.errorBold(`\n⚠️ ${getT('restore.disclaimer.errorsTitle')}\n`);
282
+ ui.info(` ${getT('restore.disclaimer.errorsIntro')}`);
283
+ ui.info(` ${getT('restore.disclaimer.errorsReason')}`);
284
+ ui.info('');
285
+ ui.info(` ${getT('restore.disclaimer.supabaseDoc')}`);
286
+ ui.link(` ${SUPABASE_RESTORE_DOC_URL}`);
287
+ ui.info('');
288
+ ui.warn(` ${getT('restore.disclaimer.waitComplete')}`);
289
+ ui.warn(` ${getT('restore.disclaimer.testResult')}`);
290
+ ui.info('');
291
+ const acceptErrors = await confirm(getT('restore.disclaimer.acceptProceed'), true);
292
+ if (!acceptErrors) {
293
+ ui.warn(`🚫 ${getT('restore.index.restoreCancelled')}`);
294
+ process.exit(0);
295
+ }
296
+
261
297
  // 6. Executar restauração
262
- console.log(chalk.blue(`\n🚀 ${getT('restore.index.startingRestore')}`));
298
+ ui.step(`\n🚀 ${getT('restore.index.startingRestore')}`);
263
299
 
264
300
  // Contar etapas totais para numeração dinâmica
265
301
  let stepNumber = 0;
@@ -276,7 +312,7 @@ module.exports = async (options) => {
276
312
  // 6.1 Database (se selecionado)
277
313
  if (components.database) {
278
314
  stepNumber++;
279
- console.log(chalk.blue(`\n📊 ${stepNumber}/${totalSteps} - ${getT('restore.index.restoringDatabase')}`));
315
+ ui.step(`\n📊 ${stepNumber}/${totalSteps} - ${getT('restore.index.restoringDatabase')}`);
280
316
  await step03Database({
281
317
  backupFilePath: path.join(selectedBackup.path, selectedBackup.backupFile),
282
318
  targetDatabaseUrl: targetProject.targetDatabaseUrl
@@ -287,7 +323,7 @@ module.exports = async (options) => {
287
323
  // 6.2 Edge Functions (se selecionado)
288
324
  if (components.edgeFunctions) {
289
325
  stepNumber++;
290
- console.log(chalk.blue(`\n⚡ ${stepNumber}/${totalSteps} - ${getT('restore.index.restoringEdgeFunctions')}`));
326
+ ui.step(`\n⚡ ${stepNumber}/${totalSteps} - ${getT('restore.index.restoringEdgeFunctions')}`);
291
327
  const edgeFunctionsResult = await step04EdgeFunctions({
292
328
  backupPath: selectedBackup.path,
293
329
  targetProject
@@ -298,7 +334,7 @@ module.exports = async (options) => {
298
334
  // 6.3 Auth Settings (se selecionado)
299
335
  if (components.authSettings) {
300
336
  stepNumber++;
301
- console.log(chalk.blue(`\n🔐 ${stepNumber}/${totalSteps} - ${getT('restore.index.restoringAuthSettings')}`));
337
+ ui.step(`\n🔐 ${stepNumber}/${totalSteps} - ${getT('restore.index.restoringAuthSettings')}`);
302
338
  await step05AuthSettings({
303
339
  backupPath: selectedBackup.path,
304
340
  targetProject
@@ -309,7 +345,7 @@ module.exports = async (options) => {
309
345
  // 6.4 Storage Buckets (se selecionado)
310
346
  if (components.storage) {
311
347
  stepNumber++;
312
- console.log(chalk.blue(`\n📦 ${stepNumber}/${totalSteps} - ${getT('restore.index.restoringStorageBuckets')}`));
348
+ ui.step(`\n📦 ${stepNumber}/${totalSteps} - ${getT('restore.index.restoringStorageBuckets')}`);
313
349
  const storageResult = await step06Storage({
314
350
  backupPath: selectedBackup.path,
315
351
  targetProject
@@ -320,7 +356,7 @@ module.exports = async (options) => {
320
356
  // 6.5 Database Settings (se selecionado)
321
357
  if (components.databaseSettings) {
322
358
  stepNumber++;
323
- console.log(chalk.blue(`\n🔧 ${stepNumber}/${totalSteps} - ${getT('restore.index.restoringDatabaseSettings')}`));
359
+ ui.step(`\n🔧 ${stepNumber}/${totalSteps} - ${getT('restore.index.restoringDatabaseSettings')}`);
324
360
  await step07DatabaseSettings({
325
361
  backupPath: selectedBackup.path,
326
362
  targetProject
@@ -331,7 +367,7 @@ module.exports = async (options) => {
331
367
  // 6.6 Realtime Settings (se selecionado)
332
368
  if (components.realtimeSettings) {
333
369
  stepNumber++;
334
- console.log(chalk.blue(`\n🔄 ${stepNumber}/${totalSteps} - ${getT('restore.index.restoringRealtimeSettings')}`));
370
+ ui.step(`\n🔄 ${stepNumber}/${totalSteps} - ${getT('restore.index.restoringRealtimeSettings')}`);
335
371
  await step08RealtimeSettings({
336
372
  backupPath: selectedBackup.path,
337
373
  targetProject
@@ -361,41 +397,41 @@ module.exports = async (options) => {
361
397
  }
362
398
 
363
399
  // Exibir resumo final
364
- console.log(chalk.green(`\n🎉 ${getT('restore.index.restoreComplete')}`));
365
- console.log(chalk.blue(`🎯 ${getT('restore.index.targetProjectFinal', { projectId: targetProject.targetProjectId || getT('restore.index.notConfigured') })}`));
366
-
400
+ ui.success(`\n🎉 ${getT('restore.index.restoreComplete')}`);
401
+ ui.link(`🎯 ${getT('restore.index.targetProjectFinal', { projectId: targetProject.targetProjectId || getT('restore.index.notConfigured') })}`);
402
+
367
403
  if (restoreResults.database) {
368
- console.log(chalk.green(`📊 ${getT('restore.index.databaseRestored')}`));
404
+ ui.success(`📊 ${getT('restore.index.databaseRestored')}`);
369
405
  }
370
-
406
+
371
407
  if (restoreResults.edgeFunctions) {
372
408
  const funcCount = restoreResults.edgeFunctions.functions_count || 0;
373
409
  const successCount = restoreResults.edgeFunctions.success_count || 0;
374
- console.log(chalk.green(`⚡ ${getT('restore.index.edgeFunctionsRestored', { success: successCount, total: funcCount })}`));
410
+ ui.success(`⚡ ${getT('restore.index.edgeFunctionsRestored', { success: successCount, total: funcCount })}`);
375
411
  }
376
-
412
+
377
413
  if (restoreResults.authSettings) {
378
- console.log(chalk.green(`🔐 ${getT('restore.index.authSettingsRestored')}`));
414
+ ui.success(`🔐 ${getT('restore.index.authSettingsRestored')}`);
379
415
  }
380
-
416
+
381
417
  if (restoreResults.storage) {
382
418
  const bucketCount = restoreResults.storage.buckets_count || 0;
383
419
  const filesRestored = restoreResults.storage.files_restored;
384
420
  const totalFiles = restoreResults.storage.total_files || 0;
385
-
421
+
386
422
  if (filesRestored) {
387
- console.log(chalk.green(`📦 ${getT('restore.index.storageRestored', { buckets: bucketCount, files: totalFiles })}`));
423
+ ui.success(`📦 ${getT('restore.index.storageRestored', { buckets: bucketCount, files: totalFiles })}`);
388
424
  } else {
389
- console.log(chalk.green(`📦 ${getT('restore.index.storageMetadataOnly', { buckets: bucketCount })}`));
425
+ ui.success(`📦 ${getT('restore.index.storageMetadataOnly', { buckets: bucketCount })}`);
390
426
  }
391
427
  }
392
-
428
+
393
429
  if (restoreResults.databaseSettings) {
394
- console.log(chalk.green(`🔧 ${getT('restore.index.databaseSettingsRestored')}`));
430
+ ui.success(`🔧 ${getT('restore.index.databaseSettingsRestored')}`);
395
431
  }
396
-
432
+
397
433
  if (restoreResults.realtimeSettings) {
398
- console.log(chalk.green(`🔄 ${getT('restore.index.realtimeSettingsRestored')}`));
434
+ ui.success(`🔄 ${getT('restore.index.realtimeSettingsRestored')}`);
399
435
  }
400
436
 
401
437
  sendTelemetry({
@@ -414,7 +450,7 @@ module.exports = async (options) => {
414
450
  });
415
451
  const { t } = require('../../i18n');
416
452
  const getT = global.smoonbI18n?.t || t;
417
- console.error(chalk.red(`❌ ${getT('restore.index.error', { message: error.message })}`));
453
+ ui.error(`❌ ${getT('restore.index.error', { message: error.message })}`);
418
454
  process.exit(1);
419
455
  }
420
456
  };
@@ -134,7 +134,7 @@
134
134
  "consent.proceed": "Do you consent to proceed?",
135
135
 
136
136
  "help.configuration": "CONFIGURATION:",
137
- "help.configurationDesc": "Configure the .env.local file in the project root with your Supabase credentials. The smoonb will map variables interactively on first execution.",
137
+ "help.configurationDesc": "Configure .env.local with Supabase credentials and SMOONB_LICENSE_KEY (required). License: paste from desktop app at https://www.smoonb.com. Optional: SMOONB_TELEMETRY_ENABLED (default true), SMOONB_OUTPUT_DIR. smoonb maps variables interactively on first run.",
138
138
  "help.update": "UPDATE TO LATEST VERSION:",
139
139
  "help.updateCommand": "npm install smoonb@latest",
140
140
  "help.manual": "MANUAL - COMPLETE EXAMPLES:",
@@ -183,9 +183,18 @@
183
183
  "help.commands.backupWhat7": "• Realtime Settings (7 interactive parameters)",
184
184
  "help.commands.backupWhat8": "• Supabase .temp (temporary files)",
185
185
  "help.commands.backupWhat9": "• Migrations (all project migrations)",
186
- "help.commands.backupPostgresMajorEnv": "Required: SUPABASE_POSTGRES_MAJOR=15 or 17 (in .env.local or environment).",
186
+ "help.commands.backupPostgresMajorEnv": "Required for backup and restore: SUPABASE_POSTGRES_MAJOR=15 or 17 (in .env.local or environment).",
187
187
  "help.commands.backupPostgresVersionInDashboardTitle": "Where to find the Postgres version (Supabase Dashboard)",
188
188
  "help.commands.backupPostgresVersionInDashboardBody": "Project Settings -> Infrastructure -> Service Versions (Postgres line). Use that major for SUPABASE_POSTGRES_MAJOR.",
189
+ "help.commands.backupFlow": "Backup flow:",
190
+ "help.commands.backupFlow1": "1. Terms of use",
191
+ "help.commands.backupFlow2": "2. License validation (SMOONB_LICENSE_KEY)",
192
+ "help.commands.backupFlow3": "3. Docker validation",
193
+ "help.commands.backupFlow4": "4. Consent to read/write .env.local",
194
+ "help.commands.backupFlow5": "5. Environment variable mapping (license not in wizard)",
195
+ "help.commands.backupFlow6": "6. Component selection",
196
+ "help.commands.backupFlow7": "7. Summary and confirmation",
197
+ "help.commands.backupFlow8": "8. Execution",
189
198
 
190
199
  "help.commands.restoreDesc": "Restore a full backup using psql (interactive mode)",
191
200
  "help.commands.restoreFile": "Full path of .backup.gz file to import and restore (optional)",
@@ -198,13 +207,16 @@
198
207
  "help.commands.restoreExample3": "npx smoonb restore --file \"backup.backup.gz\" --storage \"my-project.storage.zip\"",
199
208
  "help.commands.restoreExample3Desc": "# Imports and restores backup and storage together",
200
209
  "help.commands.restoreFlow": "Restore flow:",
201
- "help.commands.restoreFlow1": "1. Docker validation",
202
- "help.commands.restoreFlow2": "2. Consent to read/write .env.local",
203
- "help.commands.restoreFlow3": "3. Environment variable mapping",
204
- "help.commands.restoreFlow4": "4. Backup selection (skips if --file provided)",
205
- "help.commands.restoreFlow5": "5. Component selection to restore",
206
- "help.commands.restoreFlow6": "6. Detailed summary and confirmation",
207
- "help.commands.restoreFlow7": "7. Restore execution",
210
+ "help.commands.restoreFlow1": "1. Terms of use",
211
+ "help.commands.restoreFlow2": "2. License validation (SMOONB_LICENSE_KEY)",
212
+ "help.commands.restoreFlow3": "3. Docker validation",
213
+ "help.commands.restoreFlow4": "4. Consent to read/write .env.local",
214
+ "help.commands.restoreFlow5": "5. Environment variable mapping (includes SUPABASE_POSTGRES_MAJOR)",
215
+ "help.commands.restoreFlow6": "6. Backup selection (skips if --file provided)",
216
+ "help.commands.restoreFlow7": "7. Component selection to restore",
217
+ "help.commands.restoreFlow8": "8. Summary and confirmation",
218
+ "help.commands.restoreFlow9": "9. Disclaimer: expected errors during restore (Supabase doc link); wait for completion, then test result",
219
+ "help.commands.restoreFlow10": "10. Restore execution",
208
220
  "help.commands.restoreWhenFile": "When to use --file:",
209
221
  "help.commands.restoreWhenFile1": "• Automatically imports backup file before restoring",
210
222
  "help.commands.restoreWhenFile2": "• Eliminates backup selection step",
@@ -695,6 +707,13 @@
695
707
  "restore.index.notConfigured": "(not configured)",
696
708
  "restore.index.confirmRestore": "Do you want to start the restoration with these configurations?",
697
709
  "restore.index.restoreCancelled": "Restoration cancelled.",
710
+ "restore.disclaimer.errorsTitle": "IMPORTANT: Expected errors during restore",
711
+ "restore.disclaimer.errorsIntro": "During the database restore you will see many error messages in the terminal. This is NORMAL and expected.",
712
+ "restore.disclaimer.errorsReason": "Supabase confirms that errors like \"object already exists\" or \"constraint already exists\" are normal when restoring a full dump, because the backup contains CREATE commands for all schemas and your target project already has some of these objects.",
713
+ "restore.disclaimer.supabaseDoc": "Official Supabase documentation (restore and expected errors):",
714
+ "restore.disclaimer.waitComplete": "Even with numerous errors, you must wait for the process to complete fully. Do not interrupt the restore.",
715
+ "restore.disclaimer.testResult": "After completion, test your project (tables, data, functions) to verify whether the restore succeeded.",
716
+ "restore.disclaimer.acceptProceed": "I understand that errors are expected, I will wait for completion and I will test the result. Proceed with restore?",
698
717
  "restore.index.startingRestore": "Starting restoration...",
699
718
  "restore.index.restoringDatabase": "Restoring Database...",
700
719
  "restore.index.restoringEdgeFunctions": "Restoring Edge Functions...",
@@ -134,7 +134,7 @@
134
134
  "consent.proceed": "Você consente em prosseguir?",
135
135
 
136
136
  "help.configuration": "CONFIGURAÇÃO:",
137
- "help.configurationDesc": "Configure o arquivo .env.local na raiz do projeto com suas credenciais Supabase. O smoonb irá mapear as variáveis interativamente na primeira execução.",
137
+ "help.configurationDesc": "Configure o .env.local com credenciais Supabase e SMOONB_LICENSE_KEY (obrigatória). Licença: cole a chave gerada no app desktop em https://www.smoonb.com. Opcional: SMOONB_TELEMETRY_ENABLED (padrão true), SMOONB_OUTPUT_DIR. O smoonb mapeia variáveis interativamente na primeira execução.",
138
138
  "help.update": "ATUALIZAR PARA ÚLTIMA VERSÃO:",
139
139
  "help.updateCommand": "npm install smoonb@latest",
140
140
  "help.manual": "MANUAL DE USO - EXEMPLOS COMPLETOS:",
@@ -183,9 +183,18 @@
183
183
  "help.commands.backupWhat7": "• Realtime Settings (7 parâmetros interativos)",
184
184
  "help.commands.backupWhat8": "• Supabase .temp (arquivos temporários)",
185
185
  "help.commands.backupWhat9": "• Migrations (todas as migrations do projeto)",
186
- "help.commands.backupPostgresMajorEnv": "Obrigatório: SUPABASE_POSTGRES_MAJOR=15 ou 17 (em .env.local ou ambiente).",
186
+ "help.commands.backupPostgresMajorEnv": "Obrigatório para backup e restore: SUPABASE_POSTGRES_MAJOR=15 ou 17 (em .env.local ou ambiente).",
187
187
  "help.commands.backupPostgresVersionInDashboardTitle": "Onde ver a versão do Postgres (Supabase Dashboard)",
188
188
  "help.commands.backupPostgresVersionInDashboardBody": "Project Settings -> Infrastructure -> Service Versions (linha do Postgres). Use essa major em SUPABASE_POSTGRES_MAJOR.",
189
+ "help.commands.backupFlow": "Fluxo do backup:",
190
+ "help.commands.backupFlow1": "1. Termo de uso",
191
+ "help.commands.backupFlow2": "2. Validação de licença (SMOONB_LICENSE_KEY)",
192
+ "help.commands.backupFlow3": "3. Validação Docker",
193
+ "help.commands.backupFlow4": "4. Consentimento para ler/escrever .env.local",
194
+ "help.commands.backupFlow5": "5. Mapeamento de variáveis (licença não entra no wizard)",
195
+ "help.commands.backupFlow6": "6. Seleção de componentes",
196
+ "help.commands.backupFlow7": "7. Resumo e confirmação",
197
+ "help.commands.backupFlow8": "8. Execução",
189
198
 
190
199
  "help.commands.restoreDesc": "Restaurar backup completo usando psql (modo interativo)",
191
200
  "help.commands.restoreFile": "Caminho completo do arquivo .backup.gz a importar e restaurar (opcional)",
@@ -198,13 +207,16 @@
198
207
  "help.commands.restoreExample3": "npx smoonb restore --file \"backup.backup.gz\" --storage \"meu-projeto.storage.zip\"",
199
208
  "help.commands.restoreExample3Desc": "# Importa e restaura backup e storage juntos",
200
209
  "help.commands.restoreFlow": "Fluxo do restore:",
201
- "help.commands.restoreFlow1": "1. Validação Docker",
202
- "help.commands.restoreFlow2": "2. Consentimento para ler/escrever .env.local",
203
- "help.commands.restoreFlow3": "3. Mapeamento de variáveis de ambiente",
204
- "help.commands.restoreFlow4": "4. Seleção de backup disponível (pula se --file fornecido)",
205
- "help.commands.restoreFlow5": "5. Seleção de componentes para restaurar",
206
- "help.commands.restoreFlow6": "6. Resumo detalhado e confirmação",
207
- "help.commands.restoreFlow7": "7. Execução da restauração",
210
+ "help.commands.restoreFlow1": "1. Termo de uso",
211
+ "help.commands.restoreFlow2": "2. Validação de licença (SMOONB_LICENSE_KEY)",
212
+ "help.commands.restoreFlow3": "3. Validação Docker",
213
+ "help.commands.restoreFlow4": "4. Consentimento para ler/escrever .env.local",
214
+ "help.commands.restoreFlow5": "5. Mapeamento de variáveis (inclui SUPABASE_POSTGRES_MAJOR)",
215
+ "help.commands.restoreFlow6": "6. Seleção de backup (pula se --file fornecido)",
216
+ "help.commands.restoreFlow7": "7. Seleção de componentes para restaurar",
217
+ "help.commands.restoreFlow8": "8. Resumo e confirmação",
218
+ "help.commands.restoreFlow9": "9. Aviso: erros esperados durante a restauração (link doc Supabase); aguardar término e testar resultado",
219
+ "help.commands.restoreFlow10": "10. Execução da restauração",
208
220
  "help.commands.restoreWhenFile": "Quando usar --file:",
209
221
  "help.commands.restoreWhenFile1": "• Importa automaticamente o arquivo de backup antes de restaurar",
210
222
  "help.commands.restoreWhenFile2": "• Elimina a etapa de seleção de backup",
@@ -694,6 +706,13 @@
694
706
  "restore.index.notConfigured": "(não configurado)",
695
707
  "restore.index.confirmRestore": "Deseja iniciar a restauração com estas configurações?",
696
708
  "restore.index.restoreCancelled": "Restauração cancelada.",
709
+ "restore.disclaimer.errorsTitle": "IMPORTANTE: Erros esperados durante a restauração",
710
+ "restore.disclaimer.errorsIntro": "Durante a restauração do banco de dados você verá muitas mensagens de erro no terminal. Isso é NORMAL e esperado.",
711
+ "restore.disclaimer.errorsReason": "O Supabase confirma que erros como \"object already exists\" ou \"constraint already exists\" são normais ao restaurar um dump completo, pois o backup contém comandos CREATE para todos os esquemas e seu projeto destino já possui parte desses objetos.",
712
+ "restore.disclaimer.supabaseDoc": "Documentação oficial do Supabase (restauração e erros esperados):",
713
+ "restore.disclaimer.waitComplete": "Mesmo com inúmeros erros, você deve aguardar o término completo do processo. Não interrompa a restauração.",
714
+ "restore.disclaimer.testResult": "Após o término, teste seu projeto (tabelas, dados, funções) para verificar se a restauração foi bem-sucedida.",
715
+ "restore.disclaimer.acceptProceed": "Entendo que erros são esperados, aguardarei o término e testarei o resultado. Prosseguir com a restauração?",
697
716
  "restore.index.startingRestore": "Iniciando restauração...",
698
717
  "restore.index.restoringDatabase": "Restaurando Database...",
699
718
  "restore.index.restoringEdgeFunctions": "Restaurando Edge Functions...",
package/src/index.js CHANGED
@@ -1,8 +1,7 @@
1
1
  /**
2
2
  * smoonb - Complete Supabase backup and migration tool
3
3
  * Entry point principal e exports dos módulos
4
- *
5
- * Versão: 0.1.0-beta (FREE BETA PERIOD)
4
+ * Produto comercial: https://www.smoonb.com/#price
6
5
  */
7
6
 
8
7
  const chalk = require('chalk');
@@ -26,8 +25,8 @@ const validationUtils = require('./utils/validation');
26
25
  */
27
26
  const packageInfo = {
28
27
  name: 'smoonb',
29
- description: 'Complete Supabase backup and migration tool - EXPERIMENTAL VERSION - USE AT YOUR OWN RISK',
30
- author: 'Goalmoon Tecnologia LTDA <https://goalmoon.com>',
28
+ description: 'Complete Supabase backup and migration tool. https://www.smoonb.com/#price',
29
+ author: 'Goalmoon Tecnologia LTDA <https://www.smoonb.com/#price>',
31
30
  license: 'SEE LICENSE IN LICENSE.md'
32
31
  };
33
32
 
@@ -36,23 +35,16 @@ const packageInfo = {
36
35
  */
37
36
  function showLicenseInfo() {
38
37
  console.log(chalk.yellow.bold(`
39
- 📋 INFORMAÇÕES DE LICENCIAMENTO:
38
+ 📋 LICENCIAMENTO SMOONB:
40
39
 
41
- 🆓 VERSÃO EXPERIMENTAL GRATUITA (Versões 0.x.x):
42
- Uso gratuito para projetos pessoais e comerciais
43
- ✅ Sem restrições de funcionalidades
44
- ❌ SEM SUPORTE - apenas aceitamos contribuições
45
- ⚠️ USE POR SUA CONTA E RISCO - software não testado
46
-
47
- 💼 LICENÇA COMERCIAL (Versões 1.0.0+):
48
- ⚠️ A partir da versão 1.0.0, o smoonb será licenciado comercialmente
49
- 📧 Aviso prévio: Mudanças serão anunciadas 90 dias antes
50
- 💰 Desconto especial: Usuários experimentais terão condições preferenciais
40
+ 💼 PRODUTO COMERCIAL
41
+ É necessário ter licença ativa e assinatura válida (ou estar em período de trial) para usar o smoonb.
42
+ https://www.smoonb.com/#price
51
43
 
52
44
  🏢 DESENVOLVIDO POR: Goalmoon Tecnologia LTDA
53
- 🌐 Website: https://goalmoon.com
45
+ 🌐 https://www.smoonb.com/#price
54
46
 
55
- 📖 Leia a licença completa em: LICENSE.md
47
+ 📖 Licença completa: LICENSE.md | Termos: https://www.smoonb.com/terms
56
48
  `));
57
49
  }
58
50