import angular from 'angular' ; import { Injectable } from 'angular-ts-decorators' ; import autobind from 'autobind-decorator' ; import { Bookmark } from '../bookmark/bookmark.interface' ; import { SyncVersionNotSupportedError , UpgradeFailedError } from '../errors/errors' ; import { PlatformService } from '../global-shared.interface' ; import { LogService } from '../log/log.service' ; import { StoreKey } from '../store/store.enum' ; import { StoreService } from '../store/store.service' ; import { UtilityService } from '../utility/utility.service' ; import { UpgradeProvider } from './upgrade.interface' ; import { V160UpgradeProviderService } from './v1.6.0-upgrade-provider/v1.6.0-upgrade-provider.service' ; @ autobind @ Injectable ( 'UpgradeService' ) export class UpgradeService { $q : ng . IQService ; logSvc : LogService ; platformSvc : PlatformService ; storeSvc : StoreService ; utilitySvc : UtilityService ; v160UpgradeProviderSvc : V160UpgradeProviderService ; upgradeMap : Map < string , UpgradeProvider > ; static $inject = [ '$q' , 'LogService' , 'PlatformService' , 'StoreService' , 'UtilityService' , 'V160UpgradeProviderService' ] ; constructor ( $q , LogSvc , PlatformSvc , StoreSvc , UtilitySvc , V1_6_0_UpgradeProviderSvc ) { this . $q = $q ; this . logSvc = LogSvc ; this . platformSvc = PlatformSvc ; this . storeSvc = StoreSvc ; this . utilitySvc = UtilitySvc ; this . v160UpgradeProviderSvc = V1_6_0_UpgradeProviderSvc ; this . upgradeMap = new Map < string , UpgradeProvider > ( ) ; this . upgradeMap . set ( '1.6.0' , this . v160UpgradeProviderSvc ) ; } checkIfUpgradeRequired ( currentVersion ) { return this . getLastUpgradeVersion ( ) . then ( ( lastUpgradeVersion ) => { return ( angular . isUndefined ( lastUpgradeVersion ) || this . utilitySvc . compareVersions ( lastUpgradeVersion , currentVersion , '<' ) ) ; } ) ; } getLastUpgradeVersion ( ) { return this . storeSvc . get < string > ( StoreKey . LastUpgradeVersion ) ; } setLastUpgradeVersion ( version ) { return this . storeSvc . set ( StoreKey . LastUpgradeVersion , version ) ; } upgrade ( targetVersion ) { if ( angular . isUndefined ( targetVersion ) ) { throw new UpgradeFailedError ( 'Failed upgrade, target version not provided' ) ; } return this . getLastUpgradeVersion ( ) . then ( ( lastUpgradeVersion = '1.0.0' ) => { const condition = ( currentVersion ) : ng . IPromise < boolean > => { return this . $q . resolve ( this . utilitySvc . compareVersions ( currentVersion , targetVersion , '<' ) ) ; } ; const action = ( currentVersion ) : ng . IPromise < string > => { const upgradeStep = [ ... this . upgradeMap ] . find ( ( { 0 : x } ) => this . utilitySvc . compareVersions ( currentVersion , x , '<' ) ) ; const [ upgradeVersion , upgradeProvider ] = upgradeStep ?? [ ] ; return ( upgradeVersion ? upgradeProvider . upgradeApp ( lastUpgradeVersion ) . then ( ( ) => upgradeVersion ) : this . $q . resolve ( targetVersion ) ) . then ( ( newVersion ) => { return this . setLastUpgradeVersion ( newVersion ) . then ( ( ) => this . logSvc . logInfo ( `Upgraded to ${ newVersion }` ) ) . then ( ( ) => newVersion ) ; } ) ; } ; return this . utilitySvc . asyncWhile < string > ( lastUpgradeVersion , condition , action ) ; } ) . then ( ( ) => this . platformSvc . disableSync ( ) ) . catch ( ( err ) => { throw new UpgradeFailedError ( `Failed upgrade to ${ targetVersion }` , err ) ; } ) ; } upgradeBookmarks ( targetVersion , syncVersion = '1.0.0' , bookmarks = [ ] ) { if ( bookmarks . length === 0 ) { return this . $q . resolve ( bookmarks ) ; } if ( angular . isUndefined ( targetVersion ) ) { throw new UpgradeFailedError ( 'Failed upgrade bookmarks, target version not provided' ) ; } if ( this . utilitySvc . compareVersions ( syncVersion , targetVersion , '>' ) ) { throw new SyncVersionNotSupportedError ( ) ; } let upgradedBookmarks = angular . copy ( bookmarks ) ; const condition = ( currentVersion ) : ng . IPromise < boolean > => { return this . $q . resolve ( this . utilitySvc . compareVersions ( currentVersion , targetVersion , '<' ) ) ; } ; const action = ( currentVersion ) : ng . IPromise < string > => { const upgradeStep = [ ... this . upgradeMap ] . find ( ( { 0 : x } ) => this . utilitySvc . compareVersions ( currentVersion , x , '<' ) ) ; const [ upgradeVersion , upgradeProvider ] = upgradeStep ?? [ ] ; return ( upgradeVersion ? upgradeProvider . upgradeBookmarks ( upgradedBookmarks , currentVersion ) : this . $q . resolve ( upgradedBookmarks ) ) . then ( ( bookmarksUpgradeResult ) => { upgradedBookmarks = bookmarksUpgradeResult ; return upgradeVersion ?? targetVersion ; } ) ; } ; return this . utilitySvc . asyncWhile < string > ( syncVersion , condition , action ) . then ( ( ) => upgradedBookmarks ) ; } }