UNPKG

kira-crud

Version:

Intelligent CRUD Generator for Laravel and Angular

458 lines (397 loc) 13.3 kB
/** * Project Manager * Manage Kira projects and their configuration */ const chalk = require('chalk'); const inquirer = require('inquirer'); const ora = require('ora'); const path = require('path'); const projectConfig = require('./project-config'); /** * Display a styled section header * @param {string} title - The section title */ function displaySectionHeader(title) { console.log( "\n" + chalk.bold.blue( "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" ) ); console.log(chalk.bold.blue("✨ ") + chalk.bold.white(title)); console.log( chalk.bold.blue( "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" ) + "\n" ); } /** * Configure a new project * @returns {Promise<void>} */ async function configureNewProject() { console.log(chalk.blue('\nProject Configuration')); console.log(chalk.blue('=====================')); // Detect Laravel and Angular projects const spinner = ora('Scanning for Laravel and Angular projects...').start(); const detectedProjects = await projectConfig.detectProjects(process.cwd()); spinner.succeed('Scan complete'); console.log(`${chalk.green('✓')} Found ${detectedProjects.laravel.length} Laravel projects`); console.log(`${chalk.green('✓')} Found ${detectedProjects.angular.length} Angular projects`); // Load existing configuration const config = await projectConfig.loadConfig(); // Check if projects were detected if (detectedProjects.laravel.length === 0 && detectedProjects.angular.length === 0) { console.log(chalk.yellow('\nNo Laravel or Angular projects detected in the current directory.')); console.log('You will need to provide the paths manually.'); // Call the configuration function await projectConfig.configureProject(config); return; } // If projects were detected, offer to use them console.log('\nDetected projects:'); if (detectedProjects.laravel.length > 0) { console.log(chalk.blue('\nLaravel projects:')); detectedProjects.laravel.forEach((project, index) => { console.log(` ${index + 1}. ${chalk.green(project)}`); }); } if (detectedProjects.angular.length > 0) { console.log(chalk.blue('\nAngular projects:')); detectedProjects.angular.forEach((project, index) => { console.log(` ${index + 1}. ${chalk.green(project)}`); }); } // Ask if user wants to use detected projects const { useDetected } = await inquirer.prompt([ { type: 'confirm', name: 'useDetected', message: 'Would you like to use one of the detected projects?', default: true } ]); if (useDetected) { // Choose Laravel project let laravelPath = ''; if (detectedProjects.laravel.length === 1) { laravelPath = detectedProjects.laravel[0]; console.log(chalk.green(`Using Laravel project at: ${laravelPath}`)); } else if (detectedProjects.laravel.length > 1) { const { selectedLaravel } = await inquirer.prompt([ { type: 'list', name: 'selectedLaravel', message: 'Select a Laravel project:', choices: detectedProjects.laravel.map((project, index) => ({ name: `${index + 1}. ${project}`, value: project })) } ]); laravelPath = selectedLaravel; } else { // No Laravel projects detected const { manualLaravel } = await inquirer.prompt([ { type: 'input', name: 'manualLaravel', message: 'Enter the path to your Laravel project:', validate: async (input) => { const fullPath = path.resolve(input); if (await projectConfig.isLaravelProject(fullPath)) { return true; } return 'Path does not contain a valid Laravel project'; } } ]); laravelPath = path.resolve(manualLaravel); } // Choose Angular project let angularPath = ''; if (detectedProjects.angular.length === 1) { angularPath = detectedProjects.angular[0]; console.log(chalk.green(`Using Angular project at: ${angularPath}`)); } else if (detectedProjects.angular.length > 1) { const { selectedAngular } = await inquirer.prompt([ { type: 'list', name: 'selectedAngular', message: 'Select an Angular project:', choices: detectedProjects.angular.map((project, index) => ({ name: `${index + 1}. ${project}`, value: project })) } ]); angularPath = selectedAngular; } else { // No Angular projects detected const { manualAngular } = await inquirer.prompt([ { type: 'input', name: 'manualAngular', message: 'Enter the path to your Angular project:', validate: async (input) => { const fullPath = path.resolve(input); if (await projectConfig.isAngularProject(fullPath)) { return true; } return 'Path does not contain a valid Angular project'; } } ]); angularPath = path.resolve(manualAngular); } // Ask for project name const { projectName } = await inquirer.prompt([ { type: 'input', name: 'projectName', message: 'Enter a name for this project:', default: path.basename(process.cwd()), validate: (input) => input.trim() !== '' ? true : 'Project name is required' } ]); // Ask for default settings path const { settingsPath } = await inquirer.prompt([ { type: 'input', name: 'settingsPath', message: 'Enter the default path for settings components (relative to Angular src):', default: 'app/pages/admin/settings' } ]); // Update configuration config.projects[projectName] = { laravel: { path: laravelPath }, angular: { path: angularPath, settingsPath }, createdAt: new Date().toISOString() }; // Set as default if first project if (!config.defaultProject) { config.defaultProject = projectName; } else { // Ask if it should be the default const { makeDefault } = await inquirer.prompt([ { type: 'confirm', name: 'makeDefault', message: 'Set this as the default project?', default: false } ]); if (makeDefault) { config.defaultProject = projectName; } } // Save configuration await projectConfig.saveConfig(config); console.log(chalk.green(`\nProject '${projectName}' configured successfully!`)); } else { // Manual configuration await projectConfig.configureProject(config); } } /** * Switch active project * @returns {Promise<void>} */ async function switchProject() { // Load existing configuration const config = await projectConfig.loadConfig(); // Get list of projects const projects = Object.keys(config.projects); if (projects.length === 0) { console.log(chalk.yellow('\nNo projects configured yet.')); await configureNewProject(); return; } // Display project list console.log(chalk.blue('\nAvailable Projects:')); const projectChoices = projects.map(project => ({ name: `${project}${project === config.defaultProject ? ' (default)' : ''}`, value: project })); projectChoices.push({ name: 'Add a new project', value: 'new' }); // Ask user to select a project const { selectedProject } = await inquirer.prompt([ { type: 'list', name: 'selectedProject', message: 'Select a project:', choices: projectChoices } ]); if (selectedProject === 'new') { await configureNewProject(); return; } // Ask if it should be the default const { makeDefault } = await inquirer.prompt([ { type: 'confirm', name: 'makeDefault', message: 'Set this as the default project?', default: selectedProject !== config.defaultProject } ]); if (makeDefault) { config.defaultProject = selectedProject; await projectConfig.saveConfig(config); console.log(chalk.green(`\nProject '${selectedProject}' set as default.`)); } } /** * Display project information * @returns {Promise<void>} */ async function showProjectInfo() { try { // Get active project const project = await projectConfig.getActiveProject(); console.log(chalk.blue('\nActive Project Information:')); console.log(chalk.blue('===========================')); console.log(`${chalk.bold('Name:')} ${project.name}`); console.log(`${chalk.bold('Laravel Path:')} ${project.laravel.path}`); console.log(`${chalk.bold('Angular Path:')} ${project.angular.path}`); console.log(`${chalk.bold('Settings Path:')} ${project.angular.settingsPath}`); console.log(`${chalk.bold('Created:')} ${new Date(project.createdAt).toLocaleString()}`); // Verify paths are valid const laravelValid = await projectConfig.isLaravelProject(project.laravel.path); const angularValid = await projectConfig.isAngularProject(project.angular.path); console.log(`\n${chalk.bold('Status:')}`); console.log(`Laravel Project: ${laravelValid ? chalk.green('Valid') : chalk.red('Invalid')}`); console.log(`Angular Project: ${angularValid ? chalk.green('Valid') : chalk.red('Invalid')}`); if (!laravelValid || !angularValid) { console.log(chalk.yellow('\nOne or more project paths are invalid. You may need to reconfigure this project.')); } } catch (error) { console.log(chalk.red(`\nError: ${error.message}`)); } } /** * Remove a project * @returns {Promise<void>} */ async function removeProject() { // Load existing configuration const config = await projectConfig.loadConfig(); // Get list of projects const projects = Object.keys(config.projects); if (projects.length === 0) { console.log(chalk.yellow('\nNo projects configured yet.')); return; } // Display project list console.log(chalk.blue('\nAvailable Projects:')); const projectChoices = projects.map(project => ({ name: `${project}${project === config.defaultProject ? ' (default)' : ''}`, value: project })); projectChoices.push({ name: 'Cancel', value: 'cancel' }); // Ask user to select a project const { selectedProject } = await inquirer.prompt([ { type: 'list', name: 'selectedProject', message: 'Select a project to remove:', choices: projectChoices } ]); if (selectedProject === 'cancel') { return; } // Confirm deletion const { confirmDelete } = await inquirer.prompt([ { type: 'confirm', name: 'confirmDelete', message: `Are you sure you want to remove project '${selectedProject}'?`, default: false } ]); if (!confirmDelete) { console.log(chalk.yellow('\nProject removal cancelled.')); return; } // Remove project delete config.projects[selectedProject]; // Update default project if necessary if (config.defaultProject === selectedProject) { const remainingProjects = Object.keys(config.projects); if (remainingProjects.length > 0) { config.defaultProject = remainingProjects[0]; console.log(chalk.yellow(`\nDefault project set to '${config.defaultProject}'.`)); } else { config.defaultProject = null; } } // Save configuration await projectConfig.saveConfig(config); console.log(chalk.green(`\nProject '${selectedProject}' removed successfully.`)); } /** * Show project settings menu * @returns {Promise<void>} */ async function projectSettingsMenu() { displaySectionHeader('Project Settings'); const { action } = await inquirer.prompt([ { type: 'list', name: 'action', message: 'Select an action:', choices: [ { name: 'Configure a new project', value: 'new' }, { name: 'Switch active project', value: 'switch' }, { name: 'Show active project information', value: 'info' }, { name: 'Remove a project', value: 'remove' }, { name: 'Back to main menu', value: 'back' } ] } ]); switch (action) { case 'new': await configureNewProject(); break; case 'switch': await switchProject(); break; case 'info': await showProjectInfo(); break; case 'remove': await removeProject(); break; } if (action !== 'back') { // Press any key to continue await inquirer.prompt([ { type: 'input', name: 'continue', message: 'Press Enter to continue...' } ]); } } module.exports = { configureNewProject, switchProject, showProjectInfo, removeProject, projectSettingsMenu };