Utility for downloading artifacts from different versions of Electron
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Extensible downloader system allowing custom download implementations for specialized requirements. The library provides a default got-based downloader but supports any custom implementation.
Generic interface that all downloader implementations must follow.
/**
* Generic interface for the artifact downloader library.
* The default implementation is GotDownloader,
* but any custom downloader can be passed to @electron/get via
* the ElectronDownloadRequestOptions.downloader option.
*/
interface Downloader<T> {
/**
* Download an artifact from an arbitrary URL to a file path on system
* @param url URL of the file to download
* @param targetFilePath Filesystem path to download the artifact to (including the file name)
* @param options Options to pass to the downloader
*/
download(url: string, targetFilePath: string, options: T): Promise<void>;
}Built-in downloader implementation using the got HTTP library.
/**
* Default Downloader implemented with got.
*/
class GotDownloader implements Downloader<GotDownloaderOptions> {
async download(
url: string,
targetFilePath: string,
options?: Partial<GotDownloaderOptions>
): Promise<void>;
}
/**
* Options for the default got Downloader implementation.
*/
type GotDownloaderOptions = GotOptions & { isStream?: true } & {
/** if defined, triggers every time got's downloadProgress event callback is triggered. */
getProgressCallback?: (progress: GotProgress) => Promise<void>;
/** if true, disables the console progress bar */
quiet?: boolean;
};Usage Examples:
import { download, GotDownloader } from "@electron/get";
// Use default downloader with custom options
await download('31.0.0', {
downloadOptions: {
timeout: { response: 60000 },
retry: { limit: 5 },
getProgressCallback: async (progress) => {
console.log(`Progress: ${Math.round(progress.percent * 100)}%`);
}
}
});
// Create custom GotDownloader instance
const customDownloader = new GotDownloader();
await download('31.0.0', {
downloader: customDownloader,
downloadOptions: {
headers: { 'Authorization': 'Bearer token123' }
}
});Create custom downloaders for specialized requirements.
type DownloadOptions = any; // Custom downloaders can implement any set of optionsCustom Downloader Example:
import { Downloader } from "@electron/get";
import fs from 'fs';
import https from 'https';
interface CustomDownloaderOptions {
timeout?: number;
retries?: number;
userAgent?: string;
}
class CustomDownloader implements Downloader<CustomDownloaderOptions> {
async download(
url: string,
targetFilePath: string,
options: CustomDownloaderOptions = {}
): Promise<void> {
const { timeout = 30000, retries = 3, userAgent = 'CustomDownloader/1.0' } = options;
for (let attempt = 0; attempt <= retries; attempt++) {
try {
await this.downloadWithTimeout(url, targetFilePath, timeout, userAgent);
return; // Success
} catch (error) {
if (attempt === retries) throw error;
await this.delay(1000 * Math.pow(2, attempt)); // Exponential backoff
}
}
}
private downloadWithTimeout(
url: string,
targetFilePath: string,
timeout: number,
userAgent: string
): Promise<void> {
return new Promise((resolve, reject) => {
const file = fs.createWriteStream(targetFilePath);
const request = https.get(url, {
headers: { 'User-Agent': userAgent },
timeout
}, response => {
if (response.statusCode !== 200) {
reject(new Error(`HTTP ${response.statusCode}`));
return;
}
response.pipe(file);
file.on('finish', () => {
file.close();
resolve();
});
});
request.on('error', reject);
request.on('timeout', () => {
request.destroy();
reject(new Error('Download timeout'));
});
});
}
private delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// Use custom downloader
const customDownloader = new CustomDownloader();
await download('31.0.0', {
downloader: customDownloader,
downloadOptions: {
timeout: 60000,
retries: 5,
userAgent: 'MyApp/2.0'
}
});Progress information provided by the default downloader.
interface GotProgress {
/** Percentage of download completed (0-1) */
percent: number;
/** Bytes transferred so far */
transferred: number;
/** Total bytes to transfer */
total?: number;
}Progress Tracking Example:
import { download } from "@electron/get";
await download('31.0.0', {
downloadOptions: {
getProgressCallback: async (progress) => {
const percent = Math.round(progress.percent * 100);
const transferred = Math.round(progress.transferred / 1024 / 1024);
const total = progress.total ? Math.round(progress.total / 1024 / 1024) : '?';
console.log(`Download: ${percent}% (${transferred}MB / ${total}MB)`);
},
quiet: true // Disable built-in progress bar
}
});The built-in GotDownloader provides:
got library optionsinitializeProxy() is calledInstall with Tessl CLI
npx tessl i tessl/npm-electron--get