UNPKG

@haystacks/async

Version:

A framework to build any number or any kind of native application or automation solution.

957 lines (911 loc) 52.9 kB
#!/usr/bin/env node /** * @file main.js * @module main * @description Contains all customer facing functions to are used to interface with the rest of the application framework. * @requires module:warden * @requires module:loggers * @requires module:prompt * @requires module:stack * @requires module:data * @requires {@link https://www.npmjs.com/package/haystacks|haystacks} * @requires {@link https://www.npmjs.com/package/@haystacks/constants|@haystacks/constants} * @requires {@link https://www.npmjs.com/package/url|url} * @requires {@link https://www.npmjs.com/package/dotenv|dotenv} * @requires {@link https://www.npmjs.com/package/path|path} * @author Seth Hollingsead * @date 2021/10/14 * @copyright Copyright © 2022-… by Seth Hollingsead. All rights reserved */ // Internal imports import warden from './controllers/warden.js'; import loggers from './executrix/loggers.js'; import stack from './structures/stack.js'; import D from './structures/data.js'; // External imports import hayConst from '@haystacks/constants'; import url from 'url'; import dotenv from 'dotenv'; import path from 'path'; const {bas, biz, cfg, gen, msg, sys, wrd} = hayConst; const baseFileName = path.basename(import.meta.url, path.extname(import.meta.url)); // framework.main. const namespacePrefix = wrd.cframework + bas.cDot + baseFileName + bas.cDot; dotenv.config(); // eslint-disable-next-line no-undef const {NODE_ENV} = process.env; /** * @function initFramework * @description Initializes the framework systems. * @param {object} clientConfiguration A configuration data object that contains * all the data needed to bootstrap the framework for a client application. * @return {void} * @author Seth Hollingsead * @date 2021/10/07 */ async function initFramework(clientConfiguration) { let functionName = initFramework.name; // console.log(`BEGIN ${namespacePrefix}${functionName} function`); // console.log(`clientConfiguration is: ${JSON.stringify(clientConfiguration)}`); await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); await loggers.consoleLog(namespacePrefix + functionName, msg.cclientConfigurationIs + clientConfiguration); // let frameworkRootPath = path.normalize(process.cwd()); // let frameworkRootPath = path.normalize(path.dirname(import.meta.url)); let frameworkCodeRootPath = url.fileURLToPath(path.dirname(import.meta.url)); let pluginCodeRootPath = clientConfiguration[cfg.cclientRootPath]; let pluginRootPath = ''; // pluginCodeRootPath is: // console.log(msg.cpluginCodeRootPathIs + pluginCodeRootPath); await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginCodeRootPathIs + pluginCodeRootPath); let frameworkCommandAliasesPath = ''; let pluginCommandAliasesPath = ''; let frameworkWorkflowsPath = ''; let pluginWorkflowsPath = ''; frameworkCodeRootPath = await warden.processRootPath(frameworkCodeRootPath, clientConfiguration[sys.cFrameworkName]) + bas.cDoubleForwardSlash; // console.log('frameworkCodeRootPath 1 is: ' + frameworkCodeRootPath); // NOTE: In some cases there is an "/src" at the end of this path. If it's already there, we should strip it off. // Because it will get added again below and /proj/src/src/ will break the whole system! let frameworkCodeRootPathArray = []; frameworkCodeRootPathArray = frameworkCodeRootPath.split(bas.cBackSlash); if (frameworkCodeRootPathArray[frameworkCodeRootPathArray.length - 1].toLowerCase().includes(wrd.csrc)) { // console.log('caught the case that the last element does contain an src entry!! Remove it!!'); frameworkCodeRootPathArray.pop(); frameworkCodeRootPath = frameworkCodeRootPathArray.join(bas.cBackSlash) + bas.cDoubleForwardSlash; } else { // console.log('caught the case that the last element does NOT contain an src entry!! Do not remove anything!!'); } if (clientConfiguration[sys.cPluginName]) { let srcPath = ''; if (clientConfiguration[cfg.cappConfigReferencePath].includes(wrd.csrc)) { srcPath = wrd.csrc; } else if (clientConfiguration[cfg.cappConfigReferencePath].includes(wrd.cbin)) { srcPath = wrd.cbin; } pluginRootPath = await warden.processRootPath(pluginCodeRootPath, clientConfiguration[sys.cPluginName]); pluginCodeRootPath = pluginRootPath + srcPath + bas.cDoubleForwardSlash; // pluginRootPath is: // console.log(msg.cpluginRootPathIs + pluginRootPath); // pluginCodeRootPath is: // console.log(msg.cpluginCodeRootPathIs + pluginCodeRootPath); await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginCodeRootPathIs + pluginCodeRootPath); } // eslint-disable-next-line no-undef if (process.platform != gen.cwin32) { frameworkCodeRootPath = await warden.executeBusinessRules([frameworkCodeRootPath, ''], [biz.cswapBackSlashToForwardSlash]); pluginCodeRootPath = await warden.executeBusinessRules([pluginCodeRootPath, ''], [biz.cswapBackSlashToForwardSlash]); } // console.log('frameworkCodeRootPath 2 is: ' + frameworkCodeRootPath); let frameworkRootPath = frameworkCodeRootPath; if (NODE_ENV === wrd.cdevelopment) { frameworkCodeRootPath = frameworkCodeRootPath + sys.cFrameworkDevelopRootPath; } else if (NODE_ENV === wrd.cproduction) { frameworkCodeRootPath = frameworkCodeRootPath + sys.cFrameworkProductionRootPath; } else { // WARNING: No .env file found! Going to default to the DEVELOPMENT ENVIRONMENT! console.log(msg.cApplicationWarningMessage1a + msg.cApplicationWarningMessage1b); frameworkCodeRootPath = frameworkCodeRootPath + sys.cFrameworkDevelopRootPath; } // console.log('frameworkCodeRootPath 3 is: ' + frameworkCodeRootPath); // pluginCodeRootPath is: // console.log(msg.cpluginCodeRootPathIs + pluginCodeRootPath); await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginCodeRootPathIs + pluginCodeRootPath); frameworkCommandAliasesPath = frameworkCodeRootPath + sys.cframeworkResourcesCommandAliasesPath; pluginCommandAliasesPath = pluginCodeRootPath + sys.cframeworkResourcesCommandAliasesPath; frameworkWorkflowsPath = frameworkCodeRootPath + sys.cframeworkResourcesWorkflowsPath; pluginWorkflowsPath = pluginCodeRootPath + sys.cframeworkResourcesWorkflowsPath; clientConfiguration[cfg.cframeworkRootPath] = path.normalize(frameworkRootPath); clientConfiguration[cfg.cpluginRootPath] = path.normalize(pluginRootPath); clientConfiguration[cfg.cpluginReleaseResourcesPath] = path.normalize(pluginRootPath + sys.cFrameworkProductionRootPath + sys.cframeworkResourcesPath); clientConfiguration[cfg.cframeworkConstantsPath] = hayConst.constantsPath; // frameworkCodeRootPath + sys.cframeworkConstantsPath; clientConfiguration[cfg.cappConfigPath] = clientConfiguration[cfg.cappConfigReferencePath]; clientConfiguration[cfg.cframeworkResourcesPath] = path.join(frameworkCodeRootPath, sys.cframeworkResourcesPath); clientConfiguration[cfg.cpluginResourcesPath] = path.join(pluginCodeRootPath, sys.cframeworkResourcesPath); clientConfiguration[cfg.cclientMetaDataPath] = path.join(clientConfiguration[cfg.cclientRootPath], clientConfiguration[cfg.cclientMetaDataPath]); clientConfiguration[cfg.cframeworkFullMetaDataPath] = path.join(clientConfiguration[cfg.cframeworkResourcesPath], sys.cmetaDatadotJson); clientConfiguration[cfg.cpluginFullMetaDataPath] = path.join(clientConfiguration[cfg.cpluginResourcesPath], sys.cmetaDatadotJson); clientConfiguration[cfg.cframeworkConfigPath] = frameworkCodeRootPath + sys.cframeworkResourcesConfigurationPath; clientConfiguration[cfg.cframeworkThemesPath] = frameworkCodeRootPath + sys.cframeworkThemesPath; clientConfiguration[cfg.cframeworkSchemasPath] = frameworkCodeRootPath + sys.cframeworkSchemasPath; clientConfiguration[cfg.cframeworkCommandAliasesPath] = frameworkCommandAliasesPath; clientConfiguration[cfg.cpluginCommandAliasesPath] = pluginCommandAliasesPath; clientConfiguration[cfg.cframeworkWorkflowsPath] = frameworkWorkflowsPath; clientConfiguration[cfg.cpluginWorkflowsPath] = pluginWorkflowsPath; await warden.initFrameworkSchema(clientConfiguration); await loggers.consoleLog(namespacePrefix + functionName, msg.cAllLoadedDataIs + JSON.stringify(D)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); // console.log('All loaded data is: ' + JSON.stringify(D)); // console.log(`END ${namespacePrefix}${functionName} function`); } /** * @function accouterFramework * @description Equip and outfit this instance of the haystacks framework with an existing data structure. * This function essentially allows plugins to inject a clone of the D-data structure from another instance of * Haystacks into this instance of Haystacks, essentially creating a clone of the original instance of Haystacks. * The purpose being to be able to call back to Haystacks and have it perform loading and parsing operations on files. * @param {object} data A JSON data structure, that is a clone of the D-data structure from another instance of Haystacks. * @return {boolean} A True or False value to indicate if the operation was completed successfully or not. * @author Seth Hollingsead * @date 2023/01/09 * @NOTE It's not going to do any good to add framework console logs here, because the primary use case of this function is * for dumping Haystacks context data into a new instance of Haystacks to make it behave and work like the main Haystacks instance. */ async function accouterFramework(data) { // let functionName = accouterFramework.name; // console.log(`BEGIN ${namespacePrefix}${functionName} function`); // console.log(`data is: ${JSON.stringify(data)}`); let returnData = false; if (data) { // console.log('setting the data structure!'); returnData = await D.setData(data); // Haystacks-Plugin linking issue #40 // Possible fix: Apparently the business rules and commands from the data that are cloned from the original instance of Haystacks, // can only execute from the code located at the path of the original location. // When we are using the plugin to call the accouterFramework function we are actually bootstrapping a Haystacks instance // from within the plugins own node_modules path, not the original path. This is why the plugins instance of Haystacks needed to be linked. // We can get around that by re-initializing the business rules and the commands for this instance of Haystacks and over-write the same // business rules and commands in the above data structure. That should in theory solve the linking issue. await warden.resetRulesAndCommands(); } // console.log('returnData is: ' + returnData); // console.log(`END ${namespacePrefix}${functionName} function`); return returnData; } /** * @function getFrameworkData * @description Returns all the contents of the framework data. Can be used to pull the data contents of a Haystacks * instance to swap it out with mock data, then swap back afterward. * @return {object} A JSON object that contains the entire contents of the Haystacks D-data structure. * @author Seth Hollingsead * @date 2023/01/09 */ async function getFrameworkData() { let functionName = getFrameworkData.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = false; returnData = D.getData(); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function mergeClientBusinessRules * @description A wrapper function to expose the warden.mergeClientBusinessRules functionality. * @param {object} clientBusinessRules A map of client defined business rule names and client defined business rule function calls. * @return {void} * @author Seth Hollingsead * @date 2022/02/18 */ async function mergeClientBusinessRules(clientBusinessRules) { let functionName = mergeClientBusinessRules.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); await warden.mergeClientBusinessRules(clientBusinessRules); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); } /** * @function mergeClientCommands * @description A wrapper function to expose the warden.mergeClientCommands functionality. * @param {object} clientCommands A map of client defined command names and client defined command function calls. * @return {void} * @author Seth Hollingsead * @date 2022/02/18 */ async function mergeClientCommands(clientCommands) { let functionName = mergeClientCommands.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); await warden.mergeClientCommands(clientCommands); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); } /** * @function loadCommandAliases * @description Loads and merges a set of client command aliases with the framework command aliases. * This function acts as a wrapper for calling the warden.loadCommandAliases function. * @param {string} commandAliasesPath The path to where the commands aliases XML file is stored, that should be loaded. * @param {string} contextName A name for the set of command aliases that should be * used to store the path in the configuration system so it can be loaded by the framework. * @return {void} * @author Seth Hollingsead * @date 2022/02/18 */ async function loadCommandAliases(commandAliasesPath, contextName) { let functionName = loadCommandAliases.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // commandAliasesPath is: await loggers.consoleLog(namespacePrefix + functionName, msg.ccommandAliasesPathIs + commandAliasesPath); // contextName is: await loggers.consoleLog(namespacePrefix + functionName, msg.ccontextNameIs + contextName); await warden.setConfigurationSetting(wrd.csystem, contextName, commandAliasesPath); await warden.loadCommandAliases(contextName); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); } /** * @function loadCommandWorkflows * @description Loads and merges a set of client workflows with the framework workflows. * This function acts as a wrapper for calling the warden.loadCommandWorkflows function. * @param {string} workflowPath The path to where the workflows file is stored, that should be loaded. * @param {string} contextName A name for the workflows that should be used * to store the path in the configuration system so it can be loaded by the framework. * @return {void} * @author Seth Hollingsead * @date 2022/02/18 */ async function loadCommandWorkflows(workflowPath, contextName) { let functionName = loadCommandWorkflows.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // workflowPath is: await loggers.consoleLog(namespacePrefix + functionName, msg.cworkflowPathIs + workflowPath); // contextName is: await loggers.consoleLog(namespacePrefix + functionName, msg.ccontextNameIs + contextName); await warden.setConfigurationSetting(wrd.csystem, contextName, workflowPath); await warden.loadCommandWorkflows(contextName); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); } /** * @function listLoadedPlugins * @description This is a wrapper function for warden.listLoadedPlugins. * Which is in-turn a wrapper function for chiefPlugin.listLoadedPlugins. * Which is in-turn a wrapper function for pluginBroker.listAllLoadedPlugins. * @return {array<string>} A list array of the names of the plugins that are currently loaded. * @author Seth Hollingsead * @date 2023/02/06 */ async function listLoadedPlugins() { let functionName = listLoadedPlugins.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = []; returnData = await warden.listLoadedPlugins(); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function listAllPluginsInRegistry * @description This is a wrapper function for warden.listAllPluginsInRegistry. * Which is in-turn a wrapper function for chiefPlugin.getAllPluginsInRegistry. * Which is in-turn a wrapper function for pluginBroker.listPluginsInRegistry. * @return {array<string>} A list array of the names of the plugins in the plugin registry. * @author Seth Hollingsead * @date 2022/09/15 */ async function listAllPluginsInRegistry() { let functionName = listAllPluginsInRegistry.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = []; returnData = await warden.listAllPluginsInRegistry(); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function listAllPluginsInRegistryPath * @description This is a wrapper function for warden.listAllPluginsInRegistryPath. * Which is in-turn a wrapper function for chiefPlugin.getAllPluginsInRegistryPath. * Which is in-turn a wrapper function for pluginBroker.listPluginsInRegistryPath. * @return {array<string>} A list array of the names of the plugins in the plugin registry. * @author Seth Hollingsead * @date 2022/09/15 */ async function listAllPluginsInRegistryPath() { let functionName = listAllPluginsInRegistryPath.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = []; returnData = await warden.listAllPluginsInRegistryPath(); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function numberOfPluginsInRegistry * @description This is a wrapper function for warden.numberOfPluginsInRegistry. * Which is in-turn a wrapper function for chiefPlugin.countAllPluginsInRegistry. * Which is in-turn a wrapper function for pluginBroker.countPluginsInRegistry. * @return {integer} The count of the number of plugins listed in the plugin registry data hive. * @author Seth Hollingsead * @date 2022/09/15 */ async function numberOfPluginsInRegistry() { let functionName = numberOfPluginsInRegistry.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = 0; returnData = await warden.numberOfPluginsInRegistry(); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function numberOfPluginsInRegistryPath * @description This is a wrapper function for warden.numberOfPluginsInRegistryPath. * Which is in-turn a wrapper function for chiefPlugin.countAllPluginsInRegistryPath. * Which is in-turn a wrapper function for pluginBroker.countPluginsInRegistryPath. * @return {integer} Teh count of the number of plugin sub-folders in the plugins path listed in the plugn registry data hive. * @author Seth Hollingsead * @date 2022/09/15 */ async function numberOfPluginsInRegistryPath() { let functionName = numberOfPluginsInRegistryPath.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = 0; returnData = await warden.numberOfPluginsInRegistryPath(); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function registerPluginByNameAndPath * @description This is a wrapper function for warden.registerPluginByNameAndPath. * Which is in-turn a wrapper function for chiefPlugin.registerNamedPlugin. * Which is in-turn a wrapper function for pluginBroker.registerPlugin. * @param {string} pluginName The name of the plugin that should be registered. * @param {string} pluginPath The path to the plugin, to be added to the plugin registry. * This should be the path to the plugin/package.json file, but not including the package.json as part of the path URI. * @return {boolean} True or False to indicate if the plugin was added to the plugin registry successfully or not. * @author Seth Hollingsead * @date 2022/09/15 */ async function registerPluginByNameAndPath(pluginName, pluginPath) { let functionName = registerPluginByNameAndPath.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // pluginName is: await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginNameIs + pluginName); // pluginPath is: await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginPathIs + pluginPath); let returnData = false; returnData = await warden.registerPluginByNameAndPath(pluginName, pluginPath); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function unregisterPluginByName * @description This is a wrapper function for warden.unregisterPluginByName. * Which is in-turn a wrapper function for chiefPlugin.unregisterNamedPlugin. * Which is in-turn a wrapper function for pluginBroker.unregisterPlugin. * @param {string} pluginName The name of the plugin that should be removed from the plugin registry. * @return {boolean} True or False to indicate if the plugin was removed from the plugin registry successfully or not. * @author Seth Hollingsead * @date 2022/09/15 */ async function unregisterPluginByName(pluginName) { let functionName = unregisterPluginByName.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // pluginName is: await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginNameIs + pluginName); let returnData = false; returnData = await warden.unregisterPluginByName(pluginName); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function unregisterPlugins * @description This is a wrapper function for warden.unregisterPlugins. * Which is in-turn a wrapper function for chiefPlugin.unregisterPlugins. * Which is in-turn a wrapper function for pluginBroker.unregisterPlugins. * @param {string|array<string>} pluginsListArray A string or list array of plugin names that should be removed from the plugin registry. * @return {boolean} True or False to indicate if all the plugins were successfully removed from the plugin registry or not. * @author Seth Hollingsead * @date 2023/02/07 */ async function unregisterPlugins(inputData) { let functionName = unregisterPlugins.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginListArrayIs + JSON.stringify(inputData)); let returnData = false; let pluginsListArray = []; if (Array.isArray(inputData) === true && inputData.length >= 1) { pluginsListArray = inputData; } else if (inputData.includes(bas.cComa) === true) { pluginsListArray = inputData.split(bas.cComa); } else if (inputData.includes(bas.cSpace) === true) { pluginsListArray = inputData.split(bas.cSpace); } // pluginsListArray is: await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginsListArrayIs + JSON.stringify(pluginsListArray)); returnData = await warden.unregisterPlugins(pluginsListArray); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function syncPluginRegistryWithPath * @description This is a wrapper function for warden.syncPluginRegistryWithPath. * Which is in-turn a wrapper function for chiefPlugin.synchronizePluginRegistryWithPath. * Which is in-turn a wrapper function for pluginBroker.synchPluginRegistryWithPluginRegistryPath. * @return {boolean} True or False to indicate if the synchronization was performed successfully or not. * @author Seth Hollingsead * @date 2022/09/15 * @NOTE It is expected that the number of plugins loaded at any one time will not be crazy high. * The function that is called in plugnBroker.synchPluginRegistryWithPluginRegistryPath will * do a O(n^2) brute force search, * if the number of plugins needed at any one time ever grows much over 100, then this solution will need to be re-evaluated! */ async function syncPluginRegistryWithPath() { let functionName = syncPluginRegistryWithPath.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = false; returnData = await warden.syncPluginRegistryWithPath(); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function clearAllPluginRegistry * @description This is a wrapper function for warden.clearAllPluginRegistry. * Which is in-turn a wrapper function for chiefPlugin.clearPluginRegistry. * Which is in-turn a wrapper function for pluginBroker.unregisterAllPlugins. * @return {boolean} True or False to indicate if the plugin registry data hive was cleared successfully or not. * @author Seth Hollingsead * @date 2022/09/15 */ async function clearAllPluginRegistry() { let functionName = clearAllPluginRegistry.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = false; returnData = await warden.clearAllPluginRegistry(); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function writePluginRegistryToDisk * @description This is a wrapper function for warden.writePluginRegistryToDisk. * Which is in-turn a wrapper function for chiefPlugin.savePluginRegistryDisk. * Which is in-turn a wrapper function for pluginBroker.savePluginRegistry. * @return {boolean} True or False to indicate if the plugin registry was successfully saved to the disk or not. * @author Seth Hollingsead * @date 2022/09/15 */ async function writePluginRegistryToDisk() { let functionName = writePluginRegistryToDisk.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = false; returnData = await warden.writePluginRegistryToDisk(); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function loadPlugin * @description A wrapper call to the warden.loadPlugin function. * Calls various functions in the chiefPlugin and pluginBroker to load plugin metaData and data: * Business rules, Commands, Workflows, Constants, Configurations, dependencies ist(dependant plugins), etc... * @param {string} pluginPath The fully qualified path where to load the plugin from. * @return {boolean} True or False to indicate if the plugin was loaded or not. * @author Seth Hollingsead * @date 2022/09/15 */ async function loadPlugin(pluginPath) { let functionName = loadPlugin.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // pluginPath is: await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginPathIs + pluginPath); let returnData = false; returnData = await warden.loadPlugin(pluginPath); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + returnData); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function loadPlugins * @description A wrapper call to the warden.loadPlugins function. * Calls various functions in the chiefPlugin and pluginBroker to load plugin metaData and data: * Business rules, Commands, Workflows, Constants, Configurations, dependencies list (dependant plugins), etc... * @param {array<string>} pluginsPaths The fully qualified paths where to load the plugins from. * @return {boolean} True or False to indicate if all the plugins were loaded or not. * @author Seth Hollingsead * @date 2022/09/01 */ async function loadPlugins(pluginsPaths) { let functionName = loadPlugins.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // pluginPaths are: await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginsPathsAre + JSON.stringify(pluginsPaths)); let returnData = false; returnData = await warden.loadPlugins(pluginsPaths); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + returnData); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function loadPluginsFromRegistry * @description A wrapper call to warden.loadPluginsFromRegistry function. * Calls various functions in the chief Plugin and pluginBroker to oad plugin metaData and data: * Business rules, Commands, Workflows, Constants, Configurations, dependencies ist (dependant plugns), etc... * @return {boolean} True or False to indicate if all the plugins were loaded or not. * @author Seth Hollingsead * @date 2022/09/16 */ async function loadPluginsFromRegistry() { let functionName = loadPlugins.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = false; returnData = warden.loadPluginsFromRegistry(); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + returnData); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function unloadPlugin * @description A wrapper call to the warden.unloadPlugin function. * Calls various functions in the chiefPlugin and pluginBroker to unload and remove metaData and data: * Business rules, Commands, Workflows, Constants, Configurations, dependencies list (dependant plugins), etc... * @param {string} pluginName The name of the plugin that should be unloaded. * @return {boolean} True or False to indicate if the plugin was unloaded successfully or not. * @author Seth Hollingsead * @date 2022/09/15 */ async function unloadPlugin(pluginName) { let functionName = loadPlugins.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // pluginName is: await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginNameIs + pluginName); let returnData = false; returnData = await warden.unloadPlugin(pluginName); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + returnData); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function unloadPlugins * @description A wrapper call to the warden.unloadPlugins function. * Calls various functions in the chiefPlugin and pluginBroker to unload and remove all the metaData and data for a list of plugins: * Business rules, Commands, Workflows, Constants, Configurations, dependencies list (dependant plugins), etc... * @param {array<string>} pluginNames An array list of names of plugins that should be unloaded. * @return {boolean} True or False to indicate if all the plugins were unloaded successfully or not. * @author Seth Hollingsead * @date 2022/09/15 */ async function unloadPlugins(pluginNames) { let functionName = loadPlugins.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // pluginNames is: await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginNamesIs + JSON.stringify(pluginNames)); let returnData = false; returnData = await warden.unloadPlugins(pluginNames); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + returnData); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function unloadAllPlugins * @description A wrapper call to the warden.unloadAllPlugins function. * Calls various functions in the chiefPlugin and pluginBroker to unload and remove all plugin metaData and data: * Business rules, Commands, Workflows, Constants, Configurations, dependencies list (dependant plugins), etc... * @return {boolean} True or False to indicate if all the plugins were unloaded successfully or not. * @author Seth Hollingsead * @date 2022/09/15 */ async function unloadAllPlugins() { let functionName = loadPlugins.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = false; returnData = await warden.unloadAllPlugins(); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + returnData); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function getPluginsRegistryPath * @description A wrapper call to the warden.getPluginsRegistryPath function. * Which is in-turn a wrapper function for the chiefPlugin.getPluginsRegistryPath. * Which is in-turn a wrapper function for pluginBroker.getPluginsRegistryPath. * @return {string} The path to the plugins listed in the plugin registry as meta-data. * @author Seth Hollingsead * @date 2023/02/07 */ async function getPluginsRegistryPath() { let functionName = getPluginsRegistryPath.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = ''; returnData = await warden.getPluginsRegistryPath(); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function loadPluginResourceData * @description A wrapper call to the warden.loadPluginResourceData function. * @param {string} contextName The type of resource that is being loaded, eg: configuration, commandAliases, workflows, etc... * @param {string} pluginConfigPath The fully qualified path to where the plugin data is located and should be loaded from. * @return {object} The JSON data that is loaded and parsed from the plugin path. * @author Seth Hollingsead * @date 2022/09/09 */ async function loadPluginResourceData(contextName, pluginResourcePath) { let functionName = loadPluginResourceData.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // contextName is: await loggers.consoleLog(namespacePrefix + functionName, msg.ccontextNameIs + contextName); // pluginResourcePath is: await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginResourcePathIs + pluginResourcePath); let returnData = {}; returnData = await warden.loadPluginResourceData(contextName, pluginResourcePath); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function loadAllJsonData * @description Loads all of the JSON data at the specified path. * Can be used to load account data, transaction history logs, activity logs, or any other kind of JSON data. * @param {string} dataPath The path to the JSON files that should be loaded. * @param {string} contextName The type of data that should be loaded. * @return A JSON object that contains all of the data that was loaded and merged together. * @author Seth Hollingsead * @date 2023/02/27 */ async function loadAllJsonData(dataPath, contextName) { let functionName = loadAllJsonData.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // dataPath is: await loggers.consoleLog(namespacePrefix + functionName, msg.cdataPathIs + dataPath); // contextName is: await loggers.consoleLog(namespacePrefix + functionName, msg.ccontextNameIs + contextName); let returnData = false; returnData = await warden.loadAllJsonData(dataPath, contextName); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function storeData * @description Persist some data to the data storage in the D-data structure. * @param {string} dataName The name of the data, unique name used to store the data in the data structure. * @param {object|string|boolean|number|array} data The data that should be stored. * @return {boolean} True or False to indicate if the data was stored successfully or not. * @author Seth Hollingsead * @date 2023/02/27 */ async function storeData(dataName, data) { let functionName = storeData.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // dataName is: await loggers.consoleLog(namespacePrefix + functionName, msg.cdataNameIs + dataName); // data is: await loggers.consoleLog(namespacePrefix + functionName, msg.cdataIs + JSON.stringify(data)); let returnData = false; returnData = await warden.storeData(dataName, data); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + returnData); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function getData * @description Gets data from the D-Data structure data storage data hive. * @param {string} dataName The unique name the data should be stored under. * @return {object|string|boolean|number|array} The data element or object that was stored if any was found. * @author Seth Hollingsead * @date 2023/02/27 */ async function getData(dataName) { let functionName = getData.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // dataName is: await loggers.consoleLog(namespacePrefix + functionName, msg.cdataNameIs + dataName); let returnData = false; returnData = await warden.getData(dataName); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + returnData); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function clearData * @description Wipes out the data using the unique specified data name, * if any is found in the D-0data structure data storage data hive. * @param {string} dataName The unique name of the data that should be cleared. * @return {boolean} True or False to indicate if the data was cleared successfully or not. * @author Seth Hollingsead * @date 2023/02/27 */ async function clearData(dataName) { let functionName = clearData.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // dataName is: await loggers.consoleLog(namespacePrefix + functionName, msg.cdataNameIs + dataName); let returnData = false; returnData = await warden.clearData(dataName); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + returnData); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function setSchemaData * @description This is a wrapper function for the warden function of the same name. So this function exposes the same functionality * in warden. Essentially sets schema data for a specific schema name. This allows for schemas to be over-written / replaced * according to a client defined schema. This should be used with caution as it is very easy to cause/introduce breaking changes * in the haystacks-async development platform. Extra care should be taken here to only replace a schema with another schema that * adds functionality, or changes functionality but does not remove functionality. * @param {string} schemaName The name of the schema that is being added. * @param {object} schemaDataObject The JSON object that contains the schema data that is being added/replaced/over-written. * @return {boolean} True or False to indicate if the schema was successfully added/replaced/over-written. * @author Seth Hollingsead * @date 2024/12/31 */ async function setSchemaData(schemaName, schemaDataObject) { let functionName = setSchemaData.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // schemaName is: await loggers.consoleLog(namespacePrefix + functionName, msg.cschemaNameIs + schemaName); // schemaDataObject is: await loggers.consoleLog(namespacePrefix + functionName, msg.cschemaDataObjectIs + JSON.stringify(schemaDataObject)); let returnData = false; returnData = await warden.setSchemaData(schemaName, schemaDataObject); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + returnData); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function getSchemaData * @description Gets all of the schema data currently stored in the system, or a specific named schema, if a name is provided. * @param {string} schemaName The name of the schema object that should exist in the list of currently loaded schemas. * @return {object} A JSON object that contains all of the currently loaded schemas, or the data for a specific schema. * @author Seth Hollingsead * @date 2024/11/22 */ async function getSchemaData(schemaName) { let functionName = getSchemaData.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); await loggers.consoleLog(namespacePrefix + functionName, msg.cschemaNameIs + schemaName); let returnData = false; returnData = await warden.getSchemaData(schemaName); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function executeBusinessRules * @description A wrapper call to a business rule from the warden.executeBusinessRules. * @param {array<string|integer|boolean|object|function,string|integer|boolean|object|function>} inputs The array of inputs: * inputs[0] = inputData - The input to the rule that is being called. * inputs[1] = inputMetaData - Additional data the input to the rule. * @param {array<string>} businessRules The array of rule name(s) that should be executed. * @return {string} The value that is returned from the rule is also returned. * @author Seth Hollingsead * @date 2022/02/18 */ async function executeBusinessRules(inputs, businessRules) { let functionName = executeBusinessRules.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // inputs is: await loggers.consoleLog(namespacePrefix + functionName, msg.cinputsIs + JSON.stringify(inputs)); // businessRules is: await loggers.consoleLog(namespacePrefix + functionName, msg.cbusinessRulesIs + JSON.stringify(businessRules)); let returnData = await warden.executeBusinessRules(inputs, businessRules); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + returnData); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function enqueueCommand * @description Adds a command to the command queue. * It is worth noting that a command could actually load a whole workflow of commands. * So one command can spawn into many commands that cause * the command queue to be very full with a very complicated workflow. * This also acts as a wrapper for the warden.enqueueCommand function. * @param {string} command The command to add to the command queue for executing. * @return {void} * @author Seth Hollingsead * @date 2022/02/18 */ async function enqueueCommand(command) { let functionName = enqueueCommand.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // command is: await loggers.consoleLog(namespacePrefix + functionName, msg.ccommandIs + command); if (await warden.getConfigurationSetting(wrd.csystem, cfg.clogUserEnteredCommands) === true) { await stack.push(sys.cUserEnteredCommandLog, command); } await warden.enqueueCommand(command); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); } /** * @function isCommandQueueEmpty * @description Determines if the command queue is empty or not empty. * This is a wrapper function for the warden.isCommandQueueEmpty function. * @return {boolean} True or False to indicate if the command execution queue is empty or not. * Useful to determine if the command queue should continue executing or not. * @author Seth Hollingsead * @date 2022/02/18 */ async function isCommandQueueEmpty() { let functionName = isCommandQueueEmpty.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = false; returnData = await warden.isCommandQueueEmpty(); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + returnData); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function processCommandQueue * @description This is a wrapper function for the warden.processCommandQueue. * This leads to a call to the chiefCommander.processCommand to process an individual command. * This is because a command could actually invoke a command workflow that might enqueue a bunch of commands * to the command queue. All of them must be executed in sequence as part of the main application loop. * @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/18 */ async function processCommandQueue() { let functionName = processCommandQueue.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); let returnData = false; returnData = await warden.processCommandQueue(); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function setConfigurationSetting * @description This is just a wrapper for the warden.setConfigurationSetting function. * @param {string} configurationNamespace The path in the configuration JSON object * where the configuration setting should be set. * Ex: businessRules.rules.stringParsing.countCamelCaseWords * @param {string} configurationName The key of the configuration setting. * @param {string|integer|boolean|double|object} configurationValue The value of the configuration setting. * @return {void} * @author Seth Hollingsead * @date 222/02/18 */ async function setConfigurationSetting(configurationNamespace, configurationName, configurationValue) { let functionName = setConfigurationSetting.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // configurationNamespace is: await loggers.consoleLog(namespacePrefix + functionName, msg.cconfigurationNamespaceIs + configurationNamespace); // configurationName is: await loggers.consoleLog(namespacePrefix + functionName, msg.cconfigurationNameIs + configurationName); // configurationValue is: await loggers.consoleLog(namespacePrefix + functionName, msg.cconfigurationValueIs + configurationValue); let returnData = false; // D[sys.cConfiguration][configurationName] = configurationValue; returnData = await warden.setConfigurationSetting(configurationNamespace, configurationName, configurationValue); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + returnData); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function getConfigurationSetting * @description This is just a wrapper for the warden.getConfigurationSetting function. * @param {string} configurationNamespace The path in the configuration JSON object * where the configuration setting should be found. * @param {string} configurationName The key of the configuration setting. * @return {string|integer|boolean|double|object} The value of whatever was stored in the D[configuration][configurationName]. * @author Seth Hollingsead * @date 2022/02/18 */ async function getConfigurationSetting(configurationNamespace, configurationName) { let functionName = getConfigurationSetting.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); // configurationNamespace is: await loggers.consoleLog(namespacePrefix + functionName, msg.cconfigurationNamespaceIs + configurationNamespace); // configurationName is: await loggers.consoleLog(namespacePrefix + functionName, msg.cconfigurationNameIs + configurationName); // let returnConfigurationValue = D[sys.cConfiguration][configurationName]; let returnConfigurationValue = await warden.getConfigurationSetting(configurationNamespace, configurationName); // returnConfigurationValue is: await loggers.consoleLog(namespacePrefix + functionName, msg.creturnConfiguraitonValueIs + returnConfigurationValue); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnConfigurationValue; } /** * @function consoleLog * @description A wrapper function to expose the loggers.consoleLog function to the client appli