-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
114 lines (99 loc) · 3.08 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
"use strict";
const arvish = require("arvish");
const { parse } = require("tldr/lib/parser");
const CACHE_AGE = 5 * 1000 * 60; // 5 minutes
const IS_TESTING = process.env.NODE_ENV === "test";
// arvish will call the script directly, so we can detect that to either export
// the function or run it right away
if (require.main === module) {
main(arvish.input, {
username: process.env["username"],
password: process.env["password"],
}).then(arvish.output);
}
function allSettled(promises) {
const wrappedPromises = promises.map((p) =>
Promise.resolve(p).then(
(val) => ({ state: "fulfilled", value: val }),
(err) => ({ state: "rejected", reason: err })
)
);
return Promise.all(wrappedPromises);
}
/**
* Hit the Github API to fetch results for the query
*
* @param {string} url
* @param {object} options
* @return {Promise} filtered results
*/
function fetchResults(url, options) {
return arvish.fetch(url, options).then((payload) => {
const { content, encoding } = payload;
const markdown = Buffer.from(content, encoding).toString("ascii");
const { name, examples } = parse(markdown);
return examples.map((example) => ({
title: example.code,
subtitle: example.description,
quicklookurl: `https://tldr.ostera.io/${name}`,
text: {
copy: example.code,
largetype: markdown,
},
}));
});
}
/**
* Make the URL for the Github API based on the type of docs to search and the command
*
* @param {string} type the docset to search
* @param {string} command the command to search for
* @return {string} the API URL
*/
function buildURL(type, command) {
return `https://api.github.com/repos/tldr-pages/tldr/contents/pages/${type}/${command}.md?ref=master`;
}
function main(input, { username, password } = {}) {
const tokens = input.split(" ");
const [command, ...search] = tokens;
const searchCommand = search.join(" ");
const hasAuthentication = username && password;
const options = {
maxAge: IS_TESTING ? undefined : CACHE_AGE,
auth: hasAuthentication ? `${username}:${password}` : undefined,
};
return allSettled([
fetchResults(buildURL("common", command), options),
fetchResults(buildURL("osx", command), options),
]).then((results) => {
const successfulResults = results
.filter((result) => result.state === "fulfilled")
.map((result) => result.value);
if (successfulResults.length > 0) {
return successfulResults
.reduce((acc, results) => [...acc, ...results], [])
.filter((result) => result.title.includes(searchCommand));
}
const errors = results
.filter((result) => result.state === "rejected")
.map((result) => result.reason);
const [error] = errors;
if (error.statusCode === 403) {
return [
{
title:
"You're probably over your rate limit. Slow down and try again later",
},
];
} else if (error.statusCode === 404) {
return [
{
title: "Command not found",
},
];
} else {
throw error;
}
});
}
module.exports = main;