103 lines
3.3 KiB
TypeScript
103 lines
3.3 KiB
TypeScript
import { createWriteStream, promises as fs } from 'fs';
|
|
import { Readable, pipeline } from 'stream';
|
|
import { promisify } from 'util';
|
|
import { fileURLToPath } from 'url';
|
|
import { dirname, join } from 'path';
|
|
|
|
import * as smartarchive from '@push.rocks/smartarchive';
|
|
|
|
|
|
const streamPipeline = promisify(pipeline);
|
|
|
|
interface IRelease {
|
|
id: number;
|
|
tag_name: string;
|
|
assets: IAsset[];
|
|
}
|
|
|
|
interface IAsset {
|
|
url: string;
|
|
name: string;
|
|
}
|
|
|
|
class ResticReleaseDownloader {
|
|
private baseUrl: string;
|
|
|
|
constructor() {
|
|
this.baseUrl = 'https://api.github.com/repos/restic/restic/releases';
|
|
}
|
|
|
|
public async getPackageVersion(): Promise<string> {
|
|
// Get the directory of the current module
|
|
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
|
|
// Construct the path to the package.json file
|
|
const packageJsonPath = join(currentDir, '../package.json');
|
|
|
|
// Read the package.json file
|
|
const packageJsonData = await fs.readFile(packageJsonPath, 'utf8');
|
|
|
|
// Parse the package.json file
|
|
const packageJson = JSON.parse(packageJsonData);
|
|
|
|
// Return the version
|
|
return packageJson.version;
|
|
};
|
|
|
|
public async downloadAllReleases(targetFolder: string): Promise<void> {
|
|
const releases = await this.fetchReleases();
|
|
for (const release of releases) {
|
|
if (release.tag_name === `v${await this.getPackageVersion()}`) {
|
|
console.log(`Downloading restic v${await this.getPackageVersion()}`);
|
|
await this.downloadAssets(release, targetFolder);
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
private async fetchReleases(): Promise<IRelease[]> {
|
|
const response = await fetch(this.baseUrl);
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to fetch releases: ${response.statusText}`);
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
private async downloadAssets(release: IRelease, targetFolder: string): Promise<void> {
|
|
for (const asset of release.assets) {
|
|
console.error(`Downloading: ${asset.name}`);
|
|
const response = await fetch(asset.url, {
|
|
headers: { 'Accept': 'application/octet-stream' }
|
|
});
|
|
if (!response.ok) {
|
|
console.error(`Failed to download asset: ${asset.name}`);
|
|
continue;
|
|
} else {
|
|
console.log(`Downloaded asset: ${asset.name} successfully!!!`);
|
|
}
|
|
|
|
const asyncIterable = {
|
|
async *[Symbol.asyncIterator]() {
|
|
const reader = response.body.getReader();
|
|
while (true) {
|
|
const { done, value } = await reader.read();
|
|
if (done) break;
|
|
yield value;
|
|
}
|
|
}
|
|
};
|
|
|
|
const readableStream = Readable.from(asyncIterable);
|
|
const unpackStream = smartarchive.SmartArchive.fromArchiveStream(readableStream)
|
|
unpackStream
|
|
}
|
|
}
|
|
}
|
|
|
|
// lets do the actual work
|
|
const downloader = new ResticReleaseDownloader();
|
|
const targetFolder = join(dirname(fileURLToPath(import.meta.url)), '../.nogit/resticbins/');
|
|
await fs.mkdir(targetFolder, { recursive: true });
|
|
await downloader.downloadAllReleases(targetFolder);
|