generated from khrj/blueprint
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mod.ts
69 lines (62 loc) · 2.72 KB
/
mod.ts
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
const normalize = (string: string) => {
try {
return string.toUpperCase().trim()
} catch (e) {
return string
}
}
const providerMethods: Record<
string,
(
{ user, repo }: { user: string; repo: string; part?: string },
) => Promise<string[]>
> = {
GITHUB: async ({ user, repo, part = "" }: { user: string; repo: string; part?: string }) => {
const response = await fetch(`https://api.github.com/repos/${user}/${repo}/releases/latest`)
const json = await response.json()
if (json.message === "Not Found") throw new Error("Invalid repository")
if (!("assets" in json)) throw new Error("Rate limit exceeded")
const browserDownloadUrls: string[] = json.assets.map((asset: { browser_download_url: string }) =>
asset.browser_download_url
)
return browserDownloadUrls.filter((url) => url.includes(part))
},
BITBUCKET: async ({ user, repo, part = "" }: { user: string; repo: string; part?: string }) => {
const response = await fetch(`https://api.bitbucket.org/2.0/repositories/${user}/${repo}/downloads/`)
const json = await response.json()
if (json.type === "error") throw "Invalid repository"
const links: string[] = json.values.map((value: { links: { self: { href: string } } }) => value.links.self.href)
return links.filter(url => url.includes(part))
},
}
/**
* Fetches one or many matching release URLs from the selected provider
* @param options.provider The provider to fetch from. Available options are
* 'github', 'bitbucket' and any others added via `addProviderMethod`
* @param options.user Username to fetch from. This is the user name / org name
* of the repository owner
* @param options.repo Repository to fetch releases from
* @param options.part Part of the name of release assets to filter. Eg. if a
* release contains 3 assets, 'hi-1', 'hi-2', and '3', passing 'hi' as the part
* will only return 'hi-1' and 'hi-2'
*/
export default async function getReleaseURL(options: { provider: string; user: string; repo: string; part?: string }) {
const providerNormalized = normalize(options.provider)
if (!(providerNormalized in providerMethods)) {
throw new Error("Invalid provider")
}
return await providerMethods[providerNormalized]({ user: options.user, repo: options.repo, part: options.part || "" })
}
/**
* @param provider Provider for the method. You can override existing providers
* if needed
* @param method Custom method
*/
export function addProviderMethod(
provider: string,
method: (
{ user, repo, part }: { user: string; repo: string; part?: string },
) => Promise<string[]>,
) {
providerMethods[normalize(provider)] = method
}