1+ # Require modules
2+ https = require ' https'
3+ github_graphql = require ' github-graphql-client'
4+ semver = require ' semver'
5+ query = require ' ./query'
6+
7+
8+ ###
9+ Executes a GraphQL query on the API to fetch either the latest release or tag.
10+ The returned version is compared to the given version.
11+ When the fetched version is greater than the given one, the newer version
12+ is returned.
13+
14+ @param options {object} The options for the version check.
15+ @param callback {function|undefined} The callback function.
16+ ###
17+ graphql = (options , callback ) ->
18+ # build the query
19+ query =
20+ if options .fetchTags
21+ query .tags options .repo , options .owner
22+ else
23+ query .releases options .repo , options .owner
24+
25+ # do the api call
26+ github_graphql (token : options .token , query : query), (err , res ) ->
27+ if err
28+ callback err, null
29+ else
30+ # Retrieve newer version name
31+ newer =
32+ if options .fetchTags
33+ res .data .repository .refs .nodes [0 ]
34+ else
35+ res .data .repository .releases .nodes [0 ]
36+
37+ # Compare versions
38+ if semver .gt (if options .fetchTags then newer .name else newer .tag .name ), options .currentVersion
39+ callback null , newer
40+ else
41+ callback null , null
42+
43+ ###
44+ Executes an API call on the Github Rest API (v3) that should return the latest version.
45+ The returned version is compared to the given version.
46+ When the fetched version is greater than the given one, the newer version
47+ is returned.
48+
49+ @param options {object} The options for the version check.
50+ @param callback {function|undefined} The callback function.
51+ ###
52+ rest = (options , callback ) ->
53+ apiUrl = " https://api.github.com/repos/#{ options .owner } /#{ options .repo } /releases"
54+ opts =
55+ hostname : ' gvc-reduce-json.axelrindle.de'
56+ path : ' /?url=' + apiUrl
57+ method : ' GET'
58+ req = https .request opts, (res ) ->
59+ chunks = []
60+ res .on ' data' , (chunk ) -> chunks .push chunk .toString ()
61+ res .on ' end' , ->
62+ # Make sure there are no errors and try to parse the response
63+ if res .statusCode != 200 then return callback new Error (res .statusMessage ), null
64+ response = chunks .join (' ' )
65+ json = null
66+ try json = JSON .parse (response)
67+ catch err then return callback err, null
68+ if json .message then return callback new Error (json .message ), null
69+
70+ # Compare versions
71+ found = false
72+ for version in json
73+ if semver .gt version .tag_name , options .currentVersion
74+ found = true
75+ break
76+
77+ if found
78+ callback null , version
79+ else
80+ callback null , null
81+
82+ req .on ' error' , (err ) -> callback err, null
83+ req .end ()
84+
85+ ###
86+ Checks whether a new version is available. Depending on whether a token is given, the
87+ Github GraphQL API (v4) will be used. Otherwise we rely on the Github Rest API (v3), which
88+ does not require authentication.
89+
90+ @param options {object} The options for the version check.
91+ @param callback {function|undefined} The callback function.
92+ ###
93+ module .exports = (options , callback ) ->
94+ # get options
95+ options .token = options .token ? process .env .GITHUB_API_TOKEN ? ' '
96+ options .repo = options .repo ? ' '
97+ options .owner = options .owner ? ' '
98+ options .currentVersion = options .currentVersion ? ' '
99+
100+ # check if required options are defined
101+ if options .repo is ' '
102+ callback (' no repository specified' , null )
103+ return
104+ if options .owner is ' '
105+ callback (' no owner specified' , null )
106+ return
107+ if options .currentVersion is ' '
108+ callback (' no current version given' , null )
109+ return
110+
111+ # decide what to do
112+ # when we have a token supplied, we will call the GraphQL api
113+
114+ if options .token isnt ' ' then graphql (options, callback) else rest (options, callback)
0 commit comments