my-airdrop 1.2.0 → 1.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/cli.js +34 -9
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const os = require('os');
|
|
6
6
|
const fs = require('fs');
|
|
7
|
+
const { execSync } = require('child_process');
|
|
7
8
|
const chalk = require('chalk');
|
|
8
9
|
const qrcode = require('qrcode-terminal');
|
|
9
|
-
const { Tunnel } = require('cloudflared');
|
|
10
|
+
const { Tunnel, install, bin: cfBin } = require('cloudflared');
|
|
10
11
|
const { createServer } = require('../src/server');
|
|
11
12
|
|
|
12
13
|
// ── Parse args ───────────────────────────────────────
|
|
@@ -208,19 +209,43 @@ async function main() {
|
|
|
208
209
|
if (usePublic) {
|
|
209
210
|
process.stdout.write(' ' + chalk.gray('Public ') + chalk.gray('connecting...'));
|
|
210
211
|
try {
|
|
211
|
-
|
|
212
|
-
|
|
212
|
+
// 1. 바이너리 없으면 자동 설치
|
|
213
|
+
if (!fs.existsSync(cfBin)) {
|
|
214
|
+
process.stdout.write('\r ' + chalk.gray('Public ') + chalk.gray('installing cloudflared...'));
|
|
215
|
+
await install(cfBin);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// 2. macOS quarantine 제거 (Gatekeeper 차단 방지)
|
|
219
|
+
if (process.platform === 'darwin') {
|
|
220
|
+
try { execSync(`xattr -d com.apple.quarantine "${cfBin}" 2>/dev/null`); } catch {}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// 3. 터널 시작
|
|
224
|
+
const startTunnel = () => new Promise((resolve, reject) => {
|
|
225
|
+
const t = Tunnel.quick(`http://localhost:${port}`, { '--protocol': 'http2' });
|
|
213
226
|
const timer = setTimeout(() => reject(new Error('timeout')), 20000);
|
|
214
|
-
|
|
215
|
-
|
|
227
|
+
t.once('url', url => { clearTimeout(timer); resolve({ tunnel: t, url }); });
|
|
228
|
+
t.once('error', err => { clearTimeout(timer); reject(err); });
|
|
216
229
|
});
|
|
230
|
+
|
|
231
|
+
const { tunnel, url } = await startTunnel();
|
|
232
|
+
publicURL = url;
|
|
217
233
|
process.stdout.write('\r ' + chalk.gray('Public ') + chalk.bold.cyan(publicURL) + '\n');
|
|
218
234
|
|
|
219
|
-
|
|
220
|
-
|
|
235
|
+
// 4. 터널 끊기면 자동 재연결
|
|
236
|
+
tunnel.on('exit', async () => {
|
|
237
|
+
console.log('\n' + chalk.yellow(' ⚠ Public tunnel disconnected — reconnecting...'));
|
|
238
|
+
try {
|
|
239
|
+
const { tunnel: t2, url: u2 } = await startTunnel();
|
|
240
|
+
console.log(' ' + chalk.gray('Public ') + chalk.bold.cyan(u2) + chalk.gray(' (new URL)'));
|
|
241
|
+
t2.on('exit', () => console.log('\n' + chalk.yellow(' ⚠ Public tunnel closed')));
|
|
242
|
+
} catch {
|
|
243
|
+
console.log(chalk.yellow(' ⚠ Reconnect failed — use --public to restart'));
|
|
244
|
+
}
|
|
221
245
|
});
|
|
222
|
-
} catch {
|
|
223
|
-
|
|
246
|
+
} catch (e) {
|
|
247
|
+
const reason = e.message === 'timeout' ? 'timed out' : (e.message || 'no internet?');
|
|
248
|
+
process.stdout.write('\r ' + chalk.yellow(`⚠ Public tunnel failed (${reason})`) + '\n');
|
|
224
249
|
}
|
|
225
250
|
}
|
|
226
251
|
|