import { Err , ErrorCode } from "./error" ; export interface Migration { from : string ; to : string ; transforms : { [ kind ] : { up : ( inp : any , kind ? : string ) => any ; down : ( inp : any , kind ? : string ) => any ; } ; } ; } export const MIGRATIONS = [ { from : "3.0.14" , to : "3.1.0" , transforms : { account : { up : ( { mainVault , orgs , ... rest } ) => ( { mainVault : { id : mainVault } , orgs : orgs . map ( ( org ) => ( { id : org } ) ) , ... rest } ) , down : ( { mainVault , orgs , ... rest } ) => ( { mainVault : mainVault . id , orgs : orgs . map ( ( org ) => org . id ) , ... rest } ) } , all : { up : ( raw , kind ? ) => ( { kind , ... raw } ) , down : ( { kind , ... rest } ) => rest } } } ] ; export const EARLIEST_VERSION = MIGRATIONS [ 0 ] . from ; export const LATEST_VERSION = MIGRATIONS [ MIGRATIONS . length - 1 ] . to ; function norm ( version = EARLIEST_VERSION ) { return version . split ( "." ) . map ( part => part . padStart ( 3 , "0" ) ) . join ( ) ; } export function upgrade ( kind , raw , version = LATEST_VERSION ) { if ( norm ( raw . version ) > norm ( LATEST_VERSION ) ) { throw new Err ( ErrorCode . UNSUPPORTED_VERSION , "An object could not be decoded because it was encoded with a newer version of Padloc. " + "Please update to the latest version to fix this problem!" ) ; } const migration = MIGRATIONS . find ( m => norm ( m . from ) >= norm ( raw . version || EARLIEST_VERSION ) && norm ( m . to ) <= norm ( version ) ) ; if ( migration ) { let transform = migration . transforms [ "all" ] ; raw = transform ? transform . up ( raw , kind ) : raw ; transform = migration . transforms [ kind ] ; raw = transform ? transform . up ( raw , kind ) : raw ; raw . version = migration . to ; return upgrade ( kind , raw , version ) ; } else { raw . version = version ; return raw ; } } export function downgrade ( kind , raw , version = LATEST_VERSION ) { const migration = MIGRATIONS . reverse ( ) . find ( m => norm ( m . to ) <= norm ( raw . version || LATEST_VERSION ) && norm ( m . from ) >= norm ( version ) ) ; if ( migration ) { let transform = migration . transforms [ kind ] ; raw = transform ? transform . down ( raw , kind ) : raw ; transform = migration . transforms [ "all" ] ; raw = transform ? transform . down ( raw , kind ) : raw ; raw . version = migration . from ; return downgrade ( kind , raw , version ) ; } else { raw . version = norm ( version ) > norm ( LATEST_VERSION ) ? LATEST_VERSION : version ; return raw ; } }