@pega/custom-dx-components
Version:
Utility for building custom UI components
988 lines (752 loc) • 31.5 kB
JavaScript
import fs from 'fs';
import { promisify } from 'util';
import { join } from 'path';
import inquirer from 'inquirer';
import ncp from 'ncp';
import chalk from 'chalk';
import { Listr } from 'listr2';
import StreamZip from 'node-stream-zip';
import inquirerFuzzyPath from '@pega/inquirer-fuzzy-path';
import {
sanitize,
checkPathAccess,
showVersion,
getDirectoryFiles,
addDebugLog,
checkAccessTokenExpiration,
getConfigDefaults,
getLibraryBased,
getLibraryBasedCL,
unZipFromArchive,
zipVersionAndArchive,
getLibraryArchiveDirectories,
getHaveDependencyDifference,
hasLibraryAndVersion,
cleanUpTemp,
hasArchives,
restoreFromArchive,
forceDefaultsUpdate,
getUseInputConfig,
getInputConfigForCommand,
getPegaServerConfig
} from '../../util.js';
import { TASKS_CONFIG_JSON_FILENAME, ARCHIVES_PATH, TEMP_PATH } from '../../constants.js';
import { getFilePathQuestions, getFileNameQuestions, updateTempArchive, updateSavedFilePath, getServerOrDirectoryQuestion, getLibraryArchiveQuestion, getServerLibraryArchives, getServerLibraryArchive } from './helper.js';
import { showCurrentStatus } from '../show-status/index.js';
export const DXCB_CONFIG_INTERNAL_JSON_FILENAME = 'src/dxcb.config.json';
const currentDirectory = process.cwd();
const pegaConfigJsonPath = join(currentDirectory, TASKS_CONFIG_JSON_FILENAME);
import {
convertIntoPascalCase,
getComponentDirectoryPath
} from '../../util.js';
const copy = promisify(ncp);
export const updateConfig = async (
{
oldComponentKey,
newComponentKey,
library,
version,
targetDirectory,
},
options,
onlyCompanion = false
) => {
addDebugLog("updateConfig", `oldComponentKey: ${oldComponentKey}, newComponentKey: ${newComponentKey}`, "");
let configData = fs.readFileSync(join(targetDirectory, "/config.json"), { encoding: 'utf8' });
configData = configData && JSON.parse(configData);
configData.name = newComponentKey;
if (configData.componentKey) configData.componentKey = newComponentKey;
configData.library = library;
configData.version = version;
// stringify "4", makes the json string look like JSON in the file, formatted instead of a single line
fs.writeFileSync(join(targetDirectory, "/config.json"), JSON.stringify(configData, null, 4), { encoding: 'utf8',flag:'w' });
};
export const updateFile = async (
fileName,
oldComponentKeyPC,
newComponentKeyPC,
targetDirectory,
) => {
addDebugLog("updateFile", `fileName: ${fileName}, oldComponentKeyPC: ${oldComponentKeyPC}, newComponentKeyPC: ${newComponentKeyPC}, targetDirectory: ${targetDirectory}`, "");
let fileData = fs.readFileSync(join(targetDirectory, "/", fileName), { encoding: 'utf8' });
if (fileData.indexOf(oldComponentKeyPC) >= 0) {
fileData = fileData.replaceAll(oldComponentKeyPC, newComponentKeyPC);
fs.writeFileSync(join(targetDirectory, "/", fileName), fileData, { encoding: 'utf8',flag:'w' });
}
};
// rename the component
export const renameComponent = async (
componentKey,
library,
version,
options
) => {
addDebugLog("renameComponent", `library: ${library}, componentKey: ${componentKey}`, "");
const componentName = componentKey.split("_")[2];
const configDef = getConfigDefaults();
const newComponentKey = `${library}_${componentName}`;
const oldComponentKey = componentKey;
const newComponentKeyPC = convertIntoPascalCase(newComponentKey);
const oldComponentKeyPC = convertIntoPascalCase(oldComponentKey);
const currentDirectory = await getComponentDirectoryPath(componentKey);
const targetDirectory = await getComponentDirectoryPath(newComponentKey);
// custom component
try {
fs.renameSync(currentDirectory, targetDirectory);
} catch(err) {
console.log(err)
}
const targetFileList = await getDirectoryFiles(targetDirectory);
for (var fileIndex in targetFileList) {
const fileName = targetFileList[fileIndex];
if (fileName === "config.json") {
await updateConfig(
{
oldComponentKey,
newComponentKey,
componentName,
library,
version,
targetDirectory,
},
options
);
}
else {
await updateFile(
fileName,
oldComponentKeyPC,
newComponentKeyPC,
targetDirectory );
}
} // for
return newComponentKey;
};
export const getPackageOrg = async(packagePath) => {
const sPackData = fs.readFileSync(packagePath, { encoding: 'utf8' });
const packData = sPackData && JSON.parse(sPackData);
return packData.organization;
}
export const getLocalConfigData = async(tasksPath) => {
const isLibraryBasedCL = getLibraryBasedCL();
let configData = { library: "", version: "", buildVersion: "", devBuild: false};
const sTaskData = fs.readFileSync(tasksPath, { encoding: 'utf8' });
const taskData = sTaskData && JSON.parse(sTaskData);
let devBuild = taskData["server-config"].devBuild;
// no -dev in PegaInfinity
if (isLibraryBasedCL) {
devBuild = false;
}
configData.library = taskData["component"].library;
configData.version = taskData["component"].version;
configData.devBuild = devBuild;
configData.buildVersion = devBuild ? configData.version.concat("-dev") : configData.version;
return configData;
}
export const moveComp = async(componentKey, orgLibName, version, copyShared, options) => {
// put lib/version into temp directory
const currentDirectory = process.cwd();
const tempDirectory = join(currentDirectory, TEMP_PATH);
const archiveDirectory = join (currentDirectory, ARCHIVES_PATH, `${orgLibName}`, `${version}`);
const fileName = `${orgLibName}_${version}.arch.zip`;
const archFileName = join(archiveDirectory, fileName);
await unZipFromArchive(archFileName);
// rename the component
const newComponentKey = await renameComponent(componentKey, orgLibName, version);
const currentCompPath = join(currentDirectory, "src", "components");
const tempCompPath = join(tempDirectory, "src", "components");
const currentComponentsPath = join(currentCompPath, `${newComponentKey}`);
const tempDirectoryComponents = join(tempCompPath, `${newComponentKey}`);
const currentSharedPath = join(currentCompPath, "shared");
const targetSharedPath = join(tempCompPath, "shared");
// copy component into temp directory
fs.cpSync(currentComponentsPath, tempDirectoryComponents, { recursive: true, force: true });
// remove from components
fs.rmSync(currentComponentsPath, { recursive: true, force: true, maxRetries: 2 });
// copy shared
if (copyShared) {
fs.cpSync(currentSharedPath, targetSharedPath, { recursive: true, force: true });
}
console.log(`\nCopied ${chalk.green(`${componentKey}`)} to ${chalk.green(`${orgLibName}/${version}`)} as ${chalk.green(`${newComponentKey}`)}\n`);
// rearchive temp directory
await zipVersionAndArchive(orgLibName, version, tempDirectory);
// delete temp directory
fs.rmSync(tempDirectory, { recursive: true, force: true, maxRetries: 2 });
}
export const importArch = async(filePath, fileName, hadArchive) => {
addDebugLog("importArch", `filePath: ${filePath}, fileName: ${fileName}`, "");
const currentDirectory = process.cwd();
const storeDirectory = join (currentDirectory, ARCHIVES_PATH);
if (!fs.existsSync(storeDirectory)) {
fs.mkdirSync(storeDirectory);
}
const tempDirectory = join(currentDirectory, TEMP_PATH);
const zipFilePath = join(filePath, fileName);
// we are going to use node stream zip to list contents of archive first,
// before we un archive to a temp directory. If pass, then un archive
let passCount = 0;
// check to see if have a tasks.config.json and package,json file, if not, archive not good
const tempTasksConfig = join(tempDirectory, "tasks.config.json");
const tempPackage = join(tempDirectory, "package.json");
const tasksConfig = "tasks.config.json";
const packageJson = "package.json";
try {
const testZip = new StreamZip.async({ file: zipFilePath});
const entries = await testZip.entries();
for (const entry of Object.values(entries)) {
if ( entry.name.indexOf(packageJson) >= 0 || entry.name.indexOf(tasksConfig) >= 0) {
passCount++;
}
}
// Do not forget to close the file once you're done
await testZip.close();
}
catch (ex) {
passCount = 0;
}
if (passCount < 2) {
console.log(chalk.red.bold(`Zip file: ${fileName} not a compatible DX Component archive.`));
process.exit(1);
}
await unZipFromArchive(zipFilePath);
// need to get info from tasks.config and package.json
// we won't rely on name of file, as owner can change it
let organization = await getPackageOrg(tempPackage);
let localConfig = await getLocalConfigData(tempTasksConfig);
let libName = localConfig.library;
let orgLibName = `${organization}_${libName}`;
const version = localConfig.buildVersion;
const devBuild = localConfig.devBuild;
const configDef = getConfigDefaults();
if (organization !== configDef.organization) {
console.log(`\nImported ${chalk.yellow(`${orgLibName}/${version}`)} is not the same organization as your current organization: ${chalk.yellow(`${configDef.organization}`)}.`);
console.log(`\nTo import, the organization of the components will be changed to match your organization.`);
console.log(`\n\t>>> If you don't want this to happen, then end and create a new project with an organization`);
console.log(`\t of ${chalk.yellow(`${organization}`)} and import there.\n`);
const proceedAnswers = await inquirer.prompt([
{
name: 'okToContinue',
type: 'confirm',
message: `Ok to proceed ?`,
default: true
}
]);
if (proceedAnswers.okToContinue) {
// check if new version matches existing
// -dev is already on version, if present, so "false", for devBuild here
const alreadyExists = await hasLibraryAndVersion(libName, version, false);
if (alreadyExists) {
console.log(`${chalk.yellow(`${configDef.organization}_${libName}/${version}`)} already exists.`);
const archDirectories = await getLibraryArchiveDirectories();
const newLibNameAnswers = await inquirer.prompt([
{
name: 'libraryName',
message: 'Enter new library name',
validate: value => {
/* value should not be empty
It should not have spaces
It should not start with a number
Only case-insensitive alphanumeric values are allowed
*/
if (value && !/^\d/.test(value) && value === sanitize(value)) {
if (archDirectories && archDirectories.length > 0) {
const newOrgLib = `${configDef.organization}_${value}`;
if (archDirectories.includes(newOrgLib)) {
return `Library ${value} already exists.`;
}
else {
return true;
}
}
else {
return true;
}
}
else {
return 'Only alphanumeric values are allowed, starting with alphabets, no spaces.';
}
}
}
]);
libName = newLibNameAnswers.libraryName;
}
// rename orgLibName
orgLibName = `${configDef.organization}_${libName}`;
// update temp with new info
await updateTempArchive(libName, version, devBuild);
}
else {
process.exit();
}
}
// rearchive temp directory
await zipVersionAndArchive(orgLibName, version, tempDirectory);
// delete temp directory
fs.rmSync(tempDirectory, { recursive: true, force: true, maxRetries: 2 });
if (hadArchive) {
if (orgLibName === configDef.currentOrgLib && version === configDef.version) {
console.log(`\n${chalk.bold.green(`${fileName}`)} has been imported!`);
console.log(`It is the same library/version as your current source.`);
console.log(`--> You can retrieve and replace current source via ${chalk.bold.green(`npm run restoreLibVersion`)}.`);
console.log("\n");
}
else if (orgLibName === configDef.currentOrgLib && version != configDef.version) {
console.log(`\n${chalk.bold.green(`${fileName}`)} has been imported!`);
console.log(`--> You can switch to ${chalk.bold.green(`${orgLibName}/${version}`)} via ${chalk.bold.green(`npm run switchLibVersion`)}.`);
console.log("\n");
}
else {
console.log(`\n${chalk.bold.green(`${fileName}`)} has been imported!`);
console.log(`--> You can switch to ${chalk.bold.green(`${orgLibName}/${version}`)} via ${chalk.bold.green(`npm run switchLib`)}.`);
console.log("\n");
}
}
else {
const switchToFileName = `${orgLibName}_${version}.arch.zip`;
const tasks = new Listr(
[
{
title: `Restoring ${orgLibName}/${version}`,
task: async () => {
await restoreFromArchive(switchToFileName, orgLibName, version);
}
}
],
{ concurrent: false, exitOnError: true }
);
console.log(`\n${chalk.green(`${fileName}`)} has been imported!`);
await tasks.run().catch(err => {
console.log(chalk.bold.red(err.toString()));
process.exit(1);
});
console.log(`${chalk.bold.green(`\nSwitched to ${orgLibName}/${version}!\n`)}`);
await forceDefaultsUpdate();
await showCurrentStatus();
if (getHaveDependencyDifference()) {
console.log('\n***************************************************************');
console.log(chalk.bold.yellow('Dependencies have changed between versions, recommend updating.'));
console.log(`>>> PLEASE run ${chalk.bold.yellow("'npm update'")}.`);
console.log('***************************************************************\n');
}
}
}
export const importArchServer = async(filePath, fileName, hadArchive) => {
addDebugLog("importArch", `filePath: ${filePath}, fileName: ${fileName}`, "");
const currentDirectory = process.cwd();
const storeDirectory = join (currentDirectory, ARCHIVES_PATH);
if (!fs.existsSync(storeDirectory)) {
fs.mkdirSync(storeDirectory);
}
const tempDirectory = join(currentDirectory, TEMP_PATH);
const zipFilePath = join(filePath, fileName);
// we are going to use node stream zip to list contents of archive first,
// before we un archive to a temp directory. If pass, then un archive
let passCount = 0;
// check to see if have a tasks.config.json and package,json file, if not, archive not good
const tempTasksConfig = join(tempDirectory, "tasks.config.json");
const tempPackage = join(tempDirectory, "package.json");
const tasksConfig = "tasks.config.json";
const packageJson = "package.json";
let testZip;
try {
testZip = new StreamZip.async({ file: zipFilePath});
const entries = await testZip.entries();
for (const entry of Object.values(entries)) {
if ( entry.name.indexOf(packageJson) >= 0 || entry.name.indexOf(tasksConfig) >= 0) {
passCount++;
}
}
}
catch (ex) {
passCount = 0;
}
if (passCount < 2) {
console.log(chalk.red.bold(`Zip file: ${fileName} not a compatible DX Component archive.`));
// Do not forget to close the file once you're done
await testZip.close();
process.exit(1);
}
// make directory in temp dir, can NOT be the same directory as the zip file is in
const dirName = fileName.replaceAll(".zip", "");
const newDirPath = join(TEMP_PATH, dirName);
fs.mkdirSync(newDirPath);
const count = await testZip.extract(null, newDirPath);
// Do not forget to close the file once you're done
await testZip.close();
// we want file contents to be in the TEMP_PATH (copying, but temp directory eventually will be deleted)
fs.cpSync(newDirPath, TEMP_PATH, {recursive: true});
// await unZipFromArchive(zipFilePath);
// need to get info from tasks.config and package.json
// we won't rely on name of file, as owner can change it
let organization = await getPackageOrg(tempPackage);
let localConfig = await getLocalConfigData(tempTasksConfig);
let libName = localConfig.library;
let orgLibName = `${organization}_${libName}`;
const version = localConfig.buildVersion;
const devBuild = localConfig.devBuild;
const configDef = getConfigDefaults();
if (organization !== configDef.organization) {
console.log(`\nImported ${chalk.yellow(`${orgLibName}/${version}`)} is not the same organization as your current organization: ${chalk.yellow(`${configDef.organization}`)}.`);
console.log(`\nTo import, the organization of the components will be changed to match your organization.`);
console.log(`\n\t>>> If you don't want this to happen, then end and create a new project with an organization`);
console.log(`\t of ${chalk.yellow(`${organization}`)} and import there.\n`);
const proceedAnswers = await inquirer.prompt([
{
name: 'okToContinue',
type: 'confirm',
message: `Ok to proceed ?`,
default: true
}
]);
if (proceedAnswers.okToContinue) {
// check if new version matches existing
// -dev is already on version, if present, so "false", for devBuild here
const alreadyExists = await hasLibraryAndVersion(libName, version, false);
if (alreadyExists) {
console.log(`${chalk.yellow(`${configDef.organization}_${libName}/${version}`)} already exists.`);
const archDirectories = await getLibraryArchiveDirectories();
const newLibNameAnswers = await inquirer.prompt([
{
name: 'libraryName',
message: 'Enter new library name',
validate: value => {
/* value should not be empty
It should not have spaces
It should not start with a number
Only case-insensitive alphanumeric values are allowed
*/
if (value && !/^\d/.test(value) && value === sanitize(value)) {
if (archDirectories && archDirectories.length > 0) {
const newOrgLib = `${configDef.organization}_${value}`;
if (archDirectories.includes(newOrgLib)) {
return `Library ${value} already exists.`;
}
else {
return true;
}
}
else {
return true;
}
}
else {
return 'Only alphanumeric values are allowed, starting with alphabets, no spaces.';
}
}
}
]);
libName = newLibNameAnswers.libraryName;
}
// rename orgLibName
orgLibName = `${configDef.organization}_${libName}`;
// update temp with new info
await updateTempArchive(libName, version, devBuild);
}
else {
process.exit();
}
}
// rearchive temp directory
await zipVersionAndArchive(orgLibName, version, tempDirectory);
// delete temp directory
fs.rmSync(tempDirectory, { recursive: true, force: true, maxRetries: 2 });
if (hadArchive) {
if (orgLibName === configDef.currentOrgLib && version === configDef.version) {
console.log(`\n${chalk.bold.green(`${fileName}`)} has been imported!`);
console.log(`It is the same library/version as your current source.`);
console.log(`--> You can retrieve and replace current source via ${chalk.bold.green(`npm run restoreLibVersion`)}.`);
console.log("\n");
}
else if (orgLibName === configDef.currentOrgLib && version != configDef.version) {
console.log(`\n${chalk.bold.green(`${fileName}`)} has been imported!`);
console.log(`--> You can switch to ${chalk.bold.green(`${orgLibName}/${version}`)} via ${chalk.bold.green(`npm run switchLibVersion`)}.`);
console.log("\n");
}
else {
console.log(`\n${chalk.bold.green(`${fileName}`)} has been imported!`);
console.log(`--> You can switch to ${chalk.bold.green(`${orgLibName}/${version}`)} via ${chalk.bold.green(`npm run switchLib`)}.`);
console.log("\n");
}
}
else {
const switchToFileName = `${orgLibName}_${version}.arch.zip`;
const tasks = new Listr(
[
{
title: `Restoring ${orgLibName}/${version}`,
task: async () => {
await restoreFromArchive(switchToFileName, orgLibName, version);
}
}
],
{ concurrent: false, exitOnError: true }
);
console.log(`\n${chalk.green(`${fileName}`)} has been imported!`);
await tasks.run().catch(err => {
console.log(chalk.bold.red(err.toString()));
process.exit(1);
});
console.log(`${chalk.bold.green(`\nSwitched to ${orgLibName}/${version}!\n`)}`);
await forceDefaultsUpdate();
await showCurrentStatus();
if (getHaveDependencyDifference()) {
console.log('\n***************************************************************');
console.log(chalk.bold.yellow('Dependencies have changed between versions, recommend updating.'));
console.log(`>>> PLEASE run ${chalk.bold.yellow("'npm update'")}.`);
console.log('***************************************************************\n');
}
}
}
export const getZipFileList = async(filePath) => {
if (fs.existsSync(filePath)) {
return fs
.readdirSync(filePath, { withFileTypes: true })
.filter(dirent => !dirent.isDirectory() && dirent.name.match(/.*\.(zip?)/ig))
.map(dirent => dirent.name);
}
else {
console.log(chalk.red.bold(`File path: ${filePath} does not exist or no permissions.`));
process.exit(1);
}
}
function decodeBase64(encodedString) {
try {
const decodedString = atob(encodedString);
return decodedString;
} catch (error) {
console.error("Error decoding base64 string:", error);
return null;
}
}
export const writeZipBuffer = async(fileName, fileBuffer) => {
const currentDirectory = process.cwd();
const tempDirectory = join(currentDirectory, TEMP_PATH);
const storeDirectory = join (currentDirectory, ARCHIVES_PATH);
if (!fs.existsSync(storeDirectory)) {
fs.mkdirSync(storeDirectory);
}
if (!fs.existsSync (tempDirectory)) {
fs.mkdirSync(tempDirectory);
}
const filePath = join(tempDirectory, fileName);
fs.writeFileSync(filePath, fileBuffer, 'base64');
}
export default async options => {
await showVersion();
// await checkLibraryAndArchives();
await checkPathAccess(pegaConfigJsonPath);
const isLibraryBased = getLibraryBased();
const isLibraryBasedCL = getLibraryBasedCL();
const useInputConfig = getUseInputConfig();
if (!isLibraryBased) {
console.log(`Command only supported for ${chalk.bold.green('library mode')} components.`)
process.exit();
}
const hasArch = await hasArchives();
await cleanUpTemp();
addDebugLog("importArchive", "", "+");
if (options.params.length >= 6) {
const localOrServer = options.params[3];
const filePath = options.params[4];
const fileName = options.params[5];
await importArch( filePath, fileName, hasArch);
}
else {
if (useInputConfig) {
const inputConfig = await getInputConfigForCommand("importLibVersion");
if (!inputConfig || Object.keys(inputConfig).length === 0) {
console.log(chalk.redBright("Configured for input config, but no input.config.json file found."));
process.exit(1);
}
const serverOrDirectory = inputConfig.serverOrDirectory;
const filePath = inputConfig.fileLocation;
const fileName = inputConfig.fileName;
const serverAppName = "ComponentLibraryArchive";
const serverArchiveName = inputConfig.serverArchiveName;
const serverArchiveType = "zip";
const serverRulesetName = inputConfig.serverRulesetName;
const serverRulesetVersion = inputConfig.serverRulesetVersion;
console.log("");
if (serverOrDirectory.toLowerCase() === "server") {
await checkAccessTokenExpiration();
if (serverArchiveName) {
// ALL option
const defaultPegaServerConfig = await getPegaServerConfig();
let fileName = `${serverArchiveName}.${serverArchiveType}`;
let fileData;
console.log("");
const tasks = new Listr(
[
{
title: 'Fetching archive from server',
task: async () => {
// get archive
fileData = await getServerLibraryArchive(serverAppName, serverArchiveName, serverArchiveType, serverRulesetName, serverRulesetVersion);
}
},
{
title: 'Saving archive in store',
task: async () => {
await writeZipBuffer(fileName, fileData.pyFileSource);
// import archive
const currentDirectory = process.cwd();
const tempDirectory = join(currentDirectory, TEMP_PATH);
await importArchServer( tempDirectory, fileName, hasArch);
}
}
],
{ concurrent: false, exitOnError: true }
);
await tasks.run().catch(err => {
console.log(chalk.bold.red(err.toString()));
process.exit(1);
});
}
else {
// No library with that name
console.log(chalk.redBright(`No library archives exist on server.`));
process.exit();
}
}
else {
const tasks = new Listr(
[
{
title: `Importing archive`,
task: async () => {
await importArch( filePath, fileName, hasArch);
}
}
],
{ concurrent: false, exitOnError: true }
);
await tasks.run().catch(err => {
console.log(chalk.bold.red(err.toString()));
process.exit(1);
});
console.log("");
// reapply to save if changed, because imported task.config may have overridden and we want
// to keep what was entered as the latest
await updateSavedFilePath(filePath);
}
}
else {
inquirer.registerPrompt('fuzzypath', inquirerFuzzyPath);
let importFrom = "Directory";
if (isLibraryBasedCL) {
const localOrServerQuestion = await getServerOrDirectoryQuestion();
const localOrServerAnswer = await inquirer.prompt(localOrServerQuestion);
({importFrom} = localOrServerAnswer);
}
else {
importFrom = "Directory";
}
if (importFrom === "Server") {
await checkAccessTokenExpiration();
let archiveVersions = [];
try {
archiveVersions = await getServerLibraryArchives();
}
catch (ex) {
console.log(chalk.redBright(ex));
process.exit(1);
}
if (archiveVersions && archiveVersions.pxResults.length > 0) {
// ALL option
const defaultPegaServerConfig = await getPegaServerConfig();
console.log(`\nRetrieved archives from server ${chalk.bold.green(`${defaultPegaServerConfig.server}`)}.`)
// to name value pairs
const archiveResults = archiveVersions["pxResults"].map( archive => ( { value: `${archive.pyApplicationName},${archive.pyFileName},${archive.pyFileType},${archive.pyRuleSet},${archive.pyRuleSetVersion}`, name: `${archive.pyLabel}, ${archive.pyRuleSet}:${archive.pyRuleSetVersion}` }) );
const versionQuestions = await getLibraryArchiveQuestion(archiveResults);
const versionAnswers = await inquirer.prompt(versionQuestions);
const {archiveData} = versionAnswers;
if (archiveData != "") {
const arArchData = archiveData.split(",");
let fileName = `${arArchData[1]}.${arArchData[2]}`;
let fileData;
console.log("");
const tasks = new Listr(
[
{
title: 'Fetching archive from server',
task: async () => {
// get archive
fileData = await getServerLibraryArchive(arArchData[0],arArchData[1], arArchData[2], arArchData[3], arArchData[4]);
}
},
{
title: 'Saving archive in store',
task: async () => {
await writeZipBuffer(fileName, fileData.pyFileSource);
// import archive
const currentDirectory = process.cwd();
const tempDirectory = join(currentDirectory, TEMP_PATH);
await importArchServer( tempDirectory, fileName, hasArch);
}
}
],
{ concurrent: false, exitOnError: true }
);
await tasks.run().catch(err => {
console.log(chalk.bold.red(err.toString()));
process.exit(1);
});
}
}
else {
// No library with that name
console.log(chalk.redBright(`No library archives exist on server.`));
process.exit();
}
}
else {
let filePathQuestions;
try {
filePathQuestions = await getFilePathQuestions();
}
catch (ex) {
process.exit(1);
}
let filePathAnswers;
try {
filePathAnswers = await inquirer.prompt(filePathQuestions);
}
catch(ex) {
process.exit(1);
}
const { filePath } = filePathAnswers;
const zipFileList = await getZipFileList(filePath);
if (!zipFileList || zipFileList.length === 0) {
console.log(chalk.red.bold(`No zip files exist at path: ${filePath}`));
process.exit();
}
await updateSavedFilePath(filePath);
const fileNameQuestions = await getFileNameQuestions(zipFileList);
const fileNameAnswers = await inquirer.prompt(fileNameQuestions);
const {fileName} = fileNameAnswers;
console.log("");
const tasks = new Listr(
[
{
title: `Importing archive`,
task: async () => {
await importArch( filePath, fileName, hasArch);
}
}
],
{ concurrent: false, exitOnError: true }
);
await tasks.run().catch(err => {
console.log(chalk.bold.red(err.toString()));
process.exit(1);
});
console.log("");
// reapply to save if changed, because imported task.config may have overridden and we want
// to keep what was entered as the latest
await updateSavedFilePath(filePath);
}
}
}
addDebugLog("importArchive", "END", "-");
};