1
+ require ( 'ts-node/register' ) ;
2
+
3
+ import * as path from 'path' ;
4
+ import * as os from 'os' ;
5
+ import * as fs from 'fs' ;
6
+ import { promisify } from 'util' ;
7
+
8
+ import * as _ from 'lodash' ;
9
+ import * as semver from 'semver' ;
10
+ import fetch from 'node-fetch' ;
11
+ import * as rimraf from 'rimraf' ;
12
+ import * as targz from 'targz' ;
13
+
14
+ const extractTarGz = promisify ( targz . decompress ) ;
15
+ const deleteFile = promisify ( fs . unlink ) ;
16
+
17
+ const canAccess = ( path : string ) => promisify ( fs . access ) ( path ) . then ( ( ) => true ) . catch ( ( ) => false ) ;
18
+ const deleteDir = promisify ( rimraf ) ;
19
+
20
+ const packageJson = require ( './package.json' ) ;
21
+ const requiredServerVersion = 'v' + packageJson . config [ 'httptoolkit-server-version' ] ;
22
+
23
+ // For local testing of the desktop app, we need to pull the latest server and unpack it.
24
+ // This real prod server will then be used with the real prod web UI, but this local desktop app.
25
+ async function setUpLocalEnv ( ) {
26
+ const serverExists = await canAccess ( './httptoolkit-server/package.json' ) ;
27
+ const serverVersion = serverExists ? require ( './httptoolkit-server/package.json' ) . version : null ;
28
+
29
+ if ( ! serverVersion || semver . neq ( serverVersion , requiredServerVersion ) ) {
30
+ if ( serverExists ) await deleteDir ( './httptoolkit-server' ) ;
31
+ await insertServer ( __dirname , os . platform ( ) , os . arch ( ) ) ;
32
+ console . log ( 'Server setup completed.' ) ;
33
+ } else {
34
+ console . log ( 'Correct server already downloaded.' ) ;
35
+ }
36
+ }
37
+
38
+ /*
39
+ * Download the correct server binary and include it in the build directly.
40
+ * We use the binary build rather than our actual npm dev dependency
41
+ * because the binary builds are capable of autoupdating all by themselves,
42
+ * and because it makes it possible for users to run the server directly
43
+ * with minimal effort, if they so choose.
44
+ */
45
+ async function insertServer (
46
+ buildPath : string ,
47
+ platform : string ,
48
+ arch : string ,
49
+ ) {
50
+ console . log ( `Downloading httptoolkit-server ${ requiredServerVersion } for ${ platform } -${ arch } ` ) ;
51
+
52
+ const assetRegex = new RegExp ( `httptoolkit-server-${ requiredServerVersion } -${ platform } -${ arch } .tar.gz` ) ;
53
+
54
+ const headers : { Authorization : string } | { } = process . env . GITHUB_TOKEN
55
+ ? { Authorization : `token ${ process . env . GITHUB_TOKEN } ` }
56
+ : { }
57
+
58
+ const response = await fetch (
59
+ 'https://api.github.com/repos/httptoolkit/httptoolkit-server/releases' ,
60
+ { headers }
61
+ ) ;
62
+
63
+ const releases = await response . json ( ) ;
64
+
65
+ const release = _ . find ( releases , { tag_name : requiredServerVersion } ) ;
66
+
67
+ if ( ! release || ! release . assets ) {
68
+ console . error ( JSON . stringify ( release , null , 2 ) ) ;
69
+ throw new Error ( 'Could not retrieve release assets' ) ;
70
+ }
71
+
72
+ const asset = release . assets . filter ( ( asset : { name : string } ) => asset . name . match ( assetRegex ) ) [ 0 ] ;
73
+ if ( ! asset ) {
74
+ throw new Error ( `No server available matching ${ assetRegex . toString ( ) } ` ) ;
75
+ }
76
+
77
+ console . log ( `Downloading server from ${ asset . browser_download_url } ...` ) ;
78
+
79
+ const downloadPath = path . join ( buildPath , 'httptoolkit-server.tar.gz' ) ;
80
+
81
+ const assetDownload = await fetch ( asset . browser_download_url ) ;
82
+ const assetWrite = assetDownload . body . pipe ( fs . createWriteStream ( downloadPath ) ) ;
83
+
84
+ await new Promise ( ( resolve , reject ) => {
85
+ assetWrite . on ( 'finish' , resolve ) ;
86
+ assetWrite . on ( 'error' , reject ) ;
87
+ } ) ;
88
+
89
+ console . log ( `Extracting server to ${ buildPath } ` ) ;
90
+ await extractTarGz ( { src : downloadPath , dest : buildPath } ) ;
91
+ await deleteFile ( downloadPath ) ;
92
+
93
+ console . log ( 'Server download completed' ) ;
94
+ }
95
+
96
+ setUpLocalEnv ( ) . catch ( e => {
97
+ console . error ( e ) ;
98
+ process . exit ( 1 ) ;
99
+ } ) ;
0 commit comments