UNPKG

nextdevkit

Version:

A Comprehensive CLI Toolkit for Next.js Development

105 lines (104 loc) 4.13 kB
import chalk from 'chalk'; import { spawn } from 'child_process'; import fs from 'fs-extra'; import path from 'path'; import ts from 'typescript'; import files from '../files.js'; import { __dirname } from '../utils/constants/package.constant.js'; import getAliasValue from '../utils/getAliasValue.js'; import getDestinationPaths from '../utils/getDestinationPaths.js'; import getPackageManager from '../utils/getPackageManager.js'; import { handleError, handleSuccess } from '../utils/handleMessages.js'; import isTypeScriptProject from '../utils/isTypescriptProject.js'; import loadNextdevkitConfig from '../utils/loadNextdevkitConfig.js'; const addFile = async (fileName) => { if (!fileName) { console.log(chalk.red('Please specify the name of the file to add.')); console.log(chalk.yellow('Usage: npx nextdevkit@latest add <name>')); return; } const currentDirectory = process.cwd(); const config = await loadNextdevkitConfig(currentDirectory); if (!config) { handleError('Failed to load configuration file.', { message: 'Ensure the configuration file exists or can be created.', exit: true }); return; } const isTs = isTypeScriptProject(currentDirectory); const fileConfig = files.find((f) => f.command.toLowerCase() === fileName.toLowerCase()); if (!fileConfig) { console.log(chalk.red(`File name '${fileName}' not found.`)); console.log(`\nUse ${chalk.cyan('npx nextdevkit@latest list')} to list all available utility and hook files.\n`); return; } try { const aliasValue = await getAliasValue(currentDirectory, isTs); const { destFolderPath, destFilePath } = getDestinationPaths(currentDirectory, config.aliases, fileConfig, aliasValue, fileName, isTs); await fs.ensureDir(destFolderPath); const srcFilePath = path.join(__dirname, '../../files', fileConfig.destinationFolder, `${fileConfig.name}.ts`); if (isTs) { await fs.copy(srcFilePath, destFilePath); } else { await transpileToJs(srcFilePath, destFilePath, fileConfig.name); } if (fileConfig.dependencies || fileConfig.devDependencies) { await installDependencies(fileConfig.dependencies || [], false); await installDependencies(fileConfig.devDependencies || [], true); } handleSuccess(`File '${fileName}' added successfully.`); } catch (error) { handleError(error, { message: `Failed to add file '${fileName}'. Please check the input and try again.`, verbose: true }); } }; const transpileToJs = async (srcFilePath, destFilePath, fileName) => { const sourceCode = await fs.readFile(srcFilePath, 'utf8'); const transpileOptions = { compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ESNext, sourceMap: false, declaration: false }, fileName: `${fileName}.ts` }; const result = ts.transpileModule(sourceCode, transpileOptions); await fs.writeFile(destFilePath, result.outputText, 'utf8'); }; const installDependencies = async (packages, isDev) => { if (packages.length === 0) return; const currentDirectory = process.cwd(); const packageManager = await getPackageManager(); const command = packageManager; const args = [ packageManager === 'npm' ? 'install' : 'add', ...packages, isDev ? packageManager === 'npm' ? '--save-dev' : '-D' : '' ].filter(Boolean); await new Promise((resolve, reject) => { const child = spawn(command, args, { cwd: currentDirectory, stdio: 'inherit' }); child.on('close', (code) => { if (code === 0) { resolve(); } else { reject(new Error(`Failed to install ${isDev ? 'devDependencies' : 'dependencies'}`)); } }); }); }; export default addFile;