xpose-cli 0.4.4 → 0.4.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/install.js +24 -1
- package/bin/test-install.js +64 -18
- package/package.json +1 -1
package/bin/install.js
CHANGED
|
@@ -5,6 +5,7 @@ const path = require('path');
|
|
|
5
5
|
const os = require('os');
|
|
6
6
|
const https = require('https');
|
|
7
7
|
const crypto = require('crypto');
|
|
8
|
+
const { execSync } = require('child_process');
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* xpose binary downloader
|
|
@@ -150,7 +151,29 @@ async function download() {
|
|
|
150
151
|
}
|
|
151
152
|
}
|
|
152
153
|
|
|
153
|
-
console.log(`
|
|
154
|
+
console.log(`Extracting binary...`);
|
|
155
|
+
try {
|
|
156
|
+
// Unpack the tar.gz archive
|
|
157
|
+
// xpose-target.tar.gz usually contains 'xpose' or 'xpose.exe'
|
|
158
|
+
const isWin = os.platform() === 'win32';
|
|
159
|
+
const binName = isWin ? 'xpose.exe' : 'xpose';
|
|
160
|
+
|
|
161
|
+
execSync(`tar -xzf "${dest}" -C "${BIN_DIR}"`);
|
|
162
|
+
|
|
163
|
+
// Ensure permissions on Unix
|
|
164
|
+
if (!isWin) {
|
|
165
|
+
const finalBinPath = path.join(BIN_DIR, binName);
|
|
166
|
+
fs.chmodSync(finalBinPath, 0o755);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Cleanup the archive
|
|
170
|
+
fs.unlinkSync(dest);
|
|
171
|
+
} catch (e) {
|
|
172
|
+
console.error(`❌ Extraction failed: ${e.message}`);
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
console.log(`Successfully installed to ${BIN_DIR}`);
|
|
154
177
|
console.log('Note: Run "xpose" to start the tunnel.');
|
|
155
178
|
|
|
156
179
|
} catch (err) {
|
package/bin/test-install.js
CHANGED
|
@@ -2,24 +2,66 @@ const assert = require('assert');
|
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const crypto = require('crypto');
|
|
5
|
-
const
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
const { getFileContent } = require('./install');
|
|
6
7
|
|
|
7
|
-
//
|
|
8
|
-
|
|
8
|
+
// Setup temporary test environment
|
|
9
|
+
const TEST_DIR = path.join(__dirname, '..', 'test_tmp');
|
|
10
|
+
const BIN_DIR = path.join(TEST_DIR, 'bin');
|
|
11
|
+
const DUMMY_BIN = 'xpose';
|
|
12
|
+
const DUMMY_CONTENT = 'dummy binary content';
|
|
13
|
+
const ARCHIVE_NAME = 'test-target.tar.gz';
|
|
9
14
|
|
|
10
|
-
|
|
15
|
+
if (!fs.existsSync(BIN_DIR)) {
|
|
16
|
+
fs.mkdirSync(BIN_DIR, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function testExtraction() {
|
|
20
|
+
console.log('Running testExtraction...');
|
|
21
|
+
|
|
22
|
+
const archivePath = path.join(BIN_DIR, ARCHIVE_NAME);
|
|
23
|
+
const dummyBinPath = path.join(TEST_DIR, DUMMY_BIN);
|
|
24
|
+
|
|
25
|
+
// 1. Create a dummy binary (make it a shell script so it's executable on Unix)
|
|
26
|
+
if (process.platform === 'win32') {
|
|
27
|
+
fs.writeFileSync(dummyBinPath, 'echo dummy');
|
|
28
|
+
} else {
|
|
29
|
+
fs.writeFileSync(dummyBinPath, '#!/bin/sh\necho "xpose version 0.0.0-test"');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 2. Archive it
|
|
33
|
+
execSync(`tar -czf "${archivePath}" -C "${TEST_DIR}" "${DUMMY_BIN}"`);
|
|
34
|
+
fs.unlinkSync(dummyBinPath); // Remove original dummy
|
|
11
35
|
|
|
12
|
-
|
|
13
|
-
console.log(
|
|
14
|
-
// This is a minimal test to ensure the script doesn't crash
|
|
15
|
-
// and correctly identifies dev environment.
|
|
16
|
-
process.env.XPOSE_DEV = '1';
|
|
36
|
+
// 3. Run extraction logic (simulating the end of install.js download)
|
|
37
|
+
console.log(`Extracting ${ARCHIVE_NAME}...`);
|
|
17
38
|
try {
|
|
18
|
-
|
|
19
|
-
|
|
39
|
+
execSync(`tar -xzf "${archivePath}" -C "${BIN_DIR}"`);
|
|
40
|
+
|
|
41
|
+
const extractedPath = path.join(BIN_DIR, DUMMY_BIN);
|
|
42
|
+
assert(fs.existsSync(extractedPath), 'Extracted binary should exist');
|
|
43
|
+
|
|
44
|
+
// Ensure permissions on Unix and test execution
|
|
45
|
+
if (process.platform !== 'win32') {
|
|
46
|
+
fs.chmodSync(extractedPath, 0o755);
|
|
47
|
+
const stats = fs.statSync(extractedPath);
|
|
48
|
+
assert((stats.mode & 0o777) === 0o755, 'Binary should have correct permissions');
|
|
49
|
+
|
|
50
|
+
console.log('Testing binary execution...');
|
|
51
|
+
const output = execSync(`"${extractedPath}"`).toString();
|
|
52
|
+
assert(output.includes('xpose version'), 'Binary should be executable and return expected output');
|
|
53
|
+
console.log('✅ Binary execution successful');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
console.log('✅ testExtraction passed');
|
|
20
57
|
} catch (e) {
|
|
21
|
-
console.error('❌
|
|
58
|
+
console.error('❌ testExtraction failed:', e.message);
|
|
22
59
|
process.exit(1);
|
|
60
|
+
} finally {
|
|
61
|
+
// Cleanup
|
|
62
|
+
if (fs.existsSync(archivePath)) fs.unlinkSync(archivePath);
|
|
63
|
+
const extractedPath = path.join(BIN_DIR, DUMMY_BIN);
|
|
64
|
+
if (fs.existsSync(extractedPath)) fs.unlinkSync(extractedPath);
|
|
23
65
|
}
|
|
24
66
|
}
|
|
25
67
|
|
|
@@ -40,13 +82,17 @@ async function testGetFileContent404() {
|
|
|
40
82
|
}
|
|
41
83
|
}
|
|
42
84
|
|
|
43
|
-
// In a real scenario, we would mock https.get and fs.createWriteStream.
|
|
44
|
-
// Since we want to stay within standard node tools for now, we'll verify the logic structure.
|
|
45
|
-
|
|
46
85
|
async function runTests() {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
86
|
+
try {
|
|
87
|
+
await testExtraction();
|
|
88
|
+
await testGetFileContent404();
|
|
89
|
+
console.log('\n✨ All installation tests passed!');
|
|
90
|
+
} finally {
|
|
91
|
+
// Final cleanup of test directory
|
|
92
|
+
if (fs.existsSync(TEST_DIR)) {
|
|
93
|
+
fs.rmSync(TEST_DIR, { recursive: true, force: true });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
50
96
|
}
|
|
51
97
|
|
|
52
98
|
runTests().catch(err => {
|