UNPKG

myex-cli

Version:

Opinionated Express.js framework with CLI tools

109 lines (89 loc) 4.13 kB
import path from 'path'; import fs from 'fs-extra'; import chalk from 'chalk'; import ora from 'ora'; import { generateModel } from './generate-model.js'; import { generateController } from './generate-controller.js'; import { generateService } from './generate-service.js'; import { generateRoute } from './generate-route.js'; import { pascalCase, camelCase, pluralize } from '../utils/string-utils.js'; /** * Generate a complete feature (model, controller, service, route) * @param {string} name - Feature name * @param {Object} options - Command options */ export async function generateFeature(name, options) { const spinner = ora(`Generating feature: ${chalk.blue(name)}`).start(); try { // Check if we're in a MYX project (presence of src directory) if (!fs.existsSync('src')) { spinner.fail(chalk.red('Not in a MYX project. Please run this command from the root of your MYX project.')); return; } // Generate model spinner.text = `Generating model: ${chalk.blue(name)}`; await generateModel(name, options); // Generate service spinner.text = `Generating service: ${chalk.blue(name)}`; await generateService(name, { model: name }); // Generate controller spinner.text = `Generating controller: ${chalk.blue(name)}`; await generateController(name, { model: name }); // Generate route spinner.text = `Generating route: ${chalk.blue(name)}`; await generateRoute(name, { controller: name }); // Update routes index.js to include the new route await updateRoutesIndex(name); spinner.succeed(chalk.green(`Feature "${name}" generated successfully.`)); console.log(''); console.log(chalk.cyan('Generated files:')); console.log(` ${chalk.cyan('Model:')} src/models/${name}.model.js`); console.log(` ${chalk.cyan('Service:')} src/services/${name}.service.js`); console.log(` ${chalk.cyan('Controller:')} src/controllers/${name}.controller.js`); console.log(` ${chalk.cyan('Routes:')} src/routes/${name}.routes.js`); console.log(''); console.log(chalk.cyan('API Endpoints:')); const pluralName = pluralize(name); console.log(` ${chalk.green('GET')} /api/${pluralName} - Get all ${pluralName}`); console.log(` ${chalk.green('GET')} /api/${pluralName}/:id - Get ${name} by ID`); console.log(` ${chalk.yellow('POST')} /api/${pluralName} - Create new ${name}`); console.log(` ${chalk.blue('PUT')} /api/${pluralName}/:id - Update ${name}`); console.log(` ${chalk.red('DELETE')} /api/${pluralName}/:id - Delete ${name}`); console.log(''); } catch (error) { spinner.fail(chalk.red(`Failed to generate feature: ${error.message}`)); } } /** * Update the routes index.js file to include the new route * @param {string} name - Feature name */ async function updateRoutesIndex(name) { const indexPath = path.join('src', 'routes', 'index.js'); const pluralName = pluralize(name); // Read existing file let content = await fs.readFile(indexPath, 'utf8'); // Import statement to add const importStatement = `import { ${name}Routes } from './${name}.routes.js';`; // Check if import already exists if (content.includes(importStatement)) { return; // Already imported } // Add import statement after the last import const lastImportIndex = content.lastIndexOf('import'); const lastImportEndIndex = content.indexOf(';', lastImportIndex) + 1; content = content.substring(0, lastImportEndIndex) + '\\n' + importStatement + content.substring(lastImportEndIndex); // Add route registration line before the last bracket const routeRegistration = ` app.use('/api/${pluralName}', ${name}Routes);`; const lastClosingBracket = content.lastIndexOf('}'); content = content.substring(0, lastClosingBracket) + ' // Register route for ' + name + '\\n' + routeRegistration + '\\n' + content.substring(lastClosingBracket); // Write updated content back to file await fs.writeFile(indexPath, content, 'utf8'); }