@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.
154 lines (139 loc) • 4.77 kB
JavaScript
import { execa } from 'execa';
import fs from 'fs';
import path from 'path';
/**
* Detecta qual gerenciador de pacotes está disponĂvel no sistema
* @returns {Promise<string>} - 'npm', 'yarn', 'pnpm' ou 'npm' como fallback
*/
async function detectPackageManager() {
try {
// Verificar se pnpm está disponĂvel
await execa('pnpm', ['--version'], { stdio: 'ignore' });
return 'pnpm';
} catch (error) {
try {
// Verificar se yarn está disponĂvel
await execa('yarn', ['--version'], { stdio: 'ignore' });
return 'yarn';
} catch (error) {
// npm como fallback (sempre disponĂvel com Node.js)
return 'npm';
}
}
}
/**
* Executa um comando com o gerenciador de pacotes detectado
* @param {string} command - Comando a ser executado
* @param {string[]} args - Argumentos do comando
* @param {Object} options - Opções do execa
* @returns {Promise<Object>} - Resultado do comando
*/
async function runPackageManagerCommand(command, args = [], options = {}) {
const packageManager = await detectPackageManager();
console.log(`📦 Usando ${packageManager} como gerenciador de pacotes`);
let finalCommand = packageManager;
let finalArgs = args;
// Adaptar comandos para diferentes gerenciadores
if (command === 'dlx' || command === 'create') {
switch (packageManager) {
case 'pnpm':
finalArgs = ['dlx', ...args];
break;
case 'yarn':
finalArgs = ['dlx', ...args];
break;
case 'npm':
finalArgs = ['dlx', ...args];
break;
}
} else if (command === 'add') {
switch (packageManager) {
case 'pnpm':
finalArgs = ['add', ...args];
break;
case 'yarn':
finalArgs = ['add', ...args];
break;
case 'npm':
finalArgs = ['install', ...args];
break;
}
} else if (command === 'add-dev') {
switch (packageManager) {
case 'pnpm':
finalArgs = ['add', '-D', ...args];
break;
case 'yarn':
finalArgs = ['add', '-D', ...args];
break;
case 'npm':
finalArgs = ['install', '--save-dev', ...args];
break;
}
}
return execa(finalCommand, finalArgs, { stdio: 'inherit', ...options });
}
/**
* Verifica se um comando está disponĂvel no sistema
* @param {string} command - Comando a verificar
* @returns {Promise<boolean>} - true se disponĂvel, false caso contrário
*/
async function isCommandAvailable(command) {
try {
await execa(command, ['--version'], { stdio: 'ignore' });
return true;
} catch (error) {
return false;
}
}
/**
* Executa create-next-app com fallbacks
* @param {string} projectPath - Caminho do projeto
* @returns {Promise<Object>} - Resultado do comando
*/
async function createNextApp(projectPath) {
const packageManager = await detectPackageManager();
// Tentar diferentes abordagens para criar o projeto Next.js
const approaches = [
// Abordagem 1: Usar npx create-next-app
async () => {
console.log('🔄 Tentando criar projeto com npx create-next-app...');
return execa('npx', [
'create-next-app@14', projectPath, '--typescript', '--app', '--tailwind',
'--eslint', '--src-dir', '--import-alias', '@/*', '--package-manager', packageManager
], { stdio: 'inherit' });
},
// Abordagem 2: Usar gerenciador de pacotes especĂfico
async () => {
console.log(`🔄 Tentando criar projeto com ${packageManager}...`);
return runPackageManagerCommand('dlx', [
'create-next-app@14', projectPath, '--typescript', '--app', '--tailwind',
'--eslint', '--src-dir', '--import-alias', '@/*', '--package-manager', packageManager
]);
},
// Abordagem 3: Usar npm como Ăşltimo recurso
async () => {
console.log('🔄 Tentando criar projeto com npm...');
return execa('npm', [
'dlx', 'create-next-app@14', projectPath, '--typescript', '--app', '--tailwind',
'--eslint', '--src-dir', '--import-alias', '@/*', '--package-manager', 'npm'
], { stdio: 'inherit' });
}
];
for (let i = 0; i < approaches.length; i++) {
try {
return await approaches[i]();
} catch (error) {
console.log(`❌ Abordagem ${i + 1} falhou:`, error.message);
if (i === approaches.length - 1) {
throw new Error(`Todas as abordagens para criar o projeto Next.js falharam. Ăšltimo erro: ${error.message}`);
}
}
}
}
export {
detectPackageManager,
runPackageManagerCommand,
isCommandAvailable,
createNextApp
};