instatunnel 1.0.28 → 1.0.30
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/install.js +137 -153
- package/package.json +1 -1
package/install.js
CHANGED
|
@@ -21,51 +21,31 @@ const colors = {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
function log(message, color = 'reset') {
|
|
24
|
-
console.log(colors[color]
|
|
24
|
+
console.log(`${colors[color]}${message}${colors.reset}`);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function detectPlatform() {
|
|
28
28
|
const platform = os.platform();
|
|
29
29
|
const arch = os.arch();
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
// Map to our actual binary names in the bin/ directory
|
|
32
32
|
switch (platform) {
|
|
33
33
|
case 'linux':
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
if (arch === 'arm64') {
|
|
35
|
+
return 'instatunnel-linux-arm64';
|
|
36
|
+
}
|
|
37
|
+
return 'instatunnel-linux';
|
|
36
38
|
case 'darwin':
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
if (arch === 'arm64') {
|
|
40
|
+
return 'instatunnel-macos-arm64';
|
|
41
|
+
}
|
|
42
|
+
return 'instatunnel-macos';
|
|
39
43
|
case 'win32':
|
|
40
|
-
|
|
41
|
-
break;
|
|
42
|
-
case 'freebsd':
|
|
43
|
-
platformSuffix = 'freebsd';
|
|
44
|
-
break;
|
|
45
|
-
case 'openbsd':
|
|
46
|
-
platformSuffix = 'openbsd';
|
|
47
|
-
break;
|
|
48
|
-
default:
|
|
49
|
-
throw new Error('Unsupported platform: ' + platform);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
let archSuffix;
|
|
53
|
-
switch (arch) {
|
|
54
|
-
case 'x64':
|
|
55
|
-
archSuffix = 'amd64';
|
|
56
|
-
break;
|
|
57
|
-
case 'arm64':
|
|
58
|
-
archSuffix = 'arm64';
|
|
59
|
-
break;
|
|
60
|
-
case 'ia32':
|
|
61
|
-
archSuffix = '386';
|
|
62
|
-
break;
|
|
44
|
+
return 'instatunnel-windows.exe';
|
|
63
45
|
default:
|
|
64
|
-
|
|
46
|
+
// Fallback to linux binary for other Unix-like systems
|
|
47
|
+
return 'instatunnel-linux';
|
|
65
48
|
}
|
|
66
|
-
|
|
67
|
-
const extension = platform === 'win32' ? '.exe' : '';
|
|
68
|
-
return { platform: platformSuffix, arch: archSuffix, extension };
|
|
69
49
|
}
|
|
70
50
|
|
|
71
51
|
function downloadFile(url, outputPath) {
|
|
@@ -73,20 +53,29 @@ function downloadFile(url, outputPath) {
|
|
|
73
53
|
const file = fs.createWriteStream(outputPath);
|
|
74
54
|
|
|
75
55
|
https.get(url, (response) => {
|
|
56
|
+
// Handle redirects
|
|
57
|
+
if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
|
|
58
|
+
file.close();
|
|
59
|
+
fs.unlinkSync(outputPath);
|
|
60
|
+
return downloadFile(response.headers.location, outputPath).then(resolve).catch(reject);
|
|
61
|
+
}
|
|
62
|
+
|
|
76
63
|
if (response.statusCode !== 200) {
|
|
77
|
-
|
|
64
|
+
file.close();
|
|
65
|
+
fs.unlinkSync(outputPath);
|
|
66
|
+
reject(new Error(`HTTP ${response.statusCode}: ${response.statusMessage}`));
|
|
78
67
|
return;
|
|
79
68
|
}
|
|
80
69
|
|
|
81
70
|
response.pipe(file);
|
|
82
71
|
|
|
83
72
|
file.on('finish', () => {
|
|
84
|
-
file.close();
|
|
85
|
-
resolve();
|
|
73
|
+
file.close(resolve);
|
|
86
74
|
});
|
|
87
75
|
|
|
88
76
|
file.on('error', (err) => {
|
|
89
|
-
|
|
77
|
+
file.close();
|
|
78
|
+
fs.unlinkSync(outputPath);
|
|
90
79
|
reject(err);
|
|
91
80
|
});
|
|
92
81
|
}).on('error', (err) => {
|
|
@@ -95,121 +84,59 @@ function downloadFile(url, outputPath) {
|
|
|
95
84
|
});
|
|
96
85
|
}
|
|
97
86
|
|
|
98
|
-
async function
|
|
99
|
-
|
|
87
|
+
async function setupBinary() {
|
|
88
|
+
const binaryName = detectPlatform();
|
|
89
|
+
const binDir = path.join(__dirname, 'bin');
|
|
90
|
+
const isWindows = os.platform() === 'win32';
|
|
91
|
+
const outputPath = path.join(binDir, isWindows ? 'instatunnel.exe' : 'instatunnel');
|
|
92
|
+
const sourcePath = path.join(binDir, binaryName);
|
|
100
93
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
// Set permissions on source binary first
|
|
118
|
-
try {
|
|
119
|
-
fs.chmodSync(sourceBinaryPath, 0o755);
|
|
120
|
-
} catch (chmodError) {
|
|
121
|
-
// Ignore chmod errors on Windows
|
|
122
|
-
if (platform !== 'windows') {
|
|
123
|
-
console.warn('Warning: Could not set permissions on source binary');
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Copy to main binary names
|
|
128
|
-
const mainBinaryPath = path.join(binDir, BINARY_NAME + extension);
|
|
129
|
-
const aliasBinaryPath = path.join(binDir, 'it' + extension);
|
|
130
|
-
|
|
131
|
-
// Remove existing files if they exist
|
|
132
|
-
try {
|
|
133
|
-
if (fs.existsSync(mainBinaryPath)) fs.unlinkSync(mainBinaryPath);
|
|
134
|
-
if (fs.existsSync(aliasBinaryPath)) fs.unlinkSync(aliasBinaryPath);
|
|
135
|
-
} catch (unlinkError) {
|
|
136
|
-
// Continue if we can't remove existing files
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
fs.copyFileSync(sourceBinaryPath, mainBinaryPath);
|
|
140
|
-
fs.copyFileSync(sourceBinaryPath, aliasBinaryPath);
|
|
141
|
-
|
|
142
|
-
// Make executable on Unix systems
|
|
143
|
-
if (platform !== 'windows') {
|
|
144
|
-
try {
|
|
145
|
-
fs.chmodSync(mainBinaryPath, 0o755);
|
|
146
|
-
fs.chmodSync(aliasBinaryPath, 0o755);
|
|
147
|
-
} catch (chmodError) {
|
|
148
|
-
console.warn('Warning: Could not set executable permissions');
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
log('✅ InstaTunnel CLI installed successfully!', 'green');
|
|
153
|
-
log('', 'reset');
|
|
154
|
-
log('🎉 Quick start:', 'yellow');
|
|
155
|
-
log(' instatunnel 3000 # Expose port 3000', 'cyan');
|
|
156
|
-
log(' it 3000 # Short alias', 'cyan');
|
|
157
|
-
log(' instatunnel --help # Show all options', 'cyan');
|
|
158
|
-
log('', 'reset');
|
|
159
|
-
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Fallback to download if pre-compiled binary not found
|
|
164
|
-
log('📥 Downloading ' + sourceBinaryName + ' from server...', 'yellow');
|
|
165
|
-
const downloadUrl = PRIMARY_URL + '/' + sourceBinaryName;
|
|
166
|
-
|
|
167
|
-
try {
|
|
168
|
-
await downloadFile(downloadUrl, sourceBinaryPath);
|
|
169
|
-
} catch (err) {
|
|
170
|
-
log('⚠️ Primary download failed, trying fallback...', 'yellow');
|
|
171
|
-
const fallbackUrl = FALLBACK_URL + '/' + sourceBinaryName;
|
|
172
|
-
await downloadFile(fallbackUrl, sourceBinaryPath);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Verify download
|
|
176
|
-
const stats = fs.statSync(sourceBinaryPath);
|
|
177
|
-
if (stats.size < 1000000) {
|
|
178
|
-
throw new Error('Downloaded binary appears corrupted (too small)');
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Copy to main binary names
|
|
182
|
-
const mainBinaryPath = path.join(binDir, BINARY_NAME + extension);
|
|
183
|
-
const aliasBinaryPath = path.join(binDir, 'it' + extension);
|
|
184
|
-
|
|
185
|
-
fs.copyFileSync(sourceBinaryPath, mainBinaryPath);
|
|
186
|
-
fs.copyFileSync(sourceBinaryPath, aliasBinaryPath);
|
|
187
|
-
|
|
188
|
-
// Make executable on Unix systems
|
|
189
|
-
if (platform !== 'windows') {
|
|
190
|
-
fs.chmodSync(sourceBinaryPath, 0o755);
|
|
191
|
-
fs.chmodSync(mainBinaryPath, 0o755);
|
|
192
|
-
fs.chmodSync(aliasBinaryPath, 0o755);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
log('✅ InstaTunnel CLI installed successfully!', 'green');
|
|
196
|
-
log('', 'reset');
|
|
197
|
-
log('🎉 Quick start:', 'yellow');
|
|
198
|
-
log(' instatunnel 3000 # Expose port 3000', 'cyan');
|
|
199
|
-
log(' it 3000 # Short alias', 'cyan');
|
|
200
|
-
log(' instatunnel --help # Show all options', 'cyan');
|
|
201
|
-
log('', 'reset');
|
|
202
|
-
|
|
203
|
-
} catch (error) {
|
|
204
|
-
throw new Error('Installation failed: ' + error.message);
|
|
94
|
+
log('🚀 Installing InstaTunnel CLI...', 'blue');
|
|
95
|
+
log(`📋 Platform: ${os.platform()}-${os.arch()}`, 'cyan');
|
|
96
|
+
log(`🎯 Using binary: ${binaryName}`, 'cyan');
|
|
97
|
+
|
|
98
|
+
// Check if the platform-specific binary exists
|
|
99
|
+
if (!fs.existsSync(sourcePath)) {
|
|
100
|
+
throw new Error(`Binary for your platform (${binaryName}) not found. Supported platforms: linux, macOS, Windows (x64/arm64)`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Copy the platform-specific binary to the standard name
|
|
104
|
+
fs.copyFileSync(sourcePath, outputPath);
|
|
105
|
+
|
|
106
|
+
// Make executable on Unix systems
|
|
107
|
+
if (!isWindows) {
|
|
108
|
+
fs.chmodSync(outputPath, 0o755);
|
|
205
109
|
}
|
|
206
110
|
|
|
207
|
-
//
|
|
111
|
+
// Create 'it' alias
|
|
112
|
+
const itPath = path.join(binDir, isWindows ? 'it.exe' : 'it');
|
|
113
|
+
fs.copyFileSync(outputPath, itPath);
|
|
114
|
+
|
|
115
|
+
log('✅ InstaTunnel CLI installed successfully!', 'green');
|
|
116
|
+
log('', 'reset');
|
|
117
|
+
log('🚀 Quick Start:', 'cyan');
|
|
118
|
+
log(' instatunnel 3000 # Expose port 3000 instantly (no setup needed!)', 'reset');
|
|
119
|
+
log(' it 3000 # Short alias for the same command', 'reset');
|
|
120
|
+
log('', 'reset');
|
|
121
|
+
log('💡 More examples:', 'cyan');
|
|
122
|
+
log(' instatunnel # Auto-detect common ports (3000, 8000, 8080)', 'reset');
|
|
123
|
+
log(' instatunnel 8080 --name myapp', 'reset');
|
|
124
|
+
log(' instatunnel --help # See all options', 'reset');
|
|
125
|
+
log('', 'reset');
|
|
126
|
+
log('🌟 Key Benefits:', 'yellow');
|
|
127
|
+
log(' ✓ No signup required - works instantly', 'green');
|
|
128
|
+
log(' ✓ 24+ hour sessions (vs ngrok\'s 2 hours)', 'green');
|
|
129
|
+
log(' ✓ Custom subdomains included free', 'green');
|
|
130
|
+
log(' ✓ 40% cheaper than ngrok', 'green');
|
|
131
|
+
log('', 'reset');
|
|
132
|
+
log('📚 Documentation: https://docs.instatunnel.my', 'yellow');
|
|
133
|
+
|
|
134
|
+
// Test installation - skip version test to avoid hanging
|
|
208
135
|
try {
|
|
209
|
-
|
|
210
|
-
const stats = fs.statSync(
|
|
136
|
+
// Just verify the file exists and has content
|
|
137
|
+
const stats = fs.statSync(outputPath);
|
|
211
138
|
if (stats.size > 1000000) { // Binary should be at least 1MB
|
|
212
|
-
log(
|
|
139
|
+
log(`🔧 Installation verified! Binary size: ${Math.round(stats.size / 1024 / 1024)}MB`, 'green');
|
|
213
140
|
} else {
|
|
214
141
|
log('⚠️ Binary seems too small, but installation completed', 'yellow');
|
|
215
142
|
}
|
|
@@ -221,7 +148,30 @@ async function downloadBinary() {
|
|
|
221
148
|
// Create uninstall script
|
|
222
149
|
function createUninstallScript() {
|
|
223
150
|
const uninstallPath = path.join(__dirname, 'uninstall.js');
|
|
224
|
-
const uninstallScript =
|
|
151
|
+
const uninstallScript = `#!/usr/bin/env node
|
|
152
|
+
|
|
153
|
+
const fs = require('fs');
|
|
154
|
+
const path = require('path');
|
|
155
|
+
|
|
156
|
+
function cleanup() {
|
|
157
|
+
const binDir = path.join(__dirname, 'bin');
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
if (fs.existsSync(binDir)) {
|
|
161
|
+
fs.rmSync(binDir, { recursive: true, force: true });
|
|
162
|
+
}
|
|
163
|
+
console.log('✅ InstaTunnel CLI uninstalled successfully!');
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.warn('⚠️ Some cleanup may be incomplete:', error.message);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (require.main === module) {
|
|
170
|
+
cleanup();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
module.exports = { cleanup };
|
|
174
|
+
`;
|
|
225
175
|
|
|
226
176
|
fs.writeFileSync(uninstallPath, uninstallScript);
|
|
227
177
|
}
|
|
@@ -229,23 +179,57 @@ function createUninstallScript() {
|
|
|
229
179
|
// Create test script
|
|
230
180
|
function createTestScript() {
|
|
231
181
|
const testPath = path.join(__dirname, 'test.js');
|
|
232
|
-
const
|
|
233
|
-
|
|
182
|
+
const testScript = `#!/usr/bin/env node
|
|
183
|
+
|
|
184
|
+
const { execSync } = require('child_process');
|
|
185
|
+
const path = require('path');
|
|
186
|
+
const os = require('os');
|
|
187
|
+
|
|
188
|
+
function test() {
|
|
189
|
+
const binDir = path.join(__dirname, 'bin');
|
|
190
|
+
const isWindows = os.platform() === 'win32';
|
|
191
|
+
const instatunnelPath = path.join(binDir, isWindows ? 'instatunnel.exe' : 'instatunnel');
|
|
192
|
+
const itPath = path.join(binDir, isWindows ? 'it.exe' : 'it');
|
|
193
|
+
|
|
194
|
+
try {
|
|
195
|
+
// Test main command
|
|
196
|
+
const helpOutput = execSync(\`"\${instatunnelPath}" --help\`, { encoding: 'utf8', timeout: 5000 });
|
|
197
|
+
console.log('✅ instatunnel command works');
|
|
198
|
+
|
|
199
|
+
// Test alias
|
|
200
|
+
const itHelpOutput = execSync(\`"\${itPath}" --help\`, { encoding: 'utf8', timeout: 5000 });
|
|
201
|
+
console.log('✅ it alias works');
|
|
202
|
+
|
|
203
|
+
console.log('✅ All tests passed!');
|
|
204
|
+
return true;
|
|
205
|
+
} catch (error) {
|
|
206
|
+
console.error('❌ Test failed:', error.message);
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (require.main === module) {
|
|
212
|
+
const success = test();
|
|
213
|
+
process.exit(success ? 0 : 1);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
module.exports = { test };
|
|
217
|
+
`;
|
|
234
218
|
|
|
235
219
|
fs.writeFileSync(testPath, testScript);
|
|
236
220
|
}
|
|
237
221
|
|
|
238
222
|
if (require.main === module) {
|
|
239
|
-
|
|
223
|
+
setupBinary()
|
|
240
224
|
.then(() => {
|
|
241
225
|
createUninstallScript();
|
|
242
226
|
createTestScript();
|
|
243
227
|
})
|
|
244
228
|
.catch((err) => {
|
|
245
|
-
log(
|
|
229
|
+
log(`❌ Installation failed: ${err.message}`, 'red');
|
|
246
230
|
log('', 'reset');
|
|
247
231
|
log('🔧 Troubleshooting:', 'yellow');
|
|
248
|
-
log(' •
|
|
232
|
+
log(' • Your platform may not be supported yet', 'reset');
|
|
249
233
|
log(' • Try running: npm install -g instatunnel --verbose', 'reset');
|
|
250
234
|
log(' • Report issues: https://github.com/instatunnel/cli/issues', 'reset');
|
|
251
235
|
process.exit(1);
|