-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
106 lines (99 loc) · 2.62 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
// GitHub icon by Freepik <http://www.flaticon.com/free-icon/github-mascot-logo-variant_38521#term=github&page=1&position=30>
const got = require('got');
// default API endpoint
const ENDPOINT = 'https://api.github.com';
/**
* Makes a new request to the given endpoint
*
* @param {String} endpoint
* @param {Object} options
* @return {Promise}
*/
const makeRequest = (endpoint, options) => {
const opts = Object.assign({}, { json: true }, options);
const url = `${ENDPOINT}/${endpoint.replace(/^\//, '')}`;
const prom = got(url, opts);
return new Promise((resolve) => {
prom.then(res => resolve(res.body));
});
};
/**
* Converst relative URLs into absolute URLs for the given repo
*
* @param {String} html
* @param {String} fullName
* @return {String}
*/
const applyRelativeUrls = (html, fullName) => {
const url = `https://github.com/${fullName}/blob/master`;
// replace images
const parsed = html.replace(/\(([\w\d\s]+\.(?:png|gif|jpg|jpeg)+.*)\)/g, `(${url}/$1)`);
return parsed;
};
/**
* Maps the GitHub repository item to a Dext item
*
* @param {Object} item
* @return {Object}
*/
const mapItems = item => Object.assign({}, {
title: item.full_name,
subtitle: item.description,
arg: item.html_url,
icon: {
path: item.owner.avatar_url,
},
mods: {
alt: {
arg: `${item.html_url}/issues`,
subtitle: 'View project issues.',
},
cmd: {
arg: `https://github.com/${item.full_name.split('/')[0]}`,
subtitle: 'View author\'s profile.',
},
},
});
/**
* Converts a base64 string to utf8
*/
const base64ToUTF8 = (content) => {
const buff = Buffer.from(content || '', 'base64');
return buff.toString('utf8');
};
module.exports = {
keyword: 'gh',
action: 'openurl',
helper: {
title: 'Search GitHub repositories.',
subtitle: 'Example: gh dext',
icon: {
path: './icon.png',
},
},
query: q => new Promise((resolve) => {
const opts = {
query: {
q: `${q} in:name`,
},
};
// searches the API for repositories by name
// https://developer.github.com/v3/search/#search-repositories
makeRequest('/search/repositories', opts)
.then((body) => {
const items = body.items
.map(mapItems)
.slice(0, 20);
resolve({ items });
});
}),
details: {
type: 'md',
// retrieve the preferred README file
// https://developer.github.com/v3/repos/contents/#get-the-readme
render: item => new Promise((resolve) => {
makeRequest(`/repos/${item.title}/readme`)
.then(body => resolve(applyRelativeUrls(base64ToUTF8(body.content), item.title)));
}),
},
};