mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
97 lines
3.1 KiB
TypeScript
97 lines
3.1 KiB
TypeScript
import { get } from "https";
|
|
import { createWriteStream, unlink } from "fs";
|
|
import { Progression } from "main/helpers/fs.helpers";
|
|
import { Observable, shareReplay, tap } from "rxjs";
|
|
import log from "electron-log";
|
|
import fetch, { RequestInfo, RequestInit } from "node-fetch";
|
|
|
|
export class RequestService {
|
|
private static instance: RequestService;
|
|
|
|
public static getInstance(): RequestService {
|
|
if (!RequestService.instance) {
|
|
RequestService.instance = new RequestService();
|
|
}
|
|
return RequestService.instance;
|
|
}
|
|
|
|
private constructor() {}
|
|
|
|
public async getJSON<T = unknown>(url: RequestInfo, options?: RequestInit): Promise<T> {
|
|
try {
|
|
const response = await fetch(url, options);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status} ${response}`);
|
|
}
|
|
|
|
return await response.json();
|
|
} catch (err) {
|
|
log.error(err);
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
public downloadFile(url: string, dest: string): Observable<Progression<string>> {
|
|
return new Observable<Progression<string>>(subscriber => {
|
|
const progress: Progression<string> = { current: 0, total: 0 };
|
|
|
|
const file = createWriteStream(dest);
|
|
|
|
file.on("close", () => {
|
|
progress.data = dest;
|
|
subscriber.next(progress);
|
|
subscriber.complete();
|
|
});
|
|
file.on("error", err => unlink(dest, () => subscriber.error(err)));
|
|
|
|
const req = get(url, res => {
|
|
progress.total = parseInt(res.headers?.["content-length"] || "0", 10);
|
|
|
|
res.on("data", chunk => {
|
|
progress.current += chunk.length;
|
|
subscriber.next(progress);
|
|
});
|
|
|
|
res.pipe(file);
|
|
});
|
|
|
|
req.on("error", err => {
|
|
subscriber.error(err);
|
|
});
|
|
}).pipe(tap({ error: e => log.error(e, url, dest) }), shareReplay(1));
|
|
}
|
|
|
|
public downloadBuffer(url: string): Observable<Progression<Buffer>> {
|
|
return new Observable<Progression<Buffer>>(subscriber => {
|
|
const progress: Progression<Buffer> = {
|
|
current: 0,
|
|
total: 0,
|
|
data: null,
|
|
};
|
|
|
|
const allChunks: Buffer[] = [];
|
|
|
|
const req = get(url, res => {
|
|
progress.total = parseInt(res.headers?.["content-length"] || "0", 10);
|
|
|
|
res.on("data", chunk => {
|
|
allChunks.push(chunk);
|
|
progress.current += chunk.length;
|
|
subscriber.next(progress);
|
|
});
|
|
res.on("end", () => {
|
|
progress.data = Buffer.concat(allChunks);
|
|
subscriber.next(progress);
|
|
subscriber.complete();
|
|
});
|
|
res.on("error", err => subscriber.error(err));
|
|
});
|
|
|
|
req.on("error", err => {
|
|
subscriber.error(err);
|
|
});
|
|
}).pipe(tap({ error: e => log.error(e) }), shareReplay(1));
|
|
}
|
|
}
|