zura-stack-native
Version:
A comprehensive React Native CLI project generator with production-ready setup
116 lines (102 loc) • 3.24 kB
JavaScript
const inquirer = require('inquirer');
const chalk = require('chalk');
const ora = require('ora');
const fs = require('fs-extra');
const path = require('path');
const { execSync } = require('child_process');
const validateNpmPackageName = require('validate-npm-package-name');
const { ProjectGenerator } = require('../generators/ProjectGenerator');
async function createProject(projectName, options) {
// Validate project name
const validation = validateNpmPackageName(projectName);
if (!validation.validForNewPackages) {
const errors = validation.errors || validation.warnings || ['Invalid project name'];
throw new Error(`Invalid project name: ${projectName}. ${errors.join(', ')}`);
}
// Check if directory already exists
const projectPath = path.resolve(projectName);
if (await fs.pathExists(projectPath)) {
throw new Error(`Directory ${projectName} already exists. Please choose a different name.`);
}
// Gather project configuration
const config = await gatherProjectConfig(projectName, options);
// Create the project
const generator = new ProjectGenerator(config);
await generator.generate();
}
async function gatherProjectConfig(projectName, options) {
const config = {
projectName,
projectPath: path.resolve(projectName),
typescript: true,
testing: false,
template: 'default',
verbose: false
};
// If --yes flag is used, use defaults
if (options.yes) {
config.typescript = options.typescript !== false;
config.testing = options.testing || false;
config.template = options.template;
config.verbose = options.verbose || false;
return config;
}
// Interactive prompts
const questions = [];
// TypeScript question
if (options.typescript === undefined) {
questions.push({
type: 'confirm',
name: 'typescript',
message: 'Use TypeScript? (recommended)',
default: true
});
} else {
config.typescript = options.typescript;
}
// Testing question
if (options.testing === undefined) {
questions.push({
type: 'confirm',
name: 'testing',
message: 'Include testing framework? (Jest + React Native Testing Library + Detox)',
default: false
});
} else {
config.testing = options.testing;
}
// Template question
if (options.template === 'default') {
questions.push({
type: 'list',
name: 'template',
message: 'Choose a project template:',
choices: [
{ name: 'Default (Complete setup with all features)', value: 'default' },
{ name: 'Minimal (Basic setup without UI libraries)', value: 'minimal' },
{ name: 'Custom (Choose your own features)', value: 'custom' }
],
default: 'default'
});
} else {
config.template = options.template;
}
// Verbose mode question
if (!options.verbose) {
questions.push({
type: 'confirm',
name: 'verbose',
message: 'Enable verbose output?',
default: false
});
} else {
config.verbose = true;
}
// Ask questions if any
if (questions.length > 0) {
const answers = await inquirer.prompt(questions);
Object.assign(config, answers);
}
return config;
}
module.exports = { createProject };