UNPKG

nextdevkit

Version:

A Comprehensive CLI Toolkit for Next.js Development

155 lines (154 loc) • 5.64 kB
import { execSync } from 'child_process'; import fs from 'fs'; import inquirer from 'inquirer'; import ora from 'ora'; import path from 'path'; import getPackageManager from '../utils/getPackageManager.js'; import { handleError } from '../utils/handleMessages.js'; const installPackages = async (packages) => { try { const packageManager = await getPackageManager(); execSync(`${packageManager} ${packageManager === 'npm' ? 'install' : 'add'} -D ${packages.join(' ')}`, { stdio: 'ignore' }); } catch (error) { handleError(`Failed to install packages: ${error}`); } }; const setupESLint = async () => { const spinner = ora('Setting up ESLint...').start(); try { await installPackages([ 'eslint', '@typescript-eslint/eslint-plugin', '@typescript-eslint/parser' ]); execSync('npx eslint --init', { stdio: 'ignore' }); const eslintConfigPath = path.resolve('.eslintrc.js'); if (fs.existsSync(eslintConfigPath)) { const eslintConfig = fs.readFileSync(eslintConfigPath, 'utf-8'); const updatedConfig = eslintConfig.replace('parserOptions: {', `parser: '@typescript-eslint/parser', parserOptions: {`); fs.writeFileSync(eslintConfigPath, updatedConfig, 'utf-8'); } spinner.succeed('ESLint configured successfully.'); } catch (error) { spinner.fail('Failed to set up ESLint.'); throw error; } }; const setupPrettier = async () => { const spinner = ora('Setting up Prettier...').start(); try { await installPackages([ 'prettier', 'eslint-config-prettier', 'eslint-plugin-prettier' ]); const prettierConfig = { experimentalTernaries: true, printWidth: 80, tabWidth: 2, useTabs: false, semi: true, singleQuote: true, jsxSingleQuote: true, quoteProps: 'as-needed', trailingComma: 'none', bracketSpacing: true, bracketSameLine: true, jsxBracketSameLine: true, arrowParens: 'always', singleAttributePerLine: false }; const prettierIgnoreData = ['node_modules', 'dist', 'build']; fs.writeFileSync('.prettierrc', JSON.stringify(prettierConfig, null, 2)); fs.writeFileSync('.prettierignore', prettierIgnoreData.join('\n')); const packageJsonPath = path.resolve('package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); packageJson.scripts = { ...packageJson.scripts, prettier: 'prettier --write --ignore-unknown .' }; fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); spinner.succeed('Prettier configured successfully.'); } catch (error) { spinner.fail('Failed to set up Prettier.'); throw error; } }; const setupHusky = async () => { const spinner = ora('Setting up Husky...').start(); try { await installPackages(['husky']); const packageManager = await getPackageManager(); const huskyInitCommand = packageManager === 'bun' ? 'bunx husky init' : packageManager === 'pnpm' ? 'pnpm exec husky init' : 'npx husky init'; execSync(huskyInitCommand, { stdio: 'ignore' }); const preCommitPath = path.resolve('./.husky/pre-commit'); fs.writeFileSync(preCommitPath, 'npx lint-staged\n'); spinner.succeed('Husky configured successfully.'); } catch (error) { spinner.fail('Failed to set up Husky.'); throw error; } }; const setupLintStaged = async () => { const spinner = ora('Setting up lint-staged...').start(); try { await installPackages(['lint-staged']); const packageJsonPath = path.resolve('package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); packageJson['lint-staged'] = { '**/*': 'prettier --write --ignore-unknown' }; fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); spinner.succeed('lint-staged configured successfully.'); } catch (error) { spinner.fail('Failed to set up lint-staged.'); throw error; } }; const setupLinters = async () => { console.log('\nšŸ”§ Setting up linters for your project...\n'); const { selectedLinters } = await inquirer.prompt([ { type: 'checkbox', name: 'selectedLinters', message: 'Select the tools you want to set up:', choices: [ { name: 'ESLint', value: 'eslint' }, { name: 'Prettier', value: 'prettier' }, { name: 'Husky', value: 'husky' }, { name: 'lint-staged', value: 'lint-staged' } ] } ]); if (selectedLinters.length === 0) { console.log('āŒ No tools selected. Exiting setup.\n'); return; } const setupTasks = { eslint: setupESLint, prettier: setupPrettier, husky: setupHusky, 'lint-staged': setupLintStaged }; for (const linter of selectedLinters) { try { await setupTasks[linter](); } catch (error) { handleError(error, { message: `Error setting up ${linter}.`, verbose: true }); } } console.log('šŸŽ‰ Linters setup complete!\n'); }; export default setupLinters;