/**
* @file system.js
* @module system
* @description Contains all of the system level commands.
* @requires module:commandBroker
* @requires module:ruleBroker
* @requires module:workflowBroker
* @requires module:configurator
* @requires module:loggers
* @requires module:data
* @requires {@link https://www.npmjs.com/package/@haystacks/constants|@haystacks/constants}
* @requires {@link https://www.npmjs.com/package/figlet|figlet}
* @requires {@link https://www.npmjs.com/package/path|path}
* @author Seth Hollingsead
* @date 2022/04/20
* @copyright Copyright © 2022-… by Seth Hollingsead. All rights reserved
*/
// Internal imports
import commandBroker from '../../brokers/commandBroker.js';
import ruleBroker from '../../brokers/ruleBroker.js';
import workflowBroker from '../../brokers/workflowBroker.js';
import configurator from '../../executrix/configurator.js';
import loggers from '../../executrix/loggers.js';
import D from '../../structures/data.js';
// External imports
import hayConst from '@haystacks/constants';
import figlet from 'figlet';
import path from 'path';
const {bas, biz, cfg, msg, sys, wrd} = hayConst;
const baseFileName = path.basename(import.meta.url, path.extname(import.meta.url));
// commandsBlob.commands.system.
const namespacePrefix = sys.ccommandsBlob + bas.cDot + wrd.ccommands + bas.cDot + baseFileName + bas.cDot;
/**
* @function echoCommand
* @description Returns the input as the output without any changes.
* @param {array<boolean|string|integer>} inputData String that should be echoed.
* inputData[0] === 'echoCommand'
* @param {string} inputMetaData Not used for this business rule.
* @return {array<boolean,string|integer|boolean|object|array>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output.
* @author Seth Hollingsead
* @date 2022/02/04
*/
function echoCommand(inputData, inputMetaData) {
let functionName = echoCommand.name;
loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function);
loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData));
loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
let errorMessage = '';
if (inputData) {
inputData.shift();
console.log(inputData.join(bas.cSpace));
returnData[1] = inputData.join(bas.cSpace);
} else {
// Nothing to echo.
errorMessage = msg.cNothingToEcho;
console.log(errorMessage);
returnData[1] = errorMessage;
}
loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData));
loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function);
return returnData;
}
/**
* @function exit
* @description Returns false so the entire application can exit.
* @param {array<boolean|string|integer>} inputData Not used for this command.
* inputData[0] === 'exit'
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array>} An array with a boolean False value to
* indicate if the application exit, followed by the command output.
* @author Seth Hollingsead
* @date 2022/02/04
*/
function exit(inputData, inputMetaData) {
let functionName = exit.name;
loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function);
loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData));
loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [false, true];
loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData));
loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function);
return returnData;
}
/**
* @function version
* @description Displays the current version number for the current application.
* @param {array<boolean|string|integer>} inputData Not used for this command.
* inputData[0] = 'version'
* inputData[1] === 'application|framework' (optional)
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output.
* @author Seth Hollingsead
* @date 2022/02/04
*/
function version(inputData, inputMetaData) {
let functionName = version.name;
loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function);
loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData));
loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
let configVersion = '';
let appContext = '';
if (inputData.length === 2) {
appContext = inputData[1];
if (appContext.toUpperCase() === wrd.cAPPLICATION) {
configVersion = configurator.getConfigurationSetting(wrd.csystem, sys.cApplicationVersionNumber);
} else if (appContext.toUpperCase() === wrd.cFRAMEWORK) {
configVersion = configurator.getConfigurationSetting(wrd.csystem, sys.cFrameworkVersionNumber);
} else {
configVersion = configurator.getConfigurationSetting(wrd.csystem, sys.cApplicationVersionNumber);
}
} else {
configVersion = configurator.getConfigurationSetting(wrd.csystem, sys.cApplicationVersionNumber);
}
console.log(configVersion);
returnData[1] = configVersion;
loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData));
loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function);
return returnData;
}
/**
* @function about
* @description Displays the message about the current application.
* @param {array<boolean|string|integer>} inputData Not used for this command.
* inputData[0] === 'about'
* inputData[1] === 'application|framework' (optional)
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output.
* @author Seth Hollingsead
* @date 2022/02/04
*/
function about(inputData, inputMetaData) {
let functionName = about.name;
loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function);
loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData));
loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
let configDescription = '';
let appContext = '';
if (inputData.length === 2) {
appContext = inputData[1];
if (appContext.toUpperCase() === wrd.cAPPLICATION) {
configDescription = configurator.getConfigurationSetting(wrd.csystem, sys.cApplicationDescription);
} else if (appContext.toUpperCase() === wrd.cFRAMEWORK) {
configDescription = configurator.getConfigurationSetting(wrd.csystem, sys.cFrameworkDescription);
} else {
configDescription = configurator.getConfigurationSetting(wrd.csystem, sys.cApplicationDescription);
}
} else {
configDescription = configurator.getConfigurationSetting(wrd.csystem, sys.cApplicationDescription);
}
console.log(configDescription);
returnData[1] = configDescription;
loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData));
loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function);
return returnData;
}
/**
* @function name
* @description Displays the name of the current application in standard font format, nothing special.
* Optional argument to output in figlet font.
* @param {array<boolean|string|integer>} inputData An array that could really contain anything depending
* on what the user entered, but the function converts and filters out for a boolean
* True or False value internally to the function.
* inputData[0] === 'name'
* inputData[1] === 'application|framework' (optional)
* inputData[2] === 'true|false' (optional)
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output.
* @author Seth Hollingsead
* @date 2022/02/04
*/
function name(inputData, inputMetaData) {
let functionName = name.name;
loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function);
loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData));
loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, ''];
let reportedName = '';
let figletFont = '';
let appContext = '';
let useFancyFont = false;
if (inputData.length === 2) {
appContext = inputData[1];
} // End-if (inputData.length === 2)
if (inputData.length === 3) {
appContext = inputData[1];
useFancyFont = ruleBroker.processRules([inputData[2], ''], [biz.cstringToDataType]);
} // End-if (inputData.length === 3)
if (appContext !== '') {
if (appContext.toUpperCase() === wrd.cAPPLICATION) {
reportedName = configurator.getConfigurationSetting(wrd.csystem, sys.cApplicationName);
} else if (appContext.toUpperCase() === wrd.cFRAMEWORK) {
reportedName = configurator.getConfigurationSetting(wrd.csystem, sys.cFrameworkName);
} else {
reportedName = configurator.getConfigurationSetting(wrd.csystem, sys.cApplicationName);
}
} else {
reportedName = configurator.getConfigurationSetting(wrd.csystem, sys.cApplicationName);
}
if (useFancyFont === true) {
figletFont = configurator.getConfigurationSetting(wrd.csystem, cfg.cfigletFont);
console.log(figlet.textSync(reportedName, {font: figletFont, horizontalLayout: sys.cfull}));
} else {
console.log(reportedName);
}
returnData[1] = reportedName;
loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData));
loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function);
return returnData;
}
/**
* @function clearScreen
* @description Clears all data from the console cache by printing a bunch of blank lines to the screen.
* @param {string} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output.
* @author Seth Hollingsead
* @date 2022/02/04
*/
// eslint-disable-next-line no-unused-vars
function clearScreen(inputData, inputMetaData) {
let functionName = clearScreen.name;
loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function);
// loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData));
// loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + JSON.stringify(inputMetaData));
let returnData = [true, {}];
// console.clear(); // This will clear the screen, but not the cache, you can still scroll up and see the previous commands.
// process.stdout.write('\u001B[2J\u-001B[0;0f'); // Same as above.
// eslint-disable-next-line no-undef
process.stdout.write('\u001b[H\u001b[2J\u001b[3J');
returnData[1] = true;
loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData));
loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function);
return returnData;
}
/**
* @function help
* @description Displays all the information about all of the commands in the system,
* including both system defined commands and client defined commands.
* @param {array<boolean|string|integer>} inputData Not used for this command.
* inputData[0] = 'help'
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output.
* @author Seth Hollingsead
* @date 2022/02/22
*/
// eslint-disable-next-line no-unused-vars
function help(inputData, inputMetaData) {
let functionName = help.name;
loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function);
let returnData = [true, []];
let errorMessage = '';
if (inputData.length > 1) {
// calling getCommandNamespaceDataObject() function,
// because the user entered some namespace we should look for!
let namespaceCommandsData = commandBroker.getCommandNamespaceDataObject(undefined, inputData[1]);
// namespaceCommandsData is:
loggers.consoleLog(namespacePrefix + functionName, msg.cnamespaceCommandsDataIs + JSON.stringify(namespaceCommandsData));
if (namespaceCommandsData === false) {
// ERROR: The command namespace was not found.
// Please make sure you have entered the correct name and try again.
errorMessage = msg.chelpCommandMessage01 + bas.cSpace + msg.chelpCommandMessage02;
console.log(errorMessage);
returnData[1] = errorMessage;
} else {
// NOW call getAllCommandAliasData with the above found data!
loggers.consoleLog(namespacePrefix + functionName, msg.chelpCommandMessage03);
let flattenedNamespaceCommandAliasData = commandBroker.getAllCommandAliasData(namespaceCommandsData);
loggers.consoleTableLog(baseFileName + bas.cDot + functionName, flattenedNamespaceCommandAliasData[0], [wrd.cName, wrd.cDescription]);
returnData[1] = ruleBroker.processRules([flattenedNamespaceCommandAliasData[0], ''], [biz.carrayDeepClone]);
}
} else {
let allCommandAliasFlatData = commandBroker.getAllCommandAliasData(D[sys.cCommandsAliases]);
returnData[1] = ruleBroker.processRules([allCommandAliasFlatData, ''], [biz.carrayDeepClone]);
// allCommandAliasFlatData is:
loggers.consoleLog(namespacePrefix + functionName, msg.callCommandAliasFlatDataIs + JSON.stringify(allCommandAliasFlatData[0]));
loggers.consoleTableLog(baseFileName + bas.cDot + functionName, allCommandAliasFlatData[0], [wrd.cName, wrd.cDescription]);
}
loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData));
loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function);
return returnData;
}
/**
* @function workflowHelp
* @description Displays all the information about all the workflows in the system,
* including both system defined workflows & client defined workflows.
* @param {array<boolean|string|integer>} inputData Not used for this command.
* inputData[0] = 'workflowHelp'
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output.
* @author Seth Hollingsead
* @date 2022/02/22
*/
function workflowHelp(inputData, inputMetaData) {
let functionName = workflowHelp.name;
loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function);
loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData));
loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, []];
let errorMessage = '';
// The old way of printing out all the workflows, when it was a flat data structure.
// loggers.consoleTableLog(baseFileName + bas.cDot + functionName, D[sys.cCommandWorkflows][wrd.cWorkflows], [wrd.cName]);
if (inputData.length > 1) {
// calling getWorkflowNamespaceDataObject() function,
// because the user entered some namespace we should look for!
loggers.consoleLog(namespacePrefix + functionName, msg.cworkfowHelpMessage01 + msg.cworkfowHelpMessage02);
let namespaceWorkflowData = workflowBroker.getWorkflowNamespaceDataObject(undefined, inputData[1]);
// namespaceWorkflowData is:
loggers.consoleLog(namespacePrefix + functionName, msg.cnamespaceWorkflowDataIs + JSON.stringify(namespaceWorkflowData));
if (namespaceWorkflowData === false) {
// ERROR: The workflow namespace was not found.
// Please make sure you have entered the correct name and try again.
errorMessage = msg.cworkflowHelpCommandMessage01 + bas.cSpace + msg.chelpCommandMessage02;
console.log(errorMessage);
returnData[1] = errorMessage;
} else {
// NOW call getAllWorkflows with the above found data!
loggers.consoleLog(namespacePrefix + functionName, msg.cworkfowHelpMessage03);
let flattenedNamespaceWorkflowData = workflowBroker.getAllWorkflows(namespaceWorkflowData);
loggers.consoleTableLog(baseFileName + bas.cDot + functionName, flattenedNamespaceWorkflowData);
returnData[1] = ruleBroker.processRules([flattenedNamespaceWorkflowData, ''], [biz.carrayDeepClone]);
}
} else {
// User did not enter any parameters,
// just call getAllWorkflows functions with no input,
// will return all and print all.
loggers.consoleLog(namespacePrefix + functionName, msg.cworkfowHelpMessage04 + msg.cworkfowHelpMessage05 + msg.cworkfowHelpMessage06);
let allWorkflowData = workflowBroker.getAllWorkflows();
loggers.consoleLog(namespacePrefix + functionName, msg.callWorkflowDataIs + JSON.stringify(allWorkflowData));
loggers.consoleTableLog(baseFileName + bas.cDot + functionName, allWorkflowData);
returnData[1] = ruleBroker.processRules([allWorkflowData, ''], [biz.carrayDeepClone]);
}
loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData));
loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function);
return returnData;
}
export default {
echoCommand,
exit,
version,
about,
name,
clearScreen,
help,
workflowHelp
};