import { UtilsService } from "./utils.service"; import path from "path"; import { writeFileSync } from "fs"; import { BSVersion } from "shared/bs-version.interface"; import { RequestService } from "./request.service"; import { readJSON } from "fs-extra"; import { allSettled } from "../../shared/helpers/promise.helpers"; import { LinuxService } from "./linux.service"; import { IS_FLATPAK } from "main/constants"; import { StaticConfigurationService } from "./static-configuration.service"; export class BSVersionLibService { private readonly REMOTE_BS_VERSIONS_URL: string = "https://raw.githubusercontent.com/Zagrios/bs-manager/master/assets/jsons/bs-versions.json"; private readonly VERSIONS_FILE: string = "bs-versions.json"; private static instance: BSVersionLibService; private readonly linuxService: LinuxService; private readonly utilsService: UtilsService; private readonly requestService: RequestService; private readonly configService: StaticConfigurationService; private bsVersions: BSVersion[]; private constructor() { this.linuxService = LinuxService.getInstance(); this.utilsService = UtilsService.getInstance(); this.requestService = RequestService.getInstance(); this.configService = StaticConfigurationService.getInstance(); } public static getInstance(): BSVersionLibService { if (!BSVersionLibService.instance) { BSVersionLibService.instance = new BSVersionLibService(); } return BSVersionLibService.instance; } private async getRemoteVersions(): Promise { return this.requestService.getJSON(this.REMOTE_BS_VERSIONS_URL).then(res => res.data); } private async shouldLoadFromConfig(): Promise { // Some special cases of readonly memory installations return IS_FLATPAK || this.linuxService.isNixOS(); } private async getLocalVersions(): Promise { const localVersionsPath = path.join(this.utilsService.getAssestsJsonsPath(), this.VERSIONS_FILE); if (!(await this.shouldLoadFromConfig())) { return readJSON(localVersionsPath); } let versions = this.configService.get("versions"); if (!versions) { versions = await readJSON(localVersionsPath) } return versions; } private async updateLocalVersions(versions: BSVersion[]): Promise { if (await this.shouldLoadFromConfig()) { this.configService.set("versions", versions); return; } const localVersionsPath = path.join(this.utilsService.getAssestsJsonsPath(), this.VERSIONS_FILE); writeFileSync(localVersionsPath, JSON.stringify(versions, null, "\t"), { encoding: "utf-8", flag: "w" }); } private async loadBsVersions(): Promise { if (this.bsVersions) { return this.bsVersions; } const [localVersions, remoteVersions] = await allSettled([this.getLocalVersions(), this.getRemoteVersions()], { keepStructure: true }); let resVersions = localVersions; if (remoteVersions?.length) { resVersions = remoteVersions; this.updateLocalVersions(resVersions); } this.bsVersions = resVersions; return this.bsVersions; } public async getAvailableVersions(): Promise { const bsVersions = await this.loadBsVersions(); if (!bsVersions?.length) { return []; } return bsVersions; } public async getVersionDetails(version: string): Promise { const versions = await this.getAvailableVersions(); return versions.find(v => v.BSVersion === version); } }