-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
214 lines (185 loc) · 5.33 KB
/
index.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
'use strict';
const GitHub = require('github-base');
const github = (method, url, options) => new GitHub(options)[method](url);
/**
* Get publicly available information from the GitHub API for one or
* more users or organizations. If user names are passed, all orgs for those
* users are returned. If organization names are passed, an object is
* returned with information about each org.
*
* ```js
* const orgs = require('orgs');
*
* // see github-base for other authentication options
* orgs(['doowb', 'jonschlinkert'], { token: 'YOUR_GITHUB_AUTH_TOKEN' })
* .then(orgs => {
* // array of organization objects from the GitHub API
* console.log(orgs);
* })
* .catch(console.error)l
* ```
* @param {String|Array} `users` One or more users or organization names.
* @param {Object} `options`
* @return {Promise}
* @api public
*/
async function orgs(users, options) {
const opts = Object.assign({}, options);
const acc = { orgs: [], names: [] };
if (isObject(users)) {
return github('paged', '/user/orgs', users).then(res => addOrgs(acc, res));
}
if (typeof users === 'string') users = [users];
if (!Array.isArray(users)) {
return Promise.reject(new TypeError('expected users to be a string or array'));
}
const pending = [];
for (const name of users) {
pending.push(getOrgs(acc, name, options));
}
await Promise.all(pending);
if (opts.sort !== false) {
return acc.orgs.sort(compare('login'));
}
return acc.orgs;
}
/**
* Get publicly available information about the given GitHub `organization`.
* Equivalent to `GET /orgs/:orgname`.
*
* ```js
* const orgs = require('orgs');
* orgs.get('micromatch', { token: 'YOUR_GITHUB_AUTH_TOKEN' })
* .then(res => console.log(res))
* .catch(console.error);
* ```
* @param {String} `name` GitHub organization name.
* @param {Object} `options`
* @return {object} Response object with information about the organization.
* @api public
*/
orgs.get = (name, options) => github('get', `/orgs/${name}`, options);
/**
* Get publicly available information about the given GitHub `user`.
* Equivalent to `GET /users/:username`.
*
* ```js
* const orgs = require('orgs');
* orgs.user('doowb', { token: 'YOUR_GITHUB_AUTH_TOKEN' })
* .then(res => console.log(res.orgs))
* .catch(console.error);
* ```
* @param {String} `user` GitHub username.
* @param {Object} `options`
* @return {object} Response object with array of orgs on `res.orgs`.
* @api public
*/
orgs.user = (name, options) => github('get', `/users/${name}`, options);
/**
* Get publicly available information about all GitHub users.
* Equivalent to a paginated request to `GET /users`.
*
* ```js
* const orgs = require('orgs');
* orgs.users({ token: 'YOUR_GITHUB_AUTH_TOKEN' })
* .then(res => console.log(res))
* .catch(console.error);
* ```
* @param {Object} `options`
* @return {object} Response object with array of orgs on `res.orgs`.
* @api public
*/
orgs.users = options => github('paged', '/users', options);
/**
* Get an array of orgs for the given `user`. Equivalent to `GET /users/:username`.
*
* ```js
* const orgs = require('orgs');
* orgs.userOrgs('doowb', { token: 'YOUR_GITHUB_AUTH_TOKEN' })
* .then(res => console.log(res))
* .catch(console.error);
* ```
* @param {String} `user`
* @param {Object} `options`
* @return {object} Response object with array of orgs on `res.orgs`.
* @api public
*/
orgs.userOrgs = (user, options) => {
return github('paged', `/users/${user}/orgs`, options).then(reduce);
};
/**
* Get a list of objects with information for all publicly available GitHub organizations.
* Equivalent to a paginated request to `GET /organizations`.
*
* ```js
* const orgs = require('orgs');
* orgs.all({ token: 'YOUR_GITHUB_AUTH_TOKEN' })
* .then(res => console.log(res))
* .catch(console.error);
* ```
* @param {Object} `options`
* @return {object} Response object with array of orgs on `res.orgs`.
* @api public
*/
orgs.all = options => {
return github('paged', '/organizations', options).then(reduce);
};
/**
* Helpers
*/
async function getOrgs(acc, name, options) {
let res = await orgs.user(name, options);
let data = res.body || res.data;
if (data.type === 'User') {
addOrgs(acc, data);
return orgs.userOrgs(name, options).then(res => {
addOrgs(acc, res.orgs);
return res;
});
}
return addOrgs(acc, data);
}
function addOrgs(acc, org) {
if (Array.isArray(org)) {
org.forEach(o => addOrgs(acc, o));
return acc;
}
if (org.pages) {
for (const page of org.pages) {
let data = page.body || page.data;
for (const obj of data) {
obj.type = 'Organization';
addOrgs(acc, obj);
}
}
return acc;
}
const idx = acc.names.indexOf(org.login);
org.name = org.name || org.login;
if (idx === -1) {
acc.names.push(org.login);
acc.orgs.push(org);
} else if (org.type) {
acc.names[idx] = org.login;
acc.orgs[idx] = org;
}
return acc;
}
function reduce(res) {
res.orgs = res.pages.reduce((acc, page) => acc.concat(page.body), []);
return res;
}
function compare(prop) {
return (a, b) => {
if (a[prop] < b[prop]) return -1;
if (a[prop] > b[prop]) return 1;
return 0;
};
}
function isObject(val) {
return val !== null && typeof val === 'object' && !Array.isArray(val);
}
/**
* Expose `orgs`
*/
module.exports = orgs;