smoonb 0.0.71 → 0.0.73

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/bin/smoonb.js CHANGED
@@ -14,6 +14,12 @@ const { Command } = require('commander');
14
14
  const chalk = require('chalk');
15
15
  const packageJson = require('../package.json');
16
16
 
17
+ // Inicializar i18n ANTES de importar outros módulos
18
+ // Nota: --lang será processado após o parse, mas precisamos inicializar agora
19
+ const { initI18n } = require('../src/i18n');
20
+ let i18n = initI18n(process.argv, process.env);
21
+ let { t } = i18n;
22
+
17
23
  // Importar módulos principais
18
24
  const { commands, showBetaBanner, showQuickHelp } = require('../src/index');
19
25
 
@@ -25,188 +31,228 @@ program
25
31
  .name('smoonb')
26
32
  .description('Complete Supabase backup and migration tool')
27
33
  .version(packageJson.version, '-v, --version', 'display version number')
34
+ .option('--lang <code>', 'Set language (en, pt-BR). Overrides SMOONB_LANG and system locale')
28
35
  .addHelpText('before', () => {
29
36
  showBetaBanner();
30
- return chalk.yellow.bold('\n⚠️ TERMO DE USO E AVISO DE RISCO\n') +
31
- chalk.white('Ao prosseguir, você reconhece e concorda que o Supa Moonbase (smoonb) é fornecido "NO ESTADO EM QUE SE ENCONTRA" ("AS IS") e "CONFORME DISPONIBILIDADE", sem garantias de qualquer natureza—expressas, implícitas ou legais—incluindo, sem limitação, garantias de comercialização, adequação a um fim específico e não violação, na máxima extensão permitida pela lei aplicável. Operações de backup e restauração envolvem riscos, os ambientes variam amplamente e não é possível prever ou validar todas as configurações dos usuários. Você é o único responsável por validar seu ambiente, manter cópias independentes e verificar os resultados antes de utilizá-los em produção. O Supa Moonbase (smoonb) é construído com repositórios públicos, auditáveis e software livre, para auxiliar pessoas a simplificar seus fluxos, sem com isso criar qualquer garantia, promessa de suporte ou compromisso de nível de serviço.\n\n') +
32
- chalk.white('Limitação de responsabilidade (PT-BR) — Na máxima extensão permitida por lei, a Goalmoon, seus contribuidores e licenciadores não serão responsáveis por danos indiretos, incidentais, especiais, consequentes, exemplares ou punitivos (incluindo perda de dados, interrupção de negócios ou lucros cessantes) decorrentes do uso, incapacidade de uso, das operações de backup/restauração realizadas com, ou dos resultados gerados pelo Supa Moonbase (smoonb). Em qualquer hipótese, a responsabilidade total por todas as reivindicações relacionadas ao Supa Moonbase (smoonb) não excederá o valor pago por você pelo Supa Moonbase (smoonb) nos 12 meses anteriores ao evento. Nada neste aviso exclui ou limita responsabilidades onde tais limites sejam proibidos por lei, incluindo (conforme aplicável) dolo ou culpa grave.\n\n') +
33
- chalk.white('Observação para consumidores no Brasil (PT-BR) — Para consumidores brasileiros, este aviso não afasta direitos irrenunciáveis previstos no Código de Defesa do Consumidor (CDC); qualquer limitação aqui prevista só se aplica nos limites da lei e não impede a indenização obrigatória quando cabível.\n\n');
37
+ const getT = global.smoonbI18n?.t || t;
38
+ return chalk.yellow.bold(`\n⚠️ ${getT('disclaimer.title')}\n`) +
39
+ chalk.white(`${getT('disclaimer.text')}\n\n`) +
40
+ chalk.white(`${getT('disclaimer.limitation')}\n\n`);
34
41
  })
35
42
  .addHelpText('after', () => {
43
+ const getT = global.smoonbI18n?.t || t;
36
44
  return chalk.cyan.bold(`
37
- 📋 CONFIGURAÇÃO:
38
- Configure o arquivo .env.local na raiz do projeto com suas credenciais Supabase.
39
- O smoonb irá mapear as variáveis interativamente na primeira execução.
45
+ 📋 ${getT('help.configuration')}
46
+ ${getT('help.configurationDesc')}
40
47
 
41
- 🔄 ATUALIZAR PARA ÚLTIMA VERSÃO:
42
- npm install smoonb@latest
48
+ 🔄 ${getT('help.update')}
49
+ ${getT('help.updateCommand')}
43
50
 
44
- 📚 MANUAL DE USO - EXEMPLOS COMPLETOS:
51
+ 📚 ${getT('help.manual')}
45
52
 
46
- ${chalk.yellow.bold('1. BACKUP - Fazer backup completo do projeto:')}
47
- ${chalk.white('npx smoonb backup')}
48
- ${chalk.gray('# Processo interativo que captura todos os componentes do Supabase')}
53
+ ${chalk.yellow.bold(getT('help.backupTitle'))}
54
+ ${chalk.white(getT('help.backupExample1'))}
55
+ ${chalk.gray(getT('help.backupExample1Desc'))}
49
56
 
50
- ${chalk.white('npx smoonb backup --skip-realtime')}
51
- ${chalk.gray('# Pula a captura interativa de Realtime Settings')}
57
+ ${chalk.white(getT('help.backupExample2'))}
58
+ ${chalk.gray(getT('help.backupExample2Desc'))}
52
59
 
53
- ${chalk.yellow.bold('2. RESTORE - Restaurar backup em um projeto:')}
54
- ${chalk.white('npx smoonb restore')}
55
- ${chalk.gray('# Processo interativo que lista backups disponíveis e permite escolher')}
60
+ ${chalk.yellow.bold(getT('help.restoreTitle'))}
61
+ ${chalk.white(getT('help.restoreExample1'))}
62
+ ${chalk.gray(getT('help.restoreExample1Desc'))}
56
63
 
57
- ${chalk.white('npx smoonb restore --file "C:\\Downloads\\db_cluster-04-03-2024@14-16-59.backup.gz"')}
58
- ${chalk.gray('# Importa e restaura diretamente o arquivo de backup (pula seleção)')}
64
+ ${chalk.white(getT('help.restoreExample2'))}
65
+ ${chalk.gray(getT('help.restoreExample2Desc'))}
59
66
 
60
- ${chalk.white('npx smoonb restore --file "backup.backup.gz" --storage "meu-projeto.storage.zip"')}
61
- ${chalk.gray('# Importa e restaura backup e storage juntos')}
67
+ ${chalk.white(getT('help.restoreExample3'))}
68
+ ${chalk.gray(getT('help.restoreExample3Desc'))}
62
69
 
63
- ${chalk.yellow.bold('3. IMPORT - Importar backup do Dashboard do Supabase:')}
64
- ${chalk.white('npx smoonb import --file "C:\\Downloads\\db_cluster-04-03-2024@14-16-59.backup.gz"')}
65
- ${chalk.gray('# Importa apenas o arquivo de database')}
70
+ ${chalk.yellow.bold(getT('help.importTitle'))}
71
+ ${chalk.white(getT('help.importExample1'))}
72
+ ${chalk.gray(getT('help.importExample1Desc'))}
66
73
 
67
- ${chalk.white('npx smoonb import --file "backup.backup.gz" --storage "meu-projeto.storage.zip"')}
68
- ${chalk.gray('# Importa database e storage juntos (storage é opcional)')}
69
-
70
- ${chalk.yellow.bold('4. CHECK - Verificar integridade após restauração:')}
71
- ${chalk.white('npx smoonb check')}
72
- ${chalk.gray('# Verifica conexão, extensões, tabelas, RLS, Realtime e Storage')}
73
-
74
- ${chalk.yellow.bold('💡 DICAS IMPORTANTES:')}
75
- ${chalk.white('• O comando import requer um arquivo de backup (.backup.gz), mas o storage (.storage.zip) é opcional')}
76
- ${chalk.white('• O storage depende de um backup, mas o backup não depende do storage')}
77
- ${chalk.white('• Use caminhos absolutos ou relativos para os arquivos no comando import')}
78
- ${chalk.white('• O formato do arquivo de backup deve ser: db_cluster-DD-MM-YYYY@HH-MM-SS.backup.gz')}
79
- ${chalk.white('• O formato do arquivo de storage deve ser: *.storage.zip')}
74
+ ${chalk.white(getT('help.importExample2'))}
75
+ ${chalk.gray(getT('help.importExample2Desc'))}
76
+
77
+ ${chalk.yellow.bold(getT('help.checkTitle'))}
78
+ ${chalk.white(getT('help.checkExample1'))}
79
+ ${chalk.gray(getT('help.checkExample1Desc'))}
80
+
81
+ ${chalk.yellow.bold(getT('help.tipsTitle'))}
82
+ ${chalk.white(getT('help.tip1'))}
83
+ ${chalk.white(getT('help.tip2'))}
84
+ ${chalk.white(getT('help.tip3'))}
85
+ ${chalk.white(getT('help.tip4'))}
86
+ ${chalk.white(getT('help.tip5'))}
80
87
  `);
81
88
  });
82
89
 
83
90
  // Comandos principais
84
91
  program
85
92
  .command('backup')
86
- .description('Fazer backup completo do projeto Supabase usando Supabase CLI')
87
- .option('--skip-realtime', 'Pular captura interativa de Realtime Settings')
88
- .addHelpText('after', `
89
- ${chalk.yellow.bold('Exemplos:')}
90
- ${chalk.white('npx smoonb backup')}
91
- ${chalk.gray('# Processo interativo completo')}
93
+ .description(() => {
94
+ const getT = global.smoonbI18n?.t || t;
95
+ return getT('help.commands.backupDesc');
96
+ })
97
+ .option('--skip-realtime', () => {
98
+ const getT = global.smoonbI18n?.t || t;
99
+ return getT('help.commands.backupSkipRealtime');
100
+ })
101
+ .addHelpText('after', () => {
102
+ const getT = global.smoonbI18n?.t || t;
103
+ return `
104
+ ${chalk.yellow.bold(getT('help.commands.backupExamples'))}
105
+ ${chalk.white(getT('help.commands.backupExample1'))}
106
+ ${chalk.gray(getT('help.commands.backupExample1Desc'))}
92
107
 
93
- ${chalk.white('npx smoonb backup --skip-realtime')}
94
- ${chalk.gray('# Pula configuração de Realtime Settings')}
95
-
96
- ${chalk.yellow.bold('O que é capturado:')}
97
- • Database PostgreSQL (pg_dumpall + SQL separado)
98
- • Database Extensions and Settings
99
- • Custom Roles
100
- • Edge Functions (download automático)
101
- • Auth Settings (via Management API)
102
- • Storage Buckets (metadados via Management API)
103
- • Realtime Settings (7 parâmetros interativos)
104
- • Supabase .temp (arquivos temporários)
105
- • Migrations (todas as migrations do projeto)
106
- `)
108
+ ${chalk.white(getT('help.commands.backupExample2'))}
109
+ ${chalk.gray(getT('help.commands.backupExample2Desc'))}
110
+
111
+ ${chalk.yellow.bold(getT('help.commands.backupWhat'))}
112
+ ${getT('help.commands.backupWhat1')}
113
+ ${getT('help.commands.backupWhat2')}
114
+ ${getT('help.commands.backupWhat3')}
115
+ ${getT('help.commands.backupWhat4')}
116
+ ${getT('help.commands.backupWhat5')}
117
+ ${getT('help.commands.backupWhat6')}
118
+ ${getT('help.commands.backupWhat7')}
119
+ ${getT('help.commands.backupWhat8')}
120
+ ${getT('help.commands.backupWhat9')}
121
+ `;
122
+ })
107
123
  .action(commands.backup);
108
124
 
109
125
  program
110
126
  .command('restore')
111
- .description('Restaurar backup completo usando psql (modo interativo)')
112
- .option('--file <path>', 'Caminho completo do arquivo .backup.gz a importar e restaurar (opcional)')
113
- .option('--storage <path>', 'Caminho completo do arquivo .storage.zip a importar junto com o backup (opcional)')
114
- .addHelpText('after', `
115
- ${chalk.yellow.bold('Exemplos:')}
116
- ${chalk.white('npx smoonb restore')}
117
- ${chalk.gray('# Processo interativo que lista backups disponíveis')}
127
+ .description(() => {
128
+ const getT = global.smoonbI18n?.t || t;
129
+ return getT('help.commands.restoreDesc');
130
+ })
131
+ .option('--file <path>', () => {
132
+ const getT = global.smoonbI18n?.t || t;
133
+ return getT('help.commands.restoreFile');
134
+ })
135
+ .option('--storage <path>', () => {
136
+ const getT = global.smoonbI18n?.t || t;
137
+ return getT('help.commands.restoreStorage');
138
+ })
139
+ .addHelpText('after', () => {
140
+ const getT = global.smoonbI18n?.t || t;
141
+ return `
142
+ ${chalk.yellow.bold(getT('help.commands.restoreExamples'))}
143
+ ${chalk.white(getT('help.commands.restoreExample1'))}
144
+ ${chalk.gray(getT('help.commands.restoreExample1Desc'))}
118
145
 
119
- ${chalk.white('npx smoonb restore --file "C:\\Downloads\\db_cluster-04-03-2024@14-16-59.backup.gz"')}
120
- ${chalk.gray('# Importa e restaura diretamente o arquivo de backup')}
146
+ ${chalk.white(getT('help.commands.restoreExample2'))}
147
+ ${chalk.gray(getT('help.commands.restoreExample2Desc'))}
121
148
 
122
- ${chalk.white('npx smoonb restore --file "backup.backup.gz" --storage "meu-projeto.storage.zip"')}
123
- ${chalk.gray('# Importa e restaura backup e storage juntos')}
124
-
125
- ${chalk.yellow.bold('Fluxo do restore:')}
126
- 1. Validação Docker
127
- 2. Consentimento para ler/escrever .env.local
128
- 3. Mapeamento de variáveis de ambiente
129
- 4. Seleção de backup disponível (pula se --file fornecido)
130
- 5. Seleção de componentes para restaurar
131
- 6. Resumo detalhado e confirmação
132
- 7. Execução da restauração
133
-
134
- ${chalk.yellow.bold('Quando usar --file:')}
135
- • Importa automaticamente o arquivo de backup antes de restaurar
136
- • Elimina a etapa de seleção de backup
137
- • Se --storage fornecido, importa também o arquivo de storage
138
- • Útil para restaurar backups baixados diretamente do Dashboard
139
-
140
- ${chalk.yellow.bold('Formatos suportados:')}
141
- .backup.gz (compactado) - Descompacta automaticamente
142
- .backup (descompactado) - Restaura diretamente
143
- `)
149
+ ${chalk.white(getT('help.commands.restoreExample3'))}
150
+ ${chalk.gray(getT('help.commands.restoreExample3Desc'))}
151
+
152
+ ${chalk.yellow.bold(getT('help.commands.restoreFlow'))}
153
+ ${getT('help.commands.restoreFlow1')}
154
+ ${getT('help.commands.restoreFlow2')}
155
+ ${getT('help.commands.restoreFlow3')}
156
+ ${getT('help.commands.restoreFlow4')}
157
+ ${getT('help.commands.restoreFlow5')}
158
+ ${getT('help.commands.restoreFlow6')}
159
+ ${getT('help.commands.restoreFlow7')}
160
+
161
+ ${chalk.yellow.bold(getT('help.commands.restoreWhenFile'))}
162
+ ${getT('help.commands.restoreWhenFile1')}
163
+ ${getT('help.commands.restoreWhenFile2')}
164
+ ${getT('help.commands.restoreWhenFile3')}
165
+ ${getT('help.commands.restoreWhenFile4')}
166
+
167
+ ${chalk.yellow.bold(getT('help.commands.restoreFormats'))}
168
+ ${getT('help.commands.restoreFormats1')}
169
+ ${getT('help.commands.restoreFormats2')}
170
+ `;
171
+ })
144
172
  .action(async (options) => {
145
173
  await commands.restore({ file: options.file, storage: options.storage });
146
174
  });
147
175
 
148
176
  program
149
177
  .command('check')
150
- .description('Verificar integridade do projeto Supabase após restauração')
151
- .addHelpText('after', `
152
- ${chalk.yellow.bold('Exemplos:')}
153
- ${chalk.white('npx smoonb check')}
154
- ${chalk.gray('# Verifica integridade e exibe relatório no console')}
155
-
156
- ${chalk.yellow.bold('O que é verificado:')}
157
- • Conexão com database
158
- • Extensões PostgreSQL instaladas
159
- • Tabelas criadas
160
- • Políticas RLS (Row Level Security)
161
- • Publicações Realtime
162
- • Buckets de Storage
163
- `)
178
+ .description(() => {
179
+ const getT = global.smoonbI18n?.t || t;
180
+ return getT('help.commands.checkDesc');
181
+ })
182
+ .addHelpText('after', () => {
183
+ const getT = global.smoonbI18n?.t || t;
184
+ return `
185
+ ${chalk.yellow.bold(getT('help.commands.checkExamples'))}
186
+ ${chalk.white(getT('help.commands.checkExample1'))}
187
+ ${chalk.gray(getT('help.commands.checkExample1Desc'))}
188
+
189
+ ${chalk.yellow.bold(getT('help.commands.checkWhat'))}
190
+ ${getT('help.commands.checkWhat1')}
191
+ ${getT('help.commands.checkWhat2')}
192
+ ${getT('help.commands.checkWhat3')}
193
+ ${getT('help.commands.checkWhat4')}
194
+ ${getT('help.commands.checkWhat5')}
195
+ ${getT('help.commands.checkWhat6')}
196
+ `;
197
+ })
164
198
  .action(commands.check);
165
199
 
166
200
  program
167
201
  .command('import')
168
- .description('Importar arquivo .backup.gz e opcionalmente .storage.zip do Dashboard do Supabase')
169
- .requiredOption('--file <path>', 'Caminho completo do arquivo .backup.gz a importar')
170
- .option('--storage <path>', 'Caminho completo do arquivo .storage.zip a importar (opcional)')
171
- .addHelpText('after', `
172
- ${chalk.yellow.bold('Exemplos:')}
173
- ${chalk.white('npx smoonb import --file "C:\\Downloads\\db_cluster-04-03-2024@14-16-59.backup.gz"')}
174
- ${chalk.gray('# Importa apenas o arquivo de database')}
202
+ .description(() => {
203
+ const getT = global.smoonbI18n?.t || t;
204
+ return getT('help.commands.importDesc');
205
+ })
206
+ .requiredOption('--file <path>', () => {
207
+ const getT = global.smoonbI18n?.t || t;
208
+ return getT('help.commands.importFile');
209
+ })
210
+ .option('--storage <path>', () => {
211
+ const getT = global.smoonbI18n?.t || t;
212
+ return getT('help.commands.importStorage');
213
+ })
214
+ .addHelpText('after', () => {
215
+ const getT = global.smoonbI18n?.t || t;
216
+ return `
217
+ ${chalk.yellow.bold(getT('help.commands.importExamples'))}
218
+ ${chalk.white(getT('help.commands.importExample1'))}
219
+ ${chalk.gray(getT('help.commands.importExample1Desc'))}
175
220
 
176
- ${chalk.white('npx smoonb import --file "backup.backup.gz" --storage "meu-projeto.storage.zip"')}
177
- ${chalk.gray('# Importa database e storage juntos')}
178
-
179
- ${chalk.yellow.bold('Formato dos arquivos:')}
180
- • Backup: db_cluster-DD-MM-YYYY@HH-MM-SS.backup.gz (obrigatório)
181
- • Storage: *.storage.zip (opcional)
182
-
183
- ${chalk.yellow.bold('Importante:')}
184
- • O arquivo de backup é obrigatório
185
- • O arquivo de storage é opcional e depende de um backup
186
- • Ambos os arquivos serão copiados para a mesma pasta de backup
187
- • O backup importado ficará disponível para o comando restore
188
- • Use caminhos absolutos ou relativos
189
- `)
221
+ ${chalk.white(getT('help.commands.importExample2'))}
222
+ ${chalk.gray(getT('help.commands.importExample2Desc'))}
223
+
224
+ ${chalk.yellow.bold(getT('help.commands.importFormats'))}
225
+ ${getT('help.commands.importFormats1')}
226
+ ${getT('help.commands.importFormats2')}
227
+
228
+ ${chalk.yellow.bold(getT('help.commands.importImportant'))}
229
+ ${getT('help.commands.importImportant1')}
230
+ ${getT('help.commands.importImportant2')}
231
+ ${getT('help.commands.importImportant3')}
232
+ ${getT('help.commands.importImportant4')}
233
+ ${getT('help.commands.importImportant5')}
234
+ `;
235
+ })
190
236
  .action(async (options) => {
191
237
  await commands.import({ file: options.file, storage: options.storage });
192
238
  });
193
239
 
194
240
  // Tratamento de erros
195
241
  program.on('command:*', function (operands) {
196
- console.error(chalk.red.bold(' Comando não reconhecido:'), operands[0]);
197
- console.error(chalk.yellow('💡 Use'), chalk.cyan('smoonb --help'), chalk.yellow('para ver comandos disponíveis'));
242
+ console.error(chalk.red.bold(`❌ ${t('error.commandNotFound', { command: operands[0] })}`));
243
+ console.error(chalk.yellow(`💡 ${t('error.useHelp', { cmd: 'smoonb' })}`));
198
244
  process.exit(1);
199
245
  });
200
246
 
201
247
  // Tratamento de exceções não capturadas
202
248
  process.on('uncaughtException', (error) => {
203
- console.error(chalk.red.bold(' Erro não tratado:'), error.message);
249
+ console.error(chalk.red.bold(`❌ ${t('error.uncaughtException', { message: error.message })}`));
204
250
  console.error(chalk.gray('Stack trace:'), error.stack);
205
251
  process.exit(1);
206
252
  });
207
253
 
208
254
  process.on('unhandledRejection', (reason, _promise) => {
209
- console.error(chalk.red.bold(' Promise rejeitada não tratada:'), reason);
255
+ console.error(chalk.red.bold(`❌ ${t('error.unhandledRejection', { reason: String(reason) })}`));
210
256
  process.exit(1);
211
257
  });
212
258
 
@@ -219,6 +265,19 @@ if (process.argv.length === 2) {
219
265
  // Parse dos argumentos da linha de comando
220
266
  program.parse(process.argv);
221
267
 
268
+ // Re-inicializar i18n se --lang foi fornecido (após parse)
269
+ // Criar um novo argv com --lang para detectLocale
270
+ const options = program.opts();
271
+ if (options.lang) {
272
+ const { initI18n, detectLocale } = require('../src/i18n');
273
+ // Forçar detecção do locale fornecido
274
+ const forcedLocale = detectLocale(['--lang', options.lang], process.env);
275
+ const newI18n = initI18n(['--lang', forcedLocale], { ...process.env, SMOONB_LANG: forcedLocale });
276
+ i18n = newI18n;
277
+ t = newI18n.t;
278
+ Object.assign(global.smoonbI18n, newI18n);
279
+ }
280
+
222
281
  // Se nenhum comando foi fornecido, mostrar ajuda
223
282
  if (!process.argv.slice(2).length) {
224
283
  program.outputHelp();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smoonb",
3
- "version": "0.0.71",
3
+ "version": "0.0.73",
4
4
  "description": "Complete Supabase backup and migration tool - EXPERIMENTAL VERSION - USE AT YOUR OWN RISK",
5
5
  "preferGlobal": false,
6
6
  "preventGlobalInstall": true,
@@ -15,7 +15,8 @@
15
15
  "postinstall": "echo '\\n✅ smoonb instalado com sucesso!\\n💡 Execute: npx smoonb backup\\n📖 Documentação: https://github.com/almmello/smoonb\\n'",
16
16
  "lint": "eslint . --ext .js",
17
17
  "lint:fix": "eslint . --ext .js --fix",
18
- "build": "npm run lint"
18
+ "build": "node scripts/build.js",
19
+ "build:check": "node scripts/build.js"
19
20
  },
20
21
  "keywords": [
21
22
  "supabase",
@@ -55,6 +56,8 @@
55
56
  "bin/",
56
57
  "src/",
57
58
  "README.md",
58
- "LICENSE.md"
59
+ "README.pt-BR.md",
60
+ "LICENSE",
61
+ "LICENSE.pt-BR.md"
59
62
  ]
60
63
  }
@@ -27,15 +27,17 @@ module.exports = async (options) => {
27
27
  showBetaBanner();
28
28
 
29
29
  try {
30
+ const { t } = require('../../i18n');
31
+ const getT = global.smoonbI18n?.t || t;
32
+
30
33
  // Termo de uso e aviso de risco
31
- console.log(chalk.yellow.bold('\n⚠️ TERMO DE USO E AVISO DE RISCO\n'));
32
- console.log(chalk.white('Ao prosseguir, você reconhece e concorda que o Supa Moonbase (smoonb) é fornecido "NO ESTADO EM QUE SE ENCONTRA" ("AS IS") e "CONFORME DISPONIBILIDADE", sem garantias de qualquer natureza—expressas, implícitas ou legais—incluindo, sem limitação, garantias de comercialização, adequação a um fim específico e não violação, na máxima extensão permitida pela lei aplicável. Operações de backup e restauração envolvem riscos, os ambientes variam amplamente e não é possível prever ou validar todas as configurações dos usuários. Você é o único responsável por validar seu ambiente, manter cópias independentes e verificar os resultados antes de utilizá-los em produção. O Supa Moonbase (smoonb) é construído com repositórios públicos, auditáveis e software livre, para auxiliar pessoas a simplificar seus fluxos, sem com isso criar qualquer garantia, promessa de suporte ou compromisso de nível de serviço.\n'));
33
- console.log(chalk.white('Limitação de responsabilidade (PT-BR) — Na máxima extensão permitida por lei, a Goalmoon, seus contribuidores e licenciadores não serão responsáveis por danos indiretos, incidentais, especiais, consequentes, exemplares ou punitivos (incluindo perda de dados, interrupção de negócios ou lucros cessantes) decorrentes do uso, incapacidade de uso, das operações de backup/restauração realizadas com, ou dos resultados gerados pelo Supa Moonbase (smoonb). Em qualquer hipótese, a responsabilidade total por todas as reivindicações relacionadas ao Supa Moonbase (smoonb) não excederá o valor pago por você pelo Supa Moonbase (smoonb) nos 12 meses anteriores ao evento. Nada neste aviso exclui ou limita responsabilidades onde tais limites sejam proibidos por lei, incluindo (conforme aplicável) dolo ou culpa grave.\n'));
34
- console.log(chalk.white('Observação para consumidores no Brasil (PT-BR) — Para consumidores brasileiros, este aviso não afasta direitos irrenunciáveis previstos no Código de Defesa do Consumidor (CDC); qualquer limitação aqui prevista só se aplica nos limites da lei e não impede a indenização obrigatória quando cabível.\n'));
34
+ console.log(chalk.yellow.bold(`\n⚠️ ${getT('disclaimer.title')}\n`));
35
+ console.log(chalk.white(`${getT('disclaimer.text')}\n`));
36
+ console.log(chalk.white(`${getT('disclaimer.limitation')}\n`));
35
37
 
36
- const termsAccepted = await confirm('Você aceita os Termos de Uso e o Aviso de Risco de Backup?', true);
38
+ const termsAccepted = await confirm(getT('disclaimer.acceptBackup'), true);
37
39
  if (!termsAccepted) {
38
- console.log(chalk.red('🚫 Operação cancelada pelo usuário.'));
40
+ console.log(chalk.red(`🚫 ${getT('disclaimer.operationCancelled')}`));
39
41
  process.exit(1);
40
42
  }
41
43
 
@@ -43,13 +45,12 @@ module.exports = async (options) => {
43
45
  await step00DockerValidation();
44
46
 
45
47
  // Consentimento para leitura e escrita do .env.local
46
- console.log(chalk.yellow('\n⚠️ O smoonb irá ler e escrever o arquivo .env.local localmente.'));
47
- console.log(chalk.yellow(' Um backup automático do .env.local será criado antes de qualquer alteração.'));
48
- console.log(chalk.yellow(' Vamos mapear suas variáveis de ambiente para garantir que todas as chaves necessárias'));
49
- console.log(chalk.yellow(' estejam presentes e com os valores corretos do projeto alvo.'));
50
- const consentOk = await confirm('Você consente em prosseguir', true);
48
+ console.log(chalk.yellow(`\n⚠️ ${getT('consent.title')}`));
49
+ console.log(chalk.yellow(` ${getT('consent.backup')}`));
50
+ console.log(chalk.yellow(` ${getT('consent.mapping')}`));
51
+ const consentOk = await confirm(getT('consent.proceed'), true);
51
52
  if (!consentOk) {
52
- console.log(chalk.red('🚫 Operação cancelada pelo usuário.'));
53
+ console.log(chalk.red(`🚫 ${getT('disclaimer.operationCancelled')}`));
53
54
  process.exit(1);
54
55
  }
55
56
 
@@ -1,63 +1,57 @@
1
1
  const chalk = require('chalk');
2
+ const { t } = require('../../i18n');
2
3
 
3
4
  /**
4
5
  * Função para mostrar mensagens educativas e encerrar elegantemente
5
6
  */
6
7
  function showDockerMessagesAndExit(reason) {
8
+ const getT = global.smoonbI18n?.t || t;
9
+
7
10
  console.log('');
8
11
 
9
12
  switch (reason) {
10
13
  case 'docker_not_installed':
11
- console.log(chalk.red('❌ DOCKER DESKTOP NÃO ENCONTRADO'));
14
+ console.log(chalk.red(`❌ ${getT('docker.notInstalled')}`));
12
15
  console.log('');
13
- console.log(chalk.yellow('📋 Para fazer backup completo do Supabase, você precisa:'));
14
- console.log(chalk.yellow(' 1. Instalar Docker Desktop'));
15
- console.log(chalk.yellow(' 2. Executar Docker Desktop'));
16
- console.log(chalk.yellow(' 3. Repetir o comando de backup'));
16
+ console.log(chalk.yellow(`📋 ${getT('docker.instructions')}`));
17
+ console.log(chalk.yellow(` 1. ${getT('docker.installDocker')}`));
18
+ console.log(chalk.yellow(` 2. ${getT('docker.runDocker')}`));
19
+ console.log(chalk.yellow(` 3. ${getT('docker.repeatCommand')}`));
17
20
  console.log('');
18
- console.log(chalk.blue('🔗 Download: https://docs.docker.com/desktop/install/'));
21
+ console.log(chalk.blue(`🔗 ${getT('docker.download')}`));
19
22
  console.log('');
20
- console.log(chalk.gray('💡 O Docker Desktop é obrigatório para backup completo do Supabase'));
21
- console.log(chalk.gray(' - Database PostgreSQL'));
22
- console.log(chalk.gray(' - Edge Functions'));
23
- console.log(chalk.gray(' - Todos os componentes via Supabase CLI'));
23
+ console.log(chalk.gray(`💡 ${getT('docker.requiredComponents')}`));
24
24
  break;
25
25
 
26
26
  case 'docker_not_running':
27
- console.log(chalk.red('❌ DOCKER DESKTOP NÃO ESTÁ EXECUTANDO'));
27
+ console.log(chalk.red(`❌ ${getT('docker.notRunning')}`));
28
28
  console.log('');
29
- console.log(chalk.yellow('📋 Para fazer backup completo do Supabase, você precisa:'));
30
- console.log(chalk.yellow(' 1. Abrir Docker Desktop'));
31
- console.log(chalk.yellow(' 2. Aguardar inicialização completa'));
32
- console.log(chalk.yellow(' 3. Repetir o comando de backup'));
29
+ console.log(chalk.yellow(`📋 ${getT('docker.instructions')}`));
30
+ console.log(chalk.yellow(` 1. ${getT('docker.runDocker')}`));
31
+ console.log(chalk.yellow(` 2. ${getT('docker.waitInitialization')}`));
32
+ console.log(chalk.yellow(` 3. ${getT('docker.repeatCommand')}`));
33
33
  console.log('');
34
- console.log(chalk.blue('💡 Dica: Docker Desktop deve estar rodando em segundo plano'));
34
+ console.log(chalk.blue(`💡 ${getT('docker.tip')}`));
35
35
  console.log('');
36
- console.log(chalk.gray('💡 O Docker Desktop é obrigatório para backup completo do Supabase'));
37
- console.log(chalk.gray(' - Database PostgreSQL'));
38
- console.log(chalk.gray(' - Edge Functions'));
39
- console.log(chalk.gray(' - Todos os componentes via Supabase CLI'));
36
+ console.log(chalk.gray(`💡 ${getT('docker.requiredComponents')}`));
40
37
  break;
41
38
 
42
39
  case 'supabase_cli_not_found':
43
- console.log(chalk.red('❌ SUPABASE CLI NÃO ENCONTRADO'));
40
+ console.log(chalk.red(`❌ ${getT('supabase.cliNotFound')}`));
44
41
  console.log('');
45
- console.log(chalk.yellow('📋 Para fazer backup completo do Supabase, você precisa:'));
46
- console.log(chalk.yellow(' 1. Instalar Supabase CLI'));
47
- console.log(chalk.yellow(' 2. Repetir o comando de backup'));
42
+ console.log(chalk.yellow(`📋 ${getT('supabase.installInstructions')}`));
43
+ console.log(chalk.yellow(` 1. ${getT('supabase.installCli')}`));
44
+ console.log(chalk.yellow(` 2. ${getT('supabase.repeatCommand')}`));
48
45
  console.log('');
49
- console.log(chalk.blue('🔗 Instalação: npm install -g supabase'));
46
+ console.log(chalk.blue(`🔗 ${getT('supabase.installLink')}`));
50
47
  console.log('');
51
- console.log(chalk.gray('💡 O Supabase CLI é obrigatório para backup completo do Supabase'));
52
- console.log(chalk.gray(' - Database PostgreSQL'));
53
- console.log(chalk.gray(' - Edge Functions'));
54
- console.log(chalk.gray(' - Todos os componentes via Docker'));
48
+ console.log(chalk.gray(`💡 ${getT('supabase.requiredComponents')}`));
55
49
  break;
56
50
  }
57
51
 
58
52
  console.log('');
59
- console.log(chalk.red('🚫 Backup cancelado - Pré-requisitos não atendidos'));
60
- console.log(chalk.gray(' Instale os componentes necessários e tente novamente'));
53
+ console.log(chalk.red(`🚫 ${getT('docker.cancelled')}`));
54
+ console.log(chalk.gray(` ${getT('docker.installComponents')}`));
61
55
  console.log('');
62
56
 
63
57
  process.exit(1);
@@ -5,17 +5,20 @@ const { readConfig, validateFor } = require('../utils/config');
5
5
  const { writeJson } = require('../utils/fsx');
6
6
  const { IntrospectionService } = require('../services/introspect');
7
7
  const { showBetaBanner } = require('../utils/banner');
8
+ const { t } = require('../i18n');
8
9
 
9
10
  // Exportar FUNÇÃO em vez de objeto Command
10
11
  module.exports = async () => {
11
12
  showBetaBanner();
12
13
 
13
14
  try {
15
+ const getT = global.smoonbI18n?.t || t;
16
+
14
17
  // Verificar se psql está disponível
15
18
  const psqlPath = await ensureBin('psql');
16
19
  if (!psqlPath) {
17
- console.error(chalk.red('❌ psql não encontrado'));
18
- console.log(chalk.yellow('💡 Instale PostgreSQL:'));
20
+ console.error(chalk.red(`❌ ${getT('check.psqlNotFound')}`));
21
+ console.log(chalk.yellow(`💡 ${getT('check.installPostgres')}`));
19
22
  console.log(chalk.yellow(' https://www.postgresql.org/download/'));
20
23
  process.exit(1);
21
24
  }
@@ -26,12 +29,12 @@ module.exports = async () => {
26
29
 
27
30
  const databaseUrl = config.supabase.databaseUrl;
28
31
  if (!databaseUrl) {
29
- console.error(chalk.red('❌ databaseUrl não configurada'));
30
- console.log(chalk.yellow('💡 Configure databaseUrl no .smoonbrc'));
32
+ console.error(chalk.red(`❌ ${getT('check.databaseUrlNotConfigured')}`));
33
+ console.log(chalk.yellow(`💡 ${getT('check.configureDatabaseUrl')}`));
31
34
  process.exit(1);
32
35
  }
33
36
 
34
- console.log(chalk.blue(`🔍 Verificando integridade do projeto: ${config.supabase.projectId}`));
37
+ console.log(chalk.blue(`🔍 ${getT('check.start', { projectId: config.supabase.projectId })}`));
35
38
 
36
39
  // Executar verificações
37
40
  const report = await performChecks(config, databaseUrl);
@@ -43,11 +46,12 @@ module.exports = async () => {
43
46
  // Mostrar resumo
44
47
  showCheckSummary(report);
45
48
 
46
- console.log(chalk.green('\n🎉 Verificação concluída!'));
47
- console.log(chalk.blue(`📋 Relatório salvo em: ${reportPath}`));
49
+ console.log(chalk.green(`\n🎉 ${getT('check.done')}`));
50
+ console.log(chalk.blue(`📋 ${getT('check.reportSaved', { path: reportPath })}`));
48
51
 
49
52
  } catch (error) {
50
- console.error(chalk.red(`❌ Erro na verificação: ${error.message}`));
53
+ const getT = global.smoonbI18n?.t || t;
54
+ console.error(chalk.red(`❌ ${getT('check.error', { message: error.message })}`));
51
55
  process.exit(1);
52
56
  }
53
57
  };