File size: 2,983 Bytes
d530f14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/env node

import { Command } from 'commander';
import inquirer from 'inquirer';
import chalk from 'chalk';
import ora from 'ora';
import path from 'path';
import { fileURLToPath } from 'url';
import { installer } from './lib/installer.js';
import { getPrompts } from './lib/prompts.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const program = new Command();

program
  .name('create-open-lovable')
  .description('Create a new Open Lovable project with your choice of sandbox provider')
  .version('1.0.0')
  .option('-s, --sandbox <provider>', 'Sandbox provider (e2b or vercel)')
  .option('-n, --name <name>', 'Project name')
  .option('-p, --path <path>', 'Installation path (defaults to current directory)')
  .option('--skip-install', 'Skip npm install')
  .option('--dry-run', 'Run without making changes')
  .parse(process.argv);

const options = program.opts();

async function main() {
  console.log(chalk.cyan('\nπŸš€ Welcome to Open Lovable Setup!\n'));

  let config = {
    sandbox: options.sandbox,
    name: options.name || 'my-open-lovable',
    path: options.path || process.cwd(),
    skipInstall: options.skipInstall || false,
    dryRun: options.dryRun || false
  };

  // Interactive mode if sandbox not specified
  if (!config.sandbox) {
    const prompts = getPrompts(config);
    const answers = await inquirer.prompt(prompts);
    config = { ...config, ...answers };
  }

  // Validate sandbox provider
  if (!['e2b', 'vercel'].includes(config.sandbox)) {
    console.error(chalk.red(`\n❌ Invalid sandbox provider: ${config.sandbox}`));
    console.log(chalk.yellow('Valid options: e2b, vercel\n'));
    process.exit(1);
  }

  console.log(chalk.gray('\nConfiguration:'));
  console.log(chalk.gray(`  Project: ${config.name}`));
  console.log(chalk.gray(`  Sandbox: ${config.sandbox}`));
  console.log(chalk.gray(`  Path: ${path.resolve(config.path, config.name)}\n`));

  if (config.dryRun) {
    console.log(chalk.yellow('πŸ” Dry run mode - no files will be created\n'));
  }

  const spinner = ora('Creating project...').start();

  try {
    await installer({
      ...config,
      templatesDir: path.join(__dirname, 'templates')
    });

    spinner.succeed('Project created successfully!');

    console.log(chalk.green('\nβœ… Setup complete!\n'));
    console.log(chalk.white('Next steps:'));
    console.log(chalk.gray(`  1. cd ${config.name}`));
    console.log(chalk.gray(`  2. Copy .env.example to .env and add your API keys`));
    console.log(chalk.gray(`  3. npm run dev`));
    console.log(chalk.gray('\nHappy coding! πŸŽ‰\n'));

  } catch (error) {
    spinner.fail('Setup failed');
    console.error(chalk.red('\n❌ Error:'), error.message);
    if (error.stack && process.env.DEBUG) {
      console.error(chalk.gray(error.stack));
    }
    process.exit(1);
  }
}

main().catch(error => {
  console.error(chalk.red('Unexpected error:'), error);
  process.exit(1);
});