smoonb 0.0.86 → 0.0.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/README.pt-BR.md +2 -0
- package/package.json +2 -2
- package/src/commands/backup/steps/00-docker-validation.js +1 -1
- package/src/commands/backup/utils.js +21 -1
- package/src/i18n/locales/en.json +8 -0
- package/src/i18n/locales/pt-BR.json +8 -0
- package/src/utils/docker.js +80 -1
package/README.md
CHANGED
|
@@ -91,6 +91,8 @@ docker ps
|
|
|
91
91
|
npm install -g supabase
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
We recommend **Supabase CLI v2.72 or newer** for new features and bug fixes. To update: [Updating the Supabase CLI](https://supabase.com/docs/guides/cli/getting-started#updating-the-supabase-cli).
|
|
95
|
+
|
|
94
96
|
### 3. Supabase Personal Access Token
|
|
95
97
|
You need to obtain a Supabase personal access token to use the Management API:
|
|
96
98
|
|
package/README.pt-BR.md
CHANGED
|
@@ -91,6 +91,8 @@ docker ps
|
|
|
91
91
|
npm install -g supabase
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
Recomendamos **Supabase CLI v2.72 ou mais recente** para novos recursos e correções. Para atualizar: [Atualizando o Supabase CLI](https://supabase.com/docs/guides/cli/getting-started#updating-the-supabase-cli).
|
|
95
|
+
|
|
94
96
|
### 3. Personal Access Token do Supabase
|
|
95
97
|
É necessário obter um token de acesso pessoal do Supabase para usar a Management API:
|
|
96
98
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smoonb",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.87",
|
|
4
4
|
"description": "Complete Supabase backup and migration tool - EXPERIMENTAL VERSION - USE AT YOUR OWN RISK",
|
|
5
5
|
"preferGlobal": false,
|
|
6
6
|
"preventGlobalInstall": true,
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"node": ">=16.0.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@supabase/supabase-js": "^2.
|
|
37
|
+
"@supabase/supabase-js": "^2.93.0",
|
|
38
38
|
"adm-zip": "^0.5.16",
|
|
39
39
|
"chalk": "^4.1.2",
|
|
40
40
|
"commander": "^11.1.0",
|
|
@@ -15,7 +15,7 @@ module.exports = async () => {
|
|
|
15
15
|
const backupCapability = await canPerformCompleteBackup();
|
|
16
16
|
|
|
17
17
|
if (!backupCapability.canBackupComplete) {
|
|
18
|
-
showDockerMessagesAndExit(backupCapability.reason);
|
|
18
|
+
showDockerMessagesAndExit(backupCapability.reason, backupCapability);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
console.log(chalk.green(`✅ ${getT('docker.validation.detected')}`));
|
|
@@ -3,8 +3,10 @@ const { t } = require('../../i18n');
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Função para mostrar mensagens educativas e encerrar elegantemente
|
|
6
|
+
* @param {string} reason - Motivo do bloqueio
|
|
7
|
+
* @param {object} [data] - Dados extras (ex: { supabaseCliVersion } para supabase_cli_outdated)
|
|
6
8
|
*/
|
|
7
|
-
function showDockerMessagesAndExit(reason) {
|
|
9
|
+
function showDockerMessagesAndExit(reason, data = {}) {
|
|
8
10
|
const getT = global.smoonbI18n?.t || t;
|
|
9
11
|
|
|
10
12
|
console.log('');
|
|
@@ -47,6 +49,24 @@ function showDockerMessagesAndExit(reason) {
|
|
|
47
49
|
console.log('');
|
|
48
50
|
console.log(chalk.gray(`💡 ${getT('supabase.requiredComponents')}`));
|
|
49
51
|
break;
|
|
52
|
+
|
|
53
|
+
case 'supabase_cli_outdated':
|
|
54
|
+
console.log(chalk.red(`❌ ${getT('supabase.cliOutdated', { version: data.supabaseCliVersion || '?', latest: data.supabaseCliLatest || '?' })}`));
|
|
55
|
+
console.log('');
|
|
56
|
+
console.log(chalk.yellow(`📋 ${getT('supabase.cliUpdateInstructions')}`));
|
|
57
|
+
console.log(chalk.cyan(` ${getT('supabase.cliUpdateCommand')}`));
|
|
58
|
+
console.log('');
|
|
59
|
+
console.log(chalk.gray(`💡 ${getT('supabase.cliUpdateLink')}`));
|
|
60
|
+
break;
|
|
61
|
+
|
|
62
|
+
case 'supabase_cli_latest_unknown':
|
|
63
|
+
console.log(chalk.red(`❌ ${getT('supabase.cliLatestUnknown')}`));
|
|
64
|
+
console.log('');
|
|
65
|
+
console.log(chalk.yellow(`📋 ${getT('supabase.cliLatestErrorLabel')}`));
|
|
66
|
+
console.log(chalk.gray(` ${data.latestError || getT('supabase.cliLatestErrorUnknown')}`));
|
|
67
|
+
console.log('');
|
|
68
|
+
console.log(chalk.gray(`💡 ${getT('supabase.cliUpdateLink')}`));
|
|
69
|
+
break;
|
|
50
70
|
}
|
|
51
71
|
|
|
52
72
|
console.log('');
|
package/src/i18n/locales/en.json
CHANGED
|
@@ -72,6 +72,14 @@
|
|
|
72
72
|
"supabase.installLink": "Installation: npm install -g supabase",
|
|
73
73
|
"supabase.required": "Supabase CLI is required for full Supabase backup",
|
|
74
74
|
"supabase.requiredComponents": "Supabase CLI is required for full Supabase backup\n - PostgreSQL Database\n - Edge Functions\n - All components via Docker",
|
|
75
|
+
"supabase.cliUpdateRecommended": "Supabase CLI {version} detected. We recommend v2.72 or newer for new features and bug fixes: https://supabase.com/docs/guides/cli/getting-started#updating-the-supabase-cli",
|
|
76
|
+
"supabase.cliOutdated": "Supabase CLI {version} is not the latest ({latest}). Update to the latest version.",
|
|
77
|
+
"supabase.cliUpdateInstructions": "Update the Supabase CLI and run smoonb again:",
|
|
78
|
+
"supabase.cliUpdateCommand": "npm install -g supabase@latest",
|
|
79
|
+
"supabase.cliUpdateLink": "Docs: https://supabase.com/docs/guides/cli/getting-started#updating-the-supabase-cli",
|
|
80
|
+
"supabase.cliLatestUnknown": "Could not fetch the latest Supabase CLI version. Cannot continue.",
|
|
81
|
+
"supabase.cliLatestErrorLabel": "Error:",
|
|
82
|
+
"supabase.cliLatestErrorUnknown": "Unknown error",
|
|
75
83
|
|
|
76
84
|
"backup.components": "Backup Components:",
|
|
77
85
|
"backup.database": "Database PostgreSQL (pg_dumpall + separate SQL)",
|
|
@@ -72,6 +72,14 @@
|
|
|
72
72
|
"supabase.installLink": "Instalação: npm install -g supabase",
|
|
73
73
|
"supabase.required": "Supabase CLI é obrigatório para backup completo do Supabase",
|
|
74
74
|
"supabase.requiredComponents": "Supabase CLI é obrigatório para backup completo do Supabase\n - Database PostgreSQL\n - Edge Functions\n - Todos os componentes via Docker",
|
|
75
|
+
"supabase.cliUpdateRecommended": "Supabase CLI {version} detectado. Recomendamos v2.72 ou mais recente para novos recursos e correções: https://supabase.com/docs/guides/cli/getting-started#updating-the-supabase-cli",
|
|
76
|
+
"supabase.cliOutdated": "Supabase CLI {version} não é a versão mais recente ({latest}). Atualize para a última versão.",
|
|
77
|
+
"supabase.cliUpdateInstructions": "Atualize o Supabase CLI e execute o smoonb novamente:",
|
|
78
|
+
"supabase.cliUpdateCommand": "npm install -g supabase@latest",
|
|
79
|
+
"supabase.cliUpdateLink": "Documentação: https://supabase.com/docs/guides/cli/getting-started#updating-the-supabase-cli",
|
|
80
|
+
"supabase.cliLatestUnknown": "Não foi possível obter a última versão do Supabase CLI. Não é possível continuar.",
|
|
81
|
+
"supabase.cliLatestErrorLabel": "Erro:",
|
|
82
|
+
"supabase.cliLatestErrorUnknown": "Erro desconhecido",
|
|
75
83
|
|
|
76
84
|
"backup.components": "Componentes de Backup:",
|
|
77
85
|
"backup.database": "Database PostgreSQL (pg_dumpall + SQL separados)",
|
package/src/utils/docker.js
CHANGED
|
@@ -37,7 +37,6 @@ async function detectDockerRunning() {
|
|
|
37
37
|
*/
|
|
38
38
|
async function detectSupabaseCLI() {
|
|
39
39
|
try {
|
|
40
|
-
// Tentar executar supabase --version
|
|
41
40
|
await execAsync('supabase --version');
|
|
42
41
|
return true;
|
|
43
42
|
} catch {
|
|
@@ -45,6 +44,62 @@ async function detectSupabaseCLI() {
|
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Obtém a versão instalada do Supabase CLI (ex: "2.51.0").
|
|
49
|
+
* @returns {Promise<string|null>} Semver ou null se não disponível
|
|
50
|
+
*/
|
|
51
|
+
async function getSupabaseCLIVersion() {
|
|
52
|
+
try {
|
|
53
|
+
const { stdout } = await execAsync('supabase --version');
|
|
54
|
+
const match = stdout.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
55
|
+
return match ? `${match[1]}.${match[2]}.${match[3]}` : null;
|
|
56
|
+
} catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Obtém a versão latest do Supabase CLI no npm.
|
|
63
|
+
* @returns {Promise<{version: string|null, error: string|null}>} version ou error preenchido
|
|
64
|
+
*/
|
|
65
|
+
async function getSupabaseCLILatestVersion() {
|
|
66
|
+
try {
|
|
67
|
+
const res = await fetch('https://registry.npmjs.org/supabase/latest', {
|
|
68
|
+
headers: { Accept: 'application/json' }
|
|
69
|
+
});
|
|
70
|
+
if (!res.ok) {
|
|
71
|
+
return { version: null, error: `HTTP ${res.status} ${res.statusText}` };
|
|
72
|
+
}
|
|
73
|
+
const data = await res.json();
|
|
74
|
+
const version = data.version || null;
|
|
75
|
+
if (!version) {
|
|
76
|
+
return { version: null, error: 'Resposta do registro npm sem campo version' };
|
|
77
|
+
}
|
|
78
|
+
return { version, error: null };
|
|
79
|
+
} catch (err) {
|
|
80
|
+
const message = err && typeof err.message === 'string' ? err.message : String(err);
|
|
81
|
+
return { version: null, error: message };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Compara duas versões semver (ex: "2.51.0", "2.72.7").
|
|
87
|
+
* @param {string} a
|
|
88
|
+
* @param {string} b
|
|
89
|
+
* @returns {number} -1 se a < b, 0 se a === b, 1 se a > b
|
|
90
|
+
*/
|
|
91
|
+
function compareSemver(a, b) {
|
|
92
|
+
const pa = a.split('.').map(Number);
|
|
93
|
+
const pb = b.split('.').map(Number);
|
|
94
|
+
for (let i = 0; i < 3; i++) {
|
|
95
|
+
const va = pa[i] || 0;
|
|
96
|
+
const vb = pb[i] || 0;
|
|
97
|
+
if (va < vb) return -1;
|
|
98
|
+
if (va > vb) return 1;
|
|
99
|
+
}
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
48
103
|
/**
|
|
49
104
|
* Detecta Docker Desktop completo com versão
|
|
50
105
|
* @returns {Promise<{installed: boolean, running: boolean, version: string}>}
|
|
@@ -133,6 +188,27 @@ async function canPerformCompleteBackup() {
|
|
|
133
188
|
dockerStatus
|
|
134
189
|
};
|
|
135
190
|
}
|
|
191
|
+
|
|
192
|
+
const supabaseCliVersion = await getSupabaseCLIVersion();
|
|
193
|
+
const latestResult = await getSupabaseCLILatestVersion();
|
|
194
|
+
if (latestResult.error) {
|
|
195
|
+
return {
|
|
196
|
+
canBackupComplete: false,
|
|
197
|
+
reason: 'supabase_cli_latest_unknown',
|
|
198
|
+
latestError: latestResult.error,
|
|
199
|
+
supabaseCliVersion: supabaseCliVersion || null,
|
|
200
|
+
dockerStatus
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
if (supabaseCliVersion && latestResult.version && compareSemver(supabaseCliVersion, latestResult.version) < 0) {
|
|
204
|
+
return {
|
|
205
|
+
canBackupComplete: false,
|
|
206
|
+
reason: 'supabase_cli_outdated',
|
|
207
|
+
supabaseCliVersion,
|
|
208
|
+
supabaseCliLatest: latestResult.version,
|
|
209
|
+
dockerStatus
|
|
210
|
+
};
|
|
211
|
+
}
|
|
136
212
|
|
|
137
213
|
return {
|
|
138
214
|
canBackupComplete: true,
|
|
@@ -147,5 +223,8 @@ module.exports = {
|
|
|
147
223
|
detectDockerDependencies,
|
|
148
224
|
detectDockerDesktop,
|
|
149
225
|
getDockerVersion,
|
|
226
|
+
getSupabaseCLIVersion,
|
|
227
|
+
getSupabaseCLILatestVersion,
|
|
228
|
+
compareSemver,
|
|
150
229
|
canPerformCompleteBackup
|
|
151
230
|
};
|