import { FileSystemAccess } from './file-system-access' ; let fileAccess ; returns export function getFileAccess ( ) { if ( ! fileAccess ) { fileAccess = new FileSystemAccess ( ) ; } return fileAccess ; } function createFile ( info ) { const file = new File ( ) ; file . _path = info . path ; file . _name = info . name ; file . _extension = info . extension ; return file ; } function createFolder ( info ) { const documents = knownFolders . documents ( ) ; if ( info . path === documents . path ) { return documents ; } const temp = knownFolders . temp ( ) ; if ( info . path === temp . path ) { return temp ; } const folder = new Folder ( ) ; folder . _path = info . path ; folder . _name = info . name ; return folder ; } export class FileSystemEntity { _path : string ; _name : string ; _extension : string ; _locked : boolean ; _lastModified : Date ; _isKnown : boolean ; get parent ( ) : Folder { const onError = function ( error ) { throw error ; } ; const folderInfo = getFileAccess ( ) . getParent ( this . path , onError ) ; if ( ! folderInfo ) { return undefined ; } return createFolder ( folderInfo ) ; } public remove ( ) { return new Promise ( ( resolve , reject ) => { let hasError = false ; const localError = function ( error ) { hasError = true ; reject ( error ) ; } ; this . removeSync ( localError ) ; if ( ! hasError ) { resolve ( true ) ; } } ) ; } public removeSync ( onError ? ) { if ( this . _isKnown ) { if ( onError ) { onError ( { message : 'Cannot delete known folder.' } ) ; } return ; } const fileAccess = getFileAccess ( ) ; if ( this instanceof File ) { fileAccess . deleteFile ( this . path , onError ) ; } else if ( this instanceof Folder ) { fileAccess . deleteFolder ( this . path , onError ) ; } } public rename ( newName ) { return new Promise ( ( resolve , reject ) => { let hasError = false ; const localError = function ( error ) { hasError = true ; reject ( error ) ; } ; this . renameSync ( newName , localError ) ; if ( ! hasError ) { resolve ( true ) ; } } ) ; } public renameSync ( newName , onError ? ) { if ( this . _isKnown ) { if ( onError ) { onError ( new Error ( 'Cannot rename known folder.' ) ) ; } return ; } const parentFolder = this . parent ; if ( ! parentFolder ) { if ( onError ) { onError ( new Error ( 'No parent folder.' ) ) ; } return ; } const fileAccess = getFileAccess ( ) ; const path = parentFolder . path ; const newPath = fileAccess . joinPath ( path , newName ) ; const localError = function ( error ) { if ( onError ) { onError ( error ) ; } return null ; } ; fileAccess . rename ( this . path , newPath , localError ) ; this . _path = newPath ; this . _name = newName ; if ( this instanceof File ) { this . _extension = fileAccess . getFileExtension ( newPath ) ; } } get name ( ) : string { return this . _name ; } get path ( ) : string { return this . _path ; } get lastModified ( ) : Date { let value = this . _lastModified ; if ( ! this . _lastModified ) { value = this . _lastModified = getFileAccess ( ) . getLastModified ( this . path ) ; } return value ; } } export class File extends FileSystemEntity { public static fromPath ( path ) { const onError = function ( error ) { throw error ; } ; const fileInfo = getFileAccess ( ) . getFile ( path , onError ) ; if ( ! fileInfo ) { return undefined ; } return createFile ( fileInfo ) ; } public static exists ( path ) { return getFileAccess ( ) . fileExists ( path ) ; } get extension ( ) : string { return this . _extension ; } get isLocked ( ) : boolean { return ! ! this . _locked ; } get size ( ) : number { return getFileAccess ( ) . getFileSize ( this . path ) ; } public read ( ) { return new Promise < any > ( ( resolve , reject ) => { try { this . checkAccess ( ) ; } catch ( ex ) { reject ( ex ) ; return ; } this . _locked = true ; getFileAccess ( ) . readAsync ( this . path ) . then ( ( result ) => { resolve ( result ) ; this . _locked = false ; } , ( error ) => { reject ( error ) ; this . _locked = false ; } ) ; } ) ; } public readSync ( onError ? ) { this . checkAccess ( ) ; this . _locked = true ; const that = this ; const localError = ( error ) => { that . _locked = false ; if ( onError ) { onError ( error ) ; } } ; const content = getFileAccess ( ) . readSync ( this . path , localError ) ; this . _locked = false ; return content ; } public write ( content ) { return new Promise < void > ( ( resolve , reject ) => { try { this . checkAccess ( ) ; } catch ( ex ) { reject ( ex ) ; return ; } this . _locked = true ; getFileAccess ( ) . writeAsync ( this . path , content ) . then ( ( ) => { resolve ( ) ; this . _locked = false ; } , ( error ) => { reject ( error ) ; this . _locked = false ; } ) ; } ) ; } public writeSync ( content , onError ? ) { this . checkAccess ( ) ; try { this . _locked = true ; const that = this ; const localError = function ( error ) { that . _locked = false ; if ( onError ) { onError ( error ) ; } } ; getFileAccess ( ) . writeSync ( this . path , content , localError ) ; } finally { this . _locked = false ; } } public readText ( encoding ? ) { return new Promise ( ( resolve , reject ) => { try { this . checkAccess ( ) ; } catch ( ex ) { reject ( ex ) ; return ; } this . _locked = true ; getFileAccess ( ) . readTextAsync ( this . path , encoding ) . then ( ( result ) => { resolve ( result ) ; this . _locked = false ; } , ( error ) => { reject ( error ) ; this . _locked = false ; } ) ; } ) ; } public readTextSync ( onError ? , encoding ? ) { this . checkAccess ( ) ; this . _locked = true ; const that = this ; const localError = ( error ) => { that . _locked = false ; if ( onError ) { onError ( error ) ; } } ; const content = getFileAccess ( ) . readTextSync ( this . path , localError , encoding ) ; this . _locked = false ; return content ; } public writeText ( content , encoding ? ) { return new Promise ( ( resolve , reject ) => { try { this . checkAccess ( ) ; } catch ( ex ) { reject ( ex ) ; return ; } this . _locked = true ; getFileAccess ( ) . writeTextAsync ( this . path , content , encoding ) . then ( ( ) => { resolve ( true ) ; this . _locked = false ; } , ( error ) => { reject ( error ) ; this . _locked = false ; } ) ; } ) ; } public writeTextSync ( content , onError ? , encoding ? ) { this . checkAccess ( ) ; try { this . _locked = true ; const that = this ; const localError = function ( error ) { that . _locked = false ; if ( onError ) { onError ( error ) ; } } ; getFileAccess ( ) . writeTextSync ( this . path , content , localError , encoding ) ; } finally { this . _locked = false ; } } private checkAccess ( ) { if ( this . isLocked ) { throw new Error ( 'Cannot access a locked file.' ) ; } } } export class Folder extends FileSystemEntity { public static fromPath ( path ) { const onError = function ( error ) { throw error ; } ; const folderInfo = getFileAccess ( ) . getFolder ( path , onError ) ; if ( ! folderInfo ) { return undefined ; } return createFolder ( folderInfo ) ; } public static exists ( path ) { return getFileAccess ( ) . folderExists ( path ) ; } public contains ( name ) { const fileAccess = getFileAccess ( ) ; const path = fileAccess . joinPath ( this . path , name ) ; if ( fileAccess . fileExists ( path ) ) { return true ; } return fileAccess . folderExists ( path ) ; } public clear ( ) { return new Promise ( ( resolve , reject ) => { let hasError = false ; const onError = function ( error ) { hasError = true ; reject ( error ) ; } ; this . clearSync ( onError ) ; if ( ! hasError ) { resolve ( true ) ; } } ) ; } public clearSync ( onError ? ) { getFileAccess ( ) . emptyFolder ( this . path , onError ) ; } get isKnown ( ) : boolean { return this . _isKnown ; } public getFile ( name ) { const fileAccess = getFileAccess ( ) ; const path = fileAccess . joinPath ( this . path , name ) ; const onError = function ( error ) { throw error ; } ; const fileInfo = fileAccess . getFile ( path , onError ) ; if ( ! fileInfo ) { return undefined ; } return createFile ( fileInfo ) ; } public getFolder ( name ) { const fileAccess = getFileAccess ( ) ; const path = fileAccess . joinPath ( this . path , name ) ; const onError = function ( error ) { throw error ; } ; const folderInfo = fileAccess . getFolder ( path , onError ) ; if ( ! folderInfo ) { return undefined ; } return createFolder ( folderInfo ) ; } public getEntities ( ) { return new Promise ( ( resolve , reject ) => { let hasError = false ; const localError = function ( error ) { hasError = true ; reject ( error ) ; } ; const entities = this . getEntitiesSync ( localError ) ; if ( ! hasError ) { resolve ( entities ) ; } } ) ; } public getEntitiesSync ( onError ? ) { const fileInfos = getFileAccess ( ) . getEntities ( this . path , onError ) ; if ( ! fileInfos ) { return null ; } const entities = new Array < FileSystemEntity > ( ) ; for ( let i = 0 ; i < fileInfos . length ; i ++ ) { if ( fileInfos [ i ] . extension ) { entities . push ( createFile ( fileInfos [ i ] ) ) ; } else { entities . push ( createFolder ( fileInfos [ i ] ) ) ; } } return entities ; } public eachEntity ( onEntity ) { if ( ! onEntity ) { return ; } const onSuccess = function ( fileInfo ) : boolean { let entity ; if ( fileInfo . extension ) { entity = createFile ( fileInfo ) ; } else { entity = createFolder ( fileInfo ) ; } return onEntity ( entity ) ; } ; const onError = function ( error ) { throw error ; } ; getFileAccess ( ) . eachEntity ( this . path , onSuccess , onError ) ; } } export namespace knownFolders { let _documents ; let _temp ; let _app ; export function documents ( ) { if ( ! _documents ) { const path = getFileAccess ( ) . getDocumentsFolderPath ( ) ; _documents = new Folder ( ) ; _documents . _path = path ; _documents . _isKnown = true ; } return _documents ; } export function temp ( ) { if ( ! _temp ) { const path = getFileAccess ( ) . getTempFolderPath ( ) ; _temp = new Folder ( ) ; _temp . _path = path ; _temp . _isKnown = true ; } return _temp ; } export function currentApp ( ) { if ( ! _app ) { const path = getFileAccess ( ) . getCurrentAppPath ( ) ; _app = new Folder ( ) ; _app . _path = path ; _app . _isKnown = true ; } return _app ; } export namespace ios { function _checkPlatform ( knownFolderName ) { if ( ! global . isIOS ) { throw new Error ( `The "${ knownFolderName }" known folder is available on iOS only!` ) ; } } let _library ; export function library ( ) { _checkPlatform ( 'library' ) ; if ( ! _library ) { const existingFolderInfo = getExistingFolderInfo ( NSSearchPathDirectory . LibraryDirectory ) ; if ( existingFolderInfo ) { _library = existingFolderInfo . folder ; _library . _path = existingFolderInfo . path ; _library . _isKnown = true ; } } return _library ; } let _developer ; export function developer ( ) { _checkPlatform ( 'developer' ) ; if ( ! _developer ) { const existingFolderInfo = getExistingFolderInfo ( NSSearchPathDirectory . DeveloperDirectory ) ; if ( existingFolderInfo ) { _developer = existingFolderInfo . folder ; _developer . _path = existingFolderInfo . path ; _developer . _isKnown = true ; } } return _developer ; } let _desktop ; export function desktop ( ) { _checkPlatform ( 'desktop' ) ; if ( ! _desktop ) { const existingFolderInfo = getExistingFolderInfo ( NSSearchPathDirectory . DesktopDirectory ) ; if ( existingFolderInfo ) { _desktop = existingFolderInfo . folder ; _desktop . _path = existingFolderInfo . path ; _desktop . _isKnown = true ; } } return _desktop ; } let _downloads ; export function downloads ( ) { _checkPlatform ( 'downloads' ) ; if ( ! _downloads ) { const existingFolderInfo = getExistingFolderInfo ( NSSearchPathDirectory . DownloadsDirectory ) ; if ( existingFolderInfo ) { _downloads = existingFolderInfo . folder ; _downloads . _path = existingFolderInfo . path ; _downloads . _isKnown = true ; } } return _downloads ; } let _movies ; export function movies ( ) { _checkPlatform ( 'movies' ) ; if ( ! _movies ) { const existingFolderInfo = getExistingFolderInfo ( NSSearchPathDirectory . MoviesDirectory ) ; if ( existingFolderInfo ) { _movies = existingFolderInfo . folder ; _movies . _path = existingFolderInfo . path ; _movies . _isKnown = true ; } } return _movies ; } let _music ; export function music ( ) { _checkPlatform ( 'music' ) ; if ( ! _music ) { const existingFolderInfo = getExistingFolderInfo ( NSSearchPathDirectory . MusicDirectory ) ; if ( existingFolderInfo ) { _music = existingFolderInfo . folder ; _music . _path = existingFolderInfo . path ; _music . _isKnown = true ; } } return _music ; } let _pictures ; export function pictures ( ) { _checkPlatform ( 'pictures' ) ; if ( ! _pictures ) { const existingFolderInfo = getExistingFolderInfo ( NSSearchPathDirectory . PicturesDirectory ) ; if ( existingFolderInfo ) { _pictures = existingFolderInfo . folder ; _pictures . _path = existingFolderInfo . path ; _pictures . _isKnown = true ; } } return _pictures ; } let _sharedPublic ; export function sharedPublic ( ) { _checkPlatform ( 'sharedPublic' ) ; if ( ! _sharedPublic ) { const existingFolderInfo = getExistingFolderInfo ( NSSearchPathDirectory . SharedPublicDirectory ) ; if ( existingFolderInfo ) { _sharedPublic = existingFolderInfo . folder ; _sharedPublic . _path = existingFolderInfo . path ; _sharedPublic . _isKnown = true ; } } return _sharedPublic ; } function getExistingFolderInfo ( pathDirectory ) { const fileAccess = < any > getFileAccess ( ) ; const folderPath = fileAccess . getKnownPath ( pathDirectory ) ; const folderInfo = fileAccess . getExistingFolder ( folderPath ) ; if ( folderInfo ) { return { folder : createFolder ( folderInfo ) , path : folderPath , } ; } return undefined ; } } } export namespace path { export function normalize ( path ) { return getFileAccess ( ) . normalizePath ( path ) ; } export function join ( ... paths ) { const fileAccess = getFileAccess ( ) ; return fileAccess . joinPaths ( paths ) ; } export const separator = getFileAccess ( ) . getPathSeparator ( ) ; }