UNPKG

@pega/custom-dx-components

Version:

Utility for building custom UI components

357 lines (284 loc) 9.54 kB
import chalk from 'chalk'; import path from 'path'; import { join } from 'path'; import fetch from 'node-fetch'; import archiver from 'archiver'; import fs from 'fs'; import { addDebugLog, getConfigDefaults, getLibraryArchiveDirectories, getLibraryArchivesVersions, setConfigExportRelativePath, getComponentDirectoryPath, getPegaServerConfig, forceDefaultsUpdate } from '../../util.js'; export const SOURCE_OF_COMPONENT_TYPES = { SERVER: 'Server', LOCAL: 'Local' }; export const getFilePathQuestions = async () => { addDebugLog("getFilePathQuestions", "", ""); console.log("\nFile path examples:"); if (path.sep === "/") { console.log("\tMac OS/Unix:\t/Users/name/..."); } else { console.log("\tWindows:\tC:\\Users\\name\\...\n"); } const configDef = getConfigDefaults(); const currentDirectory = process.cwd(); const arPathParts = currentDirectory.split(path.sep); let defaultPath = join(arPathParts[0], arPathParts[1], arPathParts[2], configDef.exportRelativePath); let startDirectory = join(arPathParts[0], arPathParts[1], arPathParts[2]); if (path.sep === "/") { defaultPath = "/".concat(defaultPath); startDirectory = "/".concat(startDirectory).concat("/"); } return [ { name: 'filePath', type: 'fuzzypath', message: 'Enter full file path of directory to export zip file:', default: defaultPath, excludePath: nodePath => nodePath.startsWith('node_modules'), // excludePath :: (String) -> Bool // excludePath to exclude some paths from the file-system scan excludeFilter: nodePath => nodePath.indexOf('/.') >= 0, // excludeFilter :: (String) -> Bool // excludeFilter to exclude some paths from the final list, e.g. '.' itemType: 'directory', // itemType :: 'any' | 'directory' | 'file' // specify the type of nodes to display // default value: 'any' // example: itemType: 'file' - hides directories from the item list rootPath: startDirectory, // rootPath :: String // Root search directory suggestOnly: true, // suggestOnly :: Bool // Restrict prompt answer to available choices or use them as suggestions depthLimit: 2, // depthLimit :: integer >= 0 // Limit the depth of sub-folders to scan // Defaults to infinite depth if undefined } ]; }; export const getFileNameQuestions = async (zipFileList) => { addDebugLog("getFileNameQuestions", "", ""); return [ { name: 'fileName', type: 'rawlist', message: `Select zip file`, choices: zipFileList }, ]; }; export const getLibraryQuestion = async () => { addDebugLog("getLibraryQuestion", "", ""); const componentDefaults = getConfigDefaults(); const orgLib = getConfigDefaults(); const currentOrgLib = `${orgLib.organization}_${orgLib.library}`; const archVersionList = await getLibraryArchiveDirectories(""); return [ { name: 'orgLibName', type: 'rawlist', message: `Select a library (current library is ${chalk.bold.green(`${currentOrgLib}`)}) `, choices: archVersionList } ]; }; export const getLibraryVersionQuestion = async (newOrgLib) => { addDebugLog("getLibraryVersionQuestion", "", ""); const archVersionList = await getLibraryArchivesVersions(newOrgLib, "0.0.0"); return [ { name: 'selectedVersion', type: 'rawlist', message: `Select a version `, choices: archVersionList } ]; }; export const getServerOrDirectoryQuestion = async () => { addDebugLog("getLibraryVersionQuestion", "", ""); return [ { name: 'exportTo', type: 'rawlist', message: `Export to`, choices: [{name: 'Local directory', value: 'Directory'}, {name: 'Server', value: 'Server'}], default: 'Directory' } ]; }; export const getFullArchiveQuestions = async () => { return [ { name: 'fullArchive', type: 'rawlist', message: 'Type of export', choices: [{name: 'Full Archive (code)', value: 'Full'}, {name: 'CL Binary (runtime only)', value: 'Binary'}], default: 'Full' } ]; } export const getComponentInfoQuestions = async (rPackageJSON, library) => { return [ { name: 'author', message: 'Author of this component', default: rPackageJSON.author }, { name: 'isLocalized', type: 'confirm', message: 'Is this component fully localized', default: false }, { name: 'isAccessible', type: 'confirm', message: 'Is this component accessible', default: false }, { name: 'isSecure', type: 'confirm', message: 'Is this component and dependent modules secure', default: false }, { name: 'license', message: 'License of this component (MIT, Apache, GPL, etc.)', default: rPackageJSON.license }, { name: 'organization', message: 'Organization name', default: rPackageJSON.organization }, { name: 'library', message: 'Library name', default: library } ]; } export const zipComponent = async componentKey => { addDebugLog("zipComponent", `componentKey: ${componentKey}`, ""); const srcDirectory = await getComponentDirectoryPath(componentKey); const buildDirectory = await path.join(path.resolve(), 'dist/components', componentKey); const configJson = `${srcDirectory}/config.json`; const localizationJson = `${srcDirectory}/localizations.json`; const archive = archiver('zip', { zlib: { level: 9 } }); const zipChunks = []; archive.on('data', chunk => zipChunks.push(chunk)); // Add src directory archive.directory(srcDirectory, 'src'); // Add config.json file if (fs.existsSync(configJson)) { archive.file(configJson, { name: path.basename(configJson) }); } let lJson = ""; // Add localizations.json file if it exists if (fs.existsSync(localizationJson)) { archive.file(localizationJson, { name: path.basename(localizationJson) }); lJson = JSON.parse(Buffer.from(fs.readFileSync((localizationJson))).toString()); } // Add build directory archive.directory(buildDirectory, false); await archive.finalize(); const zipBuffer = Buffer.concat(zipChunks); console.log(chalk.green(`component zipped with size: ${Math.ceil(zipBuffer.length / 1024)} KB`)); const zipContent = zipBuffer.toString('base64'); //let configContent = Buffer.from(fs.readFileSync(configJson)).toString(); const configContent = JSON.parse(Buffer.from(fs.readFileSync(configJson)).toString()); // configContent = configContent.replaceAll("\n", ""); let output = { configContent }; if (lJson != "") { output = { ...output, localizationJson: lJson}; } if (fs.existsSync('dist')) { fs.rm('dist', { recursive: true }, err => { if (err) { throw err; } }); } return { zipContent, ...output}; }; export const zipRC = async (content, archiveDirectory, archiveFileName) => { addDebugLog("zipRC", ``, ""); // const configContent = Buffer.from(fs.readFileSync(configJson)).toString(); // const mainDirectory = process.cwd(); // const archiveDirectory = join (mainDirectory, ARCHIVES_PATH, `${componentKey}`, `${version}`); if (!fs.existsSync(archiveDirectory)) { fs.mkdirSync(archiveDirectory, { recursive: true }); } const archiveFile = join(archiveDirectory, archiveFileName); const output = fs.createWriteStream(archiveFile); const archive = archiver('zip', { zlib: { level: 9 } // Sets the compression level. }); const zipChunks = []; archive.on('data', chunk => zipChunks.push(chunk)); archive.append( JSON.stringify(content), { name: 'componentData.json' }); // pipe archive data to the file archive.pipe(output); output.on('end', function() { console.log('Data has been drained'); }); // good practice to catch warnings (ie stat failures and other non-blocking errors) archive.on('warning', function(err) { if (err.code === 'ENOENT') { // log warning } else { // throw error throw err; } }); // good practice to catch this error explicitly archive.on('error', function(err) { throw err; }); await archive.finalize(); return output; }; export const updateSavedExportFilePath = async(filePath) => { const currentDirectory = process.cwd(); const arPathParts = currentDirectory.split(path.sep); const configDef = getConfigDefaults(); let defaultPath = join(path.sep, arPathParts[0], arPathParts[1], arPathParts[2]); if (path.sep != "/") { // windows if (defaultPath.indexOf(path.sep) === 0) { // if start with \\, then remove defaultPath = defaultPath.substring(1); } if (filePath.indexOf(defaultPath) === 0) { let relativePath = ""; if (filePath !== defaultPath) { // same starting path, so we can save the relative relativePath = filePath.replace(defaultPath.concat(path.sep), ""); } await setConfigExportRelativePath(relativePath); await forceDefaultsUpdate(); } } else { // mac if (filePath.indexOf(defaultPath) === 0) { let relativePath = ""; if (filePath !== defaultPath) { // same starting path, so we can save the relative relativePath = filePath.replace(defaultPath.concat("/"), ""); } await setConfigExportRelativePath(relativePath); await forceDefaultsUpdate(); } } }