-
Notifications
You must be signed in to change notification settings - Fork 0
/
cli.js
101 lines (78 loc) 路 2.64 KB
/
cli.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/env node
const http = require('http');
const https = require('https');
const handler = require('serve-handler');
const localtunnel = require('localtunnel');
const getPort = require('get-port');
const clipboardy = require('clipboardy');
const help = process.argv.includes('--help');
const noCache = process.argv.includes('--no-cache');
const portRange = getPort.makeRange(9000, 9100);
if (help) {
console.log(`
Expose a static server for the current directory to the public internet. Use responsibly.
Flags:
--no-cache Set "Cache-Control: no-cache" header on all responses
--help Print this help message
`);
process.exit(0);
}
const noCacheSettings = {
headers: [{
source: '**/*',
headers: [{
key: 'Cache-Control',
value: 'no-cache'
}]
}]
};
(async () => {
const port = await getPort({ port: portRange });
const server = http.createServer((request, response) => {
// see for options: https://github.com/vercel/serve-handler#options
return handler(request, response, {
...(noCache ? noCacheSettings : {})
});
});
await new Promise(r => server.listen(port, () => r()));
const { body: password } = await request('https://loca.lt/mytunnelpassword');
console.log(`internally running at: http://localhost:${port}`);
const tunnel = await localtunnel({ port });
tunnel.on('close', () => {
// tunnels are closed
});
tunnel.on('error', err => {
console.error('the tunnel errored and does not work anymore\n', err);
tunnel.close();
});
// the assigned public url for your tunnel
// i.e. https://abcdefgjhij.localtunnel.me
console.log(`externally running at: ${tunnel.url}`);
console.log(` password: ${password}\n`);
await clipboardy.write(tunnel.url)
.then(() => void console.log('(url has been copied to clipboard)'))
.catch(() => void console.error('(failed to copy url to clipboard)'));
})().catch(err => {
console.error(err);
process.exit(1);
});
// this is stupid, but bringing in a dependency is also meh
const request = async (url, { method = 'GET', body = '', ...opts } = {}) => {
const requestMethod = url.indexOf('https://') === 0 ? https.request : http.request;
const response = await new Promise((resolve, reject) => {
const req = requestMethod(url, { ...opts, method }, (res) => resolve(res));
if (['post', 'put'].includes(method.toLowerCase())) {
req.write(body);
}
req.end();
});
let responseBody = '';
for await (const chunk of response) {
responseBody += Buffer.from(chunk).toString();
}
return {
status: response.statusCode,
headers: response.headers,
body: responseBody
};
};