module.exports = function(config) { return function(plop) { plop.setPrompt('directory', require('inquirer-directory')); const genComponent = ({ targetPath, storyfile, componentfile, stylefile, testfile, isEmotion }) => { const actions = []; actions.push({ type: 'add', path: `${targetPath}/{{pascalCase name}}/index.tsx`, templateFile: config.getTemplatePath(componentfile), }); if (isEmotion) { actions.push({ type: 'add', path: `${targetPath}/{{pascalCase name}}/{{pascalCase name}}.styled.ts`, templateFile: config.getTemplatePath('component/styled.hbs'), }); } else { stylefile = stylefile || 'component/componentStyle.hbs'; actions.push({ type: 'add', path: `${targetPath}/{{pascalCase name}}/{{pascalCase name}}.module.scss`, templateFile: config.getTemplatePath(stylefile), }); } if (testfile) { actions.push({ type: 'add', path: `${targetPath}/{{pascalCase name}}/{{pascalCase name}}.test.tsx`, templateFile: config.getTemplatePath(testfile), }); } if (storyfile) { actions.push({ type: 'add', path: `${targetPath}/{{pascalCase name}}/{{pascalCase name}}.stories.tsx`, templateFile: config.getTemplatePath(storyfile), }); } return actions; }; const componentPrompts = () => { const prompts = []; prompts.push({ type: 'input', name: 'name', message: 'Component name please', }); prompts.push({ type: 'directory', name: 'path', message: 'Where should the component go?', basePath: config.componentPath, }); prompts.push({ type: 'checkbox', name: 'options', choices: [ { name: 'redux', checked: true }, { name: 'emotion', checked: false }, { name: 'test', checked: true }, // { name: 'story', checked: true }, // { name: 'formItem', checked: false }, ], message: 'Select configuration options', }); return prompts; }; const genNormalComponent = data => { const componentMapping = { default: { redux: 'component/componentHookRedux.hbs', normal: 'component/componentHook.hbs', }, emotion: { redux: 'component/componentStyledRedux.hbs', normal: 'component/componentStyled.hbs', }, }; const isEmotion = data.options.includes('emotion'); const componentfile = componentMapping[isEmotion ? 'emotion' : 'default'][data.options.includes('redux') ? 'redux' : 'normal']; // let storyfile = data.options.includes('story') ? 'component/story.hbs' : null; // storyfile = data.options.includes('formItem') ? 'component/story-form.hbs' : storyfile; const testfile = data.options.includes('test') && 'component/componentTest.hbs'; const targetPath = config.path.join(config.componentPath, data.path); return genComponent({ componentfile, targetPath, // storyfile, testfile, isEmotion, }); }; const componentFormPrompts = () => { const prompts = []; prompts.push({ type: 'input', name: 'name', message: 'Component name please', }); return prompts; }; const genFormComponent = data => { const componentfile = 'component/componentForm.hbs'; const targetPath = config.path.join(config.componentPath, '/forms'); data.name += 'Form'; const actions = genComponent({ targetPath, componentfile }); return actions; }; /** * Resource */ const resourcePrompts = () => { const prompts = []; prompts.push({ type: 'input', name: 'name', message: 'Resource name please', }); prompts.push({ type: 'checkbox', name: 'options', choices: [{ name: 'apollo', checked: true }], message: 'Select configuration options', }); return prompts; }; const genResource = data => { const apollo = data.options.includes('apollo'); const constantsFile = 'resource/constants.hbs'; const actionsFile = 'resource/actions.hbs'; const reducerFile = 'resource/reducer.hbs'; const sagasFile = 'resource/sagas.hbs'; const apisFile = 'resource/apis.hbs'; const sagasApolloFile = 'resource/sagasApollo.hbs'; const modelsFile = 'resource/models.hbs'; const selectorsFile = 'resource/selectors.hbs'; const indexFile = 'resource/index.hbs'; const indexApolloFile = 'resource/indexApollo.hbs'; const actions = []; // data name actions.push({ type: 'add', path: `${config.storePath}/{{camelCase name}}/constants.ts`, templateFile: config.getTemplatePath(constantsFile), }); actions.push({ type: 'add', path: `${config.storePath}/{{camelCase name}}/actions.ts`, templateFile: config.getTemplatePath(actionsFile), }); actions.push({ type: 'add', path: `${config.storePath}/{{camelCase name}}/reducer.ts`, templateFile: config.getTemplatePath(reducerFile), }); if (apollo) { actions.push({ type: 'add', path: `${config.storePath}/{{camelCase name}}/models.ts`, templateFile: config.getTemplatePath(modelsFile), }); actions.push({ type: 'add', path: `${config.storePath}/{{camelCase name}}/sagas.ts`, templateFile: config.getTemplatePath(sagasApolloFile), }); actions.push({ type: 'add', path: `${config.storePath}/{{camelCase name}}/index.ts`, templateFile: config.getTemplatePath(indexApolloFile), }); } else { actions.push({ type: 'add', path: `${config.storePath}/{{camelCase name}}/sagas.ts`, templateFile: config.getTemplatePath(sagasFile), }); actions.push({ type: 'add', path: `${config.storePath}/{{camelCase name}}/apis.ts`, templateFile: config.getTemplatePath(apisFile), }); actions.push({ type: 'add', path: `${config.storePath}/{{camelCase name}}/index.ts`, templateFile: config.getTemplatePath(indexFile), }); } actions.push({ type: 'add', path: `${config.storePath}/{{camelCase name}}/selectors.ts`, templateFile: config.getTemplatePath(selectorsFile), }); return actions; }; /* Custom hook */ const hookPromps = () => { const prompts = []; prompts.push({ type: 'input', name: 'name', message: 'custom Hook name please', }); return prompts; }; const genHook = data => { const hookFile = 'component/customHook.hbs'; const hookPath = config.path.join(config.componentPath, '/hooks'); const actions = []; actions.push({ type: 'add', path: `${hookPath}/{{camelCase name}}.ts`, templateFile: config.getTemplatePath(hookFile), }); return actions; }; plop.setGenerator('Component', { description: 'Make a component', prompts: componentPrompts(), actions: genNormalComponent, }); plop.setGenerator('Component Form', { description: 'Make a form component', prompts: componentFormPrompts(), actions: genFormComponent, }); plop.setGenerator('Resource', { description: 'Make a resource in the store (action, reducer & saga)', prompts: resourcePrompts(), actions: genResource, }); plop.setGenerator('Hook', { description: 'Make a custom reusable hookc', prompts: hookPromps(), actions: genHook, }); }; };