UNPKG

@voximplant/voxengine-ci

Version:

Manage Voximplant Platform `applications`, `rules` and `scenarios` from your own environment

354 lines (353 loc) 20.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ApplicationModule = void 0; const node_process_1 = require("node:process"); const vox_rule_service_1 = require("../domains/services/vox-rule.service"); const voximplant_context_1 = require("../domains/contexts/voximplant.context"); const log_message_generator_1 = require("../utils/log-message-generator"); const file_system_context_1 = require("../domains/contexts/file-system.context"); const vox_scenario_service_1 = require("../domains/services/vox-scenario.service"); const vox_application_service_1 = require("../domains/services/vox-application.service"); const application_config_service_1 = require("../domains/services/application-config.service"); const vox_rule_platform_repository_1 = require("../domains/repositories/vox-rule.platform.repository"); const vox_rule_persistent_repository_1 = require("../domains/repositories/vox-rule.persistent.repository"); const vox_scenario_platform_repository_1 = require("../domains/repositories/vox-scenario.platform.repository"); const vox_scenario_persistent_repository_1 = require("../domains/repositories/vox-scenario.persistent.repository"); const vox_application_platform_repository_1 = require("../domains/repositories/vox-application.platform.repository"); const vox_application_persistent_repository_1 = require("../domains/repositories/vox-application.persistent.repository"); class ApplicationModule { constructor() { this.lmg = log_message_generator_1.LogMessageGeneratorFactory.getInstance(); this.init = async () => { try { /** * ApplicationConfigService */ const applicationConfigService = new application_config_service_1.ApplicationConfigService(); const applicationConfig = applicationConfigService.getConfig(); /** * Configs */ const rootDirectoryName = applicationConfig.voxengine_ci.ROOT_DIRECTORY; const metadataDirectoryName = '.voxengine-ci'; const voximplantCredentials = applicationConfig.voximplant.CREDENTIALS; /** * VoximplantContext */ const voximplantContext = new voximplant_context_1.VoximplantContext(voximplantCredentials); await voximplantContext.init(); /** * FileSystemContext */ const fileSystemContext = new file_system_context_1.FileSystemContext(rootDirectoryName, metadataDirectoryName); await fileSystemContext.init(); /** * VoxApplicationPlatformRepository */ const voxApplicationPlatformRepository = new vox_application_platform_repository_1.VoxApplicationPlatformRepository(voximplantContext); voxApplicationPlatformRepository.init(); /** * VoxRulePlatformRepository */ const voxRulePlatformRepository = new vox_rule_platform_repository_1.VoxRulePlatformRepository(voximplantContext); voxRulePlatformRepository.init(); /** * VoxScenarioPlatformRepository */ const voxScenarioPlatformRepository = new vox_scenario_platform_repository_1.VoxScenarioPlatformRepository(voximplantContext); voxScenarioPlatformRepository.init(); /** * VoxApplicationPersistentRepository */ const voxApplicationPersistentRepository = new vox_application_persistent_repository_1.VoxApplicationPersistentRepository(fileSystemContext); await voxApplicationPersistentRepository.init(); /** * VoxRulePersistentRepository */ const voxRulePersistentRepository = new vox_rule_persistent_repository_1.VoxRulePersistentRepository(fileSystemContext); await voxRulePersistentRepository.init(); /** * VoxScenarioPersistentRepository */ const voxScenarioPersistentRepository = new vox_scenario_persistent_repository_1.VoxScenarioPersistentRepository(fileSystemContext); await voxScenarioPersistentRepository.init(); /** * VoxApplicationService */ this.voxApplicationService = new vox_application_service_1.VoxApplicationService(voxApplicationPlatformRepository, voxApplicationPersistentRepository); this.voxApplicationService.init(); /** * VoxRuleService */ this.voxRuleService = new vox_rule_service_1.VoxRuleService(voxRulePlatformRepository, voxRulePersistentRepository); this.voxRuleService.init(); /** * VoxScenarioService */ this.voxScenarioService = new vox_scenario_service_1.VoxScenarioService(voxScenarioPlatformRepository, voxScenarioPersistentRepository); this.voxScenarioService.init(); } catch (error) { console.error(this.lmg.generate('INIT_FAILED', this.constructor.name)); console.error(error); (0, node_process_1.exit)(1); } }; this.projectCleanup = async () => { try { await this.voxApplicationService.cleanup(); await this.voxScenarioService.cleanup(); } catch (error) { console.error(this.lmg.generate('ERR__PROJECT_CLEANUP_FAILED', this.constructor.name)); console.error(error); } }; this.projectInit = async () => { try { const isApplicationAlreadyExists = await this.voxApplicationService.checkApplicationsAlreadyExists(); if (isApplicationAlreadyExists) { throw new Error(this.lmg.generate('ERR__PROJECT_IS_ALREADY_INITIALIZED')); } const rawScenarios = await this.voxScenarioService.downloadScenarios(); this.voxScenarioService.checkScenariosNames(rawScenarios); for (const { scenarioId } of rawScenarios) { const rawFullScenario = await this.voxScenarioService.downloadScenario(scenarioId); await this.voxScenarioService.saveScenario(rawFullScenario); await this.voxScenarioService.saveScenarioMetadata(rawFullScenario); } const rawApplications = await this.voxApplicationService.downloadApplications(); if (!rawApplications.length) { console.info(this.lmg.generate('INFO__NO_APPLICATIONS')); return; } for (const rawApplication of rawApplications) { await this.voxApplicationService.saveApplication(rawApplication); await this.voxApplicationService.saveApplicationMetadata(rawApplication); const rawRules = await this.voxRuleService.downloadApplicationRules(rawApplication); await this.voxRuleService.saveRules(rawApplication, rawRules); await this.voxRuleService.saveRulesMetadata(rawApplication, rawRules); } } catch (error) { console.error(this.lmg.generate('ERR__PROJECT_INIT_FAILED', this.constructor.name)); console.error(error); } }; this.getRulesByApplicationName = async (applicationName) => { return ((await this.voxRuleService.readApplicationRulesByName(applicationName)) ?? []); }; this.getScenariosByRuleId = async (applicationName, applicationId, ruleId) => { if (!ruleId) return; const rulesMetadataList = await this.voxRuleService.readApplicationRulesMetadata(applicationName); const ruleMetadataById = rulesMetadataList?.find((ruleMetadata) => ruleMetadata.ruleId === ruleId); const ruleList = await this.voxRuleService.readApplicationRulesByName(applicationName); const ruleToUpload = ruleList?.find((rule) => rule.ruleName === ruleMetadataById?.ruleName); if (!ruleToUpload) { throw new Error(this.lmg.generate('ERR__RULE_ID_DOES_NOT_EXIST', ruleId.toString())); } const { scenarios, rulePattern } = ruleToUpload; return { scenarios, rulePattern, }; }; this.getScenariosByRuleName = async (applicationName, applicationId, ruleName) => { if (!ruleName) return; const voxRulesList = await this.voxRuleService.readApplicationRulesByName(applicationName); await this.voxScenarioService.cleanupDist(); const ruleByName = voxRulesList?.find((rule) => rule.ruleName === ruleName); if (!ruleByName) { throw new Error(this.lmg.generate('ERR__RULE_NAME_DOES_NOT_EXIST', ruleName)); } const { scenarios, rulePattern } = ruleByName; return { scenarios, rulePattern }; }; this.addApplicationToPlatform = async (applicationName) => { try { const applicationId = await this.voxApplicationService.addApplication(applicationName); const rawApplication = { applicationName, applicationId: applicationId, modified: new Date(), secureRecordStorage: false, }; await this.voxApplicationService.saveApplicationMetadata(rawApplication); return applicationId; } catch (error) { console.error(error); throw new Error(this.lmg.generate('ERR__CANNOT_ADD_APP', applicationName)); } }; this.bindScenarios = async (existingRule, uploadedScenariosInfo, applicationId, applicationName) => { const uploadedScenariosIds = uploadedScenariosInfo.map(({ scenarioId }) => scenarioId); const uploadedScenariosNames = uploadedScenariosInfo.map(({ scenarioName }) => scenarioName); const bindScenarioRequest = { scenarioId: uploadedScenariosIds, scenarioName: uploadedScenariosNames.join(';'), ruleId: existingRule.ruleId, ruleName: existingRule.ruleName, applicationId: applicationId, applicationName, bind: true, }; const unbindScenarioRequest = { scenarioId: existingRule.scenarios // TODO: Nodejs mapper error (snake_case to camelCase) // @ts-expect-error: Nodejs mapper error (snake_case to camelCase) // eslint-disable-next-line @typescript-eslint/no-unsafe-return .map(({ scenario_id }) => scenario_id) .filter((scenarioId) => !uploadedScenariosIds.includes(scenarioId)), scenarioName: existingRule.scenarios // TODO: Nodejs mapper error (snake_case to camelCase) // @ts-expect-error: Nodejs mapper error (snake_case to camelCase) // eslint-disable-next-line @typescript-eslint/no-unsafe-return .map(({ scenario_name }) => scenario_name) .filter((scenarioName) => !uploadedScenariosNames.includes(scenarioName)) .join(';'), ruleId: existingRule.ruleId, ruleName: existingRule.ruleName, applicationId: applicationId, applicationName, bind: false, }; if (unbindScenarioRequest.scenarioId?.length) { await this.voxScenarioService.addScenariosToRule(unbindScenarioRequest); } if (uploadedScenariosInfo.length) { await this.voxScenarioService.addScenariosToRule(bindScenarioRequest); } }; this.applicationBuild = async (settings) => { const { applicationName } = await this.voxApplicationService.getApplicationNameAndId(settings); try { const voxRulesList = await this.getRulesByApplicationName(applicationName); await this.voxScenarioService.cleanupDist(); for (const voxRule of voxRulesList) { const { scenarios } = voxRule; await this.voxScenarioService.build(scenarios); } } catch (error) { console.error(this.lmg.generate('ERR__APPLICATION_BUILD_FAILED', this.constructor.name)); throw error; } }; this.applicationBuildAndUpload = async (settings) => { try { const getApplicationNameAndIdResult = await this.voxApplicationService.getApplicationNameAndId(settings); const { applicationName } = getApplicationNameAndIdResult; const applicationId = getApplicationNameAndIdResult.applicationId ?? (await this.addApplicationToPlatform(applicationName)); const voxRulesList = await this.getRulesByApplicationName(applicationName); const rawApplication = { applicationName, applicationId, modified: new Date(), secureRecordStorage: false, }; const rulesFromPlatform = await this.voxRuleService.downloadApplicationRules(rawApplication); await this.voxScenarioService.cleanupDist(); for (const voxRule of voxRulesList) { const { scenarios, rulePattern, ruleName } = voxRule; await this.voxScenarioService.build(scenarios); const { isForce } = settings; await this.voxScenarioService.upload(scenarios, isForce); const uploadedScenariosInfo = await this.voxScenarioService.getScenarioInfoFromPlatform(scenarios); const existingRule = rulesFromPlatform?.find((rule) => rule.ruleName === ruleName); if (!existingRule) { await this.voxRuleService.uploadApplicationRule(applicationId, ruleName, uploadedScenariosInfo.map(({ scenarioId }) => scenarioId), rulePattern); } const rulePatternChanged = existingRule?.rulePattern !== rulePattern; if (existingRule && rulePatternChanged) { await this.voxRuleService.updateApplicationRule(rulePattern, existingRule.ruleId); } const scenariosChanged = existingRule?.scenarios // TODO: Nodejs mapper error (snake_case to camelCase) // @ts-expect-error: Nodejs mapper error (snake_case to camelCase) // eslint-disable-next-line @typescript-eslint/no-unsafe-return .map((scenario) => scenario.scenario_name) .toString() !== scenarios.toString(); if (existingRule && scenariosChanged) { await this.bindScenarios(existingRule, uploadedScenariosInfo, applicationId, applicationName); } } const rawRulesWithOldOrder = await this.voxRuleService.downloadApplicationRules(rawApplication); await this.voxRuleService.saveRulesMetadata(rawApplication, rawRulesWithOldOrder); await this.voxRuleService.reorderRules(rawRulesWithOldOrder, voxRulesList); const rawRules = await this.voxRuleService.downloadApplicationRules(rawApplication); await this.voxRuleService.saveRulesMetadata(rawApplication, rawRules); } catch (error) { console.error(this.lmg.generate('ERR__APPLICATION_BUILD_AND_UPLOAD_FAILED', this.constructor.name)); throw error; } }; this.applicationByRuleBuild = async (settings) => { try { const { applicationName, applicationId } = settings; const fullApplicationName = await this.voxApplicationService.getApplicationFullName(applicationName); const { scenarios } = (await this.getScenariosByRuleId(fullApplicationName, applicationId, settings.ruleId)) ?? (await this.getScenariosByRuleName(fullApplicationName, applicationId, settings.ruleName)); await this.voxScenarioService.build(scenarios); } catch (error) { console.error(this.lmg.generate('ERR__APPLICATION_BY_RULE_BUILD_FAILED', this.constructor.name)); throw error; } }; this.applicationByRuleBuildAndUpload = async (settings) => { try { const { applicationName, applicationId } = await this.voxApplicationService.getApplicationNameAndId(settings); const { isForce, ruleName, ruleId } = settings; let newApplicationId; if (!applicationId && !ruleId && !ruleName) { newApplicationId = await this.addApplicationToPlatform(applicationName); } const { scenarios, rulePattern } = (await this.getScenariosByRuleId(applicationName, applicationId || newApplicationId, ruleId)) || (await this.getScenariosByRuleName(applicationName, applicationId || newApplicationId, ruleName)); await this.voxScenarioService.build(scenarios); await this.voxScenarioService.upload(scenarios, isForce); const uploadedScenariosInfo = await this.voxScenarioService.getScenarioInfoFromPlatform(scenarios); const rawApplication = { applicationName, applicationId: applicationId || newApplicationId, modified: new Date(), secureRecordStorage: false, }; const existingRule = (await this.voxRuleService.downloadApplicationRules(rawApplication))?.find((rule) => rule.ruleName === settings.ruleName || rule.ruleId === settings.ruleId); if (settings.ruleId && !existingRule) { throw new Error(this.lmg.generate('ERR__RULE_ID_DOES_NOT_EXIST', settings.ruleId.toString())); } if (!existingRule) { await this.voxRuleService.uploadApplicationRule(applicationId || newApplicationId, settings.ruleName, uploadedScenariosInfo.map(({ scenarioId }) => scenarioId), rulePattern); } const rulePatternChanged = existingRule?.rulePattern !== rulePattern; if (existingRule && rulePatternChanged) { await this.voxRuleService.updateApplicationRule(rulePattern, existingRule.ruleId); } const scenariosChanged = existingRule?.scenarios // TODO: Nodejs mapper error (snake_case to camelCase) // @ts-expect-error: Nodejs mapper error (snake_case to camelCase) // eslint-disable-next-line @typescript-eslint/no-unsafe-return .map((scenario) => scenario.scenario_name) .toString() !== scenarios.toString(); if (existingRule && scenariosChanged) { await this.bindScenarios(existingRule, uploadedScenariosInfo, applicationId || newApplicationId, applicationName); } const rawRules = await this.voxRuleService.downloadApplicationRules(rawApplication); await this.voxRuleService.saveRulesMetadata(rawApplication, rawRules); } catch (error) { console.error(this.lmg.generate('ERR__APPLICATION_BY_RULE_BUILD_AND_UPLOAD_FAILED', this.constructor.name)); throw error; } }; } } exports.ApplicationModule = ApplicationModule;