smoonb 0.0.63 → 0.0.64

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smoonb",
3
- "version": "0.0.63",
3
+ "version": "0.0.64",
4
4
  "description": "Complete Supabase backup and migration tool - EXPERIMENTAL VERSION - USE AT YOUR OWN RISK",
5
5
  "preferGlobal": false,
6
6
  "preventGlobalInstall": true,
@@ -73,8 +73,16 @@ module.exports = async (options) => {
73
73
  const envPath = path.join(process.cwd(), '.env.local');
74
74
  const envBackupPath = path.join(backupDir, 'env', '.env.local');
75
75
  await ensureDir(path.dirname(envBackupPath));
76
- await backupEnvFile(envPath, envBackupPath);
77
- console.log(chalk.blue(`📁 Backup do .env.local: ${path.relative(process.cwd(), envBackupPath)}`));
76
+
77
+ // Verificar se o arquivo existe antes de fazer backup
78
+ try {
79
+ await fs.access(envPath);
80
+ await backupEnvFile(envPath, envBackupPath);
81
+ console.log(chalk.blue(`📁 Backup do .env.local: ${path.relative(process.cwd(), envBackupPath)}`));
82
+ } catch {
83
+ // Arquivo não existe, não fazer backup
84
+ console.log(chalk.yellow('⚠️ Arquivo .env.local não encontrado. Será criado durante o mapeamento.'));
85
+ }
78
86
 
79
87
  const expectedKeys = [
80
88
  'SUPABASE_PROJECT_ID',
@@ -135,8 +135,16 @@ module.exports = async (options) => {
135
135
  // Backup do .env.local
136
136
  const envPath = path.join(process.cwd(), '.env.local');
137
137
  const envBackupPath = path.join(processDir, 'env', '.env.local');
138
- await backupEnvFile(envPath, envBackupPath);
139
- console.log(chalk.blue(`📁 Backup do .env.local: ${path.relative(process.cwd(), envBackupPath)}`));
138
+
139
+ // Verificar se o arquivo existe antes de fazer backup
140
+ try {
141
+ await fsPromises.access(envPath);
142
+ await backupEnvFile(envPath, envBackupPath);
143
+ console.log(chalk.blue(`📁 Backup do .env.local: ${path.relative(process.cwd(), envBackupPath)}`));
144
+ } catch {
145
+ // Arquivo não existe, não fazer backup
146
+ console.log(chalk.yellow('⚠️ Arquivo .env.local não encontrado. Será criado durante o mapeamento.'));
147
+ }
140
148
 
141
149
  // Leitura e mapeamento interativo
142
150
  const currentEnv = await readEnvFile(envPath);
@@ -38,22 +38,22 @@ async function mapEnvVariablesInteractively(env, expectedKeys) {
38
38
  'NEXT_PUBLIC_SUPABASE_URL': {
39
39
  notFound: 'Não foi encontrada uma entrada para a variável NEXT_PUBLIC_SUPABASE_URL.',
40
40
  help: currentProjectId
41
- ? `Acesse: https://supabase.com/dashboard/project/${currentProjectId}/settings/api`
42
- : 'Acesse: Dashboard -> Project Settings -> API -> Project URL',
41
+ ? `https://supabase.com/dashboard/project/${currentProjectId}/settings/api`
42
+ : 'Dashboard -> Project Settings -> API -> Project URL',
43
43
  link: currentProjectId ? `https://supabase.com/dashboard/project/${currentProjectId}/settings/api` : null
44
44
  },
45
45
  'NEXT_PUBLIC_SUPABASE_ANON_KEY': {
46
46
  notFound: 'Não foi encontrada uma entrada para a variável NEXT_PUBLIC_SUPABASE_ANON_KEY.',
47
47
  help: currentProjectId
48
- ? `Acesse: https://supabase.com/dashboard/project/${currentProjectId}/settings/api-keys`
49
- : 'Acesse: Dashboard -> Project Settings -> API -> API Keys -> anon public',
48
+ ? `https://supabase.com/dashboard/project/${currentProjectId}/settings/api-keys`
49
+ : 'Dashboard -> Project Settings -> API -> API Keys -> anon public',
50
50
  link: currentProjectId ? `https://supabase.com/dashboard/project/${currentProjectId}/settings/api-keys` : null
51
51
  },
52
52
  'SUPABASE_SERVICE_ROLE_KEY': {
53
53
  notFound: 'Não foi encontrada uma entrada para a variável SUPABASE_SERVICE_ROLE_KEY.',
54
54
  help: currentProjectId
55
- ? `Acesse: https://supabase.com/dashboard/project/${currentProjectId}/settings/api-keys`
56
- : 'Acesse: Dashboard -> Project Settings -> API -> API Keys -> service_role secret',
55
+ ? `https://supabase.com/dashboard/project/${currentProjectId}/settings/api-keys`
56
+ : 'Dashboard -> Project Settings -> API -> API Keys -> service_role secret',
57
57
  link: currentProjectId ? `https://supabase.com/dashboard/project/${currentProjectId}/settings/api-keys` : null
58
58
  },
59
59
  'SUPABASE_DB_URL': {
@@ -65,7 +65,7 @@ async function mapEnvVariablesInteractively(env, expectedKeys) {
65
65
  },
66
66
  'SUPABASE_ACCESS_TOKEN': {
67
67
  notFound: 'Não foi encontrada uma entrada para a variável SUPABASE_ACCESS_TOKEN.',
68
- help: 'Acesse: https://supabase.com/dashboard/account/tokens',
68
+ help: 'https://supabase.com/dashboard/account/tokens',
69
69
  link: 'https://supabase.com/dashboard/account/tokens'
70
70
  },
71
71
  'SMOONB_OUTPUT_DIR': {
@@ -91,8 +91,8 @@ async function mapEnvVariablesInteractively(env, expectedKeys) {
91
91
  // Se existir chave exatamente igual, pular seleção e ir direto para confirmação
92
92
  if (Object.prototype.hasOwnProperty.call(finalEnv, expected)) {
93
93
  clientKey = expected;
94
- } else {
95
- // Opção explícita para adicionar nova chave
94
+ } else if (allKeys.length > 0) {
95
+ // mostrar seleção se houver chaves disponíveis no env
96
96
  const choices = [
97
97
  ...allKeys.map((k, idx) => ({ name: `${idx + 1}. ${k}`, value: k })),
98
98
  new inquirer.Separator(),
@@ -119,19 +119,31 @@ async function mapEnvVariablesInteractively(env, expectedKeys) {
119
119
  }
120
120
  finalEnv[clientKey] = '';
121
121
  }
122
+ } else {
123
+ // Se não há chaves no env, criar nova chave diretamente
124
+ clientKey = expected;
125
+ finalEnv[clientKey] = '';
122
126
  }
123
127
 
124
128
  const currentValue = finalEnv[clientKey] ?? '';
125
129
  const currentProjectId = getProjectId();
126
130
  const instructions = getVariableInstructions(expected, currentProjectId);
127
131
 
128
- // Se não tem valor, mostrar mensagem específica
132
+ // Se não tem valor, mostrar mensagem específica e pular confirmação
129
133
  if (!currentValue) {
130
134
  console.log(chalk.yellow(instructions.notFound));
131
135
  if (instructions.help) {
132
- console.log(chalk.white(instructions.help));
133
- }
134
- if (instructions.link) {
136
+ // Se o help contém link (https://), mostrar como link
137
+ if (instructions.help.includes('https://')) {
138
+ console.log(chalk.cyan(`🔗 ${instructions.help}`));
139
+ } else {
140
+ console.log(chalk.white(instructions.help));
141
+ // Se há link separado e o help não contém link, mostrar link separado
142
+ if (instructions.link && !instructions.help.includes('https://')) {
143
+ console.log(chalk.cyan(`🔗 ${instructions.link}`));
144
+ }
145
+ }
146
+ } else if (instructions.link) {
135
147
  console.log(chalk.cyan(`🔗 ${instructions.link}`));
136
148
  }
137
149
  } else {
package/src/utils/env.js CHANGED
@@ -81,10 +81,12 @@ async function writeEnvFile(filePath, entries, _options = {}) {
81
81
  async function backupEnvFile(srcPath, destPath) {
82
82
  await fsp.mkdir(path.dirname(destPath), { recursive: true });
83
83
  try {
84
+ // Verificar se o arquivo existe antes de fazer backup
85
+ await fsp.access(srcPath);
84
86
  await fsp.copyFile(srcPath, destPath);
85
87
  } catch (e) {
86
88
  if (e.code === 'ENOENT') {
87
- await fsp.writeFile(destPath, '', 'utf8');
89
+ // Arquivo não existe, não fazer backup de arquivo vazio
88
90
  return;
89
91
  }
90
92
  throw e;