@admac-hub/create-roleauth-core-cli
Version:
Interactive CLI to scaffold a full-stack MERN role-based auth app with Google OAuth and .env setup.
129 lines (113 loc) • 4.52 kB
JavaScript
#!/usr/bin/env node
const fs = require('fs-extra');
const path = require('path');
const prompts = require('prompts');
const { execSync } = require('child_process');
(async () => {
const projectName = process.argv[2];
if (!projectName) {
console.log("\u274C Please provide a project name.");
console.log("\uD83D\uDC49 Example: npx @admac-hub/create-roleauth-core-cli my-app");
process.exit(1);
}
const currentPath = process.cwd();
const targetPath = path.join(currentPath, projectName);
const templatePath = path.join(__dirname, '../template');
console.log(`\ud83d\udcc1 Creating project at: ${targetPath}`);
try {
// 1. Copy template files
fs.copySync(templatePath, targetPath);
console.log("\u2705 Template copied.");
// 2. Prompt user for .env values
console.log("\n\ud83d\udeb0 Let's configure your .env backend file\n");
const envAnswers = await prompts([
{
type: 'text',
name: 'PORT',
message: 'What port should your backend run on?',
initial: '5000',
},
{
type: 'text',
name: 'MONGO_URI',
message: 'What is your MongoDB URI?\n(\ud83d\udca1 Create one here: https://www.mongodb.com/atlas/database)',
initial: 'mongodb://localhost:27017/mern-auth',
},
{
type: 'text',
name: 'JWT_SECRET',
message: 'What should we use as your JWT secret?\n(\ud83d\udd10 Generate: https://generate-random.org/string)',
initial: 'your_jwt_secret',
},
{
type: 'text',
name: 'EMAIL_HOST',
message: 'What is your email SMTP host?',
initial: 'smtp.gmail.com',
},
{
type: 'text',
name: 'EMAIL_USER',
message: 'What is your email username?',
initial: 'your_email@example.com',
},
{
type: 'password',
name: 'EMAIL_PASS',
message: 'What is your email password?',
},
{
type: 'text',
name: 'GOOGLE_CLIENT_ID',
message: 'What is your Google Client ID?\n(\ud83d\udca1 https://console.cloud.google.com/apis/credentials)',
},
{
type: 'text',
name: 'GOOGLE_CLIENT_SECRET',
message: 'What is your Google Client Secret?',
},
{
type: 'text',
name: 'GOOGLE_CALLBACK_URL',
message: 'What is your Google Callback URL?',
initial: 'http://localhost:5000/api/auth/google/callback',
},
{
type: 'text',
name: 'REACT_APP_API_BASE_URL',
message: 'What is your React API base URL?',
initial: 'http://localhost:5000',
}
]);
// 3. Write backend .env
const backendEnvText = Object.entries(envAnswers)
.filter(([key]) => !key.startsWith('REACT_APP'))
.map(([key, val]) => `${key}=${val}`)
.join('\n');
const backendEnvPath = path.join(targetPath, 'backend', '.env');
fs.writeFileSync(backendEnvPath, backendEnvText);
console.log("\u2705 .env file created at: backend/.env");
// 4. Write frontend .env (if webclient exists)
const frontendDir = path.join(targetPath, 'webclient');
const frontendEnvPath = path.join(frontendDir, '.env');
const frontendEnvText = `REACT_APP_API_BASE_URL=${envAnswers.REACT_APP_API_BASE_URL}`;
if (fs.existsSync(frontendDir)) {
fs.writeFileSync(frontendEnvPath, frontendEnvText);
console.log("\u2705 .env file created at: webclient/.env");
} else {
console.warn("\u26a0\ufe0f Warning: webclient/ folder not found. Skipping frontend .env generation.");
}
// 5. Final success message
console.log(`\n\ud83c\udf89 Project created at: ${targetPath}`);
console.log("\n\ud83d\udd19 Next steps:");
console.log(` cd ${projectName}/backend && npm install`);
console.log(` cd ../webclient && npm install`);
console.log(` npm run dev # Or however you start your project`);
console.log("\n\ud83d\udca1 Your .env files were generated — review them before starting.");
console.log("\n\u2b50 If this helped, star the repo: https://github.com/admac-hub/create-roleauth-core-cli");
console.log("\ud83d\udcf8 And follow on Instagram: https://www.instagram.com/codeoncouch");
} catch (err) {
console.error("\u274C Error creating project:", err);
process.exit(1);
}
})();