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.
Files changed (3) hide show
  1. package/bin/cli.js +96 -19
  2. package/install.js +5 -111
  3. 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 binPath = path.join(__dirname, NAME);
9
-
10
- if (!fs.existsSync(binPath)) {
11
- console.error(
12
- `${NAME} binary not found. Try reinstalling:\n` +
13
- ` npm install -g dotenvx-tui`
14
- );
15
- process.exit(1);
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
- const child = spawn(binPath, process.argv.slice(2), {
19
- stdio: "inherit",
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
- child.on("error", (err) => {
23
- console.error(`Failed to start ${NAME}: ${err.message}`);
24
- process.exit(1);
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
- child.on("close", (code) => {
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
- // Postinstall script: downloads the correct binary from GitHub Releases.
4
- // No external dependencies uses Node.js built-in https/fs/child_process.
5
-
6
- const https = require("https");
7
- const fs = require("fs");
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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dotenvx-tui",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "Full-screen terminal UI for managing dotenvx-encrypted environment variables",
5
5
  "repository": {
6
6
  "type": "git",