import { Subject, Observable } from 'rxjs' import { Http, Update, Operation, Revision, Source, Store, RPCResponse, } from 'patch-db-client' import { RR } from './api.types' import { DataModel } from 'src/app/services/patch-db/data-model' import { RequestError } from '../http.service' import { map } from 'rxjs/operators' export abstract class ApiService implements Source, Http { protected readonly sync$ = new Subject>() /** PatchDb Source interface. Post/Patch requests provide a source of patches to the db. */ // sequenceStream '_' is not used by the live api, but is overridden by the mock watch$(_?: Store): Observable>> { return this.sync$ .asObservable() .pipe(map(result => ({ result, jsonrpc: '2.0' }))) } // for getting static files: ex icons, instructions, licenses abstract getStatic(url: string): Promise // for sideloading packages abstract uploadPackage(guid: string, body: ArrayBuffer): Promise // db abstract getRevisions(since: number): Promise abstract getDump(): Promise protected abstract setDbValueRaw( params: RR.SetDBValueReq, ): Promise setDbValue = (params: RR.SetDBValueReq) => this.syncResponse(() => this.setDbValueRaw(params))() // auth abstract login(params: RR.LoginReq): Promise abstract logout(params: RR.LogoutReq): Promise abstract getSessions(params: RR.GetSessionsReq): Promise abstract killSessions(params: RR.KillSessionsReq): Promise // server abstract getServerLogs( params: RR.GetServerLogsReq, ): Promise abstract getKernelLogs( params: RR.GetServerLogsReq, ): Promise abstract getServerMetrics( params: RR.GetServerMetricsReq, ): Promise abstract getPkgMetrics( params: RR.GetPackageMetricsReq, ): Promise protected abstract updateServerRaw( params: RR.UpdateServerReq, ): Promise updateServer = (params: RR.UpdateServerReq) => this.syncResponse(() => this.updateServerWrapper(params))() async updateServerWrapper(params: RR.UpdateServerReq) { const res = await this.updateServerRaw(params) if (res.response === 'no-updates') { throw new Error('Could ont find a newer version of EmbassyOS') } return res } abstract restartServer( params: RR.RestartServerReq, ): Promise abstract shutdownServer( params: RR.ShutdownServerReq, ): Promise abstract systemRebuild( params: RR.SystemRebuildReq, ): Promise abstract repairDisk(params: RR.SystemRebuildReq): Promise // marketplace URLs abstract marketplaceProxy( path: string, params: {}, url: string, ): Promise abstract getEos( params: RR.GetMarketplaceEOSReq, ): Promise // password // abstract updatePassword (params: RR.UpdatePasswordReq): Promise // notification abstract getNotificationsRaw( params: RR.GetNotificationsReq, ): Promise getNotifications = (params: RR.GetNotificationsReq) => this.syncResponse(() => this.getNotificationsRaw(params), )() abstract deleteNotification( params: RR.DeleteNotificationReq, ): Promise abstract deleteAllNotifications( params: RR.DeleteAllNotificationsReq, ): Promise // wifi abstract getWifi( params: RR.GetWifiReq, timeout: number, ): Promise abstract setWifiCountry( params: RR.SetWifiCountryReq, ): Promise abstract addWifi(params: RR.AddWifiReq): Promise abstract connectWifi(params: RR.ConnectWifiReq): Promise abstract deleteWifi(params: RR.DeleteWifiReq): Promise // ssh abstract getSshKeys(params: RR.GetSSHKeysReq): Promise abstract addSshKey(params: RR.AddSSHKeyReq): Promise abstract deleteSshKey(params: RR.DeleteSSHKeyReq): Promise // backup abstract getBackupTargets( params: RR.GetBackupTargetsReq, ): Promise abstract addBackupTarget( params: RR.AddBackupTargetReq, ): Promise abstract updateBackupTarget( params: RR.UpdateBackupTargetReq, ): Promise abstract removeBackupTarget( params: RR.RemoveBackupTargetReq, ): Promise abstract getBackupInfo( params: RR.GetBackupInfoReq, ): Promise protected abstract createBackupRaw( params: RR.CreateBackupReq, ): Promise createBackup = (params: RR.CreateBackupReq) => this.syncResponse(() => this.createBackupRaw(params))() // package abstract getPackageProperties( params: RR.GetPackagePropertiesReq, ): Promise['data']> abstract getPackageLogs( params: RR.GetPackageLogsReq, ): Promise protected abstract installPackageRaw( params: RR.InstallPackageReq, ): Promise installPackage = (params: RR.InstallPackageReq) => this.syncResponse(() => this.installPackageRaw(params))() abstract dryUpdatePackage( params: RR.DryUpdatePackageReq, ): Promise abstract getPackageConfig( params: RR.GetPackageConfigReq, ): Promise abstract drySetPackageConfig( params: RR.DrySetPackageConfigReq, ): Promise protected abstract setPackageConfigRaw( params: RR.SetPackageConfigReq, ): Promise setPackageConfig = (params: RR.SetPackageConfigReq) => this.syncResponse(() => this.setPackageConfigRaw(params))() protected abstract restorePackagesRaw( params: RR.RestorePackagesReq, ): Promise restorePackages = (params: RR.RestorePackagesReq) => this.syncResponse(() => this.restorePackagesRaw(params))() abstract executePackageAction( params: RR.ExecutePackageActionReq, ): Promise protected abstract startPackageRaw( params: RR.StartPackageReq, ): Promise startPackage = (params: RR.StartPackageReq) => this.syncResponse(() => this.startPackageRaw(params))() abstract dryStopPackage( params: RR.DryStopPackageReq, ): Promise protected abstract stopPackageRaw( params: RR.StopPackageReq, ): Promise stopPackage = (params: RR.StopPackageReq) => this.syncResponse(() => this.stopPackageRaw(params))() abstract dryUninstallPackage( params: RR.DryUninstallPackageReq, ): Promise protected abstract uninstallPackageRaw( params: RR.UninstallPackageReq, ): Promise uninstallPackage = (params: RR.UninstallPackageReq) => this.syncResponse(() => this.uninstallPackageRaw(params))() abstract dryConfigureDependency( params: RR.DryConfigureDependencyReq, ): Promise protected abstract deleteRecoveredPackageRaw( params: RR.UninstallPackageReq, ): Promise deleteRecoveredPackage = (params: RR.UninstallPackageReq) => this.syncResponse(() => this.deleteRecoveredPackageRaw(params))() abstract sideloadPackage( params: RR.SideloadPackageReq, ): Promise // Helper allowing quick decoration to sync the response patch and return the response contents. // Pass in a tempUpdate function which returns a UpdateTemp corresponding to a temporary // state change you'd like to enact prior to request and expired when request terminates. private syncResponse< T, F extends (...args: any[]) => Promise<{ response: T; revision?: Revision }>, >(f: F, temp?: Operation): (...args: Parameters) => Promise { return (...a) => { // let expireId = undefined // if (temp) { // expireId = uuid.v4() // this.sync.next({ patch: [temp], expiredBy: expireId }) // } return f(a) .catch((e: RequestError) => { if (e.revision) this.sync$.next(e.revision) throw e }) .then(({ response, revision }) => { if (revision) this.sync$.next(revision) return response }) } } }