@babelx/cli 0.2.2 → 0.2.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 (2) hide show
  1. package/bin/bx +104 -16
  2. package/package.json +1 -1
package/bin/bx CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import { spawn } from "node:child_process";
8
- import { createWriteStream, existsSync, mkdirSync } from "node:fs";
8
+ import { createWriteStream, existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from "node:fs";
9
9
  import { join, dirname } from "node:path";
10
10
  import { fileURLToPath } from "node:url";
11
11
  import { platform as getPlatformName, arch as getArch } from "node:os";
@@ -53,6 +53,53 @@ function getBinaryPath() {
53
53
  return join(binDir, platform, binName);
54
54
  }
55
55
 
56
+ function getVersionFilePath() {
57
+ const platform = getPlatform();
58
+ const binDir = join(__dirname, "..", "vendor");
59
+ return join(binDir, platform, ".version");
60
+ }
61
+
62
+ function getPackageVersion() {
63
+ try {
64
+ const packageJson = JSON.parse(
65
+ readFileSync(join(__dirname, "..", "package.json"), "utf-8"),
66
+ );
67
+ return packageJson.version;
68
+ } catch {
69
+ return null;
70
+ }
71
+ }
72
+
73
+ function getBinaryVersion() {
74
+ try {
75
+ return readFileSync(getVersionFilePath(), "utf-8").trim();
76
+ } catch {
77
+ return null;
78
+ }
79
+ }
80
+
81
+ function saveBinaryVersion(version) {
82
+ try {
83
+ writeFileSync(getVersionFilePath(), version);
84
+ } catch {
85
+ // Ignore write errors
86
+ }
87
+ }
88
+
89
+ function removeOldBinary(binaryPath) {
90
+ try {
91
+ if (existsSync(binaryPath)) {
92
+ unlinkSync(binaryPath);
93
+ }
94
+ const versionFile = getVersionFilePath();
95
+ if (existsSync(versionFile)) {
96
+ unlinkSync(versionFile);
97
+ }
98
+ } catch {
99
+ // Ignore errors
100
+ }
101
+ }
102
+
56
103
  async function downloadBinary(platform, destPath) {
57
104
  const binaryName = getBinaryName();
58
105
  const packageJson = JSON.parse(
@@ -63,8 +110,9 @@ async function downloadBinary(platform, destPath) {
63
110
  const version = packageJson.version;
64
111
  const url = `https://github.com/${GITHUB_REPO}/releases/download/v${version}/bx-${platform}${process.platform === "win32" ? ".exe" : ""}`;
65
112
 
66
- console.log(`📦 First time setup: Downloading BabelX CLI v${version}...`);
113
+ console.log(`📦 First time setup: Downloading BabelX CLI v${version}`);
67
114
  console.log(` Platform: ${platform}`);
115
+ console.log("");
68
116
 
69
117
  // Ensure directory exists
70
118
  const dir = dirname(destPath);
@@ -74,21 +122,50 @@ async function downloadBinary(platform, destPath) {
74
122
 
75
123
  return new Promise((resolve, reject) => {
76
124
  const file = createWriteStream(destPath);
125
+ let downloaded = 0;
126
+ let total = 0;
127
+ let lastPercent = -1;
128
+
129
+ function formatBytes(bytes) {
130
+ if (bytes === 0) return "0 B";
131
+ const k = 1024;
132
+ const sizes = ["B", "KB", "MB", "GB"];
133
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
134
+ return `${(bytes / k ** i).toFixed(1)} ${sizes[i]}`;
135
+ }
136
+
137
+ function updateProgress() {
138
+ if (total === 0) return;
139
+ const percent = Math.floor((downloaded / total) * 100);
140
+ if (percent !== lastPercent && percent % 5 === 0) {
141
+ const bar = "█".repeat(Math.floor(percent / 5)) + "░".repeat(20 - Math.floor(percent / 5));
142
+ process.stdout.write(`\r ${bar} ${percent}% (${formatBytes(downloaded)} / ${formatBytes(total)})`);
143
+ lastPercent = percent;
144
+ }
145
+ }
146
+
147
+ function handleResponse(response) {
148
+ total = parseInt(response.headers["content-length"] || "0", 10);
149
+
150
+ response.on("data", (chunk) => {
151
+ downloaded += chunk.length;
152
+ updateProgress();
153
+ });
154
+
155
+ response.pipe(file);
156
+
157
+ file.on("finish", () => {
158
+ process.stdout.write("\n");
159
+ file.close();
160
+ resolve();
161
+ });
162
+ }
163
+
77
164
  get(url, { followRedirects: true }, (response) => {
78
165
  if (response.statusCode === 302 || response.statusCode === 301) {
79
- get(response.headers.location, (res) => {
80
- res.pipe(file);
81
- file.on("finish", () => {
82
- file.close();
83
- resolve();
84
- });
85
- }).on("error", reject);
166
+ get(response.headers.location, handleResponse).on("error", reject);
86
167
  } else if (response.statusCode === 200) {
87
- response.pipe(file);
88
- file.on("finish", () => {
89
- file.close();
90
- resolve();
91
- });
168
+ handleResponse(response);
92
169
  } else {
93
170
  reject(
94
171
  new Error(`HTTP ${response.statusCode}: ${response.statusMessage}`),
@@ -107,12 +184,23 @@ function makeExecutable(filePath) {
107
184
  async function main() {
108
185
  const binaryPath = getBinaryPath();
109
186
  const platform = getPlatform();
187
+ const packageVersion = getPackageVersion();
188
+ const binaryVersion = getBinaryVersion();
189
+
190
+ // Check if binary needs update (new version or doesn't exist)
191
+ const needsDownload = !existsSync(binaryPath) || !binaryVersion || binaryVersion !== packageVersion;
192
+
193
+ if (needsDownload && packageVersion) {
194
+ // Remove old binary if exists
195
+ if (binaryVersion && binaryVersion !== packageVersion) {
196
+ console.log(`📦 Updating BabelX CLI: v${binaryVersion} → v${packageVersion}`);
197
+ removeOldBinary(binaryPath);
198
+ }
110
199
 
111
- // Download binary if it doesn't exist (lazy loading)
112
- if (!existsSync(binaryPath)) {
113
200
  try {
114
201
  await downloadBinary(platform, binaryPath);
115
202
  makeExecutable(binaryPath);
203
+ saveBinaryVersion(packageVersion);
116
204
  console.log(`✅ BabelX CLI installed successfully!\n`);
117
205
  } catch (error) {
118
206
  console.error("❌ Failed to download BabelX CLI binary.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@babelx/cli",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "BabelX CLI - AI-powered translation and i18n management tool",
5
5
  "module": "index.ts",
6
6
  "type": "module",