UNPKG

@pega/custom-dx-components

Version:

Utility for building custom UI components

383 lines (314 loc) 10.3 kB
import path from 'path'; 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 { checkPathAccess, showVersion, getComponentsObj, getDirectoryFiles, addDebugLog, checkLibraryAndArchives, getConfigDefaults, getLibraryBased } from '../../util.js'; import { TASKS_CONFIG_JSON_FILENAME, COMPONENTS_DIRECTORY_PATH, COMPONENTS_PATH } from '../../constants.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, getPegaConfig, sanitize, validateSemver } from '../../util.js'; import { COMPONENT_SCHEMA } from '../../constants.js'; const copy = promisify(ncp); export const updateConfig = async ( { oldComponentKey, newComponentKey, library, organization, componentName, componentLabel, version, description, allowedApplications, 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; configData.label = componentLabel; configData.organization = organization; if (configData.componentKey) configData.componentKey = newComponentKey; configData.library = library; configData.version = version; configData.description = (description != '') ? description : componentLabel; // if (allowedApplications.trim() === '') { // allowedApplications = []; // } else { // if (allowedApplications.indexOf(',') !== -1) { // allowedApplications = allowedApplications.split(','); // } // allowedApplications = [].concat(allowedApplications); // } // allowedApplications = allowedApplications.filter(el => !!el.trim()).map(el => el.trim()); // configData.allowedApplications = allowedApplications; // 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' }); }; 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' }); } }; export const renameComponent = async ( { library, organization, componentKey, componentName, componentLabel, version, description, allowedApplications }, options, onlyCompanion = false ) => { addDebugLog("renameComponent", `library: ${library}, organization: ${organization}, componentKey: ${componentKey}`, ""); let pegaConfig = await getPegaConfig(); const newComponentKey = `${organization}_${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, componentLabel, library, version, description, allowedApplications, organization, targetDirectory, }, options ); } else { await updateFile( fileName, oldComponentKeyPC, newComponentKeyPC, targetDirectory ); } } // for console.log(chalk.green(`Component ${oldComponentKey} renamed to ${newComponentKey}`)); }; export default async options => { await showVersion(); await checkLibraryAndArchives(); addDebugLog("rename", "", "+"); await checkPathAccess(pegaConfigJsonPath); const isLibraryBased = getLibraryBased(); let data = fs.readFileSync(pegaConfigJsonPath, { encoding: 'utf8' }); data = data && JSON.parse(data); if (!data[COMPONENTS_DIRECTORY_PATH]) { console.error( `${chalk.red.bold('ERROR')} Unable to find components directory path in config.json` ); process.exit(1); } const componentData = data[COMPONENTS_PATH]; const { library } = componentData; const { organization } = JSON.parse(fs.readFileSync(path.resolve('package.json'), 'utf8')); let componentDefaults = getConfigDefaults(); componentDefaults.library = library; const localComponents = await getComponentsObj(); if (options.params.length >= 11) { const componentKey = options.params[3]; const componentName = options.params[4]; const componentLabel = options.params[5]; const organization = options.params[6]; const version = options.params[7]; const library = options.params[8]; const allowedApplications = options.params[9]; const description = options.params[10]; await renameComponent( { componentKey, componentName, componentLabel, library, version, description, allowedApplications, organization }, options ); } else { // VS Code plugin would send in the component let paramComponentKey; if (options.params.length == 4) { paramComponentKey = options.params[3]; } const questions = [ { name: 'componentKey', type: 'rawlist', pageSize: 15, message: 'Select component to rename', choices: localComponents, when: () => !paramComponentKey }, { name: 'componentName', message: 'Enter new component name (required, no spaces)', 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)) { return true; } return 'Only alphanumeric values are allowed, starting with alphabets'; } }, { name: 'componentLabel', message: 'Enter new component label for display (required)', validate: value => { if (value) { return true; } return 'Please provide value for label'; } }, { name: 'organization', message: 'Enter new component organization', default: organization, validate: value => { if (value) { return true; } return 'Please provide value for organization'; }, when: () => !isLibraryBased }, { name: 'version', message: 'Enter new component version', default: componentDefaults.version, validate: value => { if (validateSemver(value)) { return true; } return 'Please provide semver compatible version e.g 0.0.1'; }, when: () => !isLibraryBased }, { name: 'library', message: 'Enter new library name (required)', default: componentDefaults.library, 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)) { return true; } return 'Only alphanumeric values are allowed, starting with alphabets'; }, when: () => !isLibraryBased }, // { // name: 'allowedApplications', // message: 'Please enter the application names to be supported (comma-separated). ', // suffix: 'Keep empty for all applications', // when: () => !isLibraryBased // }, { name: 'description', message: 'Enter new description for the component (defaults to new label)', default: componentDefaults.description, /* if left blank and no defaults, mustache will use componentLabel, because description is used in app studio and shouldn't be blank */ } ]; await inquirer.prompt(questions).then(async answers => { const { componentKey = paramComponentKey, componentName, componentLabel, description, } = answers; let { organization, library, version, allowedApplications } = answers; if (isLibraryBased) { // these answers come from defaults const orgLib = getConfigDefaults(); library = orgLib.library; version = orgLib.buildVersion; organization = orgLib.organization; allowedApplications = ""; } await renameComponent( { componentKey, componentName, componentLabel, library, version, description, allowedApplications, organization }, options ); }); } addDebugLog("rename", "END", "-"); };