@mandors/cli 0.0.17 → 0.0.19
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/npm/lib/install.js +54 -38
- package/npm/lib/resolve.js +39 -138
- package/package.json +1 -1
package/npm/lib/install.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Post-install hook for Mandor CLI
|
|
3
|
-
* @description Downloads binary from GitHub releases
|
|
4
|
-
* @version 0.0.
|
|
3
|
+
* @description Downloads and extracts binary from GitHub releases
|
|
4
|
+
* @version 0.0.5
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const fs = require('fs');
|
|
8
8
|
const path = require('path');
|
|
9
9
|
const os = require('os');
|
|
10
10
|
const { execSync } = require('child_process');
|
|
11
|
+
const https = require('https');
|
|
11
12
|
|
|
12
13
|
const REPO = 'sanxzy/mandor';
|
|
13
|
-
const
|
|
14
|
-
const CACHE_DIR = path.join(os.homedir(), '.mandor', 'bin');
|
|
14
|
+
const INSTALL_DIR = path.join(os.homedir(), '.local', 'bin');
|
|
15
15
|
|
|
16
16
|
function getPlatform() {
|
|
17
17
|
const platform = os.platform();
|
|
@@ -26,16 +26,42 @@ function getPlatform() {
|
|
|
26
26
|
|
|
27
27
|
async function getLatestVersion(prerelease = false) {
|
|
28
28
|
const url = prerelease
|
|
29
|
-
?
|
|
30
|
-
:
|
|
29
|
+
? `https://api.github.com/repos/${REPO}/releases`
|
|
30
|
+
: `https://api.github.com/repos/${REPO}/releases/latest`;
|
|
31
|
+
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
|
+
https.get(url, { headers: { 'User-Agent': 'Mandor-CLI' } }, (res) => {
|
|
34
|
+
let data = '';
|
|
35
|
+
res.on('data', chunk => data += chunk);
|
|
36
|
+
res.on('end', () => {
|
|
37
|
+
try {
|
|
38
|
+
const parsed = JSON.parse(data);
|
|
39
|
+
const tagName = Array.isArray(parsed) ? parsed[0].tag_name : parsed.tag_name;
|
|
40
|
+
resolve(tagName.replace(/^v/, ''));
|
|
41
|
+
} catch (e) {
|
|
42
|
+
reject(e);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}).on('error', reject);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
31
48
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
49
|
+
function downloadFile(url, dest) {
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
const file = fs.createWriteStream(dest);
|
|
52
|
+
https.get(url, (res) => {
|
|
53
|
+
if (res.statusCode === 302 || res.statusCode === 301) {
|
|
54
|
+
return downloadFile(res.headers.location, dest).then(resolve).catch(reject);
|
|
55
|
+
}
|
|
56
|
+
res.pipe(file);
|
|
57
|
+
file.on('finish', () => {
|
|
58
|
+
file.close(resolve);
|
|
59
|
+
});
|
|
60
|
+
}).on('error', (err) => {
|
|
61
|
+
fs.unlink(dest, () => {});
|
|
62
|
+
reject(err);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
39
65
|
}
|
|
40
66
|
|
|
41
67
|
async function install(options = {}) {
|
|
@@ -43,7 +69,7 @@ async function install(options = {}) {
|
|
|
43
69
|
const version = options.version || 'latest';
|
|
44
70
|
const prerelease = options.prerelease || false;
|
|
45
71
|
const osArch = `${platform}-${arch}`;
|
|
46
|
-
const
|
|
72
|
+
const binaryName = platform === 'win32' ? 'mandor.exe' : 'mandor';
|
|
47
73
|
|
|
48
74
|
console.log('Mandor Installer');
|
|
49
75
|
console.log('================');
|
|
@@ -58,48 +84,38 @@ async function install(options = {}) {
|
|
|
58
84
|
console.log(`Version: ${installVersion}`);
|
|
59
85
|
console.log('');
|
|
60
86
|
|
|
61
|
-
const
|
|
62
|
-
const binaryPath = path.join(cachePath, platform === 'win32' ? 'mandor.exe' : 'mandor');
|
|
87
|
+
const binaryPath = path.join(INSTALL_DIR, binaryName);
|
|
63
88
|
|
|
64
89
|
if (fs.existsSync(binaryPath)) {
|
|
65
|
-
console.log(`
|
|
90
|
+
console.log(`Already installed: ${binaryPath}`);
|
|
66
91
|
return binaryPath;
|
|
67
92
|
}
|
|
68
93
|
|
|
69
94
|
console.log('Downloading from GitHub releases...');
|
|
70
|
-
const downloadUrl = `https://github.com/${REPO}/releases/download/v${installVersion}/${
|
|
71
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mandor-
|
|
72
|
-
const tarball = path.join(tempDir,
|
|
73
|
-
|
|
74
|
-
const response = await fetch(downloadUrl);
|
|
75
|
-
if (!response.ok) {
|
|
76
|
-
fs.rmSync(tempDir, { recursive: true });
|
|
77
|
-
throw new Error(`Download failed: ${response.statusText} (${downloadUrl})`);
|
|
78
|
-
}
|
|
95
|
+
const downloadUrl = `https://github.com/${REPO}/releases/download/v${installVersion}/${osArch}.tar.gz`;
|
|
96
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mandor-'));
|
|
97
|
+
const tarball = path.join(tempDir, `${osArch}.tar.gz`);
|
|
79
98
|
|
|
80
|
-
|
|
81
|
-
await new Promise((resolve, reject) => {
|
|
82
|
-
response.body.pipe(file);
|
|
83
|
-
file.on('finish', resolve);
|
|
84
|
-
file.on('error', reject);
|
|
85
|
-
});
|
|
99
|
+
await downloadFile(downloadUrl, tarball);
|
|
86
100
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
101
|
+
fs.mkdirSync(INSTALL_DIR, { recursive: true });
|
|
102
|
+
execSync(`tar -xzf "${tarball}" -C "${tempDir}"`, { stdio: 'inherit' });
|
|
90
103
|
|
|
91
|
-
|
|
104
|
+
const extractedBinary = path.join(tempDir, binaryName);
|
|
105
|
+
fs.copyFileSync(extractedBinary, binaryPath);
|
|
92
106
|
fs.chmodSync(binaryPath, '755');
|
|
93
107
|
|
|
94
108
|
fs.rmSync(tempDir, { recursive: true });
|
|
95
109
|
|
|
96
110
|
console.log(`Installed: ${binaryPath}`);
|
|
111
|
+
console.log('');
|
|
112
|
+
console.log('Add to PATH:');
|
|
113
|
+
console.log(` export PATH="${INSTALL_DIR}:$PATH"`);
|
|
97
114
|
return binaryPath;
|
|
98
115
|
}
|
|
99
116
|
|
|
100
117
|
if (require.main === module || process.env.npm_lifecycle_event === 'postinstall') {
|
|
101
|
-
|
|
102
|
-
install({ prerelease }).catch(error => {
|
|
118
|
+
install().catch(error => {
|
|
103
119
|
console.error('Failed to install Mandor:', error.message);
|
|
104
120
|
process.exit(1);
|
|
105
121
|
});
|
package/npm/lib/resolve.js
CHANGED
|
@@ -1,159 +1,60 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Version resolution module for Mandor CLI
|
|
3
|
-
* @description Resolves the
|
|
4
|
-
* @version 0.0.
|
|
3
|
+
* @description Resolves the binary path for the CLI
|
|
4
|
+
* @version 0.0.3
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const path = require('path');
|
|
8
|
-
const fs = require('fs');
|
|
9
8
|
const os = require('os');
|
|
10
|
-
const
|
|
9
|
+
const https = require('https');
|
|
11
10
|
|
|
12
11
|
const REPO = 'sanxzy/mandor';
|
|
13
|
-
const GITHUB_API = 'https://api.github.com';
|
|
14
12
|
const DEFAULT_VERSION = 'latest';
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
13
|
+
const INSTALL_DIR = path.join(os.homedir(), '.local', 'bin');
|
|
14
|
+
|
|
15
|
+
function getPlatform() {
|
|
16
|
+
const platform = os.platform();
|
|
17
|
+
const arch = os.arch();
|
|
18
|
+
const platformMap = { darwin: 'darwin', linux: 'linux', win32: 'win32' };
|
|
19
|
+
const archMap = { x64: 'x64', arm64: 'arm64', amd64: 'x64', aarch64: 'arm64' };
|
|
20
|
+
return {
|
|
21
|
+
platform: platformMap[platform] || platform,
|
|
22
|
+
arch: archMap[arch] || arch
|
|
23
|
+
};
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
async function getLatestVersion(prerelease = false) {
|
|
28
27
|
const url = prerelease
|
|
29
|
-
?
|
|
30
|
-
:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const cacheDir = path.join(os.homedir(), '.mandor', 'bin', version, osArch);
|
|
44
|
-
fs.mkdirSync(cacheDir, { recursive: true });
|
|
45
|
-
|
|
46
|
-
const binaryName = platform === 'win32' ? 'mandor.exe' : 'mandor';
|
|
47
|
-
const destPath = path.join(cacheDir, binaryName);
|
|
48
|
-
|
|
49
|
-
fs.copyFileSync(binaryPath, destPath);
|
|
50
|
-
fs.chmodSync(destPath, '755');
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async function resolve(options = {}) {
|
|
54
|
-
const version = options.version || DEFAULT_VERSION;
|
|
55
|
-
const { platform, arch } = getCurrentPlatform();
|
|
56
|
-
const prerelease = options.prerelease || false;
|
|
57
|
-
|
|
58
|
-
let resolveVersion = version;
|
|
59
|
-
if (version === 'latest') {
|
|
60
|
-
resolveVersion = await getLatestVersion(prerelease);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const cachedPath = getCachedBinary(resolveVersion, platform, arch);
|
|
64
|
-
if (cachedPath && !options.forceDownload) {
|
|
65
|
-
return cachedPath;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const osArch = `${platform}-${arch}`;
|
|
69
|
-
const downloadUrl = `https://github.com/${REPO}/releases/download/v${resolveVersion}/${osArch}.tar.gz`;
|
|
70
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mandor-download-'));
|
|
71
|
-
const tarball = path.join(tempDir, `${osArch}.tar.gz`);
|
|
72
|
-
|
|
73
|
-
console.log(`Downloading Mandor ${resolveVersion}...`);
|
|
74
|
-
|
|
75
|
-
const response = await fetch(downloadUrl);
|
|
76
|
-
if (!response.ok) {
|
|
77
|
-
fs.rmSync(tempDir, { recursive: true });
|
|
78
|
-
throw new Error(`Download failed: ${response.statusText}`);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const file = fs.createWriteStream(tarball);
|
|
82
|
-
await new Promise((resolve, reject) => {
|
|
83
|
-
response.body.pipe(file);
|
|
84
|
-
file.on('finish', resolve);
|
|
85
|
-
file.on('error', reject);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
const binaryName = platform === 'win32' ? 'mandor.exe' : 'mandor';
|
|
89
|
-
const cacheDir = path.join(os.homedir(), '.mandor', 'bin', resolveVersion, osArch);
|
|
90
|
-
fs.mkdirSync(cacheDir, { recursive: true });
|
|
91
|
-
|
|
92
|
-
const { execSync } = require('child_process');
|
|
93
|
-
execSync(`tar -xzf "${tarball}" -C "${cacheDir}"`, { stdio: 'pipe' });
|
|
94
|
-
fs.chmodSync(path.join(cacheDir, binaryName), '755');
|
|
95
|
-
|
|
96
|
-
fs.rmSync(tempDir, { recursive: true });
|
|
97
|
-
|
|
98
|
-
return path.join(cacheDir, binaryName);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function listCachedBinaries() {
|
|
102
|
-
const cacheDir = path.join(os.homedir(), '.mandor', 'bin');
|
|
103
|
-
|
|
104
|
-
if (!fs.existsSync(cacheDir)) {
|
|
105
|
-
return [];
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const versions = [];
|
|
109
|
-
const entries = fs.readdirSync(cacheDir);
|
|
110
|
-
|
|
111
|
-
for (const entry of entries) {
|
|
112
|
-
const versionPath = path.join(cacheDir, entry);
|
|
113
|
-
if (fs.statSync(versionPath).isDirectory()) {
|
|
114
|
-
const subEntries = fs.readdirSync(versionPath);
|
|
115
|
-
for (const subEntry of subEntries) {
|
|
116
|
-
const subPath = path.join(versionPath, subEntry);
|
|
117
|
-
if (fs.statSync(subPath).isDirectory()) {
|
|
118
|
-
const parts = subEntry.split('-');
|
|
119
|
-
const arch = parts.pop();
|
|
120
|
-
const platform = parts.join('-');
|
|
121
|
-
versions.push({ version: entry, platform, arch, path: subPath });
|
|
28
|
+
? `https://api.github.com/repos/${REPO}/releases`
|
|
29
|
+
: `https://api.github.com/repos/${REPO}/releases/latest`;
|
|
30
|
+
|
|
31
|
+
return new Promise((resolve, reject) => {
|
|
32
|
+
https.get(url, { headers: { 'User-Agent': 'Mandor-CLI' } }, (res) => {
|
|
33
|
+
let data = '';
|
|
34
|
+
res.on('data', chunk => data += chunk);
|
|
35
|
+
res.on('end', () => {
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(data);
|
|
38
|
+
const tagName = Array.isArray(parsed) ? parsed[0].tag_name : parsed.tag_name;
|
|
39
|
+
resolve(tagName.replace(/^v/, ''));
|
|
40
|
+
} catch (e) {
|
|
41
|
+
reject(e);
|
|
122
42
|
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return versions;
|
|
43
|
+
});
|
|
44
|
+
}).on('error', reject);
|
|
45
|
+
});
|
|
128
46
|
}
|
|
129
47
|
|
|
130
|
-
function
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
return 0;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const entries = fs.readdirSync(cacheDir);
|
|
138
|
-
let removed = 0;
|
|
139
|
-
|
|
140
|
-
for (const entry of entries) {
|
|
141
|
-
const entryPath = path.join(cacheDir, entry);
|
|
142
|
-
if (fs.statSync(entryPath).isDirectory()) {
|
|
143
|
-
fs.rmSync(entryPath, { recursive: true, force: true });
|
|
144
|
-
removed++;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return removed;
|
|
48
|
+
function getBinaryPath(version = DEFAULT_VERSION) {
|
|
49
|
+
const { platform, arch } = getPlatform();
|
|
50
|
+
const binaryName = platform === 'win32' ? 'mandor.exe' : 'mandor';
|
|
51
|
+
return path.join(INSTALL_DIR, binaryName);
|
|
149
52
|
}
|
|
150
53
|
|
|
151
54
|
module.exports = {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
listCachedBinaries,
|
|
156
|
-
clearCache,
|
|
55
|
+
getPlatform,
|
|
56
|
+
getLatestVersion,
|
|
57
|
+
getBinaryPath,
|
|
157
58
|
DEFAULT_VERSION,
|
|
158
|
-
|
|
59
|
+
INSTALL_DIR
|
|
159
60
|
};
|