@naoufal/create-react-component
Version:
The fastest way to create React Components
145 lines (118 loc) • 3.96 kB
JavaScript
const path = require('path');
const { red, yellow }= require('chalk');
const fs = Promise.promisifyAll(require('fs-extra'));
const { readdirAsync, readdirSync} = fs;
// Validation
// ----------------------------------------------------------------------------
function validatePath(input) {
// Check that input isn't empty
if (input.length === 0) {
console.log(yellow('\n A path is required to create a component\n'));
return false;
}
return true;
}
function validateName(input, previousAnswers) {
// Check that input isn't empty
if (input.length === 0) {
console.log(yellow('\n A component name is required\n'));
return false;
}
const dirPath = path.join(process.cwd(), previousAnswers.componentPath);
return readdirAsync(dirPath)
// Check that a file or folder with same name does not already exists
.reduce((accumulator, file) => {
// Previous file had the same name
if (accumulator) {
return true;
}
// File has the same name
const fileExtension = path.extname(file);
const fileName = file.replace(fileExtension, '');
if (input === fileName) {
return true;
}
return false;
}, false)
// Return false if filename is already used
.then(fileNameAlreadyUsed => {
if (fileNameAlreadyUsed) {
console.log(yellow('\n A file or directory with that name already exists\n'));
return false;
}
return true;
})
// Directory doesn't exist so name is valid
.catch(e => true);
}
// When
// ----------------------------------------------------------------------------
function whenDirectoryDoesNotExist({ componentPath }) {
const dirPath = path.join(process.cwd(), componentPath);
// Try to access provided directory
try {
fs.accessSync(dirPath);
return false;
} catch (e) {
return true;
}
}
function whenCreateDirectoryIsTrue(previousAnswers) {
if (previousAnswers.createDirectory === false) {
console.log(red(` Can't create component in a folder that doesn't exist`));
process.exit();
}
return true;
}
// Choices
// ----------------------------------------------------------------------------
function templateChoices() {
const selectedTemplates = getTemplates();
return selectedTemplates.map(template => template.name);
}
function typeChoices(previousAnswers) {
const { selectedTemplate } = previousAnswers;
const template = getTemplates()
.find(template => template.name === selectedTemplate);
return getTemplateTypes(template.path);
}
// We go back 3 directories because the module is currently scoped under
// `@naoufal`
const NODE_MODULES_DIR = path.join(__dirname, '../../../');
function getTemplates() {
const selectedTemplates = fs.readdirSync(NODE_MODULES_DIR)
// Filter out packages that aren't selectedTemplates
.filter(dep => /crc-template-/.test(dep))
.map(template => ({
name: template.replace('crc-template-', ''),
path: path.join(NODE_MODULES_DIR, template)
}))
// Drop selectedTemplates that don't support at least one component type
.filter(template => getTemplateTypes(template.path).length > 0)
// Remove potential duplicate `default` if user manually installs the template
.filter(template => template.name !== 'default')
.sort();
const defaultTemplate = {
name: 'default',
path: path.join(__dirname, '../node_modules/@naoufal/crc-template-default')
};
return [defaultTemplate, ...selectedTemplates];
}
function getTemplateTypes(templatePath) {
const selectedTemplate = require(templatePath);
const supportedTypes = Object.keys(selectedTemplate)
.filter(type => selectedTemplate[type]);
return supportedTypes;
}
// Exports
// ----------------------------------------------------------------------------
module.exports = {
getTemplates,
getTemplateTypes,
validatePath,
validateName,
whenDirectoryDoesNotExist,
whenCreateDirectoryIsTrue,
templateChoices,
typeChoices
};