@dbcube/cli 3.2.1 → 3.2.3
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/bun.lock +22 -22
- package/package.json +3 -3
- package/src/commands/help.js +16 -3
- package/src/commands/run/download.js +300 -0
- package/src/commands/run/upgrade.js +302 -0
- package/src/commands/version.js +2 -2
- package/src/index.js +3 -0
package/bun.lock
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
"": {
|
|
5
5
|
"name": "@dbcube/cli",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@dbcube/schema-builder": "^3.2.
|
|
8
|
-
"@inquirer/prompts": "^7.
|
|
7
|
+
"@dbcube/schema-builder": "^3.2.3",
|
|
8
|
+
"@inquirer/prompts": "^7.10.1",
|
|
9
9
|
"alwait": "^1.0.0",
|
|
10
10
|
"chalk": "^5.6.2",
|
|
11
11
|
"dotenv": "^17.2.3",
|
|
@@ -16,41 +16,41 @@
|
|
|
16
16
|
},
|
|
17
17
|
},
|
|
18
18
|
"packages": {
|
|
19
|
-
"@dbcube/core": ["@dbcube/core@3.2.
|
|
19
|
+
"@dbcube/core": ["@dbcube/core@3.2.3", "", { "dependencies": { "chalk": "^5.6.2", "deasync": "^0.1.31", "follow-redirects": "^1.15.11", "ora": "^9.0.0", "unzipper": "^0.12.3" }, "bin": { "dbcube-core": "dist/bin.cjs" } }, "sha512-4eVn65N/FXsDUFqJrDkD69JHFrZKa0mmxsEo6OzjrTLYQPG0zbANACkA4Aqml3S7pk60V5Ir8MZytdFNGzsm6g=="],
|
|
20
20
|
|
|
21
|
-
"@dbcube/schema-builder": ["@dbcube/schema-builder@3.2.
|
|
21
|
+
"@dbcube/schema-builder": ["@dbcube/schema-builder@3.2.3", "", { "dependencies": { "@dbcube/core": "^3.2.3", "chalk": "^5.6.2", "ora": "^9.0.0" } }, "sha512-NTh+vIma+uIng29xDDv3RmS0Asuorz+Lx1kXVdLJetBaCr+XOt5A7Zd+kiCpIT1MhXkPPSdXls49Nff2UUQs6A=="],
|
|
22
22
|
|
|
23
|
-
"@inquirer/ansi": ["@inquirer/ansi@1.0.
|
|
23
|
+
"@inquirer/ansi": ["@inquirer/ansi@1.0.2", "", {}, "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ=="],
|
|
24
24
|
|
|
25
|
-
"@inquirer/checkbox": ["@inquirer/checkbox@4.3.
|
|
25
|
+
"@inquirer/checkbox": ["@inquirer/checkbox@4.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA=="],
|
|
26
26
|
|
|
27
|
-
"@inquirer/confirm": ["@inquirer/confirm@5.1.
|
|
27
|
+
"@inquirer/confirm": ["@inquirer/confirm@5.1.21", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ=="],
|
|
28
28
|
|
|
29
|
-
"@inquirer/core": ["@inquirer/core@10.3.
|
|
29
|
+
"@inquirer/core": ["@inquirer/core@10.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", "wrap-ansi": "^6.2.0", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A=="],
|
|
30
30
|
|
|
31
|
-
"@inquirer/editor": ["@inquirer/editor@4.2.
|
|
31
|
+
"@inquirer/editor": ["@inquirer/editor@4.2.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/external-editor": "^1.0.3", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ=="],
|
|
32
32
|
|
|
33
|
-
"@inquirer/expand": ["@inquirer/expand@4.0.
|
|
33
|
+
"@inquirer/expand": ["@inquirer/expand@4.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew=="],
|
|
34
34
|
|
|
35
|
-
"@inquirer/external-editor": ["@inquirer/external-editor@1.0.
|
|
35
|
+
"@inquirer/external-editor": ["@inquirer/external-editor@1.0.3", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA=="],
|
|
36
36
|
|
|
37
|
-
"@inquirer/figures": ["@inquirer/figures@1.0.
|
|
37
|
+
"@inquirer/figures": ["@inquirer/figures@1.0.15", "", {}, "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g=="],
|
|
38
38
|
|
|
39
|
-
"@inquirer/input": ["@inquirer/input@4.
|
|
39
|
+
"@inquirer/input": ["@inquirer/input@4.3.1", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g=="],
|
|
40
40
|
|
|
41
|
-
"@inquirer/number": ["@inquirer/number@3.0.
|
|
41
|
+
"@inquirer/number": ["@inquirer/number@3.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg=="],
|
|
42
42
|
|
|
43
|
-
"@inquirer/password": ["@inquirer/password@4.0.
|
|
43
|
+
"@inquirer/password": ["@inquirer/password@4.0.23", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA=="],
|
|
44
44
|
|
|
45
|
-
"@inquirer/prompts": ["@inquirer/prompts@7.
|
|
45
|
+
"@inquirer/prompts": ["@inquirer/prompts@7.10.1", "", { "dependencies": { "@inquirer/checkbox": "^4.3.2", "@inquirer/confirm": "^5.1.21", "@inquirer/editor": "^4.2.23", "@inquirer/expand": "^4.0.23", "@inquirer/input": "^4.3.1", "@inquirer/number": "^3.0.23", "@inquirer/password": "^4.0.23", "@inquirer/rawlist": "^4.1.11", "@inquirer/search": "^3.2.2", "@inquirer/select": "^4.4.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg=="],
|
|
46
46
|
|
|
47
|
-
"@inquirer/rawlist": ["@inquirer/rawlist@4.1.
|
|
47
|
+
"@inquirer/rawlist": ["@inquirer/rawlist@4.1.11", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw=="],
|
|
48
48
|
|
|
49
|
-
"@inquirer/search": ["@inquirer/search@3.2.
|
|
49
|
+
"@inquirer/search": ["@inquirer/search@3.2.2", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA=="],
|
|
50
50
|
|
|
51
|
-
"@inquirer/select": ["@inquirer/select@4.4.
|
|
51
|
+
"@inquirer/select": ["@inquirer/select@4.4.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w=="],
|
|
52
52
|
|
|
53
|
-
"@inquirer/type": ["@inquirer/type@3.0.
|
|
53
|
+
"@inquirer/type": ["@inquirer/type@3.0.10", "", { "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA=="],
|
|
54
54
|
|
|
55
55
|
"@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="],
|
|
56
56
|
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
|
|
71
71
|
"chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
|
|
72
72
|
|
|
73
|
-
"chardet": ["chardet@2.1.
|
|
73
|
+
"chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="],
|
|
74
74
|
|
|
75
75
|
"cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="],
|
|
76
76
|
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
|
|
87
87
|
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
|
88
88
|
|
|
89
|
-
"deasync": ["deasync@0.1.
|
|
89
|
+
"deasync": ["deasync@0.1.31", "", { "dependencies": { "bindings": "^1.5.0", "node-addon-api": "^1.7.1" } }, "sha512-/6/cXqkw4LPqBVK6H0Y3L4zT7yI3pxykxPXErQ2tDCw0LJyThWL5VpBCpUOWX0vPq2OnF1pzcXvlNnvCiOQJuA=="],
|
|
90
90
|
|
|
91
91
|
"dotenv": ["dotenv@17.2.3", "", {}, "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w=="],
|
|
92
92
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dbcube/cli",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.3",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dbcube": "node src/index.js"
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"license": "ISC",
|
|
14
14
|
"description": "",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@dbcube/schema-builder": "^3.2.
|
|
17
|
-
"@inquirer/prompts": "^7.
|
|
16
|
+
"@dbcube/schema-builder": "^3.2.3",
|
|
17
|
+
"@inquirer/prompts": "^7.10.1",
|
|
18
18
|
"alwait": "^1.0.0",
|
|
19
19
|
"chalk": "^5.6.2",
|
|
20
20
|
"dotenv": "^17.2.3",
|
package/src/commands/help.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const { default: chalk } = require('chalk');
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Shows help information with all available
|
|
4
|
+
* Shows help information with all available Dbcube CLI commands
|
|
5
5
|
*/
|
|
6
6
|
async function showHelp() {
|
|
7
7
|
try {
|
|
8
|
-
console.log(`\n${chalk.green('🚀
|
|
8
|
+
console.log(`\n${chalk.green('🚀 Dbcube CLI - Command Reference')}`);
|
|
9
9
|
console.log(`${chalk.gray('A powerful database toolkit for modern applications')}\n`);
|
|
10
10
|
|
|
11
11
|
console.log(`${chalk.cyan.bold('USAGE:')}`);
|
|
@@ -26,7 +26,14 @@ async function showHelp() {
|
|
|
26
26
|
|
|
27
27
|
console.log(`${chalk.cyan.bold('SEEDER COMMANDS:')}`);
|
|
28
28
|
console.log(` ${chalk.yellow('run seeder:add')} ${chalk.white('Add test data from seeder .cube files')}\n`);
|
|
29
|
-
|
|
29
|
+
|
|
30
|
+
console.log(`${chalk.cyan.bold('BINARY MANAGEMENT:')}`);
|
|
31
|
+
console.log(` ${chalk.yellow('run download')} ${chalk.white('Download binaries interactively')}`);
|
|
32
|
+
console.log(` ${chalk.yellow('run download <engine>')} ${chalk.white('Download specific engine (latest version)')}`);
|
|
33
|
+
console.log(` ${chalk.yellow('run download <engine> <ver>')} ${chalk.white('Download specific engine version')}`);
|
|
34
|
+
console.log(` ${chalk.yellow('run upgrade')} ${chalk.white('Update all binaries to latest version')}`);
|
|
35
|
+
console.log(` ${chalk.gray(' Engines:')} query-engine, schema-engine, sqlite-engine\n`);
|
|
36
|
+
|
|
30
37
|
console.log(`${chalk.cyan.bold('UTILITY COMMANDS:')}`);
|
|
31
38
|
console.log(` ${chalk.yellow('version, --version, -v')} ${chalk.white('Show CLI version information')}`);
|
|
32
39
|
console.log(` ${chalk.yellow('help, --help, -h')} ${chalk.white('Show this help information')}\n`);
|
|
@@ -47,6 +54,12 @@ async function showHelp() {
|
|
|
47
54
|
|
|
48
55
|
console.log(` ${chalk.gray('# Add seed data')}`);
|
|
49
56
|
console.log(` ${chalk.white('npx dbcube run seeder:add')}\n`);
|
|
57
|
+
|
|
58
|
+
console.log(` ${chalk.gray('# Download a specific binary version')}`);
|
|
59
|
+
console.log(` ${chalk.white('npx dbcube run download query-engine v3.1.1')}\n`);
|
|
60
|
+
|
|
61
|
+
console.log(` ${chalk.gray('# Upgrade all binaries to latest version')}`);
|
|
62
|
+
console.log(` ${chalk.white('npx dbcube run upgrade')}\n`);
|
|
50
63
|
|
|
51
64
|
console.log(`${chalk.cyan.bold('CONFIGURATION:')}`);
|
|
52
65
|
console.log(` ${chalk.white('Create a')} ${chalk.yellow('dbcube.config.js')} ${chalk.white('file in your project root:')}`);
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const chalk = require('chalk');
|
|
3
|
+
const { select } = require('@inquirer/prompts');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const https = require('https');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
const unzipper = require('unzipper');
|
|
9
|
+
const ora = require('ora');
|
|
10
|
+
|
|
11
|
+
// Parse arguments: dbcube run download:query-engine v3.1.1
|
|
12
|
+
// or: dbcube run download (interactive mode)
|
|
13
|
+
const args = process.argv.slice(2);
|
|
14
|
+
|
|
15
|
+
const SUPPORTED_BINARIES = {
|
|
16
|
+
'query-engine': 'query',
|
|
17
|
+
'schema-engine': 'schema',
|
|
18
|
+
'sqlite-engine': 'sqlite'
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const PLATFORM_MAP = {
|
|
22
|
+
win32: 'windows',
|
|
23
|
+
linux: 'linux',
|
|
24
|
+
darwin: 'macos'
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const ARCH_MAP = {
|
|
28
|
+
x64: 'x64',
|
|
29
|
+
arm64: 'arm64'
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
function getPlatformInfo() {
|
|
33
|
+
const platform = PLATFORM_MAP[process.platform];
|
|
34
|
+
const arch = ARCH_MAP[process.arch];
|
|
35
|
+
|
|
36
|
+
if (!platform || !arch) {
|
|
37
|
+
throw new Error(`Plataforma no soportada: ${process.platform} ${process.arch}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return { platform, arch };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getBinDir() {
|
|
44
|
+
const possibleDirs = [
|
|
45
|
+
path.resolve(process.cwd(), '.dbcube', 'bin'),
|
|
46
|
+
path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin'),
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
for (const dir of possibleDirs) {
|
|
50
|
+
try {
|
|
51
|
+
if (!fs.existsSync(dir)) {
|
|
52
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
53
|
+
}
|
|
54
|
+
return dir;
|
|
55
|
+
} catch {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const tempDir = path.join(os.tmpdir(), '.dbcube', 'bin');
|
|
61
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
62
|
+
return tempDir;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function downloadBinary(engineType, version) {
|
|
66
|
+
const spinner = ora('Preparando descarga...').start();
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const { platform, arch } = getPlatformInfo();
|
|
70
|
+
const prefix = SUPPORTED_BINARIES[engineType];
|
|
71
|
+
|
|
72
|
+
if (!prefix) {
|
|
73
|
+
throw new Error(`Tipo de binario no soportado: ${engineType}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const baseName = `${prefix}-engine-${platform}-${arch}`;
|
|
77
|
+
const binaryName = platform === 'windows' ? `${baseName}.exe` : baseName;
|
|
78
|
+
|
|
79
|
+
// Build download URL
|
|
80
|
+
const versionTag = version === 'latest' ? version : `v${version}`;
|
|
81
|
+
const url = `https://github.com/Dbcube/binaries/releases/download/${prefix}-engine/${prefix}-engine-${versionTag}-${platform}-${arch}.zip`;
|
|
82
|
+
|
|
83
|
+
const binDir = getBinDir();
|
|
84
|
+
const finalBinaryPath = path.join(binDir, binaryName);
|
|
85
|
+
|
|
86
|
+
// Remove existing binary of the same engine if exists
|
|
87
|
+
if (fs.existsSync(finalBinaryPath)) {
|
|
88
|
+
spinner.text = `Eliminando versión anterior de ${chalk.cyan(engineType)}...`;
|
|
89
|
+
try {
|
|
90
|
+
fs.unlinkSync(finalBinaryPath);
|
|
91
|
+
spinner.text = `Versión anterior eliminada, descargando ${chalk.cyan(engineType)} ${chalk.yellow(version)}...`;
|
|
92
|
+
} catch (err) {
|
|
93
|
+
spinner.warn(chalk.yellow(`No se pudo eliminar versión anterior: ${err.message}`));
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
spinner.text = `Descargando ${chalk.cyan(engineType)} ${chalk.yellow(version)}...`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const tempZipPath = path.join(os.tmpdir(), `dbcube-${prefix}-${Date.now()}.zip`);
|
|
100
|
+
|
|
101
|
+
// Download
|
|
102
|
+
await downloadFile(url, tempZipPath, (progress) => {
|
|
103
|
+
const percentage = progress.percentage.toFixed(1);
|
|
104
|
+
const downloaded = (progress.downloaded / 1024 / 1024).toFixed(1);
|
|
105
|
+
const total = (progress.total / 1024 / 1024).toFixed(1);
|
|
106
|
+
spinner.text = `Descargando ${chalk.cyan(engineType)} ${chalk.yellow(version)}: ${percentage}% (${downloaded}/${total}MB)`;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
spinner.text = `Extrayendo ${chalk.cyan(engineType)}...`;
|
|
110
|
+
|
|
111
|
+
// Extract
|
|
112
|
+
await extractBinary(tempZipPath, finalBinaryPath);
|
|
113
|
+
|
|
114
|
+
// Cleanup
|
|
115
|
+
cleanupFile(tempZipPath);
|
|
116
|
+
|
|
117
|
+
spinner.succeed(chalk.green(`✓ ${engineType} ${version} descargado exitosamente`));
|
|
118
|
+
console.log(chalk.gray(` Ubicación: ${finalBinaryPath}`));
|
|
119
|
+
|
|
120
|
+
} catch (error) {
|
|
121
|
+
spinner.fail(chalk.red(`Error descargando ${engineType}`));
|
|
122
|
+
console.error(chalk.red(` ${error.message}`));
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function downloadFile(url, outputPath, onProgress) {
|
|
128
|
+
return new Promise((resolve, reject) => {
|
|
129
|
+
https.get(url, { timeout: 30000 }, (response) => {
|
|
130
|
+
// Handle redirects
|
|
131
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
132
|
+
const redirectUrl = response.headers.location;
|
|
133
|
+
if (redirectUrl) {
|
|
134
|
+
return downloadFile(redirectUrl, outputPath, onProgress).then(resolve).catch(reject);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (response.statusCode !== 200) {
|
|
139
|
+
reject(new Error(`HTTP ${response.statusCode}: El binario no existe para esta versión`));
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const file = fs.createWriteStream(outputPath);
|
|
144
|
+
const totalBytes = parseInt(response.headers['content-length'] || '0', 10);
|
|
145
|
+
let downloadedBytes = 0;
|
|
146
|
+
|
|
147
|
+
response.on('data', (chunk) => {
|
|
148
|
+
downloadedBytes += chunk.length;
|
|
149
|
+
file.write(chunk);
|
|
150
|
+
|
|
151
|
+
if (totalBytes > 0 && onProgress) {
|
|
152
|
+
onProgress({
|
|
153
|
+
downloaded: downloadedBytes,
|
|
154
|
+
total: totalBytes,
|
|
155
|
+
percentage: (downloadedBytes / totalBytes) * 100
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
response.on('end', () => {
|
|
161
|
+
file.end();
|
|
162
|
+
resolve();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
response.on('error', (err) => {
|
|
166
|
+
file.close();
|
|
167
|
+
cleanupFile(outputPath);
|
|
168
|
+
reject(err);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
file.on('error', (err) => {
|
|
172
|
+
file.close();
|
|
173
|
+
cleanupFile(outputPath);
|
|
174
|
+
reject(err);
|
|
175
|
+
});
|
|
176
|
+
}).on('error', reject).on('timeout', () => {
|
|
177
|
+
reject(new Error('Timeout descargando el archivo'));
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function extractBinary(zipPath, outputPath) {
|
|
183
|
+
return new Promise((resolve, reject) => {
|
|
184
|
+
let extracted = false;
|
|
185
|
+
|
|
186
|
+
fs.createReadStream(zipPath)
|
|
187
|
+
.pipe(unzipper.Parse())
|
|
188
|
+
.on('entry', (entry) => {
|
|
189
|
+
if (entry.type === 'File' && !extracted) {
|
|
190
|
+
extracted = true;
|
|
191
|
+
const writeStream = fs.createWriteStream(outputPath);
|
|
192
|
+
|
|
193
|
+
entry.pipe(writeStream);
|
|
194
|
+
|
|
195
|
+
writeStream.on('finish', () => {
|
|
196
|
+
if (process.platform !== 'win32') {
|
|
197
|
+
fs.chmodSync(outputPath, 0o755);
|
|
198
|
+
}
|
|
199
|
+
resolve();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
writeStream.on('error', (err) => {
|
|
203
|
+
reject(err);
|
|
204
|
+
});
|
|
205
|
+
} else {
|
|
206
|
+
entry.autodrain();
|
|
207
|
+
}
|
|
208
|
+
})
|
|
209
|
+
.on('error', (err) => {
|
|
210
|
+
reject(err);
|
|
211
|
+
})
|
|
212
|
+
.on('close', () => {
|
|
213
|
+
if (!extracted) {
|
|
214
|
+
reject(new Error('No se encontró archivo válido en el ZIP'));
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function cleanupFile(filePath) {
|
|
221
|
+
try {
|
|
222
|
+
if (fs.existsSync(filePath)) {
|
|
223
|
+
fs.unlinkSync(filePath);
|
|
224
|
+
}
|
|
225
|
+
} catch {
|
|
226
|
+
// Ignore cleanup errors
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async function interactiveMode() {
|
|
231
|
+
console.log(chalk.blue('\n📦 Descarga de Binarios Dbcube\n'));
|
|
232
|
+
|
|
233
|
+
const engineType = await select({
|
|
234
|
+
message: 'Selecciona el binario a descargar:',
|
|
235
|
+
choices: [
|
|
236
|
+
{ name: 'Query Engine', value: 'query-engine' },
|
|
237
|
+
{ name: 'Schema Engine', value: 'schema-engine' },
|
|
238
|
+
{ name: 'SQLite Engine', value: 'sqlite-engine' }
|
|
239
|
+
]
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
const version = await select({
|
|
243
|
+
message: 'Selecciona la versión:',
|
|
244
|
+
choices: [
|
|
245
|
+
{ name: 'Latest (última versión)', value: 'latest' },
|
|
246
|
+
{ name: 'v3.2.1', value: '3.2.1' },
|
|
247
|
+
{ name: 'v3.2.0', value: '3.2.0' },
|
|
248
|
+
{ name: 'v3.1.1', value: '3.1.1' },
|
|
249
|
+
{ name: 'v3.1.0', value: '3.1.0' },
|
|
250
|
+
{ name: 'v3.0.0', value: '3.0.0' }
|
|
251
|
+
]
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
await downloadBinary(engineType, version);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async function main() {
|
|
258
|
+
if (args.length === 0) {
|
|
259
|
+
// Interactive mode
|
|
260
|
+
await interactiveMode();
|
|
261
|
+
} else if (args.length === 1) {
|
|
262
|
+
// Download with default version (latest)
|
|
263
|
+
const engineType = args[0];
|
|
264
|
+
if (!SUPPORTED_BINARIES[engineType]) {
|
|
265
|
+
console.error(chalk.red(`\n❌ Binario no soportado: ${engineType}`));
|
|
266
|
+
console.log(chalk.yellow(`\nBinarios disponibles: ${Object.keys(SUPPORTED_BINARIES).join(', ')}\n`));
|
|
267
|
+
process.exit(1);
|
|
268
|
+
}
|
|
269
|
+
await downloadBinary(engineType, 'latest');
|
|
270
|
+
} else if (args.length === 2) {
|
|
271
|
+
// Download with specific version
|
|
272
|
+
const engineType = args[0];
|
|
273
|
+
let version = args[1];
|
|
274
|
+
|
|
275
|
+
// Remove 'v' prefix if present
|
|
276
|
+
if (version.startsWith('v')) {
|
|
277
|
+
version = version.substring(1);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (!SUPPORTED_BINARIES[engineType]) {
|
|
281
|
+
console.error(chalk.red(`\n❌ Binario no soportado: ${engineType}`));
|
|
282
|
+
console.log(chalk.yellow(`\nBinarios disponibles: ${Object.keys(SUPPORTED_BINARIES).join(', ')}\n`));
|
|
283
|
+
process.exit(1);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
await downloadBinary(engineType, version);
|
|
287
|
+
} else {
|
|
288
|
+
console.error(chalk.red('\n❌ Demasiados argumentos'));
|
|
289
|
+
console.log(chalk.yellow('\nUso:'));
|
|
290
|
+
console.log(' dbcube run download');
|
|
291
|
+
console.log(' dbcube run download query-engine');
|
|
292
|
+
console.log(' dbcube run download query-engine v3.1.1\n');
|
|
293
|
+
process.exit(1);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
main().catch(err => {
|
|
298
|
+
console.error(chalk.red('\n❌ Error inesperado:'), err.message);
|
|
299
|
+
process.exit(1);
|
|
300
|
+
});
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const chalk = require('chalk');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const https = require('https');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
const unzipper = require('unzipper');
|
|
8
|
+
const ora = require('ora');
|
|
9
|
+
|
|
10
|
+
const BINARIES = ['query-engine', 'schema-engine', 'sqlite-engine'];
|
|
11
|
+
|
|
12
|
+
const BINARY_PREFIX_MAP = {
|
|
13
|
+
'query-engine': 'query',
|
|
14
|
+
'schema-engine': 'schema',
|
|
15
|
+
'sqlite-engine': 'sqlite'
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const PLATFORM_MAP = {
|
|
19
|
+
win32: 'windows',
|
|
20
|
+
linux: 'linux',
|
|
21
|
+
darwin: 'macos'
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const ARCH_MAP = {
|
|
25
|
+
x64: 'x64',
|
|
26
|
+
arm64: 'arm64'
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function getPlatformInfo() {
|
|
30
|
+
const platform = PLATFORM_MAP[process.platform];
|
|
31
|
+
const arch = ARCH_MAP[process.arch];
|
|
32
|
+
|
|
33
|
+
if (!platform || !arch) {
|
|
34
|
+
throw new Error(`Plataforma no soportada: ${process.platform} ${process.arch}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return { platform, arch };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function getBinDir() {
|
|
41
|
+
const possibleDirs = [
|
|
42
|
+
path.resolve(process.cwd(), '.dbcube', 'bin'),
|
|
43
|
+
path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin'),
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
for (const dir of possibleDirs) {
|
|
47
|
+
try {
|
|
48
|
+
if (!fs.existsSync(dir)) {
|
|
49
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
50
|
+
}
|
|
51
|
+
return dir;
|
|
52
|
+
} catch {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const tempDir = path.join(os.tmpdir(), '.dbcube', 'bin');
|
|
58
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
59
|
+
return tempDir;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function cleanBinDirectory(binDir) {
|
|
63
|
+
if (!fs.existsSync(binDir)) {
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const files = fs.readdirSync(binDir);
|
|
68
|
+
let deletedCount = 0;
|
|
69
|
+
|
|
70
|
+
for (const file of files) {
|
|
71
|
+
const filePath = path.join(binDir, file);
|
|
72
|
+
try {
|
|
73
|
+
const stat = fs.statSync(filePath);
|
|
74
|
+
if (stat.isFile()) {
|
|
75
|
+
fs.unlinkSync(filePath);
|
|
76
|
+
deletedCount++;
|
|
77
|
+
}
|
|
78
|
+
} catch (err) {
|
|
79
|
+
console.warn(chalk.yellow(`⚠️ No se pudo eliminar: ${file}`));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return deletedCount;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function downloadBinary(engineType, version, spinner) {
|
|
87
|
+
const { platform, arch } = getPlatformInfo();
|
|
88
|
+
const prefix = BINARY_PREFIX_MAP[engineType];
|
|
89
|
+
|
|
90
|
+
if (!prefix) {
|
|
91
|
+
throw new Error(`Tipo de binario no soportado: ${engineType}`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const baseName = `${prefix}-engine-${platform}-${arch}`;
|
|
95
|
+
const binaryName = platform === 'windows' ? `${baseName}.exe` : baseName;
|
|
96
|
+
|
|
97
|
+
// Build download URL
|
|
98
|
+
const versionTag = version === 'latest' ? version : `v${version}`;
|
|
99
|
+
const url = `https://github.com/Dbcube/binaries/releases/download/${prefix}-engine/${prefix}-engine-${versionTag}-${platform}-${arch}.zip`;
|
|
100
|
+
|
|
101
|
+
const binDir = getBinDir();
|
|
102
|
+
const tempZipPath = path.join(os.tmpdir(), `dbcube-${prefix}-${Date.now()}.zip`);
|
|
103
|
+
const finalBinaryPath = path.join(binDir, binaryName);
|
|
104
|
+
|
|
105
|
+
spinner.text = `📥 Descargando ${chalk.cyan(engineType)}...`;
|
|
106
|
+
|
|
107
|
+
// Download
|
|
108
|
+
await downloadFile(url, tempZipPath, (progress) => {
|
|
109
|
+
const percentage = progress.percentage.toFixed(1);
|
|
110
|
+
spinner.text = `📥 ${chalk.cyan(engineType)}: ${percentage}%`;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
spinner.text = `📦 Extrayendo ${chalk.cyan(engineType)}...`;
|
|
114
|
+
|
|
115
|
+
// Extract
|
|
116
|
+
await extractBinary(tempZipPath, finalBinaryPath);
|
|
117
|
+
|
|
118
|
+
// Cleanup
|
|
119
|
+
cleanupFile(tempZipPath);
|
|
120
|
+
|
|
121
|
+
return finalBinaryPath;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function downloadFile(url, outputPath, onProgress) {
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
https.get(url, { timeout: 30000 }, (response) => {
|
|
127
|
+
// Handle redirects
|
|
128
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
129
|
+
const redirectUrl = response.headers.location;
|
|
130
|
+
if (redirectUrl) {
|
|
131
|
+
return downloadFile(redirectUrl, outputPath, onProgress).then(resolve).catch(reject);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (response.statusCode !== 200) {
|
|
136
|
+
reject(new Error(`HTTP ${response.statusCode}: El binario no existe`));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const file = fs.createWriteStream(outputPath);
|
|
141
|
+
const totalBytes = parseInt(response.headers['content-length'] || '0', 10);
|
|
142
|
+
let downloadedBytes = 0;
|
|
143
|
+
|
|
144
|
+
response.on('data', (chunk) => {
|
|
145
|
+
downloadedBytes += chunk.length;
|
|
146
|
+
file.write(chunk);
|
|
147
|
+
|
|
148
|
+
if (totalBytes > 0 && onProgress) {
|
|
149
|
+
onProgress({
|
|
150
|
+
downloaded: downloadedBytes,
|
|
151
|
+
total: totalBytes,
|
|
152
|
+
percentage: (downloadedBytes / totalBytes) * 100
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
response.on('end', () => {
|
|
158
|
+
file.end();
|
|
159
|
+
resolve();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
response.on('error', (err) => {
|
|
163
|
+
file.close();
|
|
164
|
+
cleanupFile(outputPath);
|
|
165
|
+
reject(err);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
file.on('error', (err) => {
|
|
169
|
+
file.close();
|
|
170
|
+
cleanupFile(outputPath);
|
|
171
|
+
reject(err);
|
|
172
|
+
});
|
|
173
|
+
}).on('error', reject).on('timeout', () => {
|
|
174
|
+
reject(new Error('Timeout descargando el archivo'));
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function extractBinary(zipPath, outputPath) {
|
|
180
|
+
return new Promise((resolve, reject) => {
|
|
181
|
+
let extracted = false;
|
|
182
|
+
|
|
183
|
+
fs.createReadStream(zipPath)
|
|
184
|
+
.pipe(unzipper.Parse())
|
|
185
|
+
.on('entry', (entry) => {
|
|
186
|
+
if (entry.type === 'File' && !extracted) {
|
|
187
|
+
extracted = true;
|
|
188
|
+
const writeStream = fs.createWriteStream(outputPath);
|
|
189
|
+
|
|
190
|
+
entry.pipe(writeStream);
|
|
191
|
+
|
|
192
|
+
writeStream.on('finish', () => {
|
|
193
|
+
if (process.platform !== 'win32') {
|
|
194
|
+
fs.chmodSync(outputPath, 0o755);
|
|
195
|
+
}
|
|
196
|
+
resolve();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
writeStream.on('error', (err) => {
|
|
200
|
+
reject(err);
|
|
201
|
+
});
|
|
202
|
+
} else {
|
|
203
|
+
entry.autodrain();
|
|
204
|
+
}
|
|
205
|
+
})
|
|
206
|
+
.on('error', (err) => {
|
|
207
|
+
reject(err);
|
|
208
|
+
})
|
|
209
|
+
.on('close', () => {
|
|
210
|
+
if (!extracted) {
|
|
211
|
+
reject(new Error('No se encontró archivo válido en el ZIP'));
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function cleanupFile(filePath) {
|
|
218
|
+
try {
|
|
219
|
+
if (fs.existsSync(filePath)) {
|
|
220
|
+
fs.unlinkSync(filePath);
|
|
221
|
+
}
|
|
222
|
+
} catch {
|
|
223
|
+
// Ignore cleanup errors
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async function main() {
|
|
228
|
+
console.log(chalk.blue('\n🔄 Dbcube Upgrade - Actualización de Binarios\n'));
|
|
229
|
+
|
|
230
|
+
const spinner = ora('Iniciando proceso de actualización...').start();
|
|
231
|
+
|
|
232
|
+
try {
|
|
233
|
+
const binDir = getBinDir();
|
|
234
|
+
|
|
235
|
+
// Step 1: Clean bin directory
|
|
236
|
+
spinner.text = '🗑️ Limpiando directorio de binarios...';
|
|
237
|
+
const deletedCount = cleanBinDirectory(binDir);
|
|
238
|
+
|
|
239
|
+
if (deletedCount > 0) {
|
|
240
|
+
spinner.succeed(chalk.green(`✓ ${deletedCount} archivo(s) eliminado(s)`));
|
|
241
|
+
} else {
|
|
242
|
+
spinner.info(chalk.gray('No había binarios previos'));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Step 2: Download all binaries
|
|
246
|
+
console.log(chalk.cyan('\n📦 Descargando binarios latest...\n'));
|
|
247
|
+
|
|
248
|
+
const results = [];
|
|
249
|
+
let successCount = 0;
|
|
250
|
+
let failCount = 0;
|
|
251
|
+
|
|
252
|
+
for (const binary of BINARIES) {
|
|
253
|
+
const binarySpinner = ora(`Procesando ${chalk.cyan(binary)}...`).start();
|
|
254
|
+
|
|
255
|
+
try {
|
|
256
|
+
const binaryPath = await downloadBinary(binary, 'latest', binarySpinner);
|
|
257
|
+
binarySpinner.succeed(chalk.green(`✓ ${binary} descargado`));
|
|
258
|
+
results.push({ binary, success: true, path: binaryPath });
|
|
259
|
+
successCount++;
|
|
260
|
+
} catch (error) {
|
|
261
|
+
binarySpinner.fail(chalk.red(`✗ ${binary} falló: ${error.message}`));
|
|
262
|
+
results.push({ binary, success: false, error: error.message });
|
|
263
|
+
failCount++;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Summary
|
|
268
|
+
console.log(chalk.cyan('\n📊 Resumen de actualización:\n'));
|
|
269
|
+
|
|
270
|
+
for (const result of results) {
|
|
271
|
+
if (result.success) {
|
|
272
|
+
console.log(chalk.green(` ✓ ${result.binary}`));
|
|
273
|
+
console.log(chalk.gray(` ${result.path}`));
|
|
274
|
+
} else {
|
|
275
|
+
console.log(chalk.red(` ✗ ${result.binary}`));
|
|
276
|
+
console.log(chalk.gray(` Error: ${result.error}`));
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
console.log('');
|
|
281
|
+
|
|
282
|
+
if (failCount === 0) {
|
|
283
|
+
console.log(chalk.green.bold(`✅ Todos los binarios (${successCount}/${BINARIES.length}) actualizados exitosamente\n`));
|
|
284
|
+
} else if (successCount > 0) {
|
|
285
|
+
console.log(chalk.yellow.bold(`⚠️ Actualización parcial: ${successCount}/${BINARIES.length} binarios descargados\n`));
|
|
286
|
+
process.exit(1);
|
|
287
|
+
} else {
|
|
288
|
+
console.log(chalk.red.bold(`❌ No se pudo descargar ningún binario\n`));
|
|
289
|
+
process.exit(1);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
} catch (error) {
|
|
293
|
+
spinner.fail(chalk.red('Error en el proceso de actualización'));
|
|
294
|
+
console.error(chalk.red(`\n❌ ${error.message}\n`));
|
|
295
|
+
process.exit(1);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
main().catch(err => {
|
|
300
|
+
console.error(chalk.red('\n❌ Error inesperado:'), err.message);
|
|
301
|
+
process.exit(1);
|
|
302
|
+
});
|
package/src/commands/version.js
CHANGED
|
@@ -3,7 +3,7 @@ const fs = require('fs');
|
|
|
3
3
|
const { default: chalk } = require('chalk');
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Muestra la versión actual del CLI de
|
|
6
|
+
* Muestra la versión actual del CLI de Dbcube
|
|
7
7
|
*/
|
|
8
8
|
async function showVersion() {
|
|
9
9
|
try {
|
|
@@ -11,7 +11,7 @@ async function showVersion() {
|
|
|
11
11
|
const packageJsonPath = path.join(__dirname, '../../package.json');
|
|
12
12
|
const packageData = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
13
13
|
|
|
14
|
-
console.log(`\n${chalk.green('🚀
|
|
14
|
+
console.log(`\n${chalk.green('🚀 Dbcube CLI')}`);
|
|
15
15
|
console.log(`${chalk.cyan('Versión:')} ${chalk.bold(packageData.version)}`);
|
|
16
16
|
console.log(`${chalk.cyan('Nombre:')} ${packageData.name}`);
|
|
17
17
|
console.log(`${chalk.gray('Licencia:')} ${packageData.license}\n`);
|
package/src/index.js
CHANGED
|
@@ -46,6 +46,9 @@ const commandMap = {
|
|
|
46
46
|
'run:database:create:config': '../src/commands/run/database/create/addDatabaseConfig.js',
|
|
47
47
|
'run:database:create:physical': '../src/commands/run/database/create/createDatabase.js',
|
|
48
48
|
|
|
49
|
+
'run:download': '../src/commands/run/download.js',
|
|
50
|
+
'run:upgrade': '../src/commands/run/upgrade.js',
|
|
51
|
+
|
|
49
52
|
'--version': '../src/commands/version.js',
|
|
50
53
|
'-v': '../src/commands/version.js',
|
|
51
54
|
|