@haystacks/async
Version:
A framework to build any number or any kind of native application or automation solution.
334 lines (324 loc) • 19.4 kB
JavaScript
/**
* @file constant.js
* @module constant
* @description Contains all of the constant system commands.
* @requires module:ruleBroker
* @requires module:configurator
* @requires module:loggers
* @requires module:queue
* @requires module:stack
* @requires {@link https://www.npmjs.com/package/@haystacks/constants|@haystacks/constants}
* @requires {@link https://www.npmjs.com/package/path|path}
* @author Seth Hollingsead
* @date 2022/02/04
* @copyright Copyright © 2022-… by Seth Hollingsead. All rights reserved
*/
// Internal imports
import ruleBroker from '../../brokers/ruleBroker.js';
import configurator from '../../executrix/configurator.js';
import loggers from '../../executrix/loggers.js';
import queue from '../../structures/queue.js';
import stack from '../../structures/stack.js';
// External imports
import hayConst from '@haystacks/constants';
import path from 'path';
const {bas, biz, cmd, cfg, gen, msg, sys, wrd} = hayConst;
const baseFileName = path.basename(import.meta.url, path.extname(import.meta.url));
// framework.commandsBlob.commands.constant.
const namespacePrefix = wrd.cframework + bas.cDot + sys.ccommandsBlob + bas.cDot + wrd.ccommands + bas.cDot + baseFileName + bas.cDot;
/**
* @function constantsGenerator
* @description Requests a string input the user would like to have converted nto a constant,
* while determining the most optimized way to define the new constant based on existing constants.
* Also checks to see if that new constant is already defined in the constants system.
* @param {string} inputData Parameterized constant to generate for.
* @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/03/30
*/
async function constantsGenerator(inputData, inputMetaData) {
let functionName = constantsGenerator.name;
await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function);
await loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData));
await loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, []];
let errorMessage = '';
if (await configurator.getConfigurationSetting(wrd.csystem, cfg.cenableConstantsValidation) === true) {
let validEntry = false;
let userDefinedConstant = '';
let constantsFulfillmentSystemRule = [biz.cconstantsFulfillmentSystem];
let recombineArrayInputRule = [biz.crecombineStringArrayWithSpaces];
if (inputData.length === 0) {
while (validEntry === false) {
console.log(msg.cConstantPrompt1);
console.log(msg.cConstantPrompt2);
console.log(msg.cConstantPrompt3);
userDefinedConstant = await ruleBroker.processRules([bas.cGreaterThan, ''], [biz.cprompt]);
validEntry = await ruleBroker.processRules([userDefinedConstant, ''], [biz.cisConstantValid]);
if (validEntry === false) {
// INVALID INPUT: Please enter a valid constant value that contains more than 4 characters.
console.log(msg.cconstantsGeneratorMessage1);
} // End-if (validEntry === false)
} // End-while (validEntry === false)
} else if (inputData.length === 2) {
userDefinedConstant = inputData[1];
} else {
// We need to recombine all of the array elements after the 0-th element into a single string with spaces in between.
userDefinedConstant = await ruleBroker.processRules([inputData, ''], [recombineArrayInputRule]);
}
// userDefinedConstant is:
await loggers.consoleLog(namespacePrefix + functionName, msg.cuserDefinedConstantIs + userDefinedConstant);
// First lets check if the constant is already defined, so we can warn the user.
// NOTE: It could be that the developer is just looking to optimize the existing constant,
// but if not, a warning to the user would be a good idea!
let doesConstantExist = await ruleBroker.processRules([userDefinedConstant, ''], [biz.cdoesConstantExist]);
if (doesConstantExist === true) {
let constantType = await ruleBroker.processRules([userDefinedConstant, false], [biz.cgetConstantType]);
// WARNING: The constant has already been defined in the following library(ies):
console.log(msg.cconstantsGeneratorMessage2 + constantType);
} // End-if (doesConstantExist === true)
userDefinedConstant = userDefinedConstant.trim();
let wordCount = await ruleBroker.processRules([userDefinedConstant, ''], [biz.cgetWordCountInString]);
// wordCount is:
await loggers.consoleLog(namespacePrefix + functionName, msg.cwordCountIs + wordCount);
// Now begin the fulfillment algorithm.
if (wordCount > 1) {
let wordsArray = await ruleBroker.processRules([userDefinedConstant, ''], [biz.cgetWordsArrayFromString]);
for (const element of wordsArray) {
let optimizedWordConstantDefinition = await ruleBroker.processRules([element.trim(), element.trim()], [constantsFulfillmentSystemRule]);
// Optimized constant definition for word:
console.log(msg.cOptimizedConstantDefinitionForWord + bas.cc + element + bas.cSpace + bas.cEqual + bas.cSpace +
optimizedWordConstantDefinition);
returnData[1].push(optimizedWordConstantDefinition);
} // End-for (const element of wordsArray)
} else { // There is only a single word to process.
returnData[1] = await ruleBroker.processRules([userDefinedConstant, userDefinedConstant], [constantsFulfillmentSystemRule])
// output a proper line of code:
// export const csomething = wrd.csome + wrd.cthing; // something
console.log(wrd.cexport + bas.cSpace + gen.cconst + bas.cSpace + bas.cc + userDefinedConstant + bas.cSpace + bas.cEqual + bas.cSpace +
returnData[1] + bas.cSemiColon + bas.cSpace + bas.cDoubleForwardSlash + bas.cSpace + userDefinedConstant);
}
} else {
// The enableConstantsValidation flag is disabled. Enable this flag in the configuration settings to activate this command.
errorMessage = msg.cconstantsGeneratorMessage3 + msg.cconstantsGeneratorMessage4;
console.log(errorMessage);
returnData[1] = errorMessage;
}
await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData));
await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function);
return returnData;
}
/**
* @function constantsGeneratorList
* @description Calls the constantsGenerator command to iterate over a list of constants and generate many constants sequentially.
* @NOTE This function will also walk the list and determine if there are any common strings
* internal to the list that could be defined as new constants to help with the optimization process.
* @NOTE Testing string: constGenL somethingXML,whatever that is,A basic NodeJS template App,that can easily
* @param {string} inputData Parameterized coma delimited list of constants to be auto-generated
* @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/03/30
*/
async function constantsGeneratorList(inputData, inputMetaData) {
let functionName = constantsGeneratorList.name;
await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function);
await loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData));
await loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, {}];
let errorMessage = '';
if (await configurator.getConfigurationSetting(wrd.csystem, cfg.cenableConstantsValidation) === true) {
let validEntry = false;
let userDefinedConstantList = '';
if (inputData.length === 0) {
while (validEntry === false) {
console.log(msg.cConstantsListPrompt1);
console.log(msg.cConstantsListPrompt2);
console.log(msg.cConstantsListPrompt3);
userDefinedConstantList = await ruleBroker.processRules([bas.cGreaterThan, ''], [biz.cprompt]);
validEntry = await ruleBroker.processRules([userDefinedConstantList, ''], [biz.cisConstantValid]);
if (validEntry === false) {
// INVALID INPUT: Please enter a valid constant list.
console.log(msg.cconstantsGeneratorListMessage1);
}
} // End-while (validEntry === false)
} else if (inputData.length === 2) {
userDefinedConstantList = inputData[1];
} else {
// Combine all of the input parameters back into a single string then we will parse it for coma's into an array.
// The array elements will then be used to enqueue the command constantsGenerator.
userDefinedConstantList = await ruleBroker.processRules([inputData, ''], [biz.crecombineStringArrayWithSpaces]);
}
// userDefinedConstantList is:
await loggers.consoleLog(namespacePrefix + functionName, msg.cuserDefinedConstantListIs + userDefinedConstantList);
if (userDefinedConstantList.includes(bas.cComa) === true) {
// userDefinedConstantList contains comas
await loggers.consoleLog(namespacePrefix + functionName, msg.cuserDefinedConstantListContainsComas);
let userDefinedConstantsListArray = userDefinedConstantList.split(bas.cComa);
// userDefinedConstantsListArray is:
await loggers.consoleLog(namespacePrefix + functionName, msg.cuserDefinedConstantsListArrayIs + JSON.stringify(userDefinedConstantsListArray));
if (userDefinedConstantsListArray.length > 1) {
for (const element of userDefinedConstantsListArray) {
let commandToQueue1 = cmd.cconstantsGenerator + bas.cSpace + element.trim()
if (await configurator.getConfigurationSetting(wrd.csystem, cfg.clogAllCommands) === true) {
await stack.push(sys.cSystemCommandLog, commandToQueue1);
}
await queue.enqueue(sys.cCommandQueue, commandToQueue1);
} // End-for (const element of userDefinedConstantsListArray)
returnData[1] = true;
} else if (userDefinedConstantsListArray.length === 1) {
// Just enqueue the constants Generator command with the input directly.
let commandToQueue2 = cmd.cconstantsGenerator + bas.cSpace + userDefinedConstantsListArray[0].trim();
if (await configurator.getConfigurationSetting(wrd.csystem, cfg.clogAllCommands) === true) {
await stack.push(sys.cSystemCommandLog, commandToQueue2);
}
await queue.enqueue(sys.cCommandQueue, commandToQueue2);
returnData[1] = true;
}
} else {
// userDefinedConstantsList DOES NOT contain comas
await loggers.consoleLog(namespacePrefix + functionName, msg.cuserDefinedConstantsListDoesNotContainComas);
let commandToQueue3 = cmd.cconstantsGenerator + bas.cSpace + userDefinedConstantList.trim();
if (await configurator.getConfigurationSetting(wrd.csystem, cfg.clogAllCommands) === true) {
await stack.push(sys.cSystemCommandLog, commandToQueue3);
}
await queue.enqueue(sys.cCommandQueue, commandToQueue3);
returnData[1] = true;
}
} else {
// The enableConstantsValidation flag is disabled. Enable this flag in the configuration settings to activate this command.
errorMessage = msg.cconstantsGeneratorMessage3 + msg.cconstantsGeneratorMessage4;
console.log(errorMessage);
returnData[1] = errorMessage;
}
await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData));
await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function);
return returnData;
}
/**
* @function constantsPatternRecognizer
* @description Walks through a list of constants looking for patterns internal to the strings.
* @param {string} inputData Parameterized coma delimited list of constants to be
* passed through pattern recognition to find common strings among them.
* @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/03/31
*/
async function constantsPatternRecognizer(inputData, inputMetaData) {
let functionName = constantsPatternRecognizer.name;
await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function);
await loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData));
await loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, {}];
let errorMessage = '';
if (await configurator.getConfigurationSetting(wrd.csystem, cfg.cenableConstantsValidation) === true) {
let validEntry = false;
let userDefinedConstantList = '';
let wordsArray = [];
let commonPatternsArray = [];
if (inputData.length === 0) {
while (validEntry === false) {
console.log(msg.cConstantsListPatternSearchPrompt1);
console.log(msg.cConstantsListPatternSearchPrompt2);
console.log(msg.cConstantsListPatternSearchPrompt3);
userDefinedConstantList = await ruleBroker.processRules([bas.cGreaterThan, ''], [biz.cprompt]);
validEntry = await ruleBroker.processRules([userDefinedConstantList, ''], [biz.cisConstantValid]);
if (validEntry === false) {
// INVALID INPUT: Please enter a valid constant list.
console.log(msg.cconstantsGeneratorListMessage1);
} // End-if (validEntry === false)
} // End-while (validEntry === false)
} else if (inputData.length === 2) {
userDefinedConstantList = inputData[1];
} else {
// Combine all of the input parameters back into a single string then we will parse it for coma's into an array.
// The array elements will then be used to enqueue the command constantsGenerator.
userDefinedConstantList = await ruleBroker.processRules([inputData, ''], [biz.crecombineStringArrayWithSpaces]);
}
// userDefinedConstantList is:
await loggers.consoleLog(namespacePrefix + functionName, msg.cuserDefinedConstantListIs + userDefinedConstantList);
if (userDefinedConstantList.includes(bas.cComa) === true) {
wordsArray = userDefinedConstantList.split(bas.cComa);
} else {
// userDefinedConstantList DOES NOT contain comas
await loggers.consoleLog(namespacePrefix + functionName, msg.cuserDefinedConstantsListDoesNotContainComas);
// Check and see if there is another delimiter we can use to break up the string into an array,
// such as a space character, Maybe the user entered a sentence and would like all the words of the sentence to be optimized.
wordsArray = await ruleBroker.processRules([userDefinedConstantList, ''], [biz.cgetWordsArrayFromString]);
}
// wordsArray is:
await loggers.consoleLog(namespacePrefix + functionName, msg.cwordsArrayIs + JSON.stringify(wordsArray));
commonPatternsArray = await ruleBroker.processRules([wordsArray, ''], [biz.csearchForPatternsInStringArray]);
// commonPatternsArray is:
await loggers.consoleLog(namespacePrefix + functionName, msg.ccommonPatternsArrayIs + JSON.stringify(commonPatternsArray));
// This next call will compare the identified string patterns with existing constants, and highlight which ones are not yet implemented.
let newConstantsList = await ruleBroker.processRules([commonPatternsArray, ''], [biz.cvalidatePatternsThatNeedImplementation]);
let constantsPatternGenerationSetting = await configurator.getConfigurationSetting(wrd.csystem, cfg.cenableConstantsPatternGeneration);
if (constantsPatternGenerationSetting === true) {
let commandToQueue = cmd.cconstantsGeneratorList + bas.cSpace + newConstantsList
if (await configurator.getConfigurationSetting(wrd.csystem, cfg.clogAllCommands) === true) {
await stack.push(sys.cSystemCommandLog, commandToQueue);
}
await queue.enqueue(sys.cCommandQueue, commandToQueue);
returnData[1] = newConstantsList;
} // End-if (constantsPatternGenerationSetting === true)
} else {
// The enableConstantsValidation flag is disabled. Enable this flag in the configuration settings to activate this command.
errorMessage = msg.cconstantsGeneratorMessage3 + msg.cconstantsGeneratorMessage4;
console.log(errorMessage);
returnData[1] = errorMessage;
}
await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData));
await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function);
return returnData;
}
/**
* @function evaluateConstant
* @description Resolves a constant and prints the output of the constant value.
* @param {array<string>} inputData A string array that contains the name of the constant that should be resolved and printed.
* inputData[0] = evaluateConstant
* inputData[1] = constantToBeEvaluated - The constant that should be resolved and printed to the output if it exists.
* @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/05/11
*/
async function evaluateConstant(inputData, inputMetaData) {
let functionName = evaluateConstant.name;
await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function);
await loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData));
await loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData);
let returnData = [true, {}];
let errorMessage = '';
if (inputData && inputData.length > 1) {
if (await ruleBroker.processRules([inputData[1], ''], [biz.cdoesConstantExist]) === true) {
returnData[1] = await ruleBroker.processRules([inputData[1], ''], [biz.cgetConstantActualValue]);
console.log(inputData[1] + bas.cSpace + bas.cEqual + bas.cSpace + returnData[1]);
} else {
// The constant does not exist:
errorMessage = msg.cTheConstantDoesNotExist + inputData[1];
console.log(errorMessage);
returnData[1] = errorMessage;
}
} else {
// ERROR: No constant value entered, please enter a constant name to evaluate.
errorMessage = msg.cevaluateConstantMessage01;
console.log(errorMessage);
returnData[1] = errorMessage;
}
await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData));
await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function);
return returnData;
}
export default {
constantsGenerator,
constantsGeneratorList,
constantsPatternRecognizer,
evaluateConstant
};