nextdevkit
Version:
A Comprehensive CLI Toolkit for Next.js Development
155 lines (154 loc) ⢠5.64 kB
JavaScript
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;