2017-03-20 16:38:14 -04:00
import { Injectable } from '@angular/core' ;
2017-04-27 00:36:12 -04:00
import { CordovaProperty , Plugin , CordovaCheck , IonicNativePlugin } from '@ionic-native/core' ;
2016-08-31 18:02:15 -03:00
2016-08-11 07:21:02 -04:00
declare var window : any ;
declare var cordova : any ;
/** This interface represents a file system. */
export interface FileSystem {
/* The name of the file system, unique across the list of exposed file systems. */
name : string ;
/** The root directory of the file system. */
root : DirectoryEntry ;
}
/**
* An abstract interface representing entries in a file system,
* each of which may be a File or DirectoryEntry.
*/
export interface Entry {
/** Entry is a file. */
isFile : boolean ;
/** Entry is a directory. */
isDirectory : boolean ;
/** The name of the entry, excluding the path leading to it. */
name : string ;
/** The full absolute path from the root to the entry. */
fullPath : string ;
/** The file system on which the entry resides. */
2016-11-24 05:28:53 -05:00
filesystem : FileSystem ;
2016-08-11 07:21:02 -04:00
nativeURL : string ;
/**
* Look up metadata about this entry.
* @param successCallback A callback that is called with the time of the last modification.
* @param errorCallback A callback that is called when errors happen.
*/
getMetadata ( successCallback : ( metadata : Metadata ) = > void ,
errorCallback ? : ( error : FileError ) = > void ) : void ;
/**
* Move an entry to a different location on the file system. It is an error to try to:
* move a directory inside itself or to any child at any depth;move an entry into its parent if a name different from its current one isn't provided;
* move a file to a path occupied by a directory;
* move a directory to a path occupied by a file;
* move any element to a path occupied by a directory which is not empty.
* A move of a file on top of an existing file must attempt to delete and replace that file.
* A move of a directory on top of an existing empty directory must attempt to delete and replace that directory.
* @param parent The directory to which to move the entry.
* @param newName The new name of the entry. Defaults to the Entry's current name if unspecified.
* @param successCallback A callback that is called with the Entry for the new location.
* @param errorCallback A callback that is called when errors happen.
*/
moveTo ( parent : DirectoryEntry ,
newName? : string ,
successCallback ? : ( entry : Entry ) = > void ,
errorCallback ? : ( error : FileError ) = > void ) : void ;
/**
* Copy an entry to a different location on the file system. It is an error to try to:
* copy a directory inside itself or to any child at any depth;
* copy an entry into its parent if a name different from its current one isn't provided;
* copy a file to a path occupied by a directory;
* copy a directory to a path occupied by a file;
* copy any element to a path occupied by a directory which is not empty.
* A copy of a file on top of an existing file must attempt to delete and replace that file.
* A copy of a directory on top of an existing empty directory must attempt to delete and replace that directory.
* Directory copies are always recursive--that is, they copy all contents of the directory.
* @param parent The directory to which to move the entry.
* @param newName The new name of the entry. Defaults to the Entry's current name if unspecified.
* @param successCallback A callback that is called with the Entry for the new object.
* @param errorCallback A callback that is called when errors happen.
*/
copyTo ( parent : DirectoryEntry ,
newName? : string ,
successCallback ? : ( entry : Entry ) = > void ,
errorCallback ? : ( error : FileError ) = > void ) : void ;
/**
* Returns a URL that can be used as the src attribute of a <video> or <audio> tag.
* If that is not possible, construct a cdvfile:// URL.
* @return string URL
*/
toURL ( ) : string ;
/**
* Return a URL that can be passed across the bridge to identify this entry.
* @return string URL that can be passed across the bridge to identify this entry
*/
toInternalURL ( ) : string ;
/**
* Deletes a file or directory. It is an error to attempt to delete a directory that is not empty. It is an error to attempt to delete the root directory of a filesystem.
* @param successCallback A callback that is called on success.
* @param errorCallback A callback that is called when errors happen.
*/
remove ( successCallback : ( ) = > void ,
errorCallback ? : ( error : FileError ) = > void ) : void ;
/**
* Look up the parent DirectoryEntry containing this Entry. If this Entry is the root of its filesystem, its parent is itself.
* @param successCallback A callback that is called with the time of the last modification.
* @param errorCallback A callback that is called when errors happen.
*/
getParent ( successCallback : ( entry : Entry ) = > void ,
errorCallback ? : ( error : FileError ) = > void ) : void ;
}
/** This interface supplies information about the state of a file or directory. */
export interface Metadata {
/** This is the time at which the file or directory was last modified. */
modificationTime : Date ;
/** The size of the file, in bytes. This must return 0 for directories. */
size : number ;
}
/** This interface represents a directory on a file system. */
export interface DirectoryEntry extends Entry {
/**
* Creates a new DirectoryReader to read Entries from this Directory.
*/
createReader ( ) : DirectoryReader ;
/**
* Creates or looks up a file.
* @param path Either an absolute path or a relative path from this DirectoryEntry
* to the file to be looked up or created.
* It is an error to attempt to create a file whose immediate parent does not yet exist.
* @param options If create and exclusive are both true, and the path already exists, getFile must fail.
* If create is true, the path doesn't exist, and no other error occurs, getFile must create it as a zero-length file and return a corresponding FileEntry.
* If create is not true and the path doesn't exist, getFile must fail.
* If create is not true and the path exists, but is a directory, getFile must fail.
* Otherwise, if no other error occurs, getFile must return a FileEntry corresponding to path.
* @param successCallback A callback that is called to return the File selected or created.
* @param errorCallback A callback that is called when errors happen.
*/
getFile ( path : string , options? : Flags ,
successCallback ? : ( entry : FileEntry ) = > void ,
errorCallback ? : ( error : FileError ) = > void ) : void ;
/**
* Creates or looks up a directory.
* @param path Either an absolute path or a relative path from this DirectoryEntry
* to the directory to be looked up or created.
* It is an error to attempt to create a directory whose immediate parent does not yet exist.
* @param options If create and exclusive are both true and the path already exists, getDirectory must fail.
* If create is true, the path doesn't exist, and no other error occurs, getDirectory must create and return a corresponding DirectoryEntry.
* If create is not true and the path doesn't exist, getDirectory must fail.
* If create is not true and the path exists, but is a file, getDirectory must fail.
* Otherwise, if no other error occurs, getDirectory must return a DirectoryEntry corresponding to path.
* @param successCallback A callback that is called to return the Directory selected or created.
* @param errorCallback A callback that is called when errors happen.
*/
getDirectory ( path : string , options? : Flags ,
successCallback ? : ( entry : DirectoryEntry ) = > void ,
errorCallback ? : ( error : FileError ) = > void ) : void ;
/**
* Deletes a directory and all of its contents, if any. In the event of an error (e.g. trying
* to delete a directory that contains a file that cannot be removed), some of the contents
* of the directory may be deleted. It is an error to attempt to delete the root directory of a filesystem.
* @param successCallback A callback that is called on success.
* @param errorCallback A callback that is called when errors happen.
*/
removeRecursively ( successCallback : ( ) = > void ,
errorCallback ? : ( error : FileError ) = > void ) : void ;
}
export interface RemoveResult {
success : boolean ;
fileRemoved : Entry ;
}
/**
* This dictionary is used to supply arguments to methods
* that look up or create files or directories.
*/
export interface Flags {
/** Used to indicate that the user wants to create a file or directory if it was not previously there. */
create? : boolean ;
/** By itself, exclusive must have no effect. Used with create, it must cause getFile and getDirectory to fail if the target path already exists. */
exclusive? : boolean ;
}
export interface WriteOptions {
replace? : boolean ;
append? : boolean ;
truncate? : number ; // if present, number of bytes to truncate file to before writing
}
/**
* This interface lets a user list files and directories in a directory. If there are
* no additions to or deletions from a directory between the first and last call to
* readEntries, and no errors occur, then:
* A series of calls to readEntries must return each entry in the directory exactly once.
* Once all entries have been returned, the next call to readEntries must produce an empty array.
* If not all entries have been returned, the array produced by readEntries must not be empty.
* The entries produced by readEntries must not include the directory itself ["."] or its parent [".."].
*/
export interface DirectoryReader {
/**
* Read the next block of entries from this directory.
* @param successCallback Called once per successful call to readEntries to deliver the next
* previously-unreported set of Entries in the associated Directory.
* If all Entries have already been returned from previous invocations
* of readEntries, successCallback must be called with a zero-length array as an argument.
* @param errorCallback A callback indicating that there was an error reading from the Directory.
*/
readEntries ( successCallback : ( entries : Entry [ ] ) = > void ,
errorCallback ? : ( error : FileError ) = > void ) : void ;
}
/** This interface represents a file on a file system. */
export interface FileEntry extends Entry {
/**
* Creates a new FileWriter associated with the file that this FileEntry represents.
* @param successCallback A callback that is called with the new FileWriter.
* @param errorCallback A callback that is called when errors happen.
*/
createWriter ( successCallback : ( writer : FileWriter ) = > void ,
errorCallback ? : ( error : FileError ) = > void ) : void ;
/**
* Returns a File that represents the current state of the file that this FileEntry represents.
* @param successCallback A callback that is called with the File.
* @param errorCallback A callback that is called when errors happen.
*/
file ( successCallback : ( file : File ) = > void ,
errorCallback ? : ( error : FileError ) = > void ) : void ;
}
/**
* This interface provides methods to monitor the asynchronous writing of blobs
* to disk using progress events and event handler attributes.
*/
export interface FileSaver extends EventTarget {
/** Terminate file operation */
abort ( ) : void ;
/**
* The FileSaver object can be in one of 3 states. The readyState attribute, on getting,
* must return the current state, which must be one of the following values:
* INIT
* WRITING
* DONE
*/
readyState : number ;
/** Handler for writestart events. */
onwritestart : ( event : ProgressEvent ) = > void ;
/** Handler for progress events. */
onprogress : ( event : ProgressEvent ) = > void ;
/** Handler for write events. */
onwrite : ( event : ProgressEvent ) = > void ;
/** Handler for abort events. */
onabort : ( event : ProgressEvent ) = > void ;
/** Handler for error events. */
onerror : ( event : ProgressEvent ) = > void ;
/** Handler for writeend events. */
onwriteend : ( event : ProgressEvent ) = > void ;
/** The last error that occurred on the FileSaver. */
error : Error ;
}
/**
* This interface expands on the FileSaver interface to allow for multiple write
* actions, rather than just saving a single Blob.
*/
export interface FileWriter extends FileSaver {
/**
* The byte offset at which the next write to the file will occur. This always less or equal than length.
* A newly-created FileWriter will have position set to 0.
*/
position : number ;
/**
* The length of the file. If the user does not have read access to the file,
* this will be the highest byte offset at which the user has written.
*/
length : number ;
/**
* Write the supplied data to the file at position.
* @param {Blob} data The blob to write.
*/
2017-02-23 20:56:26 -03:00
write ( data : ArrayBuffer | Blob | string ) : void ;
2016-08-11 07:21:02 -04:00
/**
* The file position at which the next write will occur.
* @param offset If nonnegative, an absolute byte offset into the file.
* If negative, an offset back from the end of the file.
*/
seek ( offset : number ) : void ;
/**
* Changes the length of the file to that specified. If shortening the file, data beyond the new length
* will be discarded. If extending the file, the existing data will be zero-padded up to the new length.
* @param size The size to which the length of the file is to be adjusted, measured in bytes.
*/
truncate ( size : number ) : void ;
}
2016-07-08 00:59:54 +02:00
2016-08-11 07:21:02 -04:00
/* FileWriter states */
2017-02-23 09:54:57 +01:00
export declare var FileWriter : {
2016-08-11 07:21:02 -04:00
INIT : number ;
WRITING : number ;
DONE : number
} ;
export interface FileReader {
readyState : number ; // see constants in var declaration below
error : Error ;
result : string | ArrayBuffer ; // type depends on readAsXXX() call type
onloadstart : ( evt : ProgressEvent ) = > void ;
onprogress : ( evt : ProgressEvent ) = > void ;
onload : ( evt : ProgressEvent ) = > void ;
onerror : ( evt : ProgressEvent ) = > void ;
onloadend : ( evt : ProgressEvent ) = > void ;
onabort : ( evt : ProgressEvent ) = > void ;
abort ( ) : void ;
2016-10-11 20:48:53 -04:00
readAsText ( fe : File | Blob , encoding? : string ) : void ;
readAsDataURL ( fe : File | Blob ) : void ;
readAsBinaryString ( fe : File | Blob ) : void ;
readAsArrayBuffer ( fe : File | Blob ) : void ;
2016-08-11 07:21:02 -04:00
}
2016-03-18 23:27:20 +01:00
2017-02-23 09:54:57 +01:00
export declare var FileReader : {
2016-08-11 07:21:02 -04:00
EMPTY : number ;
LOADING : number ;
DONE : number ;
new ( ) : FileReader ;
} ;
export interface FileError {
/** Error code */
code : number ;
message : string ;
}
2017-02-23 09:54:57 +01:00
export declare var FileError : {
2016-08-11 07:21:02 -04:00
new ( code : number ) : FileError ;
NOT_FOUND_ERR : number ;
SECURITY_ERR : number ;
ABORT_ERR : number ;
NOT_READABLE_ERR : number ;
ENCODING_ERR : number ;
NO_MODIFICATION_ALLOWED_ERR : number ;
INVALID_STATE_ERR : number ;
SYNTAX_ERR : number ;
INVALID_MODIFICATION_ERR : number ;
QUOTA_EXCEEDED_ERR : number ;
TYPE_MISMATCH_ERR : number ;
PATH_EXISTS_ERR : number ;
} ;
2016-03-18 23:27:20 +01:00
2016-10-11 20:44:27 -04:00
2016-03-18 23:27:20 +01:00
/**
* @name File
* @description
* This plugin implements a File API allowing read/write access to files residing on the device.
*
2016-08-17 00:11:10 -07:00
* The File class implements static convenience functions to access files and directories.
*
* Example:
* ```
2017-03-20 16:38:14 -04:00
* import { File } from '@ionic-native/file';
2016-08-17 00:11:10 -07:00
*
2017-03-20 16:38:14 -04:00
* constructor(private file: File) { }
*
* ...
*
* this.file.checkDir(this.file.dataDirectory, 'mydir').then(_ => console.log('Directory exists')).catch(err => console.log('Directory doesnt exist'));
2017-03-01 20:26:55 -05:00
*
2016-08-17 00:11:10 -07:00
* ```
*
2016-03-18 23:27:20 +01:00
* This plugin is based on several specs, including : The HTML5 File API http://www.w3.org/TR/FileAPI/
* The (now-defunct) Directories and System extensions Latest: http://www.w3.org/TR/2012/WD-file-system-api-20120417/
* Although most of the plugin code was written when an earlier spec was current: http://www.w3.org/TR/2011/WD-file-system-api-20110419/
* It also implements the FileWriter spec : http://dev.w3.org/2009/dap/file-system/file-writer.html
*/
2016-10-27 07:24:19 -04:00
@Plugin ( {
2016-10-27 12:48:50 -05:00
pluginName : 'File' ,
2016-10-27 07:24:19 -04:00
plugin : 'cordova-plugin-file' ,
pluginRef : 'cordova.file' ,
2017-03-28 08:24:04 -04:00
repo : 'https://github.com/apache/cordova-plugin-file' ,
platforms : [ 'Android' , 'BlackBerry 10' , 'Browser' , 'Firefox OS' , 'iOS' , 'OS X' , 'Ubuntu' , 'Windows' , 'Windows Phone' ]
2016-10-27 07:24:19 -04:00
} )
2017-03-20 16:38:14 -04:00
@Injectable ( )
2017-04-27 00:36:12 -04:00
export class File extends IonicNativePlugin {
2017-03-01 20:26:55 -05:00
/**
* Read-only directory where the application is installed.
*/
@CordovaProperty
2017-03-20 16:38:14 -04:00
applicationDirectory : string ;
2017-03-01 20:26:55 -05:00
/**
* Read-only directory where the application is installed.
*/
@CordovaProperty
2017-03-20 16:38:14 -04:00
applicationStorageDirectory : string ;
2017-03-01 20:26:55 -05:00
/**
* Where to put app-specific data files.
*/
@CordovaProperty
2017-03-20 16:38:14 -04:00
dataDirectory : string ;
2017-03-01 20:26:55 -05:00
/**
* Cached files that should survive app restarts.
* Apps should not rely on the OS to delete files in here.
*/
@CordovaProperty
2017-03-20 16:38:14 -04:00
cacheDirectory : string ;
2017-03-01 20:26:55 -05:00
/**
* Android: the application space on external storage.
*/
@CordovaProperty
2017-03-20 16:38:14 -04:00
externalApplicationStorageDirectory : string ;
2017-03-01 20:26:55 -05:00
/**
* Android: Where to put app-specific data files on external storage.
*/
@CordovaProperty
2017-03-20 16:38:14 -04:00
externalDataDirectory : string ;
2017-03-01 20:26:55 -05:00
/**
* Android: the application cache on external storage.
*/
@CordovaProperty
2017-03-20 16:38:14 -04:00
externalCacheDirectory : string ;
2017-03-01 20:26:55 -05:00
/**
* Android: the external storage (SD card) root.
*/
@CordovaProperty
2017-03-20 16:38:14 -04:00
externalRootDirectory : string ;
2017-03-01 20:26:55 -05:00
/**
* iOS: Temp directory that the OS can clear at will.
*/
@CordovaProperty
2017-03-20 16:38:14 -04:00
tempDirectory : string ;
2017-03-01 20:26:55 -05:00
/**
* iOS: Holds app-specific files that should be synced (e.g. to iCloud).
*/
@CordovaProperty
2017-03-20 16:38:14 -04:00
syncedDataDirectory : string ;
2017-03-01 20:26:55 -05:00
/**
* iOS: Files private to the app, but that are meaningful to other applications (e.g. Office files)
*/
@CordovaProperty
2017-03-20 16:38:14 -04:00
documentsDirectory : string ;
2017-03-01 20:26:55 -05:00
/**
* BlackBerry10: Files globally available to all apps
*/
@CordovaProperty
2017-03-20 16:38:14 -04:00
sharedDirectory : string ;
2017-03-01 20:26:55 -05:00
2017-03-20 16:38:14 -04:00
cordovaFileError : { } = {
2016-03-18 23:27:20 +01:00
1 : 'NOT_FOUND_ERR' ,
2 : 'SECURITY_ERR' ,
3 : 'ABORT_ERR' ,
4 : 'NOT_READABLE_ERR' ,
5 : 'ENCODING_ERR' ,
6 : 'NO_MODIFICATION_ALLOWED_ERR' ,
7 : 'INVALID_STATE_ERR' ,
8 : 'SYNTAX_ERR' ,
9 : 'INVALID_MODIFICATION_ERR' ,
10 : 'QUOTA_EXCEEDED_ERR' ,
11 : 'TYPE_MISMATCH_ERR' ,
2016-08-11 07:21:02 -04:00
12 : 'PATH_EXISTS_ERR' ,
13 : 'WRONG_ENTRY_TYPE' ,
14 : 'DIR_READ_ERR' ,
2016-03-18 23:27:20 +01:00
} ;
2016-10-11 20:39:26 -04:00
/**
2017-01-18 16:30:38 +01:00
* Get free disk space in Bytes
* @returns {Promise<number>} Returns a promise that resolves with the remaining free disk space in Bytes
2016-10-11 20:39:26 -04:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
getFreeDiskSpace ( ) : Promise < number > {
2016-10-11 20:44:27 -04:00
return new Promise < any > ( ( resolve , reject ) = > {
2017-03-20 16:38:14 -04:00
cordova . exec ( resolve , reject , 'File' , 'getFreeDiskSpace' , [ ] ) ;
2016-10-11 20:44:27 -04:00
} ) ;
2016-08-11 07:21:02 -04:00
}
2016-03-18 23:27:20 +01:00
2016-03-21 13:19:27 +01:00
/**
* Check if a directory exists in a certain path, directory.
*
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} dir Name of directory to check
2017-03-04 08:11:41 -05:00
* @returns {Promise<boolean>} Returns a Promise that resolves to true if the directory exists or rejects with an error.
2016-03-21 13:19:27 +01:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
checkDir ( path : string , dir : string ) : Promise < boolean > {
2016-03-18 23:27:20 +01:00
if ( ( /^\// . test ( dir ) ) ) {
2016-08-11 07:21:02 -04:00
let err = new FileError ( 5 ) ;
err . message = 'directory cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-04-14 12:48:04 -04:00
}
2016-05-12 22:55:06 -04:00
2016-08-11 07:21:02 -04:00
let fullpath = path + dir ;
2017-03-20 16:38:14 -04:00
return this . resolveDirectoryUrl ( fullpath )
2016-08-11 07:21:02 -04:00
. then ( ( ) = > {
return true ;
2016-03-18 23:27:20 +01:00
} ) ;
}
2016-03-21 13:19:27 +01:00
/**
* Creates a new directory in the specific path.
* The replace boolean value determines whether to replace an existing directory with the same name.
* If an existing directory exists and the replace value is false, the promise will fail and return an error.
*
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} dirName Name of directory to create
* @param {boolean} replace If true, replaces file with same name. If false returns error
2017-03-04 08:11:41 -05:00
* @returns {Promise<DirectoryEntry>} Returns a Promise that resolves with a DirectoryEntry or rejects with an error.
2016-03-21 13:19:27 +01:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
createDir ( path : string , dirName : string , replace : boolean ) : Promise < DirectoryEntry > {
2016-03-18 23:27:20 +01:00
if ( ( /^\// . test ( dirName ) ) ) {
2016-08-11 07:21:02 -04:00
let err = new FileError ( 5 ) ;
err . message = 'directory cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-03-18 23:27:20 +01:00
}
2016-08-11 07:21:02 -04:00
let options : Flags = {
create : true
2016-03-18 23:27:20 +01:00
} ;
2016-09-06 22:24:34 -04:00
if ( ! replace ) {
2016-08-11 07:21:02 -04:00
options . exclusive = true ;
2016-03-18 23:27:20 +01:00
}
2017-03-20 16:38:14 -04:00
return this . resolveDirectoryUrl ( path )
2016-08-11 07:21:02 -04:00
. then ( ( fse ) = > {
2017-03-20 16:38:14 -04:00
return this . getDirectory ( fse , dirName , options ) ;
2016-08-11 07:21:02 -04:00
} ) ;
2016-03-18 23:27:20 +01:00
}
2016-03-21 13:19:27 +01:00
/**
2016-05-10 17:49:21 -05:00
* Remove a directory at a given path.
2016-03-21 13:19:27 +01:00
*
* @param {string} path The path to the directory
* @param {string} dirName The directory name
2017-03-04 08:11:41 -05:00
* @returns {Promise<RemoveResult>} Returns a Promise that resolves to a RemoveResult or rejects with an error.
2016-03-21 13:19:27 +01:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
removeDir ( path : string , dirName : string ) : Promise < RemoveResult > {
2016-03-18 23:27:20 +01:00
if ( ( /^\// . test ( dirName ) ) ) {
2016-08-11 07:21:02 -04:00
let err = new FileError ( 5 ) ;
err . message = 'directory cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-03-18 23:27:20 +01:00
}
2017-03-20 16:38:14 -04:00
return this . resolveDirectoryUrl ( path )
2016-08-11 07:21:02 -04:00
. then ( ( fse ) = > {
2017-03-20 16:38:14 -04:00
return this . getDirectory ( fse , dirName , { create : false } ) ;
2016-08-11 07:21:02 -04:00
} )
. then ( ( de ) = > {
2017-03-20 16:38:14 -04:00
return this . remove ( de ) ;
2016-03-18 23:27:20 +01:00
} ) ;
}
2016-03-21 13:19:27 +01:00
/**
2016-05-10 17:49:21 -05:00
* Move a directory to a given path.
2016-03-21 13:19:27 +01:00
*
* @param {string} path The source path to the directory
* @param {string} dirName The source directory name
* @param {string} newPath The destionation path to the directory
* @param {string} newDirName The destination directory name
2017-03-04 08:11:41 -05:00
* @returns {Promise<DirectoryEntry|Entry>} Returns a Promise that resolves to the new DirectoryEntry object or rejects with an error.
2016-03-21 13:19:27 +01:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
moveDir ( path : string , dirName : string , newPath : string , newDirName : string ) : Promise < DirectoryEntry | Entry > {
2016-03-21 13:19:27 +01:00
newDirName = newDirName || dirName ;
if ( ( /^\// . test ( newDirName ) ) ) {
2016-08-11 07:21:02 -04:00
let err = new FileError ( 5 ) ;
err . message = 'directory cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-03-21 13:19:27 +01:00
}
2016-08-11 07:21:02 -04:00
return this . resolveDirectoryUrl ( path )
. then ( ( fse ) = > {
return this . getDirectory ( fse , dirName , { create : false } ) ;
} )
. then ( ( srcde ) = > {
return this . resolveDirectoryUrl ( newPath )
. then ( ( deste ) = > {
2017-03-20 16:38:14 -04:00
return this . move ( srcde , deste , newDirName ) ;
2016-03-21 13:19:27 +01:00
} ) ;
} ) ;
}
2016-03-18 23:27:20 +01:00
2016-03-21 13:19:27 +01:00
/**
* Copy a directory in various methods. If destination directory exists, will fail to copy.
*
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} dirName Name of directory to copy
* @param {string} newPath Base FileSystem of new location
* @param {string} newDirName New name of directory to copy to (leave blank to remain the same)
2017-03-04 08:11:41 -05:00
* @returns {Promise<Entry>} Returns a Promise that resolves to the new Entry object or rejects with an error.
2016-03-21 13:19:27 +01:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
copyDir ( path : string , dirName : string , newPath : string , newDirName : string ) : Promise < Entry > {
2016-03-21 13:19:27 +01:00
if ( ( /^\// . test ( newDirName ) ) ) {
2016-08-11 07:21:02 -04:00
let err = new FileError ( 5 ) ;
err . message = 'directory cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-03-21 13:19:27 +01:00
}
2016-08-11 07:21:02 -04:00
return this . resolveDirectoryUrl ( path )
. then ( ( fse ) = > {
return this . getDirectory ( fse , dirName , { create : false } ) ;
} )
. then ( ( srcde ) = > {
return this . resolveDirectoryUrl ( newPath )
. then ( ( deste ) = > {
2017-03-20 16:38:14 -04:00
return this . copy ( srcde , deste , newDirName ) ;
2016-03-21 13:19:27 +01:00
} ) ;
} ) ;
}
2016-03-18 23:27:20 +01:00
2016-03-21 13:19:27 +01:00
/**
2016-05-10 17:49:21 -05:00
* List files and directory from a given path.
2016-03-21 13:19:27 +01:00
*
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} dirName Name of directory
2016-11-29 16:40:50 -06:00
* @returns {Promise<Entry[]>} Returns a Promise that resolves to an array of Entry objects or rejects with an error.
2016-03-21 13:19:27 +01:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
listDir ( path : string , dirName : string ) : Promise < Entry [ ] > {
2016-03-18 23:27:20 +01:00
if ( ( /^\// . test ( dirName ) ) ) {
2016-08-11 07:21:02 -04:00
let err = new FileError ( 5 ) ;
err . message = 'directory cannot start with \/' ;
return Promise . reject < Entry [ ] > ( err ) ;
2016-03-18 23:27:20 +01:00
}
2017-03-20 16:38:14 -04:00
return this . resolveDirectoryUrl ( path )
2016-08-11 07:21:02 -04:00
. then ( ( fse ) = > {
2017-03-20 16:38:14 -04:00
return this . getDirectory ( fse , dirName , { create : false , exclusive : false } ) ;
2016-08-11 07:21:02 -04:00
} )
. then ( ( de ) = > {
let reader = de . createReader ( ) ;
2017-03-20 16:38:14 -04:00
return this . readEntries ( reader ) ;
2016-03-18 23:27:20 +01:00
} ) ;
}
2016-03-21 13:19:27 +01:00
/**
* Removes all files and the directory from a desired location.
*
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} dirName Name of directory
2016-11-29 16:40:50 -06:00
* @returns {Promise<RemoveResult>} Returns a Promise that resolves with a RemoveResult or rejects with an error.
2016-03-21 13:19:27 +01:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
removeRecursively ( path : string , dirName : string ) : Promise < RemoveResult > {
2016-03-18 23:27:20 +01:00
if ( ( /^\// . test ( dirName ) ) ) {
2016-08-11 07:21:02 -04:00
let err = new FileError ( 5 ) ;
err . message = 'directory cannot start with \/' ;
return Promise . reject < RemoveResult > ( err ) ;
2016-03-18 23:27:20 +01:00
}
2017-03-20 16:38:14 -04:00
return this . resolveDirectoryUrl ( path )
2016-08-11 07:21:02 -04:00
. then ( ( fse ) = > {
2017-03-20 16:38:14 -04:00
return this . getDirectory ( fse , dirName , { create : false } ) ;
2016-08-11 07:21:02 -04:00
} )
. then ( ( de ) = > {
2017-03-20 16:38:14 -04:00
return this . rimraf ( de ) ;
2016-03-18 23:27:20 +01:00
} ) ;
}
2016-03-21 13:19:27 +01:00
/**
* Check if a file exists in a certain path, directory.
*
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} file Name of file to check
2017-03-04 08:11:41 -05:00
* @returns {Promise<boolean>} Returns a Promise that resolves with a boolean or rejects with an error.
2016-03-21 13:19:27 +01:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
checkFile ( path : string , file : string ) : Promise < boolean > {
2016-03-18 23:27:20 +01:00
if ( ( /^\// . test ( file ) ) ) {
2016-08-11 07:21:02 -04:00
let err = new FileError ( 5 ) ;
err . message = 'file cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-03-18 23:27:20 +01:00
}
2017-03-20 16:38:14 -04:00
return this . resolveLocalFilesystemUrl ( path + file )
2016-08-11 07:21:02 -04:00
. then ( ( fse ) = > {
if ( fse . isFile ) {
return true ;
2016-03-18 23:27:20 +01:00
} else {
2016-08-11 07:21:02 -04:00
let err = new FileError ( 13 ) ;
err . message = 'input is not a file' ;
return Promise . reject < boolean > ( err ) ;
2016-03-18 23:27:20 +01:00
}
} ) ;
}
2016-03-21 13:19:27 +01:00
/**
* Creates a new file in the specific path.
* The replace boolean value determines whether to replace an existing file with the same name.
* If an existing file exists and the replace value is false, the promise will fail and return an error.
*
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} fileName Name of file to create
* @param {boolean} replace If true, replaces file with same name. If false returns error
2017-03-04 08:11:41 -05:00
* @returns {Promise<FileEntry>} Returns a Promise that resolves to a FileEntry or rejects with an error.
2016-03-21 13:19:27 +01:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
createFile ( path : string , fileName : string , replace : boolean ) : Promise < FileEntry > {
2016-03-18 23:27:20 +01:00
if ( ( /^\// . test ( fileName ) ) ) {
2016-08-11 07:21:02 -04:00
let err = new FileError ( 5 ) ;
err . message = 'file-name cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-03-18 23:27:20 +01:00
}
2016-08-11 07:21:02 -04:00
let options : Flags = {
create : true
2016-03-18 23:27:20 +01:00
} ;
2016-08-19 15:07:32 +02:00
if ( ! replace ) {
2016-08-11 07:21:02 -04:00
options . exclusive = true ;
2016-03-18 23:27:20 +01:00
}
2017-03-20 16:38:14 -04:00
return this . resolveDirectoryUrl ( path )
2016-08-11 07:21:02 -04:00
. then ( ( fse ) = > {
2017-03-20 16:38:14 -04:00
return this . getFile ( fse , fileName , options ) ;
2016-08-11 07:21:02 -04:00
} ) ;
2016-03-18 23:27:20 +01:00
}
2016-03-21 13:19:27 +01:00
/**
* Removes a file from a desired location.
*
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} fileName Name of file to remove
2017-03-04 08:11:41 -05:00
* @returns {Promise<RemoveResult>} Returns a Promise that resolves to a RemoveResult or rejects with an error.
2016-03-21 13:19:27 +01:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
removeFile ( path : string , fileName : string ) : Promise < RemoveResult > {
2016-03-18 23:27:20 +01:00
if ( ( /^\// . test ( fileName ) ) ) {
2016-08-11 07:21:02 -04:00
let err = new FileError ( 5 ) ;
err . message = 'file-name cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-03-18 23:27:20 +01:00
}
2017-03-20 16:38:14 -04:00
return this . resolveDirectoryUrl ( path )
2016-08-11 07:21:02 -04:00
. then ( ( fse ) = > {
2017-03-20 16:38:14 -04:00
return this . getFile ( fse , fileName , { create : false } ) ;
2016-08-11 07:21:02 -04:00
} )
. then ( ( fe ) = > {
2017-03-20 16:38:14 -04:00
return this . remove ( fe ) ;
2016-03-18 23:27:20 +01:00
} ) ;
2016-08-11 07:21:02 -04:00
}
2016-08-17 00:11:10 -07:00
/** Write a new file to the desired location.
*
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} fileName path relative to base path
2016-09-06 22:54:35 -03:00
* @param {string | Blob} text content or blob to write
2016-10-11 20:13:21 -04:00
* @param {WriteOptions} options replace file if set to true. See WriteOptions for more information.
2016-11-29 16:40:50 -06:00
* @returns {Promise<any>} Returns a Promise that resolves to updated file entry or rejects with an error.
2016-08-17 00:11:10 -07:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
writeFile ( path : string , fileName : string ,
2017-02-23 20:56:26 -03:00
text : string | Blob | ArrayBuffer , options : WriteOptions = { } ) : Promise < any > {
2016-08-11 07:21:02 -04:00
if ( ( /^\// . test ( fileName ) ) ) {
2016-11-03 06:16:08 +02:00
const err = new FileError ( 5 ) ;
2016-08-11 07:21:02 -04:00
err . message = 'file-name cannot start with \/' ;
return Promise . reject ( err ) ;
2016-03-18 23:27:20 +01:00
}
2016-11-03 06:16:08 +02:00
const getFileOpts : Flags = {
2016-11-24 05:22:04 -05:00
create : ! options . append ,
exclusive : ! options . replace
2016-10-11 20:10:47 -04:00
} ;
2017-03-20 16:38:14 -04:00
return this . resolveDirectoryUrl ( path )
. then ( ( directoryEntry : DirectoryEntry ) = > {
return this . getFile ( directoryEntry , fileName , getFileOpts ) ;
2016-08-11 07:21:02 -04:00
} )
2017-03-20 16:38:14 -04:00
. then ( ( fileEntry : FileEntry ) = > {
return this . writeFileEntry ( fileEntry , text , options ) ;
2016-11-23 08:23:55 -05:00
} ) ;
2016-11-03 06:16:08 +02:00
}
2016-10-11 20:10:47 -04:00
2016-11-03 06:16:08 +02:00
/** Write content to FileEntry.
*
2017-03-20 16:38:14 -04:00
* @hidden
2016-11-03 06:16:08 +02:00
* @param {FileEntry} fe file entry object
* @param {string | Blob} text content or blob to write
* @param {WriteOptions} options replace file if set to true. See WriteOptions for more information.
* @returns {Promise<FileEntry>} Returns a Promise that resolves to updated file entry or rejects with an error.
*/
2017-03-20 16:38:14 -04:00
private writeFileEntry ( fe : FileEntry , text : string | Blob | ArrayBuffer , options : WriteOptions ) {
return this . createWriter ( fe )
2016-11-03 06:16:08 +02:00
. then ( ( writer ) = > {
2016-10-11 20:13:21 -04:00
if ( options . append ) {
2016-08-11 07:21:02 -04:00
writer . seek ( writer . length ) ;
}
2016-03-18 23:27:20 +01:00
2016-10-11 20:13:21 -04:00
if ( options . truncate ) {
writer . truncate ( options . truncate ) ;
2016-08-11 07:21:02 -04:00
}
2016-03-18 23:27:20 +01:00
2017-03-20 16:38:14 -04:00
return this . write ( writer , text ) ;
2016-11-03 06:16:08 +02:00
} )
. then ( ( ) = > fe ) ;
2016-08-11 07:21:02 -04:00
}
2016-11-03 06:16:08 +02:00
2016-08-17 00:11:10 -07:00
/** Write to an existing file.
*
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} fileName path relative to base path
2016-09-06 22:54:35 -03:00
* @param {string | Blob} text content or blob to write
2016-08-17 00:11:10 -07:00
* @returns {Promise<void>} Returns a Promise that resolves or rejects with an error.
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
writeExistingFile ( path : string , fileName : string , text : string | Blob ) : Promise < void > {
return this . writeFile ( path , fileName , text , { replace : true } ) ;
2016-07-22 11:08:11 -07:00
}
2016-08-17 00:11:10 -07:00
/**
* Read the contents of a file as text.
*
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} file Name of file, relative to path.
2017-03-04 08:11:41 -05:00
* @returns {Promise<string>} Returns a Promise that resolves with the contents of the file as string or rejects with an error.
2016-08-17 00:11:10 -07:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
readAsText ( path : string , file : string ) : Promise < string > {
2016-08-11 07:21:02 -04:00
if ( ( /^\// . test ( file ) ) ) {
let err = new FileError ( 5 ) ;
err . message = 'file-name cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-08-11 07:21:02 -04:00
}
2017-03-20 16:38:14 -04:00
return this . resolveDirectoryUrl ( path )
. then ( ( directoryEntry : DirectoryEntry ) = > {
return this . getFile ( directoryEntry , file , { create : false } ) ;
2016-08-11 07:21:02 -04:00
} )
2017-03-20 16:38:14 -04:00
. then ( ( fileEntry : FileEntry ) = > {
2016-08-11 07:21:02 -04:00
let reader = new FileReader ( ) ;
2016-09-06 23:33:51 -04:00
return new Promise < any > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
reader . onloadend = ( ) = > {
if ( reader . result !== undefined || reader . result !== null ) {
resolve ( reader . result ) ;
} else if ( reader . error !== undefined || reader . error !== null ) {
reject ( reader . error ) ;
} else {
reject ( { code : null , message : 'READER_ONLOADEND_ERR' } ) ;
}
} ;
2017-03-20 16:38:14 -04:00
fileEntry . file ( file = > {
2016-08-26 15:22:59 +02:00
reader . readAsText ( file ) ;
} , error = > {
reject ( error ) ;
2016-08-26 12:33:28 -04:00
} ) ;
2016-08-11 07:21:02 -04:00
2016-04-06 16:36:26 +02:00
} ) ;
} ) ;
2016-08-11 07:21:02 -04:00
}
2016-08-17 00:11:10 -07:00
/**
* Read file and return data as a base64 encoded data url.
* A data url is of the form:
* data:[<mediatype>][;base64],<data>
2016-08-11 07:21:02 -04:00
2016-08-17 00:11:10 -07:00
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} file Name of file, relative to path.
2017-03-04 08:11:41 -05:00
* @returns {Promise<string>} Returns a Promise that resolves with the contents of the file as data URL or rejects with an error.
2016-08-17 00:11:10 -07:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
readAsDataURL ( path : string , file : string ) : Promise < string > {
2016-08-11 07:21:02 -04:00
if ( ( /^\// . test ( file ) ) ) {
let err = new FileError ( 5 ) ;
err . message = 'file-name cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-04-06 16:36:26 +02:00
}
2017-03-20 16:38:14 -04:00
return this . resolveDirectoryUrl ( path )
. then ( ( directoryEntry : DirectoryEntry ) = > {
return this . getFile ( directoryEntry , file , { create : false } ) ;
2016-08-11 07:21:02 -04:00
} )
2017-03-20 16:38:14 -04:00
. then ( ( fileEntry : FileEntry ) = > {
2016-08-11 07:21:02 -04:00
let reader = new FileReader ( ) ;
2016-09-06 23:33:51 -04:00
return new Promise < any > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
reader . onloadend = ( ) = > {
if ( reader . result !== undefined || reader . result !== null ) {
resolve ( reader . result ) ;
} else if ( reader . error !== undefined || reader . error !== null ) {
reject ( reader . error ) ;
} else {
reject ( { code : null , message : 'READER_ONLOADEND_ERR' } ) ;
}
} ;
2016-08-26 15:22:59 +02:00
2017-03-20 16:38:14 -04:00
fileEntry . file ( file = > {
2016-08-26 15:22:59 +02:00
reader . readAsDataURL ( file ) ;
} , error = > {
reject ( error ) ;
2016-08-26 12:33:28 -04:00
} ) ;
2016-08-11 07:21:02 -04:00
} ) ;
} ) ;
2016-04-06 16:36:26 +02:00
}
2016-03-18 23:27:20 +01:00
2016-08-17 00:11:10 -07:00
/**
* Read file and return data as a binary data.
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} file Name of file, relative to path.
2017-03-04 08:11:41 -05:00
* @returns {Promise<string>} Returns a Promise that resolves with the contents of the file as string rejects with an error.
2016-08-17 00:11:10 -07:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
readAsBinaryString ( path : string , file : string ) : Promise < string > {
2016-08-11 07:21:02 -04:00
if ( ( /^\// . test ( file ) ) ) {
let err = new FileError ( 5 ) ;
err . message = 'file-name cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-08-11 07:21:02 -04:00
}
2017-03-20 16:38:14 -04:00
return this . resolveDirectoryUrl ( path )
. then ( ( directoryEntry : DirectoryEntry ) = > {
return this . getFile ( directoryEntry , file , { create : false } ) ;
2016-08-11 07:21:02 -04:00
} )
2017-03-20 16:38:14 -04:00
. then ( ( fileEntry : FileEntry ) = > {
2016-08-11 07:21:02 -04:00
let reader = new FileReader ( ) ;
2016-09-06 23:33:51 -04:00
return new Promise < any > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
reader . onloadend = ( ) = > {
if ( reader . result !== undefined || reader . result !== null ) {
resolve ( reader . result ) ;
} else if ( reader . error !== undefined || reader . error !== null ) {
reject ( reader . error ) ;
} else {
reject ( { code : null , message : 'READER_ONLOADEND_ERR' } ) ;
}
} ;
2017-03-20 16:38:14 -04:00
fileEntry . file ( file = > {
2016-08-26 15:22:59 +02:00
reader . readAsBinaryString ( file ) ;
} , error = > {
reject ( error ) ;
2016-08-26 12:33:28 -04:00
} ) ;
2016-08-26 15:22:59 +02:00
2016-08-11 07:21:02 -04:00
} ) ;
} ) ;
}
2016-03-18 23:27:20 +01:00
2016-08-17 00:11:10 -07:00
/**
* Read file and return data as an ArrayBuffer.
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} file Name of file, relative to path.
2017-03-04 08:11:41 -05:00
* @returns {Promise<ArrayBuffer>} Returns a Promise that resolves with the contents of the file as ArrayBuffer or rejects with an error.
2016-08-17 00:11:10 -07:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
readAsArrayBuffer ( path : string , file : string ) : Promise < ArrayBuffer > {
2016-08-11 07:21:02 -04:00
if ( ( /^\// . test ( file ) ) ) {
let err = new FileError ( 5 ) ;
err . message = 'file-name cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-08-11 07:21:02 -04:00
}
2016-03-18 23:27:20 +01:00
2017-03-20 16:38:14 -04:00
return this . resolveDirectoryUrl ( path )
. then ( ( directoryEntry : DirectoryEntry ) = > {
return this . getFile ( directoryEntry , file , { create : false } ) ;
2016-08-11 07:21:02 -04:00
} )
2017-03-20 16:38:14 -04:00
. then ( ( fileEntry : FileEntry ) = > {
2016-08-11 07:21:02 -04:00
let reader = new FileReader ( ) ;
2016-09-06 23:33:51 -04:00
return new Promise < any > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
reader . onloadend = ( ) = > {
if ( reader . result !== undefined || reader . result !== null ) {
resolve ( reader . result ) ;
} else if ( reader . error !== undefined || reader . error !== null ) {
reject ( reader . error ) ;
} else {
reject ( { code : null , message : 'READER_ONLOADEND_ERR' } ) ;
}
} ;
2017-03-20 16:38:14 -04:00
fileEntry . file ( file = > {
2016-08-26 15:22:59 +02:00
reader . readAsArrayBuffer ( file ) ;
} , error = > {
reject ( error ) ;
2016-08-26 12:33:28 -04:00
} ) ;
2016-08-26 15:22:59 +02:00
2016-08-11 07:21:02 -04:00
} ) ;
} ) ;
}
2016-03-18 23:27:20 +01:00
2016-03-21 13:19:27 +01:00
/**
* Move a file to a given path.
*
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} fileName Name of file to move
* @param {string} newPath Base FileSystem of new location
* @param {string} newFileName New name of file to move to (leave blank to remain the same)
2017-03-04 08:11:41 -05:00
* @returns {Promise<Entry>} Returns a Promise that resolves to the new Entry or rejects with an error.
2016-03-21 13:19:27 +01:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
moveFile ( path : string , fileName : string , newPath : string , newFileName : string ) : Promise < Entry > {
2016-04-29 23:56:49 -04:00
newFileName = newFileName || fileName ;
2016-03-21 13:19:27 +01:00
if ( ( /^\// . test ( newFileName ) ) ) {
2016-08-11 07:21:02 -04:00
let err = new FileError ( 5 ) ;
err . message = 'file name cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-03-21 13:19:27 +01:00
}
2016-03-18 23:27:20 +01:00
2016-08-11 07:21:02 -04:00
return this . resolveDirectoryUrl ( path )
. then ( ( fse ) = > {
return this . getFile ( fse , fileName , { create : false } ) ;
} )
. then ( ( srcfe ) = > {
return this . resolveDirectoryUrl ( newPath )
. then ( ( deste ) = > {
2017-03-20 16:38:14 -04:00
return this . move ( srcfe , deste , newFileName ) ;
2016-03-21 13:19:27 +01:00
} ) ;
} ) ;
}
/**
* Copy a file in various methods. If file exists, will fail to copy.
*
* @param {string} path Base FileSystem. Please refer to the iOS and Android filesystems above
* @param {string} fileName Name of file to copy
* @param {string} newPath Base FileSystem of new location
* @param {string} newFileName New name of file to copy to (leave blank to remain the same)
2017-03-04 08:11:41 -05:00
* @returns {Promise<Entry>} Returns a Promise that resolves to an Entry or rejects with an error.
2016-03-21 13:19:27 +01:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
copyFile ( path : string , fileName : string , newPath : string , newFileName : string ) : Promise < Entry > {
2016-04-29 23:56:49 -04:00
newFileName = newFileName || fileName ;
2016-03-21 13:19:27 +01:00
if ( ( /^\// . test ( newFileName ) ) ) {
2016-08-11 07:21:02 -04:00
let err = new FileError ( 5 ) ;
err . message = 'file name cannot start with \/' ;
2017-03-04 08:11:41 -05:00
return Promise . reject < any > ( err ) ;
2016-03-21 13:19:27 +01:00
}
2016-08-11 07:21:02 -04:00
return this . resolveDirectoryUrl ( path )
. then ( ( fse ) = > {
return this . getFile ( fse , fileName , { create : false } ) ;
} )
. then ( ( srcfe ) = > {
return this . resolveDirectoryUrl ( newPath )
. then ( ( deste ) = > {
2017-03-20 16:38:14 -04:00
return this . copy ( srcfe , deste , newFileName ) ;
2016-03-21 13:19:27 +01:00
} ) ;
2016-08-11 07:21:02 -04:00
} ) ;
}
2016-08-30 14:45:52 -03:00
/**
2017-03-20 16:38:14 -04:00
* @hidden
2016-08-30 14:45:52 -03:00
*/
2017-03-20 16:38:14 -04:00
private fillErrorMessage ( err : FileError ) : void {
2017-03-01 21:28:05 -05:00
try {
2017-03-20 16:38:14 -04:00
err . message = this . cordovaFileError [ err . code ] ;
2017-03-01 21:28:05 -05:00
} catch ( e ) { }
2016-08-11 07:21:02 -04:00
}
2016-08-30 14:45:52 -03:00
/**
2016-10-11 20:16:39 -04:00
* Resolves a local file system URL
2016-10-11 20:30:14 -04:00
* @param fileUrl {string} file system url
2016-10-11 20:16:39 -04:00
* @returns {Promise<Entry>}
2016-08-30 14:45:52 -03:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
resolveLocalFilesystemUrl ( fileUrl : string ) : Promise < Entry > {
2016-09-06 23:33:51 -04:00
return new Promise < Entry > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
try {
2016-10-11 20:30:14 -04:00
window . resolveLocalFileSystemURL ( fileUrl , ( entry ) = > {
2016-08-11 07:21:02 -04:00
resolve ( entry ) ;
} , ( err ) = > {
2017-03-20 16:38:14 -04:00
this . fillErrorMessage ( err ) ;
2016-08-11 07:21:02 -04:00
reject ( err ) ;
2016-03-21 13:19:27 +01:00
} ) ;
2016-08-11 07:21:02 -04:00
} catch ( xc ) {
2017-03-20 16:38:14 -04:00
this . fillErrorMessage ( xc ) ;
2016-08-11 07:21:02 -04:00
reject ( xc ) ;
}
} ) ;
}
2016-08-30 14:45:52 -03:00
/**
2016-10-11 20:16:39 -04:00
* Resolves a local directory url
2016-10-11 20:30:14 -04:00
* @param directoryUrl {string} directory system url
2016-10-11 20:16:39 -04:00
* @returns {Promise<DirectoryEntry>}
2016-08-30 14:45:52 -03:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
resolveDirectoryUrl ( directoryUrl : string ) : Promise < DirectoryEntry > {
return this . resolveLocalFilesystemUrl ( directoryUrl )
2016-08-11 07:21:02 -04:00
. then ( ( de ) = > {
if ( de . isDirectory ) {
return < DirectoryEntry > de ;
} else {
let err = new FileError ( 13 ) ;
err . message = 'input is not a directory' ;
return Promise . reject < DirectoryEntry > ( err ) ;
}
2016-03-21 13:19:27 +01:00
} ) ;
2016-08-11 07:21:02 -04:00
}
2016-03-21 13:19:27 +01:00
2016-08-30 14:45:52 -03:00
/**
2016-10-11 20:30:14 -04:00
* Get a directory
* @param directoryEntry {DirectoryEntry} Directory entry, obtained by resolveDirectoryUrl method
* @param directoryName {string} Directory name
* @param flags {Flags} Options
* @returns {Promise<DirectoryEntry>}
2016-08-30 14:45:52 -03:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
getDirectory ( directoryEntry : DirectoryEntry , directoryName : string , flags : Flags ) : Promise < DirectoryEntry > {
2016-09-06 23:33:51 -04:00
return new Promise < DirectoryEntry > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
try {
2016-10-11 20:30:14 -04:00
directoryEntry . getDirectory ( directoryName , flags , ( de ) = > {
2016-08-11 07:21:02 -04:00
resolve ( de ) ;
} , ( err ) = > {
2017-03-20 16:38:14 -04:00
this . fillErrorMessage ( err ) ;
2016-08-11 07:21:02 -04:00
reject ( err ) ;
} ) ;
} catch ( xc ) {
2017-03-20 16:38:14 -04:00
this . fillErrorMessage ( xc ) ;
2016-08-11 07:21:02 -04:00
reject ( xc ) ;
}
} ) ;
}
2016-08-30 14:45:52 -03:00
/**
2016-10-11 20:30:14 -04:00
* Get a file
* @param directoryEntry {DirectoryEntry} Directory entry, obtained by resolveDirectoryUrl method
* @param fileName {string} File name
* @param flags {Flags} Options
* @returns {Promise<FileEntry>}
2016-08-30 14:45:52 -03:00
*/
2017-03-20 16:38:14 -04:00
@CordovaCheck ( )
getFile ( directoryEntry : DirectoryEntry , fileName : string , flags : Flags ) : Promise < FileEntry > {
2016-09-06 23:33:51 -04:00
return new Promise < FileEntry > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
try {
2016-10-11 20:30:14 -04:00
directoryEntry . getFile ( fileName , flags , resolve , ( err ) = > {
2017-03-20 16:38:14 -04:00
this . fillErrorMessage ( err ) ;
2016-08-11 07:21:02 -04:00
reject ( err ) ;
} ) ;
} catch ( xc ) {
2017-03-20 16:38:14 -04:00
this . fillErrorMessage ( xc ) ;
2016-08-11 07:21:02 -04:00
reject ( xc ) ;
}
} ) ;
}
2016-08-30 14:45:52 -03:00
/**
2017-03-20 16:38:14 -04:00
* @hidden
2016-08-30 14:45:52 -03:00
*/
2017-03-20 16:38:14 -04:00
private remove ( fe : Entry ) : Promise < RemoveResult > {
2016-09-06 23:33:51 -04:00
return new Promise < RemoveResult > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
fe . remove ( ( ) = > {
resolve ( { success : true , fileRemoved : fe } ) ;
} , ( err ) = > {
2017-03-20 16:38:14 -04:00
this . fillErrorMessage ( err ) ;
2016-08-11 07:21:02 -04:00
reject ( err ) ;
} ) ;
} ) ;
}
2016-08-30 14:45:52 -03:00
/**
2017-03-20 16:38:14 -04:00
* @hidden
2016-08-30 14:45:52 -03:00
*/
2017-03-20 16:38:14 -04:00
private move ( srce : Entry , destdir : DirectoryEntry , newName : string ) : Promise < Entry > {
2016-09-06 23:33:51 -04:00
return new Promise < Entry > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
srce . moveTo ( destdir , newName , ( deste ) = > {
resolve ( deste ) ;
} , ( err ) = > {
2017-03-20 16:38:14 -04:00
this . fillErrorMessage ( err ) ;
2016-08-11 07:21:02 -04:00
reject ( err ) ;
} ) ;
} ) ;
}
2016-08-30 14:45:52 -03:00
/**
2017-03-20 16:38:14 -04:00
* @hidden
2016-08-30 14:45:52 -03:00
*/
2017-03-20 16:38:14 -04:00
private copy ( srce : Entry , destdir : DirectoryEntry , newName : string ) : Promise < Entry > {
2016-09-06 23:33:51 -04:00
return new Promise < Entry > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
srce . copyTo ( destdir , newName , ( deste ) = > {
resolve ( deste ) ;
} , ( err ) = > {
2017-03-20 16:38:14 -04:00
this . fillErrorMessage ( err ) ;
2016-08-11 07:21:02 -04:00
reject ( err ) ;
} ) ;
} ) ;
}
2016-08-30 14:45:52 -03:00
/**
2017-03-20 16:38:14 -04:00
* @hidden
2016-08-30 14:45:52 -03:00
*/
2017-03-20 16:38:14 -04:00
private readEntries ( dr : DirectoryReader ) : Promise < Entry [ ] > {
2016-09-06 23:33:51 -04:00
return new Promise < Entry [ ] > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
dr . readEntries ( ( entries ) = > {
resolve ( entries ) ;
} , ( err ) = > {
2017-03-20 16:38:14 -04:00
this . fillErrorMessage ( err ) ;
2016-08-11 07:21:02 -04:00
reject ( err ) ;
} ) ;
} ) ;
}
2016-08-30 14:45:52 -03:00
/**
2017-03-20 16:38:14 -04:00
* @hidden
2016-08-30 14:45:52 -03:00
*/
2017-03-20 16:38:14 -04:00
private rimraf ( de : DirectoryEntry ) : Promise < RemoveResult > {
2016-09-06 23:33:51 -04:00
return new Promise < RemoveResult > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
de . removeRecursively ( ( ) = > {
resolve ( { success : true , fileRemoved : de } ) ;
} , ( err ) = > {
2017-03-20 16:38:14 -04:00
this . fillErrorMessage ( err ) ;
2016-08-11 07:21:02 -04:00
reject ( err ) ;
} ) ;
} ) ;
}
2016-08-30 14:45:52 -03:00
/**
2017-03-20 16:38:14 -04:00
* @hidden
2016-08-30 14:45:52 -03:00
*/
2017-03-20 16:38:14 -04:00
private createWriter ( fe : FileEntry ) : Promise < FileWriter > {
2016-09-06 23:33:51 -04:00
return new Promise < FileWriter > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
fe . createWriter ( ( writer ) = > {
resolve ( writer ) ;
} , ( err ) = > {
2017-03-20 16:38:14 -04:00
this . fillErrorMessage ( err ) ;
2016-08-11 07:21:02 -04:00
reject ( err ) ;
} ) ;
} ) ;
}
2016-08-30 14:45:52 -03:00
/**
2017-03-20 16:38:14 -04:00
* @hidden
2016-08-30 14:45:52 -03:00
*/
2017-03-20 16:38:14 -04:00
private write ( writer : FileWriter , gu : string | Blob | ArrayBuffer ) : Promise < any > {
2016-09-07 04:53:42 +03:00
if ( gu instanceof Blob ) {
return this . writeFileInChunks ( writer , gu ) ;
}
2016-10-11 20:10:47 -04:00
return new Promise < any > ( ( resolve , reject ) = > {
2016-08-11 07:21:02 -04:00
writer . onwriteend = ( evt ) = > {
if ( writer . error ) {
reject ( writer . error ) ;
} else {
2016-10-11 20:10:47 -04:00
resolve ( evt ) ;
2016-08-11 07:21:02 -04:00
}
} ;
writer . write ( gu ) ;
} ) ;
2016-03-21 13:19:27 +01:00
}
2016-09-07 04:53:42 +03:00
/**
2017-03-20 16:38:14 -04:00
* @hidden
2016-09-07 04:53:42 +03:00
*/
2017-03-20 16:38:14 -04:00
private writeFileInChunks ( writer : FileWriter , file : Blob ) {
2016-09-07 04:53:42 +03:00
const BLOCK_SIZE = 1024 * 1024 ;
let writtenSize = 0 ;
function writeNextChunk() {
const size = Math . min ( BLOCK_SIZE , file . size - writtenSize ) ;
const chunk = file . slice ( writtenSize , writtenSize + size ) ;
writtenSize += size ;
writer . write ( chunk ) ;
}
2016-09-06 23:33:51 -04:00
return new Promise < any > ( ( resolve , reject ) = > {
2016-09-07 04:53:42 +03:00
writer . onerror = reject ;
writer . onwrite = ( ) = > {
if ( writtenSize < file . size ) {
writeNextChunk ( ) ;
} else {
resolve ( ) ;
}
} ;
writeNextChunk ( ) ;
} ) ;
}
2016-03-18 23:27:20 +01:00
}