/**
* @class
* @abstract
* @classdesc Each command processed by the macro-command package, should extend this superclass.
* All subclasses must override the 'execute()' method, with their specific implementations.
* @author ruckola
* @property {CommandResult} this.result
* @property {CommandContext} this.ctxt
*/
class Command {
/**
* @constructor
*/
constructor() {
if (this.constructor === Command) {
throw new Error("The Command class is abstract. You can't instantiate it!");
}
var CommandResult = require('../core/commandResult');
this.result = new CommandResult();
this.context = {};
}
/**
* @method
* @param {CommandContext} context - The context object is used to inject the data
* that is required to successfully execute the command. It contains all configurations
* and all commandResult-objects of any previous subcommands in the same macro. So you don
* need any other parameters. You can even add extra parameters to the context on-the-fly,
* and the new parameters will be available to any subcommand running after this one.
* (in the same macro)
* @description The execute method is used to run the command. Normally this is taken
* care of by the controller and you don't have to worry about it at all. When you start
* developing your own subcommands the following is very important:<br>
* <br>
* 1) Each subcommand that extends this abstract Command-class must override the execute()-method.
* <strong> This is the entry and exit point, for your own implementation.</strong><br>
*
* 2) The execute() method must have a 'context'-parameter.<br>
*
* 3) The execute() method must return a new Promise.<br>
*
* 4) The promise must resolve/reject with a value of type {@link CommandResult}.<br>
*
* @returns {Promise} - The value of the promise should be this.result in most cases.
* @example <caption>Sample subcommand extending this abstract Command class
* and overriding the 'execute()' method </caption>
*
* Command = require('macro-command').Command;
* class Example extends Command {
*
* execute(context) {
*
* var key = this.constructor.name;
* this.context = context;
* var self = this;
* var cmdConf = context.parameters.cmdConfiguration;
*
* return new Promise(function (resolve, reject) {
*
* //CHECK REQUIRED INPUT PARAMETERS ...
*
* //DO SOMETHING HERE ...
*
* self.result.cmd = key;
* self.result.data.push({ 'some example key': 'some example value' });
* self.result.msg = 'The result from ' + key;
* resolve(self.result);
*
* });
* }
* }
* module.exports = Example;
*/
execute(context) {
}
/**
* @method
* @deprecated
* @description Will be removed in the next major version.
* If the execution fails before the command task() has returned a promise,
* we have to return a rejected promise manually to the client. Since there
* is no data to return yet, we pass an error object as the value.
* @param {Error} err - An error object that will be set as the value for the rejected promise.
* @returns {Promise} - Allways rejects with an error object as its value.
*/
abort(err) {
return new Promise(function (resolve, reject) {
reject(err);
});
}
/**
* @method
* @description
* Finds and returns the commandResult of a previous command.
* @param {string} commandName - The name of the previous command.
* @param {commandContext=} context - A context other than the current context.
* @returns {commandResult} - The result of the previous command.
*/
findPrevResult(commandName, context = false) {
var ctxt = context !== false ? context : this.context;
var arrPrevResults = ctxt.parameters.prevResults;
var cmd = commandName;
var fn = function (obj) {
if (obj['cmd'] == cmd) {
return obj;
}
};
var objPrevResult = arrPrevResults.find(fn);
if (objPrevResult)
return objPrevResult;
else
return -1;
}
}
module.exports = Command;