xpose-cli 0.4.5 → 0.4.7

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 CHANGED
@@ -5,7 +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
+ const tar = require('tar');
9
9
 
10
10
  /**
11
11
  * xpose binary downloader
@@ -153,15 +153,17 @@ async function download() {
153
153
 
154
154
  console.log(`Extracting binary...`);
155
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}"`);
156
+ // Unpack the tar.gz archive using the 'tar' package
157
+ // This is cross-platform and doesn't require the system 'tar' command
158
+ await tar.x({
159
+ file: dest,
160
+ cwd: BIN_DIR
161
+ });
162
162
 
163
163
  // Ensure permissions on Unix
164
+ const isWin = os.platform() === 'win32';
164
165
  if (!isWin) {
166
+ const binName = isWin ? 'xpose.exe' : 'xpose';
165
167
  const finalBinPath = path.join(BIN_DIR, binName);
166
168
  fs.chmodSync(finalBinPath, 0o755);
167
169
  }
@@ -2,24 +2,74 @@ const assert = require('assert');
2
2
  const fs = require('fs');
3
3
  const path = require('path');
4
4
  const crypto = require('crypto');
5
- const http = require('http'); // We'll use this to mock
5
+ const tar = require('tar');
6
+ const { getFileContent } = require('./install');
6
7
 
7
- // Mocking dependencies would be complex without a library like proxyquire or jest.
8
- // For a simple standalone test, we'll use environment variables and temporary paths.
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 ARCHIVE_NAME = 'test-target.tar.gz';
9
13
 
10
- const { download, getFileContent } = require('./install');
14
+ if (!fs.existsSync(BIN_DIR)) {
15
+ fs.mkdirSync(BIN_DIR, { recursive: true });
16
+ }
17
+
18
+ async function testExtraction() {
19
+ console.log('Running testExtraction (using tar package)...');
20
+
21
+ const archivePath = path.join(BIN_DIR, ARCHIVE_NAME);
22
+ const dummyBinPath = path.join(TEST_DIR, DUMMY_BIN);
23
+
24
+ // 1. Create a dummy binary (make it a shell script so it's executable on Unix)
25
+ if (process.platform === 'win32') {
26
+ fs.writeFileSync(dummyBinPath, 'echo dummy');
27
+ } else {
28
+ fs.writeFileSync(dummyBinPath, '#!/bin/sh\necho "xpose version 0.0.0-test"');
29
+ }
30
+
31
+ // 2. Archive it using the 'tar' package (simulating CI build output)
32
+ await tar.c({
33
+ gzip: true,
34
+ file: archivePath,
35
+ cwd: TEST_DIR
36
+ }, [DUMMY_BIN]);
11
37
 
12
- async function testSuccessfulDownload() {
13
- console.log('Running testSuccessfulDownload...');
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';
38
+ fs.unlinkSync(dummyBinPath); // Remove original dummy
39
+
40
+ // 3. Run extraction logic using the 'tar' package (simulating install.js)
41
+ console.log(`Extracting ${ARCHIVE_NAME}...`);
17
42
  try {
18
- await download();
19
- console.log('✅ testSuccessfulDownload passed (dev skip)');
43
+ await tar.x({
44
+ file: archivePath,
45
+ cwd: BIN_DIR
46
+ });
47
+
48
+ const extractedPath = path.join(BIN_DIR, DUMMY_BIN);
49
+ assert(fs.existsSync(extractedPath), 'Extracted binary should exist');
50
+
51
+ // Ensure permissions on Unix and test execution
52
+ if (process.platform !== 'win32') {
53
+ fs.chmodSync(extractedPath, 0o755);
54
+ const stats = fs.statSync(extractedPath);
55
+ assert((stats.mode & 0o777) === 0o755, 'Binary should have correct permissions');
56
+
57
+ console.log('Testing binary execution...');
58
+ const { execSync } = require('child_process');
59
+ const output = execSync(`"${extractedPath}"`).toString();
60
+ assert(output.includes('xpose version'), 'Binary should be executable and return expected output');
61
+ console.log('✅ Binary execution successful');
62
+ }
63
+
64
+ console.log('✅ testExtraction passed');
20
65
  } catch (e) {
21
- console.error('❌ testSuccessfulDownload failed:', e);
66
+ console.error('❌ testExtraction failed:', e.message);
22
67
  process.exit(1);
68
+ } finally {
69
+ // Cleanup
70
+ if (fs.existsSync(archivePath)) fs.unlinkSync(archivePath);
71
+ const extractedPath = path.join(BIN_DIR, DUMMY_BIN);
72
+ if (fs.existsSync(extractedPath)) fs.unlinkSync(extractedPath);
23
73
  }
24
74
  }
25
75
 
@@ -40,13 +90,17 @@ async function testGetFileContent404() {
40
90
  }
41
91
  }
42
92
 
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
93
  async function runTests() {
47
- await testSuccessfulDownload();
48
- await testGetFileContent404();
49
- console.log('\nAll tests passed!');
94
+ try {
95
+ await testExtraction();
96
+ await testGetFileContent404();
97
+ console.log('\n✨ All installation tests passed!');
98
+ } finally {
99
+ // Final cleanup of test directory
100
+ if (fs.existsSync(TEST_DIR)) {
101
+ fs.rmSync(TEST_DIR, { recursive: true, force: true });
102
+ }
103
+ }
50
104
  }
51
105
 
52
106
  runTests().catch(err => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xpose-cli",
3
- "version": "0.4.5",
3
+ "version": "0.4.7",
4
4
  "description": "Cloudflare Tunnel CLI for developers - Vivid TUI, auto-copy, and smart defaults.",
5
5
  "bin": {
6
6
  "xpose": "bin/cli.js"
@@ -31,6 +31,7 @@
31
31
  "node": ">=16.0.0"
32
32
  },
33
33
  "dependencies": {
34
- "cli-progress": "^3.12.0"
34
+ "cli-progress": "^3.12.0",
35
+ "tar": "^6.2.1"
35
36
  }
36
37
  }