import fs from "fs"; import path from "path"; import { promisify } from "util"; import readline from "readline"; import { fileURLToPath } from "url"; import chalk from "chalk"; const copyFile = promisify(fs.copyFile); const mkdir = promisify(fs.mkdir); const readdir = promisify(fs.readdir); const writeFile = promisify(fs.writeFile); // Get current file's directory const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); async function copyDir(src: string, dest: string) { await mkdir(dest, { recursive: true }); const entries = await 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 { await copyFile(srcPath, destPath); } } } async function askYesNo(question: string): Promise { const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); return new Promise((resolve) => { rl.question(question, (answer) => { rl.close(); resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes"); }); }); } async function askQuestion(question: string, defaultValue: string): Promise { const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); return new Promise((resolve) => { rl.question(`${question} (${defaultValue}): `, (answer) => { rl.close(); resolve(answer.trim() || defaultValue); }); }); } export async function init() { try { // Get the directory where the command is executed const rootDir = process.env.INIT_CWD || process.cwd(); console.log("Root directory:", rootDir); const misoDir = path.join(rootDir, ".miso"); const configPath = path.join(rootDir, "miso.config.mjs"); // Get the CLI package root directory const cliRootDir = path.resolve(__dirname, "../"); const templatesDir = path.join(cliRootDir, "src", "templates", ".miso"); // Check if templates directory exists if (!fs.existsSync(templatesDir)) { console.error(`Templates directory not found at: ${templatesDir}`); process.exit(1); } // Check if .miso directory exists if (fs.existsSync(misoDir)) { const shouldOverwrite = await askYesNo( ".miso directory already exists. Do you want to overwrite it? (y/N) " ); if (!shouldOverwrite) { console.log("Operation cancelled by user."); return; } // Remove existing directory fs.rmSync(misoDir, { recursive: true, force: true }); } // Ask for React app directory name const reactAppRoot = await askQuestion("Enter React app directory name", "react-app"); // Create .miso directory and copy templates await copyDir(templatesDir, misoDir); // Create or update miso.config.json const config = { reactAppRoot }; if (fs.existsSync(configPath)) { const shouldOverwrite = await askYesNo( "miso.config.json already exists. Do you want to overwrite it? (y/N) " ); if (!shouldOverwrite) { console.log("Operation cancelled by user."); return; } } await writeFile(configPath, `export default ${JSON.stringify(config, null, 2)}`); console.log( chalk.green("✅ Successfully initialized miso project in .miso directory") ); console.log( chalk.green(`✅ Created miso.config.json with reactAppRoot: ${reactAppRoot}`) ); } catch (error) { console.error(chalk.red("❌ Error during initialization:"), error); process.exit(1); } }