@heetmehta18/autodev 0.1.5 → 0.1.6
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/index.js +93 -34
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const { spawnSync } = require('child_process');
|
|
3
|
+
const { spawnSync, execSync } = require('child_process');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const os = require('os');
|
|
7
|
-
const
|
|
7
|
+
const https = require('https');
|
|
8
|
+
const http = require('http');
|
|
8
9
|
|
|
9
10
|
// Determine OS & Arch mapping
|
|
10
11
|
const platformMap = {
|
|
@@ -29,12 +30,24 @@ if (!platform || !arch) {
|
|
|
29
30
|
const ext = platform === 'windows' ? 'zip' : 'tar.gz';
|
|
30
31
|
const binaryName = platform === 'windows' ? 'autodev.exe' : 'autodev';
|
|
31
32
|
|
|
32
|
-
// Version
|
|
33
|
+
// Version: prefer the latest GitHub release tag; fall back to package.json
|
|
33
34
|
const pkgJson = require('../package.json');
|
|
34
|
-
const
|
|
35
|
+
const fallbackVersion = `v${pkgJson.version}`;
|
|
36
|
+
|
|
37
|
+
function getLatestReleaseTag() {
|
|
38
|
+
try {
|
|
39
|
+
const out = execSync(
|
|
40
|
+
'curl -fsSL https://api.github.com/repos/HEETMEHTA18/autodev/releases/latest',
|
|
41
|
+
{ encoding: 'utf8', timeout: 10000 }
|
|
42
|
+
);
|
|
43
|
+
const match = out.match(/"tag_name"\s*:\s*"([^"]+)"/);
|
|
44
|
+
if (match && match[1]) return match[1];
|
|
45
|
+
} catch (_) { /* fall through */ }
|
|
46
|
+
return fallbackVersion;
|
|
47
|
+
}
|
|
35
48
|
|
|
36
49
|
// Resolve target paths
|
|
37
|
-
const binDir =
|
|
50
|
+
const binDir = __dirname;
|
|
38
51
|
const binaryPath = path.join(binDir, binaryName);
|
|
39
52
|
|
|
40
53
|
// Development fallback paths
|
|
@@ -54,9 +67,43 @@ for (const devPath of devPaths) {
|
|
|
54
67
|
}
|
|
55
68
|
}
|
|
56
69
|
|
|
57
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Download a file using Node.js built-in https module (follows redirects).
|
|
72
|
+
* This avoids issues with curl/wget not being available or behaving
|
|
73
|
+
* differently in sandboxed npx environments.
|
|
74
|
+
*/
|
|
75
|
+
function download(url, destPath, maxRedirects = 5) {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
if (maxRedirects <= 0) return reject(new Error('Too many redirects'));
|
|
78
|
+
|
|
79
|
+
const client = url.startsWith('https') ? https : http;
|
|
80
|
+
client.get(url, (res) => {
|
|
81
|
+
// Follow redirects (GitHub releases return 302)
|
|
82
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
83
|
+
return download(res.headers.location, destPath, maxRedirects - 1)
|
|
84
|
+
.then(resolve)
|
|
85
|
+
.catch(reject);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (res.statusCode !== 200) {
|
|
89
|
+
return reject(new Error(`HTTP ${res.statusCode} from ${url}`));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const fileStream = fs.createWriteStream(destPath);
|
|
93
|
+
res.pipe(fileStream);
|
|
94
|
+
fileStream.on('finish', () => {
|
|
95
|
+
fileStream.close();
|
|
96
|
+
resolve();
|
|
97
|
+
});
|
|
98
|
+
fileStream.on('error', reject);
|
|
99
|
+
}).on('error', reject);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function downloadBinary() {
|
|
104
|
+
const version = getLatestReleaseTag();
|
|
58
105
|
console.log(`\n[autodev] Native binary not found. Downloading AutoDev ${version} for ${platform}/${arch}...`);
|
|
59
|
-
|
|
106
|
+
|
|
60
107
|
if (!fs.existsSync(binDir)) {
|
|
61
108
|
fs.mkdirSync(binDir, { recursive: true });
|
|
62
109
|
}
|
|
@@ -64,27 +111,28 @@ function downloadBinary() {
|
|
|
64
111
|
// Construct download URL
|
|
65
112
|
const archiveName = `autodev_${platform}_${arch}`;
|
|
66
113
|
const archiveFile = `${archiveName}.${ext}`;
|
|
67
|
-
// Using the user's repository URL
|
|
68
114
|
const url = `https://github.com/HEETMEHTA18/autodev/releases/download/${version}/${archiveFile}`;
|
|
69
|
-
|
|
70
|
-
const tempFile = path.join(os.tmpdir(),
|
|
71
|
-
|
|
72
|
-
// Download using
|
|
115
|
+
|
|
116
|
+
const tempFile = path.join(os.tmpdir(), `autodev_download_${Date.now()}.${ext}`);
|
|
117
|
+
|
|
118
|
+
// Download using Node.js built-in HTTPS (handles redirects properly)
|
|
73
119
|
try {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
execSync(`wget -q "${url}" -O "${tempFile}"`, { stdio: 'inherit' });
|
|
81
|
-
} else {
|
|
82
|
-
throw new Error('Neither curl nor wget was found on the system path.');
|
|
83
|
-
}
|
|
120
|
+
console.log(`[autodev] Downloading from: ${url}`);
|
|
121
|
+
await download(url, tempFile);
|
|
122
|
+
|
|
123
|
+
// Verify the file was actually downloaded
|
|
124
|
+
if (!fs.existsSync(tempFile)) {
|
|
125
|
+
throw new Error('Download completed but file not found on disk.');
|
|
84
126
|
}
|
|
127
|
+
const stat = fs.statSync(tempFile);
|
|
128
|
+
if (stat.size < 1000) {
|
|
129
|
+
throw new Error(`Downloaded file is too small (${stat.size} bytes), likely an error page.`);
|
|
130
|
+
}
|
|
131
|
+
console.log(`[autodev] Downloaded ${(stat.size / 1024 / 1024).toFixed(1)} MB`);
|
|
85
132
|
} catch (err) {
|
|
86
133
|
console.error(`\n[autodev] Error downloading release asset: ${err.message}`);
|
|
87
|
-
console.error(`
|
|
134
|
+
console.error(`[autodev] URL: ${url}`);
|
|
135
|
+
console.error(`[autodev] Please verify that the release version ${version} exists and has compiled assets.`);
|
|
88
136
|
process.exit(1);
|
|
89
137
|
}
|
|
90
138
|
|
|
@@ -100,30 +148,41 @@ function downloadBinary() {
|
|
|
100
148
|
} else {
|
|
101
149
|
execSync(`tar -xzf "${tempFile}" -C "${binDir}"`, { stdio: 'inherit' });
|
|
102
150
|
}
|
|
103
|
-
|
|
151
|
+
|
|
104
152
|
// Clean up temp archive
|
|
105
153
|
if (fs.existsSync(tempFile)) {
|
|
106
154
|
fs.unlinkSync(tempFile);
|
|
107
155
|
}
|
|
108
|
-
|
|
156
|
+
|
|
109
157
|
// Set execution permissions on Linux/macOS
|
|
110
|
-
if (process.platform !== 'win32') {
|
|
158
|
+
if (process.platform !== 'win32' && fs.existsSync(binaryPath)) {
|
|
111
159
|
fs.chmodSync(binaryPath, 0o755);
|
|
112
160
|
}
|
|
113
161
|
console.log(`[autodev] Installation successful.\n`);
|
|
114
162
|
} catch (err) {
|
|
163
|
+
// Clean up temp file on error too
|
|
164
|
+
if (fs.existsSync(tempFile)) {
|
|
165
|
+
fs.unlinkSync(tempFile);
|
|
166
|
+
}
|
|
115
167
|
console.error(`\n[autodev] Error extracting archive: ${err.message}`);
|
|
116
168
|
process.exit(1);
|
|
117
169
|
}
|
|
118
170
|
}
|
|
119
171
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
172
|
+
async function main() {
|
|
173
|
+
// If no local dev binary is found and the packaged binary is missing, download it
|
|
174
|
+
if (activeBinaryPath === binaryPath && !fs.existsSync(binaryPath)) {
|
|
175
|
+
await downloadBinary();
|
|
176
|
+
}
|
|
124
177
|
|
|
125
|
-
// Forward execution
|
|
126
|
-
const args = process.argv.slice(2);
|
|
127
|
-
const result = spawnSync(activeBinaryPath, args, { stdio: 'inherit' });
|
|
178
|
+
// Forward execution
|
|
179
|
+
const args = process.argv.slice(2);
|
|
180
|
+
const result = spawnSync(activeBinaryPath, args, { stdio: 'inherit' });
|
|
128
181
|
|
|
129
|
-
process.exit(result.status ?? 0);
|
|
182
|
+
process.exit(result.status ?? 0);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
main().catch((err) => {
|
|
186
|
+
console.error(`[autodev] Fatal error: ${err.message}`);
|
|
187
|
+
process.exit(1);
|
|
188
|
+
});
|