aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code/src')
-rw-r--r--editors/code/src/github/download_file.ts26
-rw-r--r--editors/code/src/github/fetch_latest_artifact_metadata.ts55
2 files changed, 81 insertions, 0 deletions
diff --git a/editors/code/src/github/download_file.ts b/editors/code/src/github/download_file.ts
new file mode 100644
index 000000000..f40750be9
--- /dev/null
+++ b/editors/code/src/github/download_file.ts
@@ -0,0 +1,26 @@
1import fetch from "node-fetch";
2import { throttle } from "throttle-debounce";
3import * as fs from "fs";
4
5export async function downloadFile(
6 url: string,
7 destFilePath: fs.PathLike,
8 onProgress: (readBytes: number, totalBytes: number) => void
9): Promise<void> {
10 onProgress = throttle(100, /* noTrailing: */ true, onProgress);
11
12 const response = await fetch(url);
13
14 const totalBytes = Number(response.headers.get('content-length'));
15 let readBytes = 0;
16
17 return new Promise<void>((resolve, reject) => response.body
18 .on("data", (chunk: Buffer) => {
19 readBytes += chunk.length;
20 onProgress(readBytes, totalBytes);
21 })
22 .on("end", resolve)
23 .on("error", reject)
24 .pipe(fs.createWriteStream(destFilePath))
25 );
26}
diff --git a/editors/code/src/github/fetch_latest_artifact_metadata.ts b/editors/code/src/github/fetch_latest_artifact_metadata.ts
new file mode 100644
index 000000000..52641ca67
--- /dev/null
+++ b/editors/code/src/github/fetch_latest_artifact_metadata.ts
@@ -0,0 +1,55 @@
1import fetch from "node-fetch";
2
3const GITHUB_API_ENDPOINT_URL = "https://api.github.com";
4
5export interface FetchLatestArtifactMetadataOpts {
6 repoName: string;
7 repoOwner: string;
8 artifactFileName: string;
9}
10
11export interface ArtifactMetadata {
12 releaseName: string;
13 releaseDate: Date;
14 downloadUrl: string;
15}
16
17export async function fetchLatestArtifactMetadata(
18 opts: FetchLatestArtifactMetadataOpts
19): Promise<ArtifactMetadata | null> {
20
21 const repoOwner = encodeURIComponent(opts.repoOwner);
22 const repoName = encodeURIComponent(opts.repoName);
23
24 const apiEndpointPath = `/repos/${repoOwner}/${repoName}/releases/latest`;
25 const requestUrl = GITHUB_API_ENDPOINT_URL + apiEndpointPath;
26
27 // We skip runtime type checks for simplicity (here we cast from `any` to `Release`)
28
29 const response: GithubRelease = await fetch(requestUrl, {
30 headers: { Accept: "application/vnd.github.v3+json" }
31 })
32 .then(res => res.json());
33
34 const artifact = response.assets.find(artifact => artifact.name === opts.artifactFileName);
35
36 return !artifact ? null : {
37 releaseName: response.name,
38 releaseDate: new Date(response.published_at),
39 downloadUrl: artifact.browser_download_url
40 };
41
42 // Noise denotes tremendous amount of data that we are not using here
43 interface GithubRelease {
44 name: string;
45 published_at: Date;
46 assets: Array<{
47 browser_download_url: string;
48
49 [noise: string]: unknown;
50 }>;
51
52 [noise: string]: unknown;
53 }
54
55}