dotenvx-tui 2.0.2 → 2.0.4
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/cli.js +96 -19
- package/install.js +5 -111
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1,29 +1,106 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const { spawn } = require("child_process");
|
|
3
|
+
const { spawn, execSync } = require("child_process");
|
|
4
|
+
const https = require("https");
|
|
4
5
|
const path = require("path");
|
|
5
6
|
const fs = require("fs");
|
|
6
7
|
|
|
7
8
|
const NAME = "dotenvx-tui";
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
const REPO = "SpyrosBou/dotenvx-tui";
|
|
10
|
+
const VERSION = require("../package.json").version;
|
|
11
|
+
const binDir = __dirname;
|
|
12
|
+
const binPath = path.join(binDir, NAME);
|
|
13
|
+
|
|
14
|
+
const PLATFORM_MAP = { darwin: "darwin", linux: "linux" };
|
|
15
|
+
const ARCH_MAP = { x64: "amd64", arm64: "arm64" };
|
|
16
|
+
|
|
17
|
+
function downloadFile(url) {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
https
|
|
20
|
+
.get(url, (res) => {
|
|
21
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
22
|
+
return downloadFile(res.headers.location).then(resolve, reject);
|
|
23
|
+
}
|
|
24
|
+
if (res.statusCode !== 200) {
|
|
25
|
+
return reject(new Error(`HTTP ${res.statusCode}`));
|
|
26
|
+
}
|
|
27
|
+
const total = parseInt(res.headers["content-length"] || "0", 10);
|
|
28
|
+
const chunks = [];
|
|
29
|
+
let downloaded = 0;
|
|
30
|
+
res.on("data", (chunk) => {
|
|
31
|
+
chunks.push(chunk);
|
|
32
|
+
downloaded += chunk.length;
|
|
33
|
+
const mb = (downloaded / 1024 / 1024).toFixed(1);
|
|
34
|
+
if (total > 0) {
|
|
35
|
+
const pct = Math.round((downloaded / total) * 100);
|
|
36
|
+
process.stderr.write(`\r downloading ${NAME}... ${mb} MB (${pct}%)`);
|
|
37
|
+
} else {
|
|
38
|
+
process.stderr.write(`\r downloading ${NAME}... ${mb} MB`);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
res.on("end", () => {
|
|
42
|
+
process.stderr.write("\n");
|
|
43
|
+
resolve(Buffer.concat(chunks));
|
|
44
|
+
});
|
|
45
|
+
res.on("error", reject);
|
|
46
|
+
})
|
|
47
|
+
.on("error", reject);
|
|
48
|
+
});
|
|
16
49
|
}
|
|
17
50
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
51
|
+
async function ensureBinary() {
|
|
52
|
+
if (fs.existsSync(binPath)) return;
|
|
53
|
+
|
|
54
|
+
const platform = PLATFORM_MAP[process.platform];
|
|
55
|
+
const arch = ARCH_MAP[process.arch];
|
|
56
|
+
if (!platform || !arch) {
|
|
57
|
+
console.error(
|
|
58
|
+
`Unsupported platform: ${process.platform}-${process.arch}\n` +
|
|
59
|
+
`Supported: darwin-arm64, darwin-x64, linux-arm64, linux-x64\n` +
|
|
60
|
+
`Build from source: go install github.com/${REPO}@latest`
|
|
61
|
+
);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
21
64
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
65
|
+
const archiveName = `${NAME}_${VERSION}_${platform}_${arch}.tar.gz`;
|
|
66
|
+
const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${archiveName}`;
|
|
67
|
+
|
|
68
|
+
process.stderr.write(`${NAME} v${VERSION} — first run setup\n`);
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const buffer = await downloadFile(url);
|
|
72
|
+
const tmpFile = path.join(binDir, "_archive.tar.gz");
|
|
73
|
+
fs.writeFileSync(tmpFile, buffer);
|
|
74
|
+
execSync(`tar -xzf "${tmpFile}" -C "${binDir}" "${NAME}"`, { stdio: "ignore" });
|
|
75
|
+
fs.unlinkSync(tmpFile);
|
|
76
|
+
fs.chmodSync(binPath, 0o755);
|
|
77
|
+
process.stderr.write(` ready!\n\n`);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
console.error(
|
|
80
|
+
`\nFailed to download ${NAME}: ${err.message}\n\n` +
|
|
81
|
+
`Install manually:\n` +
|
|
82
|
+
` go install github.com/${REPO}@latest\n` +
|
|
83
|
+
` # or: https://github.com/${REPO}/releases`
|
|
84
|
+
);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function main() {
|
|
90
|
+
await ensureBinary();
|
|
91
|
+
|
|
92
|
+
const child = spawn(binPath, process.argv.slice(2), {
|
|
93
|
+
stdio: "inherit",
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
child.on("error", (err) => {
|
|
97
|
+
console.error(`Failed to start ${NAME}: ${err.message}`);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
child.on("close", (code) => {
|
|
102
|
+
process.exit(code ?? 1);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
26
105
|
|
|
27
|
-
|
|
28
|
-
process.exit(code ?? 1);
|
|
29
|
-
});
|
|
106
|
+
main();
|
package/install.js
CHANGED
|
@@ -1,113 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const path = require("path");
|
|
9
|
-
const { execSync } = require("child_process");
|
|
10
|
-
const { createGunzip } = require("zlib");
|
|
11
|
-
|
|
12
|
-
const REPO = "SpyrosBou/dotenvx-tui";
|
|
13
|
-
const NAME = "dotenvx-tui";
|
|
14
|
-
const VERSION = require("./package.json").version;
|
|
15
|
-
|
|
16
|
-
const PLATFORM_MAP = {
|
|
17
|
-
darwin: "darwin",
|
|
18
|
-
linux: "linux",
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const ARCH_MAP = {
|
|
22
|
-
x64: "amd64",
|
|
23
|
-
arm64: "arm64",
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
function getTarget() {
|
|
27
|
-
const platform = PLATFORM_MAP[process.platform];
|
|
28
|
-
const arch = ARCH_MAP[process.arch];
|
|
29
|
-
|
|
30
|
-
if (!platform || !arch) {
|
|
31
|
-
console.error(
|
|
32
|
-
`Unsupported platform: ${process.platform}-${process.arch}\n` +
|
|
33
|
-
`Supported: darwin-arm64, darwin-x64, linux-arm64, linux-x64\n` +
|
|
34
|
-
`Build from source: go install github.com/${REPO}@latest`
|
|
35
|
-
);
|
|
36
|
-
process.exit(1);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return { platform, arch };
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function downloadFile(url) {
|
|
43
|
-
return new Promise((resolve, reject) => {
|
|
44
|
-
https
|
|
45
|
-
.get(url, (res) => {
|
|
46
|
-
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
47
|
-
return downloadFile(res.headers.location).then(resolve, reject);
|
|
48
|
-
}
|
|
49
|
-
if (res.statusCode !== 200) {
|
|
50
|
-
return reject(new Error(`Download failed: HTTP ${res.statusCode}`));
|
|
51
|
-
}
|
|
52
|
-
const total = parseInt(res.headers["content-length"] || "0", 10);
|
|
53
|
-
const chunks = [];
|
|
54
|
-
let downloaded = 0;
|
|
55
|
-
res.on("data", (chunk) => {
|
|
56
|
-
chunks.push(chunk);
|
|
57
|
-
downloaded += chunk.length;
|
|
58
|
-
if (total > 0) {
|
|
59
|
-
const pct = Math.round((downloaded / total) * 100);
|
|
60
|
-
const mb = (downloaded / 1024 / 1024).toFixed(1);
|
|
61
|
-
process.stdout.write(`\r downloading... ${mb} MB (${pct}%)`);
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
res.on("end", () => {
|
|
65
|
-
if (total > 0) process.stdout.write("\n");
|
|
66
|
-
resolve(Buffer.concat(chunks));
|
|
67
|
-
});
|
|
68
|
-
res.on("error", reject);
|
|
69
|
-
})
|
|
70
|
-
.on("error", reject);
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function extractTarGz(buffer, destDir) {
|
|
75
|
-
// Write to temp file and use system tar (available on macOS + Linux)
|
|
76
|
-
const tmpFile = path.join(destDir, "_archive.tar.gz");
|
|
77
|
-
fs.writeFileSync(tmpFile, buffer);
|
|
78
|
-
execSync(`tar -xzf "${tmpFile}" -C "${destDir}" "${NAME}"`, { stdio: "ignore" });
|
|
79
|
-
fs.unlinkSync(tmpFile);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async function main() {
|
|
83
|
-
const { platform, arch } = getTarget();
|
|
84
|
-
const archiveName = `${NAME}_${VERSION}_${platform}_${arch}.tar.gz`;
|
|
85
|
-
const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${archiveName}`;
|
|
86
|
-
const binDir = path.join(__dirname, "bin");
|
|
87
|
-
|
|
88
|
-
// Skip if binary already exists
|
|
89
|
-
const binPath = path.join(binDir, NAME);
|
|
90
|
-
if (fs.existsSync(binPath)) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
console.log(`Downloading ${NAME} v${VERSION} for ${platform}/${arch}...`);
|
|
95
|
-
|
|
96
|
-
try {
|
|
97
|
-
const buffer = await downloadFile(url);
|
|
98
|
-
fs.mkdirSync(binDir, { recursive: true });
|
|
99
|
-
extractTarGz(buffer, binDir);
|
|
100
|
-
fs.chmodSync(binPath, 0o755);
|
|
101
|
-
console.log(`Installed ${NAME} to ${binPath}`);
|
|
102
|
-
} catch (err) {
|
|
103
|
-
console.error(
|
|
104
|
-
`Failed to download ${NAME}: ${err.message}\n\n` +
|
|
105
|
-
`You can install manually:\n` +
|
|
106
|
-
` go install github.com/${REPO}@latest\n` +
|
|
107
|
-
` # or download from: https://github.com/${REPO}/releases`
|
|
108
|
-
);
|
|
109
|
-
process.exit(1);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
main();
|
|
3
|
+
// Binary is now downloaded on first run (from bin/cli.js) instead of postinstall.
|
|
4
|
+
// npm v7+ suppresses all postinstall output, so download-on-first-run gives
|
|
5
|
+
// users visible progress feedback.
|
|
6
|
+
//
|
|
7
|
+
// This file is kept as a no-op so existing installs don't break.
|