Source: commands/command.js

/**
 * @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;