UNPKG

@meyje/meyje-setup

Version:

🪄 MEYJE Setup: produtividade e organização desde o primeiro comando. Automatiza a criação de projetos Next.js 14 com as melhores práticas do mercado.

183 lines (153 loc) 6.42 kB
import path from 'path'; import fs from 'fs'; import chalk from 'chalk'; import { displayWelcome, promptUser } from './utils/prompts.js'; import { runCommand } from './utils/fileSystem.js'; import { normalizeProjectName } from './utils/slugify.js'; import { getDependencies } from './config/dependencies.js'; import { messages } from './config/constants.js'; import { createNextApp, runPackageManagerCommand } from './utils/packageManager.js'; // Importar módulos import { createEnvExampleFile, createDocumentationTemplates, createQuickstartGuide, createDefaultFoldersAndFiles, ensureGlobalsCssExists, updatePackageJsonWithScripts, initializeGitRepository, configureShadcn, createSwaggerExampleFiles, createDbFiles, createJestConfig } from './modules/index.js'; /** * Cria a estrutura base do projeto Next.js * @param {string} projectPath - Caminho do projeto */ const createNextAppWrapper = async (projectPath) => { console.log(chalk.hex('#4f46e5').bold('\n[1/7] Estruturando seu projeto Next.js com as melhores práticas do mercado.')); console.log(chalk.yellow(messages.nextjsCreated)); console.log(chalk.yellow(messages.nextjsTip)); return createNextApp(projectPath); }; /** * Instala as dependências selecionadas * @param {string} projectPath - Caminho do projeto * @param {Object} answers - Respostas do usuário */ const installDependencies = async (projectPath, answers) => { console.log(chalk.hex('#4f46e5').bold('\n[3/7] Instalando dependências essenciais para um stack moderno e escalável.')); const { dependencies, devDependencies } = getDependencies(answers); if (dependencies.length > 0) { await runPackageManagerCommand('add', dependencies, { cwd: projectPath }); console.log(chalk.yellow(messages.dependenciesInstalled)); console.log(chalk.yellow(messages.dependenciesTip)); } if (devDependencies.length > 0) { console.log(chalk.hex('#4f46e5').bold('\n[4/7] Preparando ambiente de testes e documentação.')); await runPackageManagerCommand('add-dev', devDependencies, { cwd: projectPath }); console.log(chalk.yellow(messages.devDependenciesInstalled)); console.log(chalk.yellow(messages.devDependenciesTip)); } }; /** * Exibe a mensagem final de sucesso * @param {string} projectPath - Caminho do projeto */ const printSuccessMessage = (projectPath) => { console.log(chalk.yellow('\n' + messages.setupComplete)); console.log(chalk.yellow(messages.setupCompleteTip)); console.log(chalk.hex('#4f46e5').bold('\n' + messages.usefulCommands)); console.log(chalk.hex('#4f46e5')(` cd "${projectPath}"`)); console.log(chalk.hex('#4f46e5')(' pnpm dev')); console.log(chalk.hex('#4f46e5')(' pnpm test')); console.log(chalk.hex('#4f46e5')(' pnpm db:studio')); console.log(chalk.hex('#4f46e5')(' pnpm docs:gen\n')); console.log(chalk.gray(messages.envReminder)); console.log(chalk.gray('📖 Leia o QUICKSTART.md para mais informações')); // Beep sonoro process.stdout.write('\x07'); }; /** * Função principal do CLI */ const main = async () => { let projectPath = ''; try { // Exibir banner de boas-vindas displayWelcome(); // Coletar preferências do usuário const answers = await promptUser(); // Verificar se answers foi obtido corretamente if (!answers) { throw new Error('Não foi possível obter as preferências do usuário. Tente novamente.'); } // Normalizar nome do projeto const normalizedProjectName = normalizeProjectName(answers.projectName); projectPath = path.resolve(answers.basePath, normalizedProjectName); // Verificar se o diretório já existe if (fs.existsSync(projectPath)) { throw new Error(`O diretório "${projectPath}" já existe. Por favor, escolha outro nome ou local.`); } // Criar projeto Next.js await createNextAppWrapper(projectPath); // Criar arquivos de configuração e documentação createEnvExampleFile(projectPath); createQuickstartGuide(projectPath, answers); console.log(chalk.yellow(messages.quickstartCreated)); console.log(chalk.yellow(messages.quickstartTip)); if (answers && answers.useSwagger === true) { createDocumentationTemplates(projectPath); createSwaggerExampleFiles(projectPath); console.log(chalk.yellow(messages.swaggerConfigured)); console.log(chalk.yellow(messages.swaggerTip)); } else { createDocumentationTemplates(projectPath); } // Criar estrutura de pastas createDefaultFoldersAndFiles(projectPath); // Atualizar package.json com scripts await updatePackageJsonWithScripts(projectPath, answers); // Configurar banco de dados se solicitado if (answers && answers.useDb === true) { await createDbFiles(projectPath); console.log(chalk.yellow(messages.databaseConfigured)); console.log(chalk.yellow(messages.databaseTip)); } // Configurar testes se solicitado if (answers && answers.useTesting === true) { await createJestConfig(projectPath); console.log(chalk.yellow(messages.testsConfigured)); console.log(chalk.yellow(messages.testsTip)); } // Instalar dependências await installDependencies(projectPath, answers); // Configurar ShadCN se solicitado if (answers && answers.useShadcn === true) { await configureShadcn(projectPath); } // Inicializar Git if (answers && answers.useGit === true) { await initializeGitRepository(projectPath); } // Garantir que o globals.css exista await ensureGlobalsCssExists(projectPath); // Exibir mensagem de sucesso printSuccessMessage(projectPath); } catch (error) { console.error(chalk.bold.red('\n❌ Ocorreu um erro durante a execução do script.')); if (error.exitCode) { console.error(chalk.red(`O comando "${error.command}" falhou com o código de saída ${error.exitCode}.`)); } else { console.error(chalk.red(error.message)); } if (projectPath && fs.existsSync(projectPath)) { console.log(chalk.yellow(`\nA pasta do projeto "${projectPath}" foi criada, mas pode estar em um estado inconsistente.`)); console.log(chalk.yellow(`É recomendado removê-la ('rm -rf ${projectPath}' ou manualmente) e tentar novamente.`)); } process.exit(1); } }; // Executar o CLI main();