-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathghutils.js
105 lines (87 loc) · 2.72 KB
/
ghutils.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
102
103
104
105
const jsonist = require('jsonist')
const qs = require('querystring')
const apiRoot = 'https://api.github.com'
function makeOptions (auth, options) {
const headers = Object.assign(
{ 'user-agent': 'Magic Node.js application that does magic things' },
typeof options === 'object' && typeof options.headers === 'object' ? options.headers : {}
)
options = Object.assign({ auth: `${auth.user}:${auth.token}` }, options)
options.headers = headers
if (!options.auth) {
delete options.auth
}
return options
}
function handler (callback) {
return function responseHandler (err, data, res) {
if (err) {
return callback(err)
}
if (data && (data.error || data.message)) {
return callback(createError(data))
}
callback(null, data, res)
}
}
function createError (data) {
const message = data.error || data.message
const extra = data.errors ? ` (${JSON.stringify(data.errors)})` : ''
return new Error(`Error from GitHub: ${message}${extra}`)
}
function ghget (auth, url, options, callback) {
options = makeOptions(auth, options)
jsonist.get(url, Object.assign(options, { followRedirects: true }), handler(callback))
}
function ghpost (auth, url, data, options, callback) {
options = makeOptions(auth, options)
jsonist.post(url, data, options, handler(callback))
}
function lister (auth, urlbase, options, callback) {
let retdata = []
const afterDate = (options.afterDate instanceof Date) && options.afterDate
// overloading use of 'options' is ... not great
const optqsobj = Object.assign(options)
delete optqsobj.afterDate
delete optqsobj.headers
const optqs = qs.stringify(optqsobj)
;(function next (url) {
if (optqs) {
url += '&' + optqs
}
ghget(auth, url, options, (err, data, res) => {
if (err) {
return callback(err)
}
if (data.length) {
retdata.push.apply(retdata, data)
}
const nextUrl = getNextUrl(res.headers.link)
let createdAt
if (nextUrl) {
if (!afterDate || ((createdAt = retdata[retdata.length - 1].created_at) && new Date(createdAt) > afterDate)) {
return next(nextUrl)
}
}
if (afterDate) {
retdata = retdata.filter((data) => {
return !data.created_at || new Date(data.created_at) > afterDate
})
}
callback(null, retdata)
})
}(urlbase))
function getNextUrl (link) {
if (typeof link === 'undefined') {
return
}
const match = /<([^>]+)>; rel="next"/.exec(link)
return match && match[1]
}
}
module.exports.makeOptions = makeOptions
module.exports.ghpost = ghpost
module.exports.ghget = ghget
module.exports.handler = handler
module.exports.lister = lister
module.exports.apiRoot = apiRoot