UNPKG

create-kaplay-game

Version:

CLI to scaffold an Electron+Vite+Kaplay game project.

153 lines (136 loc) 4.65 kB
#!/usr/bin/env node const inquirer = require("inquirer"); const fs = require("fs-extra"); const path = require("path"); const chalk = require("chalk"); const { execSync } = require("child_process"); async function main() { console.log(chalk.cyan("\nKaplay Game Creator - Electron + Vite + Kaplay\n")); // Support project name as CLI argument const cliProjectName = process.argv[2]; const questions = []; if (!cliProjectName) { questions.push({ type: "input", name: "projectName", message: "Project name:", validate: (input) => (input ? true : "Project name cannot be empty."), }); } questions.push( { type: "list", name: "language", message: "Choose language:", choices: ["JavaScript", "TypeScript"], }, { type: "number", name: "width", message: "Window width:", default: 800, validate: (input) => (input > 0 ? true : "Width must be positive."), }, { type: "number", name: "height", message: "Window height:", default: 600, validate: (input) => (input > 0 ? true : "Height must be positive."), } ); const answers = await inquirer.prompt(questions); const projectName = cliProjectName || answers.projectName; const { language, width, height } = answers; const templateDir = path.join( __dirname, "templates", language === "JavaScript" ? "js" : "ts" ); const targetDir = projectName === "./" ? process.cwd() : path.resolve(process.cwd(), projectName); if (projectName !== "./" && fs.existsSync(targetDir)) { console.log(chalk.red(`\nDirectory '${projectName}' already exists!`)); process.exit(1); } // Copy template files (do not overwrite existing files in ./) await fs.copy(templateDir, targetDir, { overwrite: false, errorOnExist: false, }); // Explicitly copy .tools folder (even if hidden) const toolsSrc = path.join(templateDir, ".tools"); const toolsDest = path.join(targetDir, ".tools"); if (await fs.pathExists(toolsSrc)) { await fs.copy(toolsSrc, toolsDest, { overwrite: false, errorOnExist: false, }); } // Replace window size placeholders in electron.js or electron.ts const electronFile = language === "JavaScript" ? path.join("src", "electron", "electron.js") : path.join("src", "electron", "electron.ts"); const electronPath = path.join(targetDir, electronFile); let electronContent = await fs.readFile(electronPath, "utf8"); electronContent = electronContent .replace(/__KAPLAY_WIDTH__/g, width) .replace(/__KAPLAY_HEIGHT__/g, height); await fs.writeFile(electronPath, electronContent, "utf8"); // Update main field and clear script in package.json const packageJsonPath = path.join(targetDir, "package.json"); let packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf8")); packageJson.main = electronFile; packageJson.scripts = packageJson.scripts || {}; packageJson.scripts.clear = "node .tools/clear.js"; await fs.writeFile( packageJsonPath, JSON.stringify(packageJson, null, 2), "utf8" ); // Ensure .tools/ is in .gitignore const gitignorePath = path.join(targetDir, ".gitignore"); let gitignore = ""; if (await fs.pathExists(gitignorePath)) { gitignore = await fs.readFile(gitignorePath, "utf8"); if (!gitignore.includes(".tools/")) { gitignore += (gitignore.endsWith("\n") ? "" : "\n") + ".tools/\n"; await fs.writeFile(gitignorePath, gitignore, "utf8"); } } else { await fs.writeFile(gitignorePath, ".tools/\n", "utf8"); } // Update canvas size in index.html const htmlPath = path.join(targetDir, "index.html"); let htmlContent = await fs.readFile(htmlPath, "utf8"); htmlContent = htmlContent .replace(/width="\d+"/, `width=\"${width}\"`) .replace(/height="\d+"/, `height=\"${height}\"`); await fs.writeFile(htmlPath, htmlContent, "utf8"); // Install dependencies console.log( chalk.green("\nInstalling dependencies... (this may take a minute)") ); execSync("npm install", { cwd: targetDir, stdio: "inherit" }); console.log( chalk.green( `\nSuccess! Your Kaplay game is ready in '${ projectName === "./" ? "current directory" : projectName }'.` ) ); console.log(chalk.cyan(`\nTo get started:`)); if (projectName !== "./") { console.log(chalk.white(` cd ${projectName}`)); } if (language === "TypeScript") { console.log( chalk.white(" npm run build # (first time, to compile TypeScript)") ); } console.log(chalk.white(` npm run dev`)); } main();