-
Notifications
You must be signed in to change notification settings - Fork 84
/
setup-server.ts
110 lines (88 loc) · 4.14 KB
/
setup-server.ts
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
102
103
104
105
106
107
108
109
110
import * as path from 'path';
import * as os from 'os';
import * as fs from 'fs';
import { promisify } from 'util';
import * as _ from 'lodash';
import * as semver from 'semver';
import fetch from 'node-fetch';
import rimraf from 'rimraf';
import * as targz from 'targz';
import { execSync } from 'child_process';
const extractTarGz = promisify(targz.decompress);
const deleteFile = promisify(fs.unlink);
const canAccess = (path: string) => promisify(fs.access)(path).then(() => true).catch(() => false);
const deleteDir = promisify(rimraf);
const packageJson = require('./package.json');
const requiredServerVersion = 'v' + packageJson.config['httptoolkit-server-version'];
// For local testing of the desktop app, we need to pull the latest server and unpack it.
// This real prod server will then be used with the real prod web UI, but this local desktop app.
async function setUpLocalEnv() {
const serverExists = await canAccess('./httptoolkit-server/package.json');
const serverVersion = serverExists ? require('./httptoolkit-server/package.json').version : null;
if (!serverVersion || semver.neq(serverVersion, requiredServerVersion)) {
if (serverExists) await deleteDir('./httptoolkit-server');
await insertServer(__dirname, os.platform(), os.arch());
console.log('Server setup completed.');
} else {
console.log('Correct server already downloaded.');
}
if (os.platform() !== 'win32') {
// To work around https://github.com/nodejs/node-gyp/issues/2713,
// caused by https://github.com/nodejs/node-gyp/commit/b9ddcd5bbd93b05b03674836b6ebdae2c2e74c8c,
// we manually remove node_gyp_bins subdirectories. Done by shell just
// because it's a quick easy fix:
execSync('find httptoolkit-server/node_modules -type d -name node_gyp_bins -prune -exec rm -r {} \\;');
}
}
/*
* Download the correct server binary and include it in the build directly.
* We use the binary build rather than our actual npm dev dependency
* because the binary builds are capable of autoupdating all by themselves,
* and because it makes it possible for users to run the server directly
* with minimal effort, if they so choose.
*/
async function insertServer(
buildPath: string,
platform: string,
arch: string,
) {
console.log(`Downloading httptoolkit-server ${requiredServerVersion} for ${platform}-${arch}`);
const assetRegex = new RegExp(`httptoolkit-server-${requiredServerVersion}-${platform}-${arch}.tar.gz`);
const headers: { Authorization: string } | {} = process.env.GITHUB_TOKEN
? { Authorization: `token ${process.env.GITHUB_TOKEN}` }
: {}
const response = await fetch(
'https://api.github.com/repos/httptoolkit/httptoolkit-server/releases',
{ headers }
);
if (!response.ok) {
console.log(`${response.status} response, body: `, await response.text());
throw new Error(`Server releases request rejected with ${response.status}`);
}
const releases = await response.json();
const release = _.find(releases, { tag_name: requiredServerVersion });
if (!release || !release.assets) {
console.error(JSON.stringify(release, null, 2));
throw new Error('Could not retrieve release assets');
}
const asset = release.assets.filter((asset: { name: string }) => asset.name.match(assetRegex))[0];
if (!asset) {
throw new Error(`No server available matching ${assetRegex.toString()}`);
}
console.log(`Downloading server from ${asset.browser_download_url}...`);
const downloadPath = path.join(buildPath, 'httptoolkit-server.tar.gz');
const assetDownload = await fetch(asset.browser_download_url);
const assetWrite = assetDownload.body.pipe(fs.createWriteStream(downloadPath));
await new Promise((resolve, reject) => {
assetWrite.on('finish', resolve);
assetWrite.on('error', reject);
});
console.log(`Extracting server to ${buildPath}`);
await extractTarGz({ src: downloadPath, dest: buildPath });
await deleteFile(downloadPath);
console.log('Server download completed');
}
setUpLocalEnv().catch(e => {
console.error(e);
process.exit(1);
});