const { execSync } = require('child_process'); const fs = require('fs'); // variables const COMPONENT_NAME = 'name'; const optional_types = 'types'; const optional_helpers = 'helpers'; const optional_styles = 'styles'; // colors const RED_COLOR = '\x1b[31m%s\x1b[0m'; const GREEN_COLOR = '\x1b[32m%s\x1b[0m'; const BLUE_COLOR = '\x1b[36m%s\x1b[0m'; const mandatoryArgs = [COMPONENT_NAME]; // create args obj from the user input function getArgs() { const args = {}; process.argv.slice(2, process.argv.length).forEach(arg => { if (arg.slice(0, 2) === '--') { const longArg = arg.split('='); const longArgFlag = longArg[0].slice(2, longArg[0].length); const longArgValue = longArg.length > 1 ? longArg[1] : true; if (longArgFlag === COMPONENT_NAME && (typeof longArgValue !== 'string' || !longArgValue)) { throw new Error(`${longArgFlag} must be a string and contain a value.`); } args[longArgFlag] = longArgValue; } }); // validate that the mandatory args are provided mandatoryArgs.forEach(mandatoryArg => { if (!args[mandatoryArg]) { throw new Error(`${mandatoryArg} was not provided. --${mandatoryArg}='EXAMPLE_NAME'`); } }); return args; } const args = getArgs(); // generate component & story const argName = args[COMPONENT_NAME].toLowerCase(); const createComponent = `npx nx g @nrwl/react:component --project=ui --directory=components --name=${argName} --style=none`; const createStory = `npx nx g @nrwl/react:component-story --project=ui --componentPath=components/${argName}/${argName}.tsx`; const generate = execSync(`${createComponent} && ${createStory}`, error => { if (error) { console.log(`${RED_COLOR}`, `error: ${error.message}`); return; } }); console.log(`${GREEN_COLOR}`, `${generate.toString()}`); // register component in UI lib package file const data = fs.readFileSync('./libs/ui/src/index.ts'); const fd = fs.openSync('./libs/ui/src/index.ts', 'w+'); const buffer = Buffer.from(`export * from './components/${argName}';\n`); fs.writeSync(fd, buffer, 0, buffer.length, 0); fs.writeSync(fd, data, 0, data.length, buffer.length); fs.close(fd); // fix component's test file const componentTestFilename = `./libs/ui/src/components/${argName}/${argName}.spec.tsx`; fs.readFile(componentTestFilename, 'utf8', function (err, data) { if (err) { return console.log(err); } var result = data.replace( "import { render } from '@testing-library/react'", "import { render } from '../../utils/theme-render-wrapper'" ); fs.writeFile(componentTestFilename, result, 'utf8', function (err) { if (err) return console.log(err); }); }); // create component's index const componentIndexFilename = `./libs/ui/src/components/${argName}/index.ts`; fs.appendFileSync(componentIndexFilename, `export * from './${argName}';\n`); // *OPTIONAL*: create types.ts | helpers.ts | styles.ts if those args are provided for (const key in args) { if (key === optional_types || key === optional_helpers || key === optional_styles) { try { fs.appendFileSync(`./libs/ui/src/components/${argName}/${key}.ts`, ''); console.log(`${BLUE_COLOR}`, `The file ${key}.ts was created successfully!`); } catch (err) { console.log(`${RED_COLOR}`, `error: ${err}`); } } }