UNPKG

create-node-template

Version:

Create node.js/express boilerplate with one command

134 lines 4.66 kB
import * as util from 'util'; import * as readline from 'node:readline/promises'; import * as fs from 'node:fs/promises'; import path from 'path'; import { exec } from 'node:child_process'; import { supportedPMs, supportedTemplates } from '../../config/index.js'; import { blue, cyan, green, underline, yellow } from '../../utils/index.js'; /* * Execute command asynchronusly */ const execPromise = util.promisify(exec); /* * */ export const runCmd = async (command) => { try { const { stdout, stderr } = await execPromise(command); console.log(stdout); console.log(stderr); } catch (error) { console.log(error); } }; /* * */ export const readlinePromise = readline.createInterface({ input: process.stdin, output: process.stdout, }); /* * Used to map package managers to their install commands */ export const installCommandMap = { npm: 'npm install', yarn: 'yarn', pnpm: 'pnpm install', bun: 'bun install', }; /* * Used with process.argv[2] to get project name */ export const getProjectName = async (cwd, currFolder, name) => { let projectName = name; if (!projectName) { projectName = await readlinePromise.question(`\nYou have not specified a project name.\n${underline('Press Enter')} to create a project in your current folder (${underline.bold(currFolder)})\nOr enter a ${blue('project name')}: `); } const foldersInCwd = await fs.readdir(cwd); if (foldersInCwd.includes(projectName)) { const res = await readlinePromise.question(`\nA folder with that name already exists.\nPress Enter to overwrite\nOr enter a new project ${blue('name')}: `); projectName = res || projectName; } return projectName; }; /* * */ export async function findPackageManagers() { const packageManagers = []; await Promise.all(supportedPMs.map(async (pm) => { await execPromise(pm + ' --version'); packageManagers.push(pm); })); return packageManagers; } /* * */ export const getPackageManager = async (name) => { let packageManager = name; while (!supportedPMs.includes(packageManager)) { const packageManagers = await findPackageManagers(); const input = await readlinePromise.question(`\nThese package managers have been detected on your system:\n${packageManagers .filter(pm => pm !== 'npm') .map((pm, index) => `${index + 1} - ${pm}`) .join('\n')}\n\nSelect a ${underline('number')} or press Enter for ${blue('npm')}: `); packageManager = input === '' ? 'npm' : packageManagers[+input - 1] || null; if (!packageManager) { console.log(`\nInvalid selection. You must input a number. Try again.`); } } console.log(`You have selected: ${yellow(packageManager)} \n`); return packageManager; }; /* * */ export const getTemplate = async (name) => { let template = name; while (!template || !supportedTemplates.includes(template)) { const input = await readlinePromise.question(`\nSelect a template from this list (${underline('input number')}):\n${supportedTemplates .filter(temp => temp !== 'node-basic') .map((temp, index) => `${index + 1} - ${temp}`) .join('\n')}\n\nOr press Enter for ${blue('node-basic')}: `); template = input === '' ? 'node-basic' : supportedTemplates[+input] || null; if (!template) { console.log('Invalid template name'); } } console.log(`Creating project with template: ${yellow(template)} \n`); return template; }; /* * */ export const renameProject = async (projectName, destPath) => { const packageJsonPath = path.join(destPath, 'package.json'); const packageJson = await fs.readFile(packageJsonPath, 'utf-8'); const newPackageJson = packageJson.replace(/"name": ".*"/, `"name": "${projectName}"`); await fs.writeFile(packageJsonPath, newPackageJson); }; /* * */ export const getSuccessString = (projectName, template) => { const emoji = '🦉'; const chars = 53; const extraChars = projectName.length + template.length; const hashString = Array.from({ length: extraChars + chars }) .map(el => '#') .join(''); const successString = ` ${cyan(hashString)} ${emoji} ${green('Success!')} Created new project ${yellow.bold(projectName)} using template: ${yellow.italic(template)} ${emoji} ${cyan(hashString)} `; return successString; }; /* Test */ // const projectName = 'my-new-project'; // const template = 'node-basic'; // console.log(getSuccessString(projectName, template)); //# sourceMappingURL=utils.js.map