/**
* @class CommandFactory
* @classdesc This class has one static method that returns a new instance
* of a command.
* @author ruckola
*/
class CommandFactory {
/**
* @method
* @static
* @param {String} action - The name of the command to return. If no action
* is given, it returns the {@link Macro} command.
* @param {string} commandDir - The directory in which the command can be found.
* Normally this directory should be specified in the module configuration.<br>
* If namespaces are used, they must be included.
* @description Searches the commands directory for a file with a
* filename that equals the value of the 'action' parameter. If it is found
* it tries to create a new instance of the command and returns it.<br>
* If the the 'action' parameter has value "macro", then the build-in {@link Macro} command
* is returned.<br><br>
* <strong>Warning! - Command filepaths must not contain whitespaces!<br></strong>
*/
static getCommand(action = 'macro', commandDir) {
if (action == 'macro') {
var cmdClass = require('../commands/macro.js');
var cmd = new cmdClass;
return cmd;
}
var fs = require('fs');
var helper = require('./helper');
const path = require('path');
var appRootDir = require('app-root-dir').get();
if (!(typeof action === 'string')) { //check if action is of type string.
throw new TypeError("Parameter 'action' is of the wrong type. It should be of type 'string'.")
} else if(!(typeof commandDir === 'string')) { //check if commandDir is of type string.
throw new TypeError("Parameter 'commandDir' is of the wrong type. It should be of type 'string'.")
};
//DANGEROUS!
//you can't rely on directory names above the application root. Needs to be fixed.
var re = /\s/;
if (action.match(re)) { //check for whitespaces in 'action'
throw new Error("Illegal character found in 'action'-parameter.");
}else if (commandDir.match(re)){ //check for whitespaces in 'commandDir'
throw new Error("Illegal character found in 'commandDir'-parameter.");
}
//build command file-path from 'action'
var className = action;
var filePath = path.normalize(commandDir + "/" + className + ".js");
var absolutePath = path.resolve(__dirname, filePath);
//check if file exists
if (!fs.existsSync(absolutePath)) {
throw new Error("The file '" + filePath + "' doesn't exist.");
}
//require the file
//instantiate the class
//throw an error if the required class doesn't exists
try {
var cmdClass = require(filePath);
var cmd = new cmdClass;
} catch (err) {
console.log("The class %s in file '%s' couldn't be instantiated. Error: %s", helper.ucfirst(className), filePath, err);
}
//write custom properties for testing purposes.
cmd.props = {
action: action,
className: className,
filePath: filePath,
absolutePath: absolutePath
};
//return the command object
return cmd;
}
}
module.exports = CommandFactory;