@pega/custom-dx-components
Version:
Utility for building custom UI components
439 lines (327 loc) • 13.3 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 {
checkPathAccess,
showVersion,
addDebugLog,
checkLibraryAndArchives,
getConfigDefaults,
getLibraryBased,
getLibraryBasedCL,
zipVersionAndArchive,
zipVersionAndArchiveCL,
cleanUpTemp,
checkAccessTokenExpiration
} from '../../util.js';
import { TASKS_CONFIG_JSON_FILENAME, ARCHIVES_PATH, BIN_ARCHIVES_PATH } from '../../constants.js';
import { getFilePathQuestions, getLibraryQuestion, getLibraryVersionQuestion, updateSavedExportFilePath, getServerOrDirectoryQuestion } from './helper.js';
import { localBuildLibrary } from '../build-lib/index.js';
import publishArchive from '../publish-archive/index.js';
import inquirerFuzzyPath from '@pega/inquirer-fuzzy-path';
export const DXCB_CONFIG_INTERNAL_JSON_FILENAME = 'src/dxcb.config.json';
const currentDirectory = process.cwd();
const pegaConfigJsonPath = join(currentDirectory, TASKS_CONFIG_JSON_FILENAME);
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' });
}
};
export const exportCLArch = async(exportPath, orgLibName, selectedVersion) => {
addDebugLog("exportCLArch", `exportPath: ${exportPath}, orgLibName: ${orgLibName}, selectedVersion: ${selectedVersion}`, "");
const currentDirectory = process.cwd();
const archiveDirectory = join (currentDirectory, BIN_ARCHIVES_PATH);
const fileName = `${orgLibName}_${selectedVersion}.zip`;
const archFileName = join(archiveDirectory, fileName);
const configDef = await getConfigDefaults();
const exportFile = join(exportPath, fileName);
let output;
// need to build the library
console.log(chalk.green(`\nBuilding binaries...\n`));
const arOrgLib = orgLibName.split("_")
const arVersion = selectedVersion.split("-");
const devBuild = arVersion.length > 1 ? true : false;
await localBuildLibrary(arOrgLib[0], arOrgLib[1], arVersion[0], devBuild);
const libraryDir = join(currentDirectory, orgLibName, selectedVersion );
if (fs.existsSync(libraryDir)) {
console.log(chalk.green(`\nExporting binaries...\n`));
if (!fs.existsSync(exportPath)) {
console.log(`\Path: ${chalk.yellow(`${exportPath}`)} doesn't exist.`);
const newPathAnswer = await inquirer.prompt([
{
name: 'createNewPath',
type: 'confirm',
message: 'Create path',
default: true
},
]);
const createNewPath = newPathAnswer.createNewPath;
if (createNewPath) {
fs.mkdirSync(exportPath, { recursive: true });
await updateSavedExportFilePath(exportPath);
}
else {
console.log(chalk.green("Store not exported."));
process.exit();
}
}
if (fs.existsSync(exportFile)) {
console.log(`\nFile: ${chalk.yellow(`${fileName}`)} already exists in ${chalk.yellow(`${exportPath}`)}.`);
const overwriteQuestion = await inquirer.prompt([
{
name: 'overWriteFile',
type: 'confirm',
message: 'Overwrite',
default: true
},
]);
if (!overwriteQuestion.overWriteFile) {
console.log(chalk.green("Store not exported."));
process.exit();
}
}
// archive it
output = await zipVersionAndArchiveCL(configDef.currentOrgLib, configDef.buildVersion);
// if archiving, need to wait before copying
output.on('close', function() {
fs.copyFileSync(archFileName, exportFile );
console.log(`\n${chalk.green(`${fileName}`)} has been exported to ${chalk.green(`${exportPath}`)}`);
});
}
else {
console.log.chalk.green(`\nBinary does not exist.`);
}
}
export const exportArch = async(exportPath, orgLibName, selectedVersion, fullArchive = "Full", currentOrArchive = "" ) => {
addDebugLog("exportArch", `exportPath: ${exportPath}, orgLibName: ${orgLibName}, selectedVersion: ${selectedVersion}`, "");
const currentDirectory = process.cwd();
const archiveDirectory = join (currentDirectory, ARCHIVES_PATH, `${orgLibName}`, `${selectedVersion}`);
const fileName = `${orgLibName}_${selectedVersion}.arch.zip`;
const archFileName = join(archiveDirectory, fileName);
const configDef = await getConfigDefaults();
const exportFile = join(exportPath, fileName);
let output;
let archiveBeforeStore = false;
if (fullArchive != "Full") {
await exportCLArch(exportPath, orgLibName, selectedVersion);
return;
}
if (orgLibName === configDef.currentOrgLib && selectedVersion === configDef.buildVersion) {
// We are just going to archive before store and not ask
archiveBeforeStore = true;
}
if (!fs.existsSync(exportPath)) {
console.log(`\Path: ${chalk.yellow(`${exportPath}`)} doesn't exist.`);
const newPathAnswer = await inquirer.prompt([
{
name: 'createNewPath',
type: 'confirm',
message: 'Create path',
default: true
},
]);
const createNewPath = newPathAnswer.createNewPath;
if (createNewPath) {
fs.mkdirSync(exportPath, { recursive: true });
await updateSavedExportFilePath(exportPath);
}
else {
console.log(chalk.green("Store not exported."));
process.exit();
}
}
if (fs.existsSync(exportFile)) {
console.log(`\nFile: ${chalk.yellow(`${fileName}`)} already exists in ${chalk.yellow(`${exportPath}`)}.`);
const overwriteQuestion = await inquirer.prompt([
{
name: 'overWriteFile',
type: 'confirm',
message: 'Overwrite',
default: true
},
]);
if (!overwriteQuestion.overWriteFile) {
console.log(chalk.green("Store not exported."));
process.exit();
}
}
if (archiveBeforeStore) {
// archive it
output = await zipVersionAndArchive(configDef.currentOrgLib, configDef.buildVersion);
// if archiving, need to wait before copying
output.on('close', function() {
fs.copyFileSync(archFileName, exportFile );
console.log(`\n${chalk.green(`${fileName}`)} has been exported to ${chalk.green(`${exportPath}`)}`);
});
}
else {
fs.copyFileSync(archFileName, exportFile );
console.log(`\n${chalk.green(`${fileName}`)} has been exported to ${chalk.green(`${exportPath}`)}`);
}
}
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);
}
}
export default async options => {
await showVersion();
await checkLibraryAndArchives();
await checkPathAccess(pegaConfigJsonPath);
const isLibraryBased = getLibraryBased();
if (!isLibraryBased) {
console.log(`Command only supported for ${chalk.bold.green('library mode')} components.`)
process.exit();
}
const isLibraryBasedCL = getLibraryBasedCL();
await cleanUpTemp();
addDebugLog("exportArchive", "", "+");
let exportTo = "";
if (options.params.length >= 8) {
// params pick full, what library/name and path
// vs no params then we will select the current library
let fullArchive = options.params[3];
const libraryName = options.params[4];
const libraryVersion = options.params[5];
const filePath = options.params[6];
exportTo = "Directory";
const currentOrArchive = options.params[7];
await exportArch(filePath, libraryName, libraryVersion, fullArchive, currentOrArchive );
}
else {
let orgLibName = "";
let selectedVersion = "";
let fullArchive = "";
// if (options.params.length >= 5) {
// fullArchive = options.params[3];
// orgLibName = options.params[4];
// if (options.params.length >= 6) {
// selectedVersion = options.params[5];
// }
// }
// disable question to build "CL"
// if (fullArchive === "" ) {
// const fullArchiveQuestions = await getFullArchiveQuestions();
// const fullArchiveAnswers = await inquirer.prompt(fullArchiveQuestions);
// ({ fullArchive } = fullArchiveAnswers);
// }
// force full archive, binary deprecated
fullArchive = "Full";
let filePathQuestions;
let filePathAnswers;
let filePath;
// if Binary, then we need to just build the current library, get the results and
// and export an archive as zip
// currently this is deprecated, we are not going to export a CL as of yet.
if (fullArchive === "Binary") {
inquirer.registerPrompt('fuzzypath', inquirerFuzzyPath);
filePathQuestions = await getFilePathQuestions();
filePathAnswers = await inquirer.prompt(filePathQuestions);
({ filePath } = filePathAnswers);
await updateSavedExportFilePath(filePath);
const configDef = getConfigDefaults();
orgLibName = configDef.currentOrgLib;
selectedVersion = configDef.buildVersion;
}
else {
const configDef = getConfigDefaults();
orgLibName = configDef.currentOrgLib;
selectedVersion = configDef.buildVersion;
console.log(`\nExporting library ${chalk.bold.green(`${orgLibName}/${selectedVersion}`)}\n`);
// deprecating this code, only export current library, don't ask for others
// need to switchLib/Version to that library to export it
// await zipVersionAndArchive(configDef.currentOrgLib, configDef.buildVersion);
// console.log(chalk.bold.yellow(`Exporting from local store, be sure to "npm run storeLibVersion" if archiving current library.\n`));
// if (orgLibName === "") {
// const libraryQuestion = await getLibraryQuestion();
// const libraryAnswers = await inquirer.prompt(libraryQuestion);
// ({ orgLibName } = libraryAnswers);
// }
// if (selectedVersion === "") {
// const libraryVersionQuestion = await getLibraryVersionQuestion(orgLibName);
// const libraryVersionAnswer = await inquirer.prompt(libraryVersionQuestion);
// ({ selectedVersion } = libraryVersionAnswer);
// }
if (isLibraryBasedCL) {
if (exportTo === "") {
const serverOrDirectoryQuestion = await getServerOrDirectoryQuestion();
const serverOrDirectoryAnswer = await inquirer.prompt(serverOrDirectoryQuestion);
({ exportTo } = serverOrDirectoryAnswer);
}
}
else {
exportTo = "Directory";
}
if (exportTo === "Directory") {
inquirer.registerPrompt('fuzzypath', inquirerFuzzyPath);
filePathQuestions = await getFilePathQuestions();
filePathAnswers = await inquirer.prompt(filePathQuestions);
({ filePath } = filePathAnswers);
await updateSavedExportFilePath(filePath);
await exportArch( filePath, orgLibName, selectedVersion, fullArchive);
}
else {
await checkAccessTokenExpiration();
const tasks = new Listr(
[
{
title: 'Saving local archive',
task: async () => {
// local archive so it will get stored
await zipVersionAndArchive(orgLibName, selectedVersion);
}
}
],
{ concurrent: false, exitOnError: true }
);
await tasks.run().catch(err => {
console.log(chalk.bold.red(err.toString()));
process.exit(1);
});
await publishArchive(orgLibName, selectedVersion);
}
}
}
addDebugLog("exportArchive", "END", "-");
};