diff options
| author | Veetaha <gerzoh1@gmail.com> | 2020-02-07 03:11:24 +0200 |
|---|---|---|
| committer | Veetaha <gerzoh1@gmail.com> | 2020-02-08 04:34:11 +0200 |
| commit | 3e0e4e90aeeff25db674f8db562c611bd8016482 (patch) | |
| tree | 638756f88bf4c370135b3984667c2618438f6d01 /editors/code/src | |
| parent | 1bdb78a89f6618527f2dc23f8f76e83ee77e3ea5 (diff) | |
| download | rust-3e0e4e90aeeff25db674f8db562c611bd8016482.tar.gz rust-3e0e4e90aeeff25db674f8db562c611bd8016482.zip | |
added fetchLatestArtifactMetadata() and downloadFile() functions
Diffstat (limited to 'editors/code/src')
| -rw-r--r-- | editors/code/src/github/download_file.ts | 26 | ||||
| -rw-r--r-- | editors/code/src/github/fetch_latest_artifact_metadata.ts | 55 |
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 00000000000..f40750be905 --- /dev/null +++ b/editors/code/src/github/download_file.ts @@ -0,0 +1,26 @@ +import fetch from "node-fetch"; +import { throttle } from "throttle-debounce"; +import * as fs from "fs"; + +export async function downloadFile( + url: string, + destFilePath: fs.PathLike, + onProgress: (readBytes: number, totalBytes: number) => void +): Promise<void> { + onProgress = throttle(100, /* noTrailing: */ true, onProgress); + + const response = await fetch(url); + + const totalBytes = Number(response.headers.get('content-length')); + let readBytes = 0; + + return new Promise<void>((resolve, reject) => response.body + .on("data", (chunk: Buffer) => { + readBytes += chunk.length; + onProgress(readBytes, totalBytes); + }) + .on("end", resolve) + .on("error", reject) + .pipe(fs.createWriteStream(destFilePath)) + ); +} 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 00000000000..52641ca67d6 --- /dev/null +++ b/editors/code/src/github/fetch_latest_artifact_metadata.ts @@ -0,0 +1,55 @@ +import fetch from "node-fetch"; + +const GITHUB_API_ENDPOINT_URL = "https://api.github.com"; + +export interface FetchLatestArtifactMetadataOpts { + repoName: string; + repoOwner: string; + artifactFileName: string; +} + +export interface ArtifactMetadata { + releaseName: string; + releaseDate: Date; + downloadUrl: string; +} + +export async function fetchLatestArtifactMetadata( + opts: FetchLatestArtifactMetadataOpts +): Promise<ArtifactMetadata | null> { + + const repoOwner = encodeURIComponent(opts.repoOwner); + const repoName = encodeURIComponent(opts.repoName); + + const apiEndpointPath = `/repos/${repoOwner}/${repoName}/releases/latest`; + const requestUrl = GITHUB_API_ENDPOINT_URL + apiEndpointPath; + + // We skip runtime type checks for simplicity (here we cast from `any` to `Release`) + + const response: GithubRelease = await fetch(requestUrl, { + headers: { Accept: "application/vnd.github.v3+json" } + }) + .then(res => res.json()); + + const artifact = response.assets.find(artifact => artifact.name === opts.artifactFileName); + + return !artifact ? null : { + releaseName: response.name, + releaseDate: new Date(response.published_at), + downloadUrl: artifact.browser_download_url + }; + + // Noise denotes tremendous amount of data that we are not using here + interface GithubRelease { + name: string; + published_at: Date; + assets: Array<{ + browser_download_url: string; + + [noise: string]: unknown; + }>; + + [noise: string]: unknown; + } + +} |
