Ftp.js

/**
 * @classdesc
 * FTP/SFTP client supporting the standard FTP/SFTP operations, such as listing, uploading, 
 * downloading, renaming and deletion.
 *
 * ```
 * var ftp = new Ftp();
 * ftp.hostName = "myftpserver";
 * ftp.protocol = "SFTP";
 * ftp.userName = "myusername";
 * ftp.password = "mypassword";
 * try {
 *   ftp.connect();
 * } catch (e) {
 *   throw "Could not connect to server.";
 * }
 * try {
 *   ftp.upload("/home/myusername/myfile.dat");
 *   console.log("Upload complete");
 * } catch (e) {
 *   throw "Error while uploading file.";
 * }
 * ftp.close();
 * ```
 *
 * The call to {@linkcode Ftp#connect connect()} is optional since upload() will auto-connect, but is done here so that any exceptions can be dealt
 * with properly.  The call to close() is usually optional since all clients are closed at the completion of a request or an
 * event-handler invocation.
 * 
 * **General Notes about this class:**
 *
 *  * Connection parameters, such as server-address and user-name, may be set in the constructor after constructor using fields.
 * 
 *  * Calling connect() is optional as each method will auto-connect.
 * 
 *  * Calling close() is recommended but is not mandatory as every client connection is closed when each JSS request is complete.
 * 
 *  * Methods that don't need to return a value return 'this' object so that method-calls may be chained together, e.g.
 * 
 *     new Ftp(host, userName, password).download(filePath).remove(filePath))
 *
 *
 * @constructor
 * @param {String} [hostName] IP address or host-name of remote server.
 * @param {String} [userName] User-name of account on remote server.
 * @param {String} [password] Password of account on remote server.
 * @param {String} [protocol] Protocol to use.  May be FTP, FTPS, FTPSImplicit, SFTP or SCP.
 * @param {String} [serverPort] Port number to connect to on the remote server.
 */
Ftp = function (hostName, userName, password, protocol, serverPort) {

	/**
	 * IP address or host-name of remote server.
	 * 
	 * @type {String}
	 */
	this.hostName = null;

	/**
	 * Protocol to use.  May be FTP, FTPS, FTPSImplicit, SFTP or SCP.
	 * 
	 * @type {String}
	 */
	this.protocol = null;

	/**
	 * Port number to connect to on the remote server.
	 * 
	 * @type {Number}
	 */
	this.serverPort = null;

	/**
	 * User-name of account on remote server.
	 * 
	 * @type {String}
	 */
	this.userName = null;

	/**
	 * Password of account on remote server.
	 * 
	 * @type {String}
	 */
	this.password = null;

	/**
	 * Current working directory on remote server.  Before connection the value of this field is null unless it's set.
	 * If it's set before connection then its value will be the initial working directory.  After connection its value
	 * will reflect the remote working directory.
	 * 
	 * @type {String}
	 */
	this.serverDirectory = null;

	/**
	 * Current working directory in local virtual file-system.  It's used only when uploading or downloading and the
	 * local path is not absolute.
	 * 
	 * @type {String}
	 */
	this.localDirectory = null;

	/**
	 * Virtual file-system path of file containing private key.  
	 * 
	 * @type {String}
	 */
	this.privateKeyFile = null;

	/**
	 * Password of file containing private key.
	 * 
	 * @type {String}
	 */
	this.privateKeyPassword = null;


	/**
	 * Connect to remote server.  Note that calling this method is optional as the client will automatically connect 
	 * when any other method is called if it hasn't already connected.  Calling it explicitly may be useful for 
	 * error-handling.
	 * 
	 * @method
	 * @return {Ftp} A reference to 'this' object is returned so that methods may be chained together (see class description).
	 */
	this.connect = function () { }

	/**
	 * Closes the connection.  Note that calling this method is recommended but not essential since all open clients are
	 * closed at the end of each request.
	 * 
	 * @method
	 * @param {Boolean} [waitForServerAck] If true then the client will wait for the server to acknowledge that the connection is being close.  Default is 'false'.
	 * @return {Ftp} A reference to 'this' object is returned so that methods may be chained together (see class description).
	 */
	this.close = function (waitForServerAck) { }

	/**
	 * Uploads a file from the local virtual file-system to the remote server.
	 * 
	 * @method
	 * @param {String} localPath Path of the file to be uploaded from the local virtual file-system.
	 * @param {String} [remotePath] Path or name of the file being uploaded to the remote file-system.
	 * @return {Ftp} A reference to 'this' object is returned so that methods may be chained together (see class description).
	 */
	this.upload = function (localPath, remotePath) { }

	/**
	 * Downloads a file from the remote server to the local virtual file-system.
	 * 
	 * @method
	 * @param {String} remotePath Path or name of the file to be downloaded from the remote file-system.
	 * @param {String} [localPath] Path of the file being downloaded to the local virtual file-system.
	 * @return {Ftp} A reference to 'this' object is returned so that methods may be chained together (see class description).
	 */
	this.download = function (remotePath, localPath) { }

	/**
	 * Tests whether or not a file or directory exists on the remote server.  Note that this method doesn't
	 * strictly return a boolean.  It will return false if the file/directory doesn't exist, but if the it
	 * does exist then the type ("file" or "directory") is returned.  These are truthy values so the return
	 * values may be used in boolean expressions.
	 * 
	 * @method
	 * @param {String} remotePath Path or name of the file or directory in the remote file-system.
	 * @return {String} Returns "file" or "directory" if either of these exists and false otherwise.
	 */
	this.exists = function (remotePath) { }

	/**
	 * Deletes the given file or directory.
	 * 
	 * @method
	 * @param {String} remotePath Path or name of the file or directory to be deleted from the remote file-system.
	 * @param {String} [recursive=false] Remove all files and subdirectories of the directory as well.
	 * @return {Ftp} A reference to 'this' object is returned so that methods may be chained together (see class description).
	 */
	this.remove = function (remotePath, recursive) { }

	/**
	 * Moves or renames the given file or directory from one path or name to another.  Some servers support renaming but not moving.
	 * 
	 * @method
	 * @param {String} fromRemotePath Path or name of the existing file or directory to moved in the remote file-system.
	 * @param {String} toRemotePath Path or name of the file or directory to move it to in the remote file-system.
	 * @return {Ftp} A reference to 'this' object is returned so that methods may be chained together (see class description).
	 */
	this.move = function (fromRemotePath, toRemotePath) { }

	/**
	 * Creates a folder with the given name under the current working directory
	 * 
	 * @method
	 * @param {String} name Name of directory to create.
	 * @return {Ftp} A reference to 'this' object is returned so that methods may be chained together (see class description).
	 */
	this.createFolder = function (name) { }

	/**
	 * Returns a listing of the remote directory in the form of an array of FileInfo objects.
	 * 
	 * @method
	 * @param {String} [remotePath] Path or name of the directory to be listed in the remote file-system.
	 * @return {FileInfo[]} Array of FileInfo objects each representing a file or a folder.
	 */
	this.list = function (remotePath) { }

	/**
	 * Returns a listing of the remote directory in the form of an array of strings being the names of the files and directories (without paths).
	 * 
	 * @method
	 * @param {String} [remotePath] Path or name of the directory to be listed in the remote file-system.
	 * @return {String[]} Array of strings being the names of the files and directories (without paths).
	 */
	this.listNames = function (name) { }

	/**
	 * Set a SecureFTPConnection property.  The JSS Ftp class is implemented by EnterpriseDT's secure FTP .NET component, 
	 * <a href="http://enterprisedt.com/products/edtftpnetpro/doc/manual/api/html/T_EnterpriseDT_Net_Ftp_SecureFTPConnection.htm">SecureFTPConnection</a>.
	 * This class is very mature and has 
	 * <a href="https://enterprisedt.com/products/edtftpnetpro/doc/manual/api/html/AllMembers_T_EnterpriseDT_Net_Ftp_SecureFTPConnection.htm#propertyTableToggle">many properties</a>
	 * that are not exposed in the JSS Ftp class.  Use this method to set these properties.  Properties that have non-primitive types
	 * must be initialized using .NET objects, which can be instantiated in JSS by specifying their full name, e.g. new System.Text.StringBuilder().
	 * 
	 * @method
	 * @param {String} propertyName Name of property to set.
	 * @param {Object} propertyValue Value to set property to.
	 */
	this.setAdvancedProperty = function (propertyName, propertyValue) { }

	/**
	 * Get the value of a SecureFTPConnection property.  The JSS Ftp class is implemented by EnterpriseDT's secure FTP .NET component, 
	 * <a href="http://enterprisedt.com/products/edtftpnetpro/doc/manual/api/html/T_EnterpriseDT_Net_Ftp_SecureFTPConnection.htm">SecureFTPConnection</a>.
	 * This class is very mature and has 
	 * <a href="https://enterprisedt.com/products/edtftpnetpro/doc/manual/api/html/AllMembers_T_EnterpriseDT_Net_Ftp_SecureFTPConnection.htm#propertyTableToggle">many properties</a>
	 * that are not exposed in the JSS Ftp class.  Use this method to get the value of these properties.
	 * 
	 * @method
	 * @param {String} propertyName Name of property to get.
	 */
	this.getAdvancedProperty = function (propertyName) { }

}

/**
 * Represents a single file or folder in a file listing
 * @typedef {Object} FileInfo
 * @property {String} name Name of the file or folder
 * @property {Number} length Length of the file (0 if folder)
 * @property {Boolean} isDirectory Is this a folder?
 * @property {Date} modified Date when the file (or folder - excluding contents) was last modified.
 * @property {String} permissions Permissions of the file or folder.
 * @property {String} owner Name of the user account which owns the file or folder.
 * @property {String} group Name of the group to which the folder belongs.
*/