UNPKG

orchetera

Version:

Welcome to **Orchetera** — your orchestration tool to kickstart Firebase-ready projects with ease!

164 lines (137 loc) 4.91 kB
#!/usr/bin/env node const { execSync } = require("child_process"); const fs = require("fs"); const path = require("path"); const fse = require("fs-extra"); // Get app name const appName = process.argv[2] || "."; const isCurrentDir = appName === "."; const skipStart = process.argv.includes("--no-start"); // Path to installation directory const appPath = path.resolve(process.cwd(), appName); const firebasePath = path.join(appPath, "../firebaseConfig.js"); // if firebaseConfig.js doesn't exist if (!fs.existsSync(firebasePath)) { console.log("[INFO] Creating firebaseConfig..."); const firebaseTemplateContent = `const firebaseConfig = { apiKey: "", authDomain: "", projectId: "", storageBucket: "", messagingSenderId: "", appId: "", measurementId: "" };`; fs.mkdirSync(path.dirname(firebasePath), { recursive: true }); fs.writeFileSync(firebasePath, firebaseTemplateContent); console.warn( `[!] firebaseConfig.js not exist. Generated at: ${firebasePath}. Please open and complete it.` ); process.exit(1); } // if firebaseConfig is exist // mapping firebaseConfig to object form const firebaseRaw = fs.readFileSync(firebasePath, "utf8"); let configMatch = firebaseRaw.match(/firebaseConfig\s*=\s*{([^}]*)}/s); if (!configMatch) { console.error("[x] firebaseConfig not found in firebaseConfig.js"); process.exit(1); } if (!firebaseRaw.includes("const firebaseConfig")) { console.error("[x] firebaseConfig is not properly declared."); process.exit(1); } const configBlock = configMatch[1]; const configObj = {}; configBlock.split("\n").forEach((line) => { const match = line.trim().match(/^(\w+):\s*["'](.*?)["'],?$/); if (match) { const [, key, value] = match; configObj[key] = value; } }); const emptyFields = Object.entries(configObj).filter(([_, v]) => !v); if (emptyFields.length) { console.error("[!] Some firebaseConfig values are still empty:"); emptyFields.forEach(([k]) => console.warn(`- ${k}`)); process.exit(1); } // Run CRA with local template console.log("[INFO] Creating react app..."); if (!isCurrentDir && fs.existsSync(appPath)) { console.error(`[x] Directory "${appName}" already exists. Aborting.`); process.exit(1); } execSync(`npx create-react-app ${appName} --template file:${__dirname}`, { stdio: "inherit", }); // Generate PORT console.log("[INFO] Generating Port..."); const randomPort = Math.floor(1000 + Math.random() * 9000); // Path setup const envPath = path.join(appPath, ".env"); const firebasercPath = path.join(appPath, ".firebaserc"); // Prepare .env content console.log("[INFO] Generating .env and .firebaserc..."); let envContent = `PORT=${randomPort}\n`; let firebasercContent = ""; let projectId = ""; // Inject firebase config for (const [key, val] of Object.entries(configObj)) { const upperKey = key.toUpperCase(); envContent += `REACT_APP_FIREBASE_${upperKey}=${val}\n`; if (upperKey === "PROJECTID") { projectId = val; } } // Overwrite warning if (fs.existsSync(envPath)) { console.warn("[!] .env file exists. Will be overwritten."); } fs.writeFileSync(envPath, envContent); console.log(`[INFO] .env file created at: ${envPath}`); // Write .firebaserc if projectId found if (projectId) { firebasercContent = JSON.stringify( { projects: { default: projectId } }, null, 2 // prettier format ); if (fs.existsSync(firebasercPath)) { console.warn("[!] .firebaserc file exists. Will be overwritten."); } fs.writeFileSync(firebasercPath, firebasercContent); console.log(`[INFO] .firebaserc file created at: ${firebasercPath}`); } else { console.warn( "[!] projectId not found in firebase config. .firebaserc not created." ); } console.log(`[INFO] Encrypting .env with dechipera...`); execSync("npx dechipera --no-exit", { cwd: appPath, stdio: "inherit" }); console.log("[INFO] Removing firebaseConfig..."); fse.removeSync(firebasePath); console.log("[INFO] Change application title..."); // Replace <title> in public/index.html with app name const htmlPath = path.join(appPath, "public", "index.html"); let html = fs.readFileSync(htmlPath, "utf-8"); const titleName = isCurrentDir ? path.basename(process.cwd()) : appName; html = html.replace(/<title>.*<\/title>/, `<title>${titleName}</title>`); fs.writeFileSync(htmlPath, html); console.log( `[OK] Orchetera successfully generated and run on PORT ${randomPort}, and will be running soon...` ); console.log("[INFO] Opening Visual Studio Code..."); execSync(`code .`, { cwd: appPath, stdio: "inherit" }); // Run npm start in generated folder console.log("[INFO] Running app on PORT " + randomPort + "..."); try { if (!skipStart) { execSync(`npm start`, { cwd: appPath, stdio: "inherit" }); } else { console.log("[INFO] run the app using `npm start`"); } } catch (e) { console.error("[x] Failed to run app:", e.message); process.exit(1); }