@chaibuilder/create
Version:
Create a new app with Chai template
104 lines (83 loc) • 3.29 kB
JavaScript
const chalk = require('chalk');
const ora = require('ora');
const simpleGit = require('simple-git');
const fs = require('fs');
const path = require('path');
// Repository to clone - change this to your desired template
const TEMPLATE_REPO = 'https://github.com/chaibuilder/chaibuilder-nextjs.git';
// Get command line arguments
const args = process.argv.slice(2);
const appName = args[0];
const envVars = args.slice(1);
// Show usage if no app name
if (!appName) {
console.log(chalk.yellow('Usage: npx @chaibuilder/create <app-name> [ENV_VARS...]'));
console.log(chalk.dim('Example: npx @chaibuilder/create my-app CHAIBUILDER_API_KEY=123 CHAIBUILDER_API_SECRET=123'));
process.exit(1);
}
// Validate app name
if (!/^[a-zA-Z0-9-_]+$/.test(appName)) {
console.log(chalk.red('❌ Invalid app name. Use only letters, numbers, hyphens, and underscores.'));
process.exit(1);
}
// Check if directory exists
const projectPath = path.resolve(process.cwd(), appName);
if (fs.existsSync(projectPath)) {
console.log(chalk.red(`❌ Directory "${appName}" already exists!`));
process.exit(1);
}
// Create .env file with environment variables
const createEnvFile = (envVars) => {
if (!envVars || envVars.length === 0) return;
const spinner = ora('Creating .env file').start();
const envContent = envVars.map(env => {
// Handle KEY=VALUE format
if (env.includes('=')) {
return env;
}
// Handle KEY only (no value)
return `${env}=`;
}).join('\n').replace("-key=", "CHAIBUILDER_API_KEY=");
const envPath = path.join(projectPath, '.env');
fs.writeFileSync(envPath, `${envContent}\nCHAIBUILDER_WEBHOOK_SECRET=<your-webhook-secret>`);
spinner.succeed(chalk.green('API keys added to project'));
};
// Main function to create the app
const createApp = async () => {
console.log(chalk.cyan(`\n✔ Creating Your Chaibuilder Project - ${chalk.bold(appName)}\n`));
const git = simpleGit();
const spinner = ora('Preparing your chaibuilder starter').start();
try {
// Clone the repository
await git.clone(TEMPLATE_REPO, projectPath);
spinner.succeed(chalk.green('Your project is ready.'));
// Remove .git directory for fresh start
const gitDir = path.join(projectPath, '.git');
if (fs.existsSync(gitDir)) {
fs.rmSync(gitDir, { recursive: true, force: true });
}
// Create .env file if environment variables provided
if (envVars.length > 0) {
createEnvFile(envVars);
}
// Success message
console.log(chalk.bold('\nTo run your app'));
console.log(chalk.white(`➝ cd ${appName}`));
console.log(chalk.white(`➝ pnpm i OR npm i --legacy-peer-deps`));
console.log(chalk.white(`➝ pnpm dev OR npm run dev`));
console.log(chalk.white('\n📖 Check the documentation: https://www.chaibuilder.com/docs'));
console.log(chalk.greenBright(chalk.bold('🚀 Happy Building with Chaibuilder! ❤️')));
} catch (error) {
spinner.fail('Failed to create project');
console.error(chalk.red('Error:', error.message));
process.exit(1);
}
};
// Handle unhandled promise rejections
process.on('unhandledRejection', (err) => {
console.error(chalk.red('Unexpected error:', err.message));
process.exit(1);
});
// Run the app
createApp();