@haystacks/async
Version:
A framework to build any number or any kind of native application or automation solution.
470 lines (452 loc) • 26.5 kB
JavaScript
/**
* @file clientCommands.js
* @module clientCommands
* @description Contains all client defined commands for execution client actions with various operations.
* @requires module:application.command.constants
* @requires {@link https://www.npmjs.com/package/@haystacks/async|@haystacks/async}
* @requires {@link https://www.npmjs.com/package/@haystacks/constants|@haystacks/constants}
* @requires {@link https://www.npmjs.com/package/chalk|chalk}
* @requires {@link https://www.npmjs.com/package/path|path}
* @author Seth Hollingsead
* @date 2022/02/07
* @copyright Copyright © 2022-… by Seth Hollingsead. All rights reserved
*/
// Internal imports
import * as apc from '../../constants/application.constants.js';
// External imports
import haystacks from '@haystacks/async';
import hayConst from '@haystacks/constants';
import chalk from 'chalk';
import path from 'path';
const {abt, bas, biz, cfg, msg, num, wrd} = hayConst;
const baseFileName = path.basename(import.meta.url, path.extname(import.meta.url));
// application.testHarness.commands.clientCommands.clientCommands.
const namespacePrefix = wrd.capplication + bas.cDot + apc.cApplicationName + bas.cDot + wrd.ccommands + bas.cDot + wrd.cclient + wrd.cCommands + bas.cDot + baseFileName + bas.cDot;
/**
* @function customEchoCommand
* @description A quick command to validate that the new
* dynamic data storage technique for client commands is working.
* @param {string} inputData The string input data.
* @param {string} inputMetaData The string of input meta-data.
* @return {array<boolean,string|integer|boolean|object|array,object>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output and finally the promise for the command execution.
* @author Seth Hollingsead
* @date 2022/02/08
*/
async function customEchoCommand(inputData, inputMetaData) {
let functionName = customEchoCommand.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [false, false];
returnData[1] = inputData + ' clientStringParsing.customEchoCommand';
console.log(returnData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function bossPanic
* @description Prints out random text on the screen
* in a custom length loop that makes the screen look like it is doing something busy.
* So anybody who looks at the screen will think you are working on something super important like: "quantum" cryptography or artificial Intelligence.
* (As if putting the word "Quantum" in front of everything some how makes it smarter!)
* Could also be used to turn a computer into a movie or TV-episode set-piece to make the people standing in front of the computer seem smarter.
* If someone does some fake typing on the keyboard and the BossPanic command is configured to run slowly then it might look like someone is writing code super fast!
* Like an expert Hacker!
* @param {string} inputData The string used to load the BossPanic configuration setting.
* This command can work with no arguments or with any of the following optional arguments.
* They are all numbers so if you want the 3rd one you need to provide the first 2 parameters as well.
* inputData[1] = PerformanceIndex - This is the number of milliseconds that should be delayed between running each loop iteration.
* inputData[2] = Maximum line length - The maximum number of characters that should be generated for printing on the screen.
* inputData[3] = Maximum number of no-colored sequential lines, a smaller number means more colored lines will be generated over all.
* inputData[4] = Maximum number of colored sequential lines, a smaller number means less colored lines will be generated sequentially.
* inputData[5] = Boolean True or False to indicate if typing individual characters should be enabled.
* inputData[6] = Speed-Typing Performance Index, time-out in milliseconds between typing each character.
* @param {string} inputMetaData Not used for this command.
* @return {boolean} True to indicate that the command should not exit when it is completed, however,
* this command puts the application into an infinite loop, so it will technically never return.
* @author Seth Hollingsead
* @date 2022/03/31
* @NOTE This is an INFINITE LOOP function, so press control+C to exit rom the application when you want to exit.
*/
async function bossPanic(inputData, inputMetaData) {
let functionName = bossPanic.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let stringLength = 0;
let colorBreakPoint = 0;
let stringToPrint = '';
let subString1 = '';
let subString2 = '';
let brightColor1 = [];
let darkColor1 = [];
let brightColor2 = [];
let darkColor2 = [];
let colorMode1 = false;
let colorMode2 = false;
let enableColoredLine = false;
let noColoredLineCount = 0;
let coloredLineCount = 0;
let performanceIndex = 0; // Zero is as fast as possible, this will be the delay between loop iterations in milliseconds.
let lineLength = 10;
let noColoredLinesMaxLength = 30;
let coloredLinesMaxLength = 20;
let fastTypingOutput = false;
let speedTypingPerformanceIndex = 100; // Default to a fast typing speed.
let systemColorLogsEnabled = await haystacks.getConfigurationSetting(wrd.csystem, cfg.cenableColorizedConsoleLogs);
// Rather than doing the above, I'll just call the business rule to generate a random number between 1 and 100.
// Then I can call the string generator to generate a random string of characters to match that length.
// And we can build up each line of code that way.
// In such a way we can have much finer control over how strings are generated and colorized without going into scanning the hard drive,
// and printing out file paths and file names.
if (inputData && inputData.length > 1) {
performanceIndex = parseInt(inputData[1]);
if (performanceIndex < 0) {
performanceIndex = Math.abs(performanceIndex);
}
if (inputData.length > 2) {
lineLength = parseInt(inputData[2]);
if (lineLength < 0) {
lineLength = Math.abs(lineLength);
}
} // End-if (inputData.length > 2)
if (inputData.length > 3) {
noColoredLinesMaxLength = parseInt(inputData[3]);
if (noColoredLinesMaxLength < 0) {
noColoredLinesMaxLength = Math.abs(noColoredLinesMaxLength);
}
} // End-if (inputData.length > 3)
if (inputData.length > 4) {
coloredLinesMaxLength = parseInt(inputData[4]);
if (coloredLinesMaxLength < 0) {
coloredLinesMaxLength = Math.abs(coloredLinesMaxLength);
}
} // End-if (inputData.length > 4)
if (inputData.length > 5) {
fastTypingOutput = await haystacks.executeBusinessRules([inputData[5], ''], [biz.cstringToBoolean]);
}
if (inputData.length > 6) {
speedTypingPerformanceIndex = parseInt(inputData[6]);
if (speedTypingPerformanceIndex < 0) {
speedTypingPerformanceIndex = Math.abs(speedTypingPerformanceIndex);
}
} // End-if (inputData.length > 6)
} // End-if (inputData && inputData.length > 1)
// eslint-disable-next-line no-constant-condition
while (true) { // Start the infinite loop
if (noColoredLineCount <= 0 && enableColoredLine === false) {
noColoredLineCount = await haystacks.executeBusinessRules([num.c1, [noColoredLinesMaxLength, false, false]], [biz.crandomlyGenerateNumberInRange]);
enableColoredLine = true;
}
if (coloredLineCount <= 0 && enableColoredLine === true) {
coloredLineCount = await haystacks.executeBusinessRules([num.c2, [coloredLinesMaxLength, false, false]], [biz.crandomlyGenerateNumberInRange]);
enableColoredLine = false;
}
stringLength = await haystacks.executeBusinessRules([num.c1, [lineLength, false, false]], [biz.crandomlyGenerateNumberInRange]);
// Now we will generate a number between 0 and the string length, this will be the color limit so we can break the ine up randomly into a beginning segment and an ending segment.
// Each segment of the line will get a different random foreground font color and random background font color.
colorBreakPoint = await haystacks.executeBusinessRules([num.c1, [stringLength, false, false]], [biz.crandomlyGenerateNumberInRange]);
stringToPrint = await haystacks.executeBusinessRules([stringLength, abt.cMostSpecialCharacters], [biz.cgenerateRandomMixedCaseAlphaNumericCodeWithSpecialCharactersByLength]);
if (enableColoredLine === true && systemColorLogsEnabled === true) {
subString1 = stringToPrint.substr(0, colorBreakPoint);
subString2 = stringToPrint.substr(colorBreakPoint, stringToPrint.length);
// Determine if the first part of the string will have a light foreground and dark background or dark foreground and light background.
if (await haystacks.executeBusinessRules(['', ''], [biz.crandomlyGenerateBooleanValue]) === true) {
brightColor1 = await haystacks.executeBusinessRules([200, 255], [biz.cgenerateRandomBrightColor]);
darkColor1 = await haystacks.executeBusinessRules([0, 60], [biz.cgenerateRandomDarkColor]);
colorMode1 = await haystacks.executeBusinessRules(['', ''], [biz.crandomlyGenerateBooleanValue]);
if (colorMode1 === true) {
subString1 = chalk.rgb(brightColor1[0], brightColor1[1], brightColor1[2])(subString1);
subString2 = chalk.bgRgb(darkColor1[0], darkColor1[1], darkColor1[2])(subString1);
} else {
subString1 = chalk.rgb(darkColor1[0], darkColor1[1], darkColor1[2])(subString1);
subString2 = chalk.bgRgb(brightColor1[0], brightColor1[1], brightColor1[2])(subString1);
}
} // End-if (haystacks.executeBusinessRule(biz.crandomlyGenerateBooleanValue, '', '') === true)
if (await haystacks.executeBusinessRules(['', ''], [biz.crandomlyGenerateBooleanValue]) === true) {
brightColor2 = await haystacks.executeBusinessRules([200, 255], [biz.cgenerateRandomBrightColor]);
darkColor2 = await haystacks.executeBusinessRules([0, 60], [biz.cgenerateRandomDarkColor]);
colorMode2 = await haystacks.executeBusinessRules(['', ''], [biz.crandomlyGenerateBooleanValue]);
if (colorMode2 === true) {
subString2 = chalk.rgb(brightColor2[0], brightColor2[1], brightColor2[2])(subString2);
subString2 = chalk.bgRgb(darkColor2[0], darkColor2[1], darkColor2[2])(subString2);
} else {
subString2 = chalk.rgb(darkColor2[0], darkColor2[1], darkColor2[2])(subString2);
subString2 = chalk.bgRgb(brightColor2[0], brightColor2[1], brightColor2[2])(subString2);
}
} // End-if (haystacks.executeBusinessRule(biz.crandomlyGenerateBooleanValue, '', '') === true)
// Now colorize the different string segments and we will recombine them before printing out to the screen.
stringToPrint = subString1 + subString2;
coloredLineCount--;
} else {
noColoredLineCount--;
}
if (fastTypingOutput === true) {
for (let i = 0; i < stringToPrint.length; i++) {
// eslint-disable-next-line no-undef
await process.stdout.write(stringToPrint.charAt(i));
await haystacks.executeBusinessRules([speedTypingPerformanceIndex, ''], [wrd.csleep]);
} // End-for (let i = 0; i < stringToPrint.length; i++)
console.log('\r'); // Carriage return
} else {
console.log(stringToPrint);
}
await haystacks.executeBusinessRules([performanceIndex, ''], [wrd.csleep]);
} // End-while (true) // End of the infinite loop
}
/**
* @function clientCommand01
* @description Client Command One.
* @param {string} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array,object>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output and finally the promise for the command execution.
* @author Seth Hollingsead
* @date 2022/08/01
* @NOTE: This command will be used to test the order in which commands are enqueued and the order in which commands are executed.
* Especially when commands are nested inside deeply nested workflows.
*/
async function clientCommand01(inputData, inputMetaData) {
let functionName = clientCommand01.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, false];
returnData[1] = 'clientStringParsing.clientCommand01';
console.log(returnData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function clientCommand02
* @description Client Command Two.
* @param {string} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array,object>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output and finally the promise for the command execution.
* @author Seth Hollingsead
* @date 2022/08/01
* @NOTE: This command will be used to test the order in which commands are enqueued and the order in which commands are executed.
* Especially when commands are nested inside deeply nested workflows.
*/
async function clientCommand02(inputData, inputMetaData) {
let functionName = clientCommand02.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, false];
returnData[1] = 'clientStringParsing.clientCommand02';
console.log(returnData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function clientCommand03
* @description Client Command Three.
* @param {string} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array,object>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output and finally the promise for the command execution.
* @author Seth Hollingsead
* @date 2022/08/01
* @NOTE: This command will be used to test the order in which commands are enqueued and the order in which commands are executed.
* Especially when commands are nested inside deeply nested workflows.
*/
async function clientCommand03(inputData, inputMetaData) {
let functionName = clientCommand03.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, false];
returnData[1] = 'clientStringParsing.clientCommand03';
console.log(returnData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function clientCommand04
* @description Client Command Four.
* @param {string} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array,object>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output and finally the promise for the command execution.
* @author Seth Hollingsead
* @date 2022/08/01
* @NOTE: This command will be used to test the order in which commands are enqueued and the order in which commands are executed.
* Especially when commands are nested inside deeply nested workflows.
*/
async function clientCommand04(inputData, inputMetaData) {
let functionName = clientCommand04.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, false];
returnData[1] = 'clientStringParsing.clientCommand04';
console.log(returnData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function clientCommand05
* @description Client Command Five.
* @param {string} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array,object>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output and finally the promise for the command execution.
* @author Seth Hollingsead
* @date 2022/08/01
* @NOTE: This command will be used to test the order in which commands are enqueued and the order in which commands are executed.
* Especially when commands are nested inside deeply nested workflows.
*/
async function clientCommand05(inputData, inputMetaData) {
let functionName = clientCommand05.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, false];
returnData[1] = 'clientStringParsing.clientCommand05';
console.log(returnData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function clientCommand06
* @description Client Command Six.
* @param {string} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array,object>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output and finally the promise for the command execution.
* @author Seth Hollingsead
* @date 2022/08/01
* @NOTE: This command will be used to test the order in which commands are enqueued and the order in which commands are executed.
* Especially when commands are nested inside deeply nested workflows.
*/
async function clientCommand06(inputData, inputMetaData) {
let functionName = clientCommand06.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, false];
returnData[1] = 'clientStringParsing.clientCommand06';
console.log(returnData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function clientCommand07
* @description Client Command Seven.
* @param {string} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array,object>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output and finally the promise for the command execution.
* @author Seth Hollingsead
* @date 2022/08/01
* @NOTE: This command will be used to test the order in which commands are enqueued and the order in which commands are executed.
* Especially when commands are nested inside deeply nested workflows.
*/
async function clientCommand07(inputData, inputMetaData) {
let functionName = clientCommand07.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, false];
returnData[1] = 'clientStringParsing.clientCommand07';
console.log(returnData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function clientCommand08
* @description Client Command Eight.
* @param {string} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array,object>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output and finally the promise for the command execution.
* @author Seth Hollingsead
* @date 2022/08/01
* @NOTE: This command will be used to test the order in which commands are enqueued and the order in which commands are executed.
* Especially when commands are nested inside deeply nested workflows.
*/
async function clientCommand08(inputData, inputMetaData) {
let functionName = clientCommand08.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, false];
returnData[1] = 'clientStringParsing.clientCommand08';
console.log(returnData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function clientCommand09
* @description Client Command Nine.
* @param {string} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array,object>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output and finally the promise for the command execution.
* @author Seth Hollingsead
* @date 2022/08/01
* @NOTE: This command will be used to test the order in which commands are enqueued and the order in which commands are executed.
* Especially when commands are nested inside deeply nested workflows.
*/
async function clientCommand09(inputData, inputMetaData) {
let functionName = clientCommand09.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, false];
returnData[1] = 'clientStringParsing.clientCommand09';
console.log(returnData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
/**
* @function clientCommand10
* @description Client Command Ten.
* @param {string} inputData Not used for this command.
* @param {string} inputMetaData Not used for this command.
* @return {array<boolean,string|integer|boolean|object|array,object>} An array with a boolean True or False value to
* indicate if the application should exit or not exit, followed by the command output and finally the promise for the command execution.
* @author Seth Hollingsead
* @date 2022/08/01
* @NOTE: This command will be used to test the order in which commands are enqueued and the order in which commands are executed.
* Especially when commands are nested inside deeply nested workflows.
*/
async function clientCommand10(inputData, inputMetaData) {
let functionName = clientCommand10.name;
await haystacks.consoleLog(namespacePrefix, functionName, msg.cBEGIN_Function);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputDataIs + inputData);
await haystacks.consoleLog(namespacePrefix, functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, false];
returnData[1] = 'clientStringParsing.clientCommand10';
console.log(returnData[1]);
await haystacks.consoleLog(namespacePrefix, functionName, msg.creturnDataIs + JSON.stringify(returnData));
await haystacks.consoleLog(namespacePrefix, functionName, msg.cEND_Function);
return returnData;
}
export default {
customEchoCommand,
bossPanic,
clientCommand01,
clientCommand02,
clientCommand03,
clientCommand04,
clientCommand05,
clientCommand06,
clientCommand07,
clientCommand08,
clientCommand09,
clientCommand10
};