UNPKG

create-react-component-folder-jovpet

Version:

Creates single react component folder structure. Forked version with enhanced scss

349 lines (315 loc) 9.93 kB
const Handlebars = require('handlebars'); const stringHelper = require('../utils/stringHelper'); const { readFileAsync } = require('../utils/fileHelpers'); const config = require('../config'); /** * Get either a functional or class component template * * @returns {Promise|Promise<string>} */ async function getComponentTemplate() { const templateName = config.hasFlag('functional') ? 'fnComponent.handlebars' : 'classComponent.handlebars'; try { return await readFileAsync(`${config.getValue('templates')}/${templateName}`); } catch (error) { return readFileAsync(`${config.getValue('crcf')}/templates/${templateName}`); } } /** * Get either a functional or class controller template * * @returns {Promise|Promise<string>} */ async function getControllerTemplate() { const templateName = config.hasFlag('functional') ? 'fnController.handlebars' : 'classController.handlebars'; try { return await readFileAsync(`${config.getValue('templates')}/${templateName}`); } catch (error) { return readFileAsync(`${config.getValue('crcf')}/templates/${templateName}`); } } /** * Get either a functional or class controller template * * @returns {Promise|Promise<string>} */ async function getApolloTemplate() { const templateName = config.hasFlag('functional') ? 'fnApollo.handlebars' : 'classApollo.handlebars'; try { return await readFileAsync(`${config.getValue('templates')}/${templateName}`); } catch (error) { return readFileAsync(`${config.getValue('crcf')}/templates/${templateName}`); } } /** * Get the test template * * @returns {Promise|Promise<string>} */ async function getTestTemplate() { try { return await readFileAsync(`${config.getValue('templates')}/test.handlebars`); } catch (error) { return readFileAsync(`${config.getValue('crcf')}/templates/test.handlebars`); } } /** * Get the mocks template * * @returns {Promise|Promise<string>} */ async function getMocksTemplate() { try { return await readFileAsync(`${config.getValue('templates')}/mocks.handlebars`); } catch (error) { return readFileAsync(`${config.getValue('crcf')}/templates/mocks.handlebars`); } } /** * Get the style template * * @returns {Promise|Promise<string>} */ async function getStyleTemplate() { try { return await readFileAsync(`${config.getValue('templates')}/cssComponent.handlebars`); } catch (error) { return readFileAsync(`${config.getValue('crcf')}/templates/cssComponent.handlebars`); } } /** * Get the storybook stories template * * @returns {Promise|Promise<string>} */ async function getStorybookTemplate() { try { return await readFileAsync(`${config.getValue('templates')}/stories.handlebars`); } catch (error) { return readFileAsync(`${config.getValue('crcf')}/templates/stories.handlebars`); } } /** * Creates a React component view * * @param {String} componentName - Component name * @param {String} cssext - css file extension used for css modules (css, less, scss) * @returns {Promise|Promise<string>} */ async function createReactComponent(componentName, cssext) { const name = stringHelper.componentNameWithoutSpecialCharacter(componentName); const file = getComponentTemplate(); const template = Handlebars.compile(await file); return template({ name, cssmodules: config.hasFlag('cssmodules'), cssext, typescript: config.hasFlag('typescript'), native: config.hasFlag('reactnative'), proptypes: config.hasFlag('proptypes'), export: config.hasFlag('namedexports'), }); } /** * Creates a React controller * * @param {String} componentName - Component name * @returns {Promise|Promise<string>} */ async function createReactController(componentName) { const name = stringHelper.componentNameWithoutSpecialCharacter(componentName); const file = getControllerTemplate(); const template = Handlebars.compile(await file); return template({ name, typescript: config.hasFlag('typescript'), proptypes: config.hasFlag('proptypes'), export: config.hasFlag('namedexports'), }); } /** * Creates a React Apollo file * * @param {String} componentName - Component name * @param {String} pathToTypesDefinition - relative path to tpes definition file * @returns {Promise|Promise<string>} */ async function createReactApollo(componentName, pathToTypesDefinition) { const name = stringHelper.componentNameWithoutSpecialCharacter(componentName); const file = getApolloTemplate(); const template = Handlebars.compile(await file); const uppercaseName = name.toUpperCase(); const lowercaseName = name.toLowerCase(); return template({ name, uppercaseName, lowercaseName, pathToTypesDefinition, typescript: config.hasFlag('typescript'), proptypes: config.hasFlag('proptypes'), export: config.hasFlag('namedexports'), }); } /** * Creates a test file for the generated component * * @param {String} componentName - Component name * @returns {Promise|Promise<string>} */ async function createReactComponentTest(componentName) { const componentNameUpperCase = stringHelper.componentNameWithoutSpecialCharacter(componentName); const file = getTestTemplate(); const template = Handlebars.compile(await file); const nameUpperCase = componentNameUpperCase.toUpperCase(); return template({ name: componentNameUpperCase, nameLowerCase: componentName, nameUpperCase, hasApollo: config.hasFlag('graphql'), uppercase: config.hasFlag('uppercase'), typescript: config.hasFlag('typescript'), native: config.hasFlag('reactnative'), proptypes: config.hasFlag('proptypes'), export: config.hasFlag('namedexports'), }); } /** * Creates a test file for the generated component * * @param {String} componentName - Component name * @param {String} pathToTypesDefinition - Path to name * @returns {Promise|Promise<string>} */ async function createReactMocks(componentName, pathToTypesDefinition) { const componentNameUpperCase = stringHelper.componentNameWithoutSpecialCharacter(componentName); const file = getMocksTemplate(); const template = Handlebars.compile(await file); const nameUpperCase = componentNameUpperCase.toUpperCase(); return template({ name: componentNameUpperCase, nameUpperCase, pathToTypesDefinition, typescript: config.hasFlag('typescript'), }); } /** * Creates Stories for the React component * * @param {String} componentName - Component name * @param {String} contextPath - Component path * @param {String} apolloLinkPath - path to ApolloMockingLink function * @returns {Promise|Promise<string>} */ async function createReactComponentStories(componentName, contextPath, apolloLinkPath) { let patternName; let apolloLink; let apolloLinkName; if (config.hasFlag('graphql')) { patternName = 'Apollo'; apolloLink = !!config.getValue('apollolink'); apolloLinkName = apolloLink ? config.getValue('apollolink').name : false; } else if (config.hasFlag('controller')) { patternName = 'Controller'; } else { patternName = 'View'; } const patternFile = `.${patternName.toLowerCase()}`; const name = stringHelper.componentNameWithoutSpecialCharacter(componentName); const nameUppercase = name.toUpperCase(); const nameLowercase = name.toLowerCase(); const file = getStorybookTemplate(); const template = Handlebars.compile(await file); return template({ name, nameLowercase, nameUppercase, patternFile, patternName, contextPath, apolloLink, apolloLinkName, apolloLinkPath, notest: config.hasFlag('notest'), hasApollo: config.hasFlag('graphql'), uppercase: config.hasFlag('uppercase'), typescript: config.hasFlag('typescript'), native: config.hasFlag('reactnative'), proptypes: config.hasFlag('proptypes'), export: config.hasFlag('namedexports'), }); } /** * Creates a React style file * * @param {String} componentName - Component name * @returns {Promise|Promise<string>} */ async function createReactComponentStyle(componentName) { const name = stringHelper.componentNameWithoutSpecialCharacter(componentName); const hyphenatedname = stringHelper.hypehnateName(name); const file = getStyleTemplate(); const template = Handlebars.compile(await file); return template({ name, scss: config.hasFlag('scss'), hyphenatedcss: config.hasFlag('hyphenatedcss'), hyphenatedname, scssinclude: config.getValue('scssinclude'), }); } /** * Creates a default index file * * @param {String} componentName - Component name * @returns {String} */ function createIndex(componentName) { const name = config.hasFlag('uppercase') ? stringHelper.componentNameWithoutSpecialCharacter(componentName) : componentName; let patternName; if (config.hasFlag('graphql')) { patternName = 'Apollo'; } else if (config.hasFlag('controller')) { patternName = 'Controller'; } else { patternName = 'View'; } const exportedAs = config.hasFlag('namedexports') ? `${name}${patternName} as ${name}` : 'default'; return `export { ${exportedAs} } from './${name}.${patternName.toLowerCase()}';\n`; } /** * Creates index file that includes all generated component folders * * @param {Array} folders - folders array * @returns {String} */ function createIndexForFolders(folders) { return `${folders .map((folderName) => `import ${folderName} from './${folderName}' \n`) .join('')}export { ${folders .map((folderName, index) => { if (index === folders.length - 1) return folderName; return `${folderName}, \n`; }) .join('')} }`; } module.exports = { createReactComponent, createReactController, createReactApollo, createReactComponentTest, createReactMocks, createReactComponentStories, createReactComponentStyle, createIndex, createIndexForFolders, };