create-nest-template-malahimdev
Version:
Scaffolds a NestJS template with Swagger, global pipes, exception filters, MongoDB connection and response helpers.
108 lines (92 loc) • 3.31 kB
JavaScript
const fs = require('fs');
const fsp = fs.promises;
const path = require('path');
const { execSync } = require('child_process');
const readline = require('readline');
const args = process.argv.slice(2);
const projectName = args[0] || '.';
const targetDir = path.resolve(process.cwd(), projectName);
const templateDir = path.resolve(__dirname, '../template');
async function exists(p) {
try {
await fsp.access(p);
return true;
} catch {
return false;
}
}
async function copyDir(src, dest) {
await fsp.mkdir(dest, { recursive: true });
const entries = await fsp.readdir(src, { withFileTypes: true });
for (const entry of entries) {
const srcPath = path.join(src, entry.name);
const destPath = path.join(dest, entry.name);
if (entry.isDirectory()) {
await copyDir(srcPath, destPath);
} else if (entry.isSymbolicLink()) {
const link = await fsp.readlink(srcPath);
await fsp.symlink(link, destPath);
} else {
await fsp.copyFile(srcPath, destPath);
}
}
}
function askInstall() {
return new Promise((resolve) => {
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
rl.question('Do you want to run `npm install` now? (y/N) ', (answer) => {
rl.close();
resolve(answer.trim().toLowerCase() === 'y');
});
});
}
async function main() {
if (!(await exists(templateDir))) {
console.error('ERROR: template/ folder not found inside package.');
process.exit(1);
}
if (projectName !== '.' && (await exists(targetDir))) {
const targetFiles = await fsp.readdir(targetDir);
if (targetFiles.length > 0) {
console.error(`ERROR: target folder ${targetDir} already exists and is not empty.`);
process.exit(1);
}
}
try {
console.log(`Creating project at: ${targetDir}`);
await copyDir(templateDir, targetDir);
// Update package.json name
const pkgPath = path.join(targetDir, 'package.json');
if (await exists(pkgPath) && projectName !== '.') {
try {
const pkg = JSON.parse(await fsp.readFile(pkgPath, 'utf8'));
pkg.name = projectName.replace(/\s+/g, '-').toLowerCase();
await fsp.writeFile(pkgPath, JSON.stringify(pkg, null, 2));
console.log('Updated template package.json `name` to', pkg.name);
} catch (e) {
// ignore parsing errors
}
}
console.log('Template copied.');
// Ask user about npm install
if (await askInstall()) {
console.log('Running `npm install` in the target directory...');
execSync('npm install', { cwd: targetDir, stdio: 'inherit' });
console.log('\nAll done! Next steps:');
console.log(projectName === '.' ? ' - inspect files in current directory' : ` cd ${projectName}`);
console.log(' - read README.md inside the new project for further instructions');
} else {
console.log('\nSkipped installing dependencies.');
console.log('Next steps:');
console.log(projectName === '.' ? ' - inspect files in current directory' : ` cd ${projectName}`);
console.log(' npm install');
console.log(' npm run start:dev');
}
process.exit(0);
} catch (err) {
console.error('ERROR copying template:', err);
process.exit(1);
}
}
main();