create-mngts
Version:
Template for a Node.js project using TypeScript
301 lines (260 loc) • 8.75 kB
JavaScript
const fs = require("fs");
const path = require("path");
const { execSync } = require("child_process");
const colors = {
reset: "\x1b[0m",
green: "\x1b[32m",
yellow: "\x1b[33m",
cyan: "\x1b[36m",
red: "\x1b[31m",
};
const catgirlPhrases = [
"Meow~ Starting the process, master!",
"O-oh! Something's happening, nyaa~",
"Working hard for you, master! *purrs*",
"Is there anything else I can do? Nya~",
"Oops! Did I do that right, master? >w<",
"I'm doing my best, nyaa~!",
"Processing... processing... *tail wags*",
"Purrfect! It's working!",
"Hiss! An error occurred, master!",
"Nyaa! Almost done!",
"I hope I'm being helpful, meow~",
"Did I do a good job, master? *hopeful eyes*",
"Creating things just for you, nyaa~",
"I'm on it, meow~!",
];
const catgirlChance = 0.5;
function getRandomPhrase() {
return catgirlPhrases[Math.floor(Math.random() * catgirlPhrases.length)];
}
function maybeAddCatgirlPhrase() {
if (Math.random() < catgirlChance) {
return " " + getRandomPhrase();
}
return "";
}
function colorize(text, color) {
return `${color}${text}${colors.reset}`;
}
function loadingMessage(message, frames = ["\\", "|", "/", "-"]) {
let i = 0;
return setInterval(() => {
process.stdout.write(
`\r${colorize(message, colors.cyan)} ${
frames[(i = (i + 1) % frames.length)]
}`
);
}, 150);
}
function exec(command, options = {}) {
try {
execSync(command, { stdio: "inherit", ...options });
} catch (error) {
console.error(colorize(`Error executing command: ${command}`, colors.red));
process.exit(1);
}
}
function ensureDirExists(filePath) {
const dirname = path.dirname(filePath);
if (fs.existsSync(dirname)) {
return;
}
ensureDirExists(dirname);
fs.mkdirSync(dirname);
}
function isGitConfigured() {
try {
const userName = execSync("git config --get user.name", { stdio: "pipe" }).toString().trim();
const userEmail = execSync("git config --get user.email", { stdio: "pipe" }).toString().trim();
return !!userName && !!userEmail;
} catch {
return false;
}
}
function createProject() {
const projectName = process.argv[2];
if (!projectName) {
console.error(
colorize("Nyaa~ Please specify the project name, master!", colors.yellow)
);
console.error(
colorize(
"Like this: npx create-node-ts-project my-new-project, meow~",
colors.yellow
)
);
process.exit(1);
}
const projectDir = path.resolve(process.cwd(), projectName);
if (fs.existsSync(projectDir)) {
console.error(
colorize(
`Nyaa! Directory '${projectName}' already exists, master!`,
colors.red
)
);
process.exit(1);
}
fs.mkdirSync(projectDir);
console.log(
colorize(
`Created project directory: ${projectName}, nyaa~${maybeAddCatgirlPhrase()}`,
colors.green
)
);
const templatesDir = path.join(__dirname, "templates");
let packageJsonContent = fs.readFileSync(
path.join(templatesDir, "package.json"),
"utf-8"
);
const packageJsonPath = path.join(projectDir, "package.json");
const tsconfigPath = path.join(projectDir, "tsconfig.json");
const srcDirPath = path.join(projectDir, "src");
const indexTsPath = path.join(srcDirPath, "main.ts");
const eslintrcPath = path.join(projectDir, ".eslintrc.js");
const prettierrcPath = path.join(projectDir, ".prettierrc.js");
const gitignorePath = path.join(projectDir, ".gitignore");
const templateGitignorePath = path.join(templatesDir, "gitignore")
const replaceProjectName = (content, projectName) => {
return content.replace(/\${projectName}/g, projectName);
};
packageJsonContent = replaceProjectName(packageJsonContent, projectName);
const tsconfigContent = fs.readFileSync(
path.join(templatesDir, "tsconfig.json"),
"utf-8"
);
const eslintrcContent = fs.readFileSync(
path.join(templatesDir, ".eslintrc.js"),
"utf-8"
);
const prettierrcContent = fs.readFileSync(
path.join(templatesDir, ".prettierrc.js"),
"utf-8"
);
const gitignoreContent = fs.readFileSync(templateGitignorePath,
"utf-8"
);
const indexTsContent = fs.readFileSync(
path.join(templatesDir, "src/main.ts"),
"utf-8"
);
ensureDirExists(packageJsonPath);
fs.writeFileSync(packageJsonPath, packageJsonContent);
console.log(
colorize(
`Created package.json, master, nyaa~${maybeAddCatgirlPhrase()}`,
colors.green
)
);
ensureDirExists(tsconfigPath);
fs.writeFileSync(tsconfigPath, tsconfigContent);
console.log(
colorize(
`Created tsconfig.json, nyaa~${maybeAddCatgirlPhrase()}`,
colors.green
)
);
ensureDirExists(eslintrcPath);
fs.writeFileSync(eslintrcPath, eslintrcContent);
console.log(
colorize(
`Created .eslintrc.js, nyaa~${maybeAddCatgirlPhrase()}`,
colors.green
)
);
ensureDirExists(prettierrcPath);
fs.writeFileSync(prettierrcPath, prettierrcContent);
console.log(
colorize(
`Created .prettierrc.js, master!${maybeAddCatgirlPhrase()}`,
colors.green
)
);
ensureDirExists(gitignorePath);
fs.writeFileSync(gitignorePath, gitignoreContent);
console.log(
colorize(
`Created .gitignore, shhh!${maybeAddCatgirlPhrase()}`,
colors.green
)
);
ensureDirExists(indexTsPath);
fs.writeFileSync(indexTsPath, indexTsContent);
console.log(
colorize(
`Created src/main.ts, nyaa~${maybeAddCatgirlPhrase()}`,
colors.green
)
);
console.log(
colorize(
"Installing dependencies, master... Nyaa~! Please be patient, I'm on it!",
colors.cyan
)
);
const installLoading = loadingMessage(
"Installing dependencies... Please wait, nyaa~! Almost there, master!"
);
exec("npm install", { cwd: projectDir });
clearInterval(installLoading);
process.stdout.write(
`\r${colorize(
"Installed dependencies, master! All done, nyaa~!",
colors.green
)} \n`
);
if (isGitConfigured()) {
console.log(
colorize(
"Initializing git repository, nyaa~... Let's make it official, master!",
colors.cyan
)
);
exec("git init", { cwd: projectDir });
exec("git add .", { cwd: projectDir });
exec('git commit -m "Initial commit"', { cwd: projectDir });
console.log(
colorize(
`Initialized git repository, master!${maybeAddCatgirlPhrase()}`,
colors.green
)
);
} else {
console.warn(
colorize(
"Git is not configured with a username or email. Skipping git initialization, master.",
colors.yellow
)
);
}
console.log(
colorize(
`Project '${projectName}' successfully created, master!${maybeAddCatgirlPhrase()}`,
colors.green
)
);
const asciiArt = `
⣇⣿⠘⣿⣿⣿⡿⡿⣟⣟⢟⢟⢝⠵⡝⣿⡿⢂⣼⣿⣷⣌⠩⡫⡻⣝⠹⢿⣿⣷
⡆⣿⣆⠱⣝⡵⣝⢅⠙⣿⢕⢕⢕⢕⢝⣥⢒⠅⣿⣿⣿⡿⣳⣌⠪⡪⣡⢑⢝⣇
⡆⣿⣿⣦⠹⣳⣳⣕⢅⠈⢗⢕⢕⢕⢕⢕⢈⢆⠟⠋⠉⠁⠉⠉⠁⠈⠼⢐⢕⢽
⡗⢰⣶⣶⣦⣝⢝⢕⢕⠅⡆⢕⢕⢕⢕⢕⣴⠏⣠⡶⠛⡉⡉⡛⢶⣦⡀⠐⣕⢕
⡝⡄⢻⢟⣿⣿⣷⣕⣕⣅⣿⣔⣕⣵⣵⣿⣿⢠⣿⢠⣮⡈⣌⠨⠅⠹⣷⡀⢱⢕
⡝⡵⠟⠈⢀⣀⣀⡀⠉⢿⣿⣿⣿⣿⣿⣿⣿⣼⣿⢈⡋⠴⢿⡟⣡⡇⣿⡇⡀⢕
⡝⠁⣠⣾⠟⡉⡉⡉⠻⣦⣻⣿⣿⣿⣿⣿⣿⣿⣿⣧⠸⣿⣦⣥⣿⡇⡿⣰⢗⢄
⠁⢰⣿⡏⣴⣌⠈⣌⠡⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣬⣉⣉⣁⣄⢖⢕⢕⢕
⡀⢻⣿⡇⢙⠁⠴⢿⡟⣡⡆⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣵⣵⣿
⡻⣄⣻⣿⣌⠘⢿⣷⣥⣿⠇⣿⣿⣿⣿⣿⣿⠛⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣷⢄⠻⣿⣟⠿⠦⠍⠉⣡⣾⣿⣿⣿⣿⣿⣿⢸⣿⣦⠙⣿⣿⣿⣿⣿⣿⣿⣿⠟
⡕⡑⣑⣈⣻⢗⢟⢞⢝⣻⣿⣿⣿⣿⣿⣿⣿⠸⣿⠿⠃⣿⣿⣿⣿⣿⣿⡿⠁⣠
⡝⡵⡈⢟⢕⢕⢕⢕⣵⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣿⣿⣿⣿⣿⠿⠋⣀⣈⠙
⡝⡵⡕⡀⠑⠳⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⢉⡠⡲⡫⡪⡪⡣
`;
console.log(asciiArt);
console.log(colorize("To get started, nyaa~:", colors.cyan));
console.log(colorize(` cd ${projectName}`, colors.yellow));
console.log(colorize(" npm run dev", colors.yellow));
console.log(colorize("Happy hacking! Nyaa~<3", colors.green));
}
createProject();