@babelx/cli 0.2.0 → 0.2.2

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/bx CHANGED
@@ -1,74 +1,143 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * BabelX CLI - Binary wrapper
4
- * Detects platform and runs the appropriate binary
3
+ * BabelX CLI - Binary wrapper with lazy download
4
+ * Downloads the appropriate binary on first run
5
5
  */
6
6
 
7
- const { spawn } = require('child_process');
8
- const path = require('path');
9
- const fs = require('fs');
10
- const os = require('os');
7
+ import { spawn } from "node:child_process";
8
+ import { createWriteStream, existsSync, mkdirSync } from "node:fs";
9
+ import { join, dirname } from "node:path";
10
+ import { fileURLToPath } from "node:url";
11
+ import { platform as getPlatformName, arch as getArch } from "node:os";
12
+ import { get } from "node:https";
13
+
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = dirname(__filename);
16
+
17
+ const GITHUB_REPO = "babelxdev/bx-cli";
11
18
 
12
19
  function getPlatform() {
13
- const platform = os.platform();
14
- const arch = os.arch();
20
+ const platform = getPlatformName();
21
+ const arch = getArch();
15
22
 
16
23
  const platformMap = {
17
- 'darwin': 'darwin',
18
- 'linux': 'linux',
19
- 'win32': 'windows'
24
+ darwin: "darwin",
25
+ linux: "linux",
26
+ win32: "windows",
20
27
  };
21
28
 
22
29
  const archMap = {
23
- 'x64': 'x64',
24
- 'arm64': 'arm64'
30
+ x64: "x64",
31
+ arm64: "arm64",
25
32
  };
26
33
 
27
34
  const p = platformMap[platform];
28
35
  const a = archMap[arch];
29
36
 
30
37
  if (!p || !a) {
31
- console.error(`Unsupported platform: ${platform} ${arch}`);
38
+ console.error(`❌ Unsupported platform: ${platform} ${arch}`);
32
39
  process.exit(1);
33
40
  }
34
41
 
35
42
  return `${p}-${a}`;
36
43
  }
37
44
 
45
+ function getBinaryName() {
46
+ return process.platform === "win32" ? "bx.exe" : "bx";
47
+ }
48
+
38
49
  function getBinaryPath() {
39
50
  const platform = getPlatform();
40
- const binDir = path.join(__dirname, '..', 'vendor');
41
- const binName = platform.startsWith('windows') ? 'bx.exe' : 'bx';
42
- const binPath = path.join(binDir, platform, binName);
51
+ const binDir = join(__dirname, "..", "vendor");
52
+ const binName = getBinaryName();
53
+ return join(binDir, platform, binName);
54
+ }
55
+
56
+ async function downloadBinary(platform, destPath) {
57
+ const binaryName = getBinaryName();
58
+ const packageJson = JSON.parse(
59
+ await import("node:fs").then((fs) =>
60
+ fs.readFileSync(join(__dirname, "..", "package.json"), "utf-8"),
61
+ ),
62
+ );
63
+ const version = packageJson.version;
64
+ const url = `https://github.com/${GITHUB_REPO}/releases/download/v${version}/bx-${platform}${process.platform === "win32" ? ".exe" : ""}`;
43
65
 
44
- return binPath;
66
+ console.log(`📦 First time setup: Downloading BabelX CLI v${version}...`);
67
+ console.log(` Platform: ${platform}`);
68
+
69
+ // Ensure directory exists
70
+ const dir = dirname(destPath);
71
+ if (!existsSync(dir)) {
72
+ mkdirSync(dir, { recursive: true });
73
+ }
74
+
75
+ return new Promise((resolve, reject) => {
76
+ const file = createWriteStream(destPath);
77
+ get(url, { followRedirects: true }, (response) => {
78
+ 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);
86
+ } else if (response.statusCode === 200) {
87
+ response.pipe(file);
88
+ file.on("finish", () => {
89
+ file.close();
90
+ resolve();
91
+ });
92
+ } else {
93
+ reject(
94
+ new Error(`HTTP ${response.statusCode}: ${response.statusMessage}`),
95
+ );
96
+ }
97
+ }).on("error", reject);
98
+ });
45
99
  }
46
100
 
47
- function main() {
101
+ function makeExecutable(filePath) {
102
+ if (process.platform !== "win32") {
103
+ import("node:fs").then((fs) => fs.chmodSync(filePath, 0o755));
104
+ }
105
+ }
106
+
107
+ async function main() {
48
108
  const binaryPath = getBinaryPath();
109
+ const platform = getPlatform();
49
110
 
50
- // Check if binary exists
51
- if (!fs.existsSync(binaryPath)) {
52
- console.error('BabelX CLI binary not found.');
53
- console.error(`Expected path: ${binaryPath}`);
54
- console.error('');
55
- console.error('Please run: npm install @babelx/cli');
56
- console.error('Or download the binary manually from GitHub releases.');
57
- process.exit(1);
111
+ // Download binary if it doesn't exist (lazy loading)
112
+ if (!existsSync(binaryPath)) {
113
+ try {
114
+ await downloadBinary(platform, binaryPath);
115
+ makeExecutable(binaryPath);
116
+ console.log(`✅ BabelX CLI installed successfully!\n`);
117
+ } catch (error) {
118
+ console.error("❌ Failed to download BabelX CLI binary.");
119
+ console.error(`Error: ${error.message}`);
120
+ console.error("");
121
+ console.error("Please try:");
122
+ console.error("1. Check your internet connection");
123
+ console.error("2. Download manually from:");
124
+ console.error(` https://github.com/${GITHUB_REPO}/releases`);
125
+ process.exit(1);
126
+ }
58
127
  }
59
128
 
60
129
  // Run the binary with all arguments
61
130
  const child = spawn(binaryPath, process.argv.slice(2), {
62
- stdio: 'inherit',
63
- windowsHide: true
131
+ stdio: "inherit",
132
+ windowsHide: true,
64
133
  });
65
134
 
66
- child.on('error', (err) => {
67
- console.error('Failed to start BabelX CLI:', err.message);
135
+ child.on("error", (err) => {
136
+ console.error("Failed to start BabelX CLI:", err.message);
68
137
  process.exit(1);
69
138
  });
70
139
 
71
- child.on('exit', (code) => {
140
+ child.on("exit", (code) => {
72
141
  process.exit(code || 0);
73
142
  });
74
143
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@babelx/cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "BabelX CLI - AI-powered translation and i18n management tool",
5
5
  "module": "index.ts",
6
6
  "type": "module",
@@ -1,23 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Post-install script for @babelx/cli
4
- * Downloads the appropriate binary for the current platform
3
+ * Post-install script for @babelx/cli (optional)
4
+ * Pre-downloads the binary during installation (if allowed)
5
+ * If this fails, the CLI will download lazily on first run
5
6
  */
6
7
 
7
- import {
8
- chmodSync,
9
- createWriteStream,
10
- existsSync,
11
- mkdirSync,
12
- readFileSync,
13
- } from "node:fs";
8
+ import { createWriteStream, existsSync, mkdirSync } from "node:fs";
14
9
  import { get } from "node:https";
15
10
  import { dirname, join } from "node:path";
16
11
  import { fileURLToPath } from "node:url";
17
12
 
18
13
  const GITHUB_REPO = "babelxdev/bx-cli";
19
14
 
20
- // ES modules don't have __dirname
21
15
  const __filename = fileURLToPath(import.meta.url);
22
16
  const __dirname = dirname(__filename);
23
17
 
@@ -39,14 +33,7 @@ function getPlatform() {
39
33
  const p = platformMap[platform];
40
34
  const a = archMap[arch];
41
35
 
42
- if (!p || !a) {
43
- console.error(`❌ Unsupported platform: ${platform} ${arch}`);
44
- console.error(
45
- "Supported platforms: darwin-x64, darwin-arm64, linux-x64, linux-arm64, windows-x64",
46
- );
47
- process.exit(1);
48
- }
49
-
36
+ if (!p || !a) return null;
50
37
  return `${p}-${a}`;
51
38
  }
52
39
 
@@ -58,14 +45,10 @@ async function downloadBinary(version, platform, destPath) {
58
45
  const binaryExt = process.platform === "win32" ? ".exe" : "";
59
46
  const url = `https://github.com/${GITHUB_REPO}/releases/download/v${version}/bx-${platform}${binaryExt}`;
60
47
 
61
- console.log(`📦 Downloading BabelX CLI v${version} for ${platform}...`);
62
- console.log(` URL: ${url}`);
63
-
64
48
  return new Promise((resolve, reject) => {
65
49
  const file = createWriteStream(destPath);
66
50
  get(url, { followRedirects: true }, (response) => {
67
51
  if (response.statusCode === 302 || response.statusCode === 301) {
68
- // Handle redirect
69
52
  get(response.headers.location, (res) => {
70
53
  res.pipe(file);
71
54
  file.on("finish", () => {
@@ -80,78 +63,47 @@ async function downloadBinary(version, platform, destPath) {
80
63
  resolve();
81
64
  });
82
65
  } else {
83
- reject(
84
- new Error(`HTTP ${response.statusCode}: ${response.statusMessage}`),
85
- );
66
+ reject(new Error(`HTTP ${response.statusCode}`));
86
67
  }
87
68
  }).on("error", reject);
88
69
  });
89
70
  }
90
71
 
91
- function makeExecutable(filePath) {
92
- if (process.platform !== "win32") {
93
- chmodSync(filePath, 0o755);
94
- }
95
- }
96
-
97
72
  async function main() {
98
- // Skip in CI environment or if explicitly disabled
73
+ // Skip if CI, disabled, or not interactive
99
74
  if (process.env.CI || process.env.SKIP_BABELX_BINARY) {
100
- console.log("⏭️ Skipping binary download (CI environment)");
101
75
  return;
102
76
  }
103
77
 
104
78
  try {
105
- // Get package version
79
+ const platform = getPlatform();
80
+ if (!platform) return;
81
+
82
+ const { readFileSync } = await import("node:fs");
106
83
  const packageJson = JSON.parse(
107
84
  readFileSync(join(__dirname, "..", "package.json"), "utf-8"),
108
85
  );
109
86
  const version = packageJson.version;
110
-
111
- const platform = getPlatform();
112
87
  const binaryName = getBinaryName();
113
-
114
- // Create vendor directory
115
88
  const vendorDir = join(__dirname, "..", "vendor", platform);
116
- if (!existsSync(vendorDir)) {
117
- mkdirSync(vendorDir, { recursive: true });
118
- }
119
-
120
89
  const binaryPath = join(vendorDir, binaryName);
121
90
 
122
- // Check if binary already exists
123
- if (existsSync(binaryPath)) {
124
- console.log(`✅ BabelX CLI binary already exists for ${platform}`);
125
- return;
91
+ if (existsSync(binaryPath)) return;
92
+
93
+ if (!existsSync(vendorDir)) {
94
+ mkdirSync(vendorDir, { recursive: true });
126
95
  }
127
96
 
128
- // Download binary
129
97
  await downloadBinary(version, platform, binaryPath);
130
98
 
131
- // Make executable (Unix only)
132
- makeExecutable(binaryPath);
133
-
134
- console.log(`✅ BabelX CLI v${version} installed successfully!`);
135
- console.log(` Binary: ${binaryPath}`);
136
- } catch (error) {
137
- // Don't fail installation if binary download fails (e.g., first release)
138
- if (error.message.includes("404")) {
139
- console.warn("⚠️ Binary not found for this version yet.");
140
- console.warn(" The CLI will use the bundled JavaScript version.");
141
- console.warn(
142
- ` Check https://github.com/${GITHUB_REPO}/releases for updates.`,
143
- );
144
- return; // Don't fail installation
99
+ if (process.platform !== "win32") {
100
+ const { chmodSync } = await import("node:fs");
101
+ chmodSync(binaryPath, 0o755);
145
102
  }
146
103
 
147
- console.error("❌ Failed to install BabelX CLI binary:", error.message);
148
- console.error("");
149
- console.error("You can try:");
150
- console.error("1. Check your internet connection");
151
- console.error("2. Set SKIP_BABELX_BINARY=1 to skip binary download");
152
- console.error("3. Install manually from GitHub releases:");
153
- console.error(` https://github.com/${GITHUB_REPO}/releases`);
154
- // Don't exit with error - allow npm install to continue
104
+ console.log(`✅ BabelX CLI binary pre-downloaded for ${platform}`);
105
+ } catch {
106
+ // Silent fail - CLI will download on first run
155
107
  }
156
108
  }
157
109