1
1
'use strict'
2
2
3
3
const http = require ( 'http' )
4
+ const fetch = require ( 'node-fetch' )
4
5
5
6
class Updates {
6
- constructor ( ) {
7
- this . cache = new Map ( )
8
- }
9
-
10
7
listen ( port , cb ) {
11
8
const server = http . createServer ( ( req , res ) => {
12
9
this . handle ( req , res ) . catch ( err => {
@@ -21,41 +18,50 @@ class Updates {
21
18
22
19
async handle ( req , res ) {
23
20
const segs = req . url . split ( '/' ) . filter ( Boolean )
24
- const [ account , repository , method , platform , version ] = segs
21
+ const [ account , repository , platform , version ] = segs
22
+ if ( ! account || ! repository || ! platform || ! version ) return notFound ( res )
25
23
26
- if ( account && repository && method === 'update' && platform && version ) {
27
- this . handleUpdate ( res , account , repository , platform , version )
28
- } else if ( account && repository && method === 'download' && platform ) {
29
- this . handleDownload ( res , account , repository , platform )
30
- } else {
31
- notFound ( res )
32
- }
24
+ await this . handleUpdate ( res , account , repository , platform , version )
33
25
}
34
26
35
- handleUpdate ( res , account , repository , platform , version ) {
36
- const key = `${ account } /${ repository } /${ platform } `
37
- if ( this . cache . has ( key ) ) {
38
- const latest = this . cache . get ( key )
39
- if ( latest . version === version ) return noContent ( res )
27
+ async handleUpdate ( res , account , repository , platform , version ) {
28
+ const latest = await this . getLatest ( account , repository , platform )
29
+
30
+ if ( ! latest ) {
31
+ notFound ( res )
32
+ } else if ( latest . version === version ) {
33
+ noContent ( res )
34
+ } else {
40
35
json ( res , {
41
36
name : latest . version ,
42
- url : `/ ${ account } / ${ repository } /download/ ${ platform } `
37
+ url : latest . url
43
38
} )
44
- } else {
45
- if ( this . cache . has ( `${ account / repository } ` ) ) return notFound ( res )
46
39
}
47
40
}
48
41
49
- handleDownload ( res , account , repository , platform ) {
50
- const key = `${ account } /${ repository } /${ platform } `
51
- if ( this . cache . has ( key ) ) {
52
- const latest = this . cache . get ( key )
53
- redirect ( res , latest . url )
54
- } else {
42
+ async getLatest ( account , repository , platform ) {
43
+ const url = `https://api.github.com/repos/${ account } /${ repository } /releases?per_page=100`
44
+ const headers = { Accept : 'application/vnd.github.preview' }
45
+ const res = await fetch ( url , { headers } )
46
+ const releases = await res . json ( )
47
+ const latest = { }
48
+ for ( const release of releases ) {
49
+ for ( const asset of release . assets ) {
50
+ if ( assetPlatform ( asset . name ) === platform ) {
51
+ latest . version = release . name
52
+ latest . url = asset . browser_download_url
53
+ return latest
54
+ }
55
+ }
55
56
}
56
57
}
57
58
}
58
59
60
+ const assetPlatform = fileName => {
61
+ if ( / .* m a c .* \. z i p / . test ( fileName ) ) return 'darwin'
62
+ return false
63
+ }
64
+
59
65
const notFound = res => {
60
66
res . statusCode = 404
61
67
res . end ( 'Not found' )
@@ -71,10 +77,4 @@ const json = (res, obj) => {
71
77
res . end ( JSON . stringify ( obj ) )
72
78
}
73
79
74
- const redirect = ( res , url ) => {
75
- res . statusCode = 302
76
- res . setHeader ( 'Location' , url )
77
- res . end ( url )
78
- }
79
-
80
80
module . exports = Updates
0 commit comments