UNPKG

@pega/custom-dx-components

Version:

Utility for building custom UI components

227 lines (195 loc) 6.98 kB
import path from 'path'; import fs from 'fs'; import { fileURLToPath } from 'url'; import { promisify } from 'util'; import chalk from 'chalk'; import { execa } from 'execa'; import { Listr } from 'listr2'; import gitignore from 'gitignore'; import inquirer from 'inquirer'; import { compileMustacheTemplate, isPascalCase, convertIntoPascalCase, sanitize } from '../../util.js'; import { getInitProjectQuestions } from './helper.js'; const writeGitignore = promisify(gitignore.writeFile); const copyProjectDir = async (src, dest) => { if (typeof fs.cp === 'function') { await fs.promises.cp(src, dest, { recursive: true, errorOnExist: false, force: false }); } }; const createGitignore = async options => { const file = fs.createWriteStream(path.join(options.targetDirectory, '.gitignore'), { flags: 'a' }); return writeGitignore({ type: 'Node', file }); }; const createLicense = async options => { // Write LICENSE file directly const targetPath = path.join(options.targetDirectory, 'LICENSE'); const licenseContent = 'Enter license text here'; await fs.promises.writeFile(targetPath, licenseContent, 'utf8'); }; const copyProjectTemplate = async options => { // Use fast copy await copyProjectDir(options.templateDirectory, options.targetDirectory); const packageJsonPath = path.join(options.targetDirectory, 'package.json.mustache'); const templateNPMRCPath = path.join(options.targetDirectory, 'templateNPMRC.txt'); let { organization, projectName } = options; projectName = sanitize(projectName).toLowerCase(); organization = sanitize(organization); if (!isPascalCase(organization)) { organization = convertIntoPascalCase(organization); } options = { ...options, organization, projectName }; // Compile and write package.json in one go const output = compileMustacheTemplate(packageJsonPath, options); await fs.promises.writeFile(packageJsonPath, output); await fs.promises.rename(packageJsonPath, packageJsonPath.replace('.mustache', '')); // Rename templateNPMRC.txt to .npmrc if exists try { await fs.promises.rename(templateNPMRCPath, templateNPMRCPath.replace('templateNPMRC.txt', '.npmrc')); } catch (e) { // ignore if not present } await createLicense(options); }; const initGit = async options => { // Use execa for async git init const result = await execa('git', ['init'], { cwd: options.targetDirectory }); if (result.failed) { throw new Error('Failed to initialize git'); } }; export default async options => { options.templateDirectory = path.resolve( path.dirname(fileURLToPath(import.meta.url)), 'template' ); let projectName = 'test'; const questions = getInitProjectQuestions(); const answers = await inquirer.prompt(questions); projectName = sanitize(answers.projectName).toLowerCase(); options = { ...options, ...answers }; const projectDirectory = `./${projectName}`; if (!fs.existsSync(projectDirectory)) { fs.mkdirSync(projectDirectory); } else { console.log(chalk.bold.red(`A project with name ${projectName} already exists. Exiting...`)); process.exit(); } const targetDirectory = options.targetDirectory || process.cwd(); options.targetDirectory = path.join(targetDirectory, projectName); options.componentDirectory = path.join( options.targetDirectory, 'node_modules/@pega/custom-dx-components' ); options.componentLibraryUtilsDirectory = path.join( options.targetDirectory, 'node_modules/@pega/constellation-dx-components-build-utils' ); const installDependenciesText = `Installing dependencies. This will take a couple of minutes.`; const tasks = new Listr( [ { title: `Creating a new custom component project in ${chalk.blue(options.targetDirectory)}`, task: () => copyProjectTemplate(options) }, { title: 'Create gitignore', task: () => createGitignore(options) }, { title: 'Initialize git', task: () => initGit(options), enabled: () => options.git }, /* { title: installDependenciesText, task: () => execa('npm', ['i', '--force', '--production=false'], { cwd: options.targetDirectory }) }, */ { title: installDependenciesText, task: () => execa('npm', ['i', '--force', '--no-audit', '--no-fund', '--loglevel=error'], { cwd: options.targetDirectory }) }, /* { title: 'Installing tasks dependencies', task: () => { if (!fs.existsSync(options.componentDirectory)){ fs.mkdirSync(options.componentDirectory, { recursive: true }); }; execa('npm', ['i', '--force', '--no-audit', '--no-fund', '--loglevel=error'], { cwd: options.componentDirectory }); } }, { title: 'Installing tasks library dependencies', task: () => { if (!fs.existsSync(options.componentLibraryUtilsDirectory)){ fs.mkdirSync(options.componentLibraryUtilsDirectory, { recursive: true }); }; execa('npm', ['i', '--force', '--no-audit', '--no-fund', '--loglevel=error'], { cwd: options.componentLibraryUtilsDirectory }); } }, */ { title: 'Updating', task: () => execa('npm', ['update', '--dev', '--no-audit', '--no-fund', '--loglevel=error'], { cwd: options.targetDirectory }) } /* { title: 'Installing quick run', task: () => execa('npm', ['i', '-g', 'npm-quick-run'], { cwd: options.targetDirectory }) } */ ], { exitOnError: false } ); await tasks.run(); console.log('\n'); console.log( `${chalk.green('Success!!')} Project created at ${chalk.blueBright(options.targetDirectory)}` ); console.log( '\n', `Inside that directory, you can run several commands:`, '\n\n', `Get a list of commands\n`, ` ${chalk.blueBright('npm run help')}`, '\n\n', `Create or import a library first\n`, ` ${chalk.blueBright('npm run createLib')}\n`, ` ${chalk.blueBright('npm run importLibVersion')}`, '\n\n', `Try out custom-component actions like create, list, etc. \n`, ` ${chalk.blueBright('npm run create')}\n`, ` ${chalk.blueBright('npm run list')}`, '\n\n', `Start Storybook in development mode\n`, ` ${chalk.blueBright('npm run startStorybook')}`, '\n\n', `Validate components (schema, lint, test build of a library)\n`, ` ${chalk.blueBright('npm run validateAll')}`, '\n\n', `Publish component library\n`, ` ${chalk.blueBright('npm run publish')}`, '\n' ); console.log( `We suggest that you begin by typing:`, '\n\n', `${chalk.blueBright('cd')} ${chalk.bold(projectName)}`, '\n', `${chalk.blueBright('npm run createLib')} or ${chalk.blueBright('npm run importLibVersion')}`, '\n' ); return true; };