@exiloncms/cli 1.1.2 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -55,6 +55,84 @@ async function checkCommandExists(command) {
55
55
  return false;
56
56
  }
57
57
  }
58
+ async function checkPHPExtensions(spinner) {
59
+ const requiredExtensions = ["zip", "fileinfo", "mbstring", "pdo", "ctype", "json", "tokenizer", "xml"];
60
+ spinner.start("V\xE9rification des extensions PHP...");
61
+ const checkScript = `<?php
62
+ $missing = [];
63
+ $required = ${JSON.stringify(requiredExtensions)};
64
+
65
+ foreach ($required as $ext) {
66
+ if (!extension_loaded($ext)) {
67
+ $missing[] = $ext;
68
+ }
69
+ }
70
+
71
+ if (!empty($missing)) {
72
+ echo 'MISSING:' . implode(',', $missing);
73
+ exit(1);
74
+ }
75
+
76
+ echo 'OK';
77
+ exit(0);
78
+ `;
79
+ const tempFile = path.join(process.cwd(), "php_check.php");
80
+ await fs.writeFile(tempFile, checkScript);
81
+ try {
82
+ const { stdout } = await execaCommand(`php "${tempFile}"`, { stdio: "pipe" });
83
+ await fs.remove(tempFile);
84
+ if (stdout.includes("OK")) {
85
+ spinner.succeed("Toutes les extensions PHP sont install\xE9es");
86
+ return;
87
+ }
88
+ } catch (execError) {
89
+ if (await fs.pathExists(tempFile)) {
90
+ await fs.remove(tempFile);
91
+ }
92
+ const stdout = execError.stdout || "";
93
+ if (stdout.includes("MISSING:")) {
94
+ const missing = stdout.replace("MISSING:", "").trim().split(",");
95
+ spinner.warn("Extensions PHP manquantes");
96
+ console.log(chalk.red(`
97
+ \u274C Extensions PHP manquantes: ${missing.join(", ")}!
98
+ `));
99
+ console.log(chalk.bold("Pour utiliser ExilonCMS, PHP doit avoir ces extensions activ\xE9es.\n"));
100
+ const isWindows = process.platform === "win32";
101
+ if (isWindows) {
102
+ console.log(chalk.bold("Windows - Activer les extensions PHP:\n"));
103
+ console.log(chalk.cyan("1. Trouvez votre fichier php.ini:"));
104
+ console.log(chalk.gray(" php --ini"));
105
+ console.log(chalk.gray(" Ou: C:\\php\\php.ini\n"));
106
+ console.log(chalk.cyan("2. \xC9ditez php.ini et cherchez ces lignes:"));
107
+ for (const ext of missing) {
108
+ console.log(chalk.gray(` ;extension=${ext}`));
109
+ }
110
+ console.log(chalk.gray(" Changez-les en:"));
111
+ for (const ext of missing) {
112
+ console.log(chalk.green(` extension=${ext}`));
113
+ }
114
+ console.log("");
115
+ console.log(chalk.cyan("3. Sauvegardez et red\xE9marrez votre terminal.\n"));
116
+ console.log(chalk.yellow("\u{1F4A1} Alternative: Utilisez PHP via XAMPP/WAMP qui inclut ces extensions.\n"));
117
+ console.log(chalk.gray("T\xE9l\xE9charger XAMPP: https://www.apachefriends.org/download.html"));
118
+ console.log(chalk.gray("T\xE9l\xE9charger WAMP: https://www.wampserver.com/\n"));
119
+ console.log(chalk.yellow("\u26A0\uFE0F PHP install\xE9 via WinGet:"));
120
+ console.log(chalk.gray(" Le PHP WinGet est souvent minimaliste. Consid\xE9rez XAMPP/WAMP pour un environnement complet.\n"));
121
+ } else {
122
+ console.log(chalk.bold("Linux/macOS - Activer les extensions PHP:\n"));
123
+ console.log(chalk.cyan("Ubuntu/Debian:"));
124
+ const packages = missing.map((ext) => `php-${ext}`).join(" ");
125
+ console.log(chalk.gray(` sudo apt install ${packages}
126
+ `));
127
+ console.log(chalk.cyan("macOS:"));
128
+ console.log(chalk.gray(" brew install php\n"));
129
+ }
130
+ console.log(chalk.bold("\u{1F4A1} Apr\xE8s avoir activ\xE9 les extensions, relancez ce CLI.\n"));
131
+ throw new Error("Extensions PHP manquantes - Veuillez suivre les instructions ci-dessus");
132
+ }
133
+ spinner.succeed("V\xE9rification des extensions PHP termin\xE9e");
134
+ }
135
+ }
58
136
  async function checkDependencies(spinner) {
59
137
  const requiredDeps = [
60
138
  { name: "PHP", command: "php", url: "https://windows.php.net/download/" },
@@ -328,37 +406,66 @@ async function installDependencies(config, targetDir, spinner) {
328
406
  }
329
407
  spinner.start("Installation des d\xE9pendances PHP (Composer)...");
330
408
  try {
331
- await execaCommand("composer update --no-interaction", { cwd: targetDir, stdio: "inherit" });
409
+ const { stdout, stderr } = await execaCommand("composer update --no-interaction", { cwd: targetDir });
332
410
  spinner.succeed("D\xE9pendances PHP install\xE9es");
333
411
  } catch (error) {
334
- spinner.fail("Erreur lors de l'installation Composer");
335
- const errorStr = error.toString() || "";
412
+ const errorStr = (error.toString() || "") + (error.stdout || "") + (error.stderr || "");
413
+ const missingExtensions = [];
336
414
  if (errorStr.includes("ext-zip") || errorStr.includes("extension zip")) {
337
- console.log(chalk.red("\n\u274C Extension PHP zip manquante!\n"));
338
- console.log(chalk.bold("Pour utiliser ExilonCMS, PHP doit avoir l'extension zip activ\xE9e.\n"));
415
+ missingExtensions.push("zip");
416
+ }
417
+ if (errorStr.includes("ext-fileinfo") || errorStr.includes("extension fileinfo")) {
418
+ missingExtensions.push("fileinfo");
419
+ }
420
+ if (errorStr.includes("ext-mbstring") || errorStr.includes("extension mbstring")) {
421
+ missingExtensions.push("mbstring");
422
+ }
423
+ if (errorStr.includes("ext-pdo") || errorStr.includes("extension pdo")) {
424
+ missingExtensions.push("pdo");
425
+ }
426
+ if (missingExtensions.length > 0) {
427
+ spinner.fail("Extensions PHP manquantes");
428
+ console.log(chalk.red(`
429
+ \u274C Extensions PHP manquantes: ${missingExtensions.join(", ")}!
430
+ `));
431
+ console.log(chalk.bold("Pour utiliser ExilonCMS, PHP doit avoir ces extensions activ\xE9es.\n"));
339
432
  const isWindows = process.platform === "win32";
340
433
  if (isWindows) {
341
- console.log(chalk.bold("Windows - Activer l'extension zip:\n"));
434
+ console.log(chalk.bold("Windows - Activer les extensions PHP:\n"));
342
435
  console.log(chalk.cyan("1. Trouvez votre fichier php.ini:"));
343
436
  console.log(chalk.gray(" php --ini"));
344
- console.log(chalk.gray(" Ou: C:\\php\\php.ini\n"));
437
+ console.log(chalk.gray(` Dans votre cas:
438
+ ${errorStr.match(/([A-Z]:\\[^[]+php\.ini)/)?.[1] || "C:\\php\\php.ini"}
439
+ `));
345
440
  console.log(chalk.cyan("2. \xC9ditez php.ini et cherchez:"));
346
- console.log(chalk.gray(" ;extension=zip\n"));
441
+ for (const ext of missingExtensions) {
442
+ console.log(chalk.gray(` ;extension=${ext}`));
443
+ }
347
444
  console.log(chalk.gray(" Changez en:"));
348
- console.log(chalk.gray(" extension=zip\n"));
445
+ for (const ext of missingExtensions) {
446
+ console.log(chalk.green(` extension=${ext}`));
447
+ }
448
+ console.log("");
349
449
  console.log(chalk.cyan("3. Sauvegardez et red\xE9marrez votre terminal.\n"));
350
450
  console.log(chalk.yellow("\u{1F4A1} Alternative: Utilisez PHP via XAMPP/WAMP qui inclut ces extensions.\n"));
351
451
  console.log(chalk.gray("T\xE9l\xE9charger XAMPP: https://www.apachefriends.org/download.html"));
352
452
  console.log(chalk.gray("T\xE9l\xE9charger WAMP: https://www.wampserver.com/\n"));
453
+ console.log(chalk.yellow("\u26A0\uFE0F PHP install\xE9 via WinGet:"));
454
+ console.log(chalk.gray(" Le PHP WinGet est souvent minimaliste. Consid\xE9rez XAMPP/WAMP pour un environnement complet.\n"));
353
455
  } else {
354
- console.log(chalk.bold("Linux/macOS - Activer l'extension zip:\n"));
456
+ console.log(chalk.bold("Linux/macOS - Activer les extensions PHP:\n"));
355
457
  console.log(chalk.cyan("Ubuntu/Debian:"));
356
- console.log(chalk.gray(" sudo apt install php-zip\n"));
458
+ const packages = missingExtensions.map((ext) => `php-${ext}`).join(" ");
459
+ console.log(chalk.gray(` sudo apt install ${packages}
460
+ `));
357
461
  console.log(chalk.cyan("macOS:"));
358
462
  console.log(chalk.gray(" brew install php\n"));
359
463
  }
360
- console.log(chalk.bold("\u{1F4A1} Apr\xE8s avoir activ\xE9 l'extension zip, relancez ce CLI.\n"));
464
+ console.log(chalk.bold("\u{1F4A1} Apr\xE8s avoir activ\xE9 les extensions, relancez ce CLI.\n"));
465
+ process.exit(1);
361
466
  }
467
+ spinner.fail("Erreur lors de l'installation Composer");
468
+ console.error(errorStr);
362
469
  throw error;
363
470
  }
364
471
  spinner.start("Installation des d\xE9pendances Node.js...");
@@ -546,6 +653,7 @@ async function createCommand(projectName, options) {
546
653
  try {
547
654
  console.log(chalk.bold("\n\u{1F50D} V\xE9rification des d\xE9pendances...\n"));
548
655
  await checkDependencies(spinner);
656
+ await checkPHPExtensions(spinner);
549
657
  const registry = await fetchMarketplaceRegistry();
550
658
  const config = await promptForConfig({
551
659
  projectName,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport prompts from 'prompts';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { execaCommand } from 'execa';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport degit from 'degit';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst packageJson = await fs.readJson(path.join(__dirname, '../package.json'));\n\n// ASCII Art Banner\nconst banner = `\n${chalk.cyan('╔═══════════════════════════════════════════════════════════╗')}\n${chalk.cyan('║')} ${chalk.bold.white('ExilonCMS CLI')} ${chalk.gray(`v${packageJson.version}`)} ${' '.repeat(36)} ${chalk.cyan('║')}\n${chalk.cyan('║')} ${chalk.white('Create modern ExilonCMS projects with ease')} ${' '.repeat(24)} ${chalk.cyan('║')}\n${chalk.cyan('╚═══════════════════════════════════════════════════════════╝')}\n`;\n\n// Marketplace Registry URL\nconst MARKETPLACE_REGISTRY_URL = 'https://raw.githubusercontent.com/Exilon-Studios/ExilonCMS-marketplace/main/registry.json';\n\n// Marketplace Registry Types\ninterface MarketplacePlugin {\n id: number;\n extension_id: string;\n name: string;\n description: string;\n version: string;\n author: string;\n url: string;\n repo_url?: string;\n hash: string;\n}\n\ninterface MarketplaceTheme {\n id: number;\n extension_id: string;\n name: string;\n description: string;\n version: string;\n author: string;\n url: string;\n hash: string;\n}\n\ninterface MarketplaceRegistry {\n plugins: MarketplacePlugin[];\n themes: MarketplaceTheme[];\n games: any[];\n alerts: any[];\n}\n\n// Fetch marketplace registry\nasync function fetchMarketplaceRegistry(): Promise<MarketplaceRegistry | null> {\n const spinner = ora();\n try {\n spinner.start('Récupération du marketplace...');\n const response = await fetch(MARKETPLACE_REGISTRY_URL);\n if (!response.ok) {\n spinner.warn('Impossible de récupérer le marketplace, utilisation des options par défaut');\n return null;\n }\n const registry: MarketplaceRegistry = await response.json();\n spinner.succeed(`Marketplace connecté - ${registry.plugins.length} plugins, ${registry.themes.length} thèmes`);\n return registry;\n } catch (error) {\n spinner.warn('Impossible de connecter au marketplace, utilisation des options par défaut');\n return null;\n }\n}\n\n// Database options\nconst databaseOptions = [\n { title: 'SQLite (Recommandé - Pas de configuration)', value: 'sqlite', description: 'Base de données fichier, aucune configuration requise' },\n { title: 'PostgreSQL', value: 'postgresql', description: 'Base de données serveur, performante et robuste' },\n { title: 'MySQL', value: 'mysql', description: 'Base de données serveur, populaire et répandue' },\n];\n\ninterface ProjectConfig {\n projectName: string;\n database: string;\n theme: string;\n plugins: string[];\n siteName: string;\n adminName: string;\n adminEmail: string;\n adminPassword: string;\n installDeps: boolean;\n runMigrations: boolean;\n}\n\nfunction validateProjectName(name: string): boolean {\n return /^[a-zA-Z0-9_-]+$/.test(name);\n}\n\n// Check if a command exists on the system\nasync function checkCommandExists(command: string): Promise<boolean> {\n try {\n const isWindows = process.platform === 'win32';\n const checkCmd = isWindows ? `where ${command}` : `which ${command}`;\n await execaCommand(checkCmd, { stdio: 'pipe' });\n return true;\n } catch {\n return false;\n }\n}\n\n// Check all required dependencies\nasync function checkDependencies(spinner: ReturnType<typeof ora>): Promise<void> {\n const requiredDeps = [\n { name: 'PHP', command: 'php', url: 'https://windows.php.net/download/' },\n { name: 'Composer', command: 'composer', url: 'https://getcomposer.org/download/', windowsExe: 'https://getcomposer.org/Composer-Setup.exe' },\n { name: 'Node.js', command: 'node', url: 'https://nodejs.org/' },\n { name: 'npm', command: 'npm', url: 'https://nodejs.org/' },\n ];\n\n const missing: typeof requiredDeps = [];\n\n for (const dep of requiredDeps) {\n const exists = await checkCommandExists(dep.command);\n if (!exists) {\n missing.push(dep);\n }\n }\n\n if (missing.length > 0) {\n console.log(chalk.bold('\\n⚠️ Dépendances manquantes:\\n'));\n\n for (const dep of missing) {\n console.log(chalk.red(` ❌ ${dep.name}`));\n }\n\n console.log(chalk.bold('\\n📋 Veuillez installer les dépendances manuellement:\\n'));\n\n const isWindows = process.platform === 'win32';\n\n if (isWindows) {\n console.log(chalk.bold('Windows - Instructions d\\'installation:\\n'));\n\n for (const dep of missing) {\n if (dep.name === 'Composer') {\n console.log(chalk.cyan(`${dep.name}:`));\n console.log(chalk.gray(` Téléchargez: ${dep.windowsExe}`));\n console.log(chalk.gray(` Ou visitez: ${dep.url}\\n`));\n console.log(chalk.yellow(` IMPORTANT: Après l'installation, fermez et rouvrez votre terminal.\\n`));\n } else if (dep.name === 'PHP') {\n console.log(chalk.cyan(`${dep.name}:`));\n console.log(chalk.gray(` Téléchargez PHP 8.2+: ${dep.url}`));\n console.log(chalk.gray(` Choisissez: VC15 x64 Non Thread Safe (NTS)\\n`));\n } else if (dep.name === 'Node.js') {\n console.log(chalk.cyan(`${dep.name}:`));\n console.log(chalk.gray(` Téléchargez LTS: ${dep.url}\\n`));\n }\n }\n } else {\n console.log(chalk.bold('Linux/macOS - Instructions d\\'installation:\\n'));\n\n for (const dep of missing) {\n console.log(chalk.cyan(`${dep.name}:`));\n console.log(chalk.gray(` Visitez: ${dep.url}\\n`));\n }\n\n console.log(chalk.gray('Ubuntu/Debian: sudo apt install php composer nodejs npm'));\n console.log(chalk.gray('macOS: brew install php composer node\\n'));\n }\n\n console.log(chalk.bold('💡 Après l\\'installation, relancez ce CLI.\\n'));\n\n throw new Error('Dépendances manquantes - Veuillez suivre les instructions ci-dessus');\n }\n\n spinner.succeed('Toutes les dépendances sont installées');\n}\n\nasync function promptForConfig(args: Partial<ProjectConfig> = {}, registry: MarketplaceRegistry | null): Promise<ProjectConfig> {\n console.log(banner);\n\n const config: ProjectConfig = {\n projectName: '',\n database: 'sqlite',\n theme: 'default',\n plugins: [],\n siteName: 'Mon Site ExilonCMS',\n adminName: 'Admin',\n adminEmail: 'admin@example.com',\n adminPassword: 'password',\n installDeps: true,\n runMigrations: true,\n };\n\n // Build theme options from registry or defaults\n const themeOptions = registry && registry.themes.length > 0\n ? [\n ...registry.themes.map(theme => ({\n title: `${theme.name} v${theme.version}`,\n value: theme.extension_id,\n description: `${theme.description} par ${theme.author}`,\n })),\n { title: 'Aucun thème (minimal)', value: 'none', description: 'Installation sans thème personnalisé' },\n ]\n : [\n { title: 'Thème par défaut', value: 'default', description: 'Thème par défaut d\\'ExilonCMS' },\n { title: 'Aucun thème (minimal)', value: 'none', description: 'Installation sans thème personnalisé' },\n ];\n\n // Build plugin options from registry or defaults\n const pluginOptions = registry && registry.plugins.length > 0\n ? registry.plugins.map(plugin => ({\n title: `${plugin.name} v${plugin.version}`,\n value: plugin.extension_id,\n description: plugin.description,\n }))\n : [];\n\n // Project Name\n if (!args.projectName) {\n const nameResponse = await prompts({\n type: 'text',\n name: 'projectName',\n message: 'Nom du projet:',\n initial: 'mon-site-exiloncms',\n validate: (value: string) => {\n if (!value) return 'Le nom du projet est requis';\n if (!validateProjectName(value)) return 'Le nom ne peut contenir que des lettres, chiffres, tirets et underscores';\n return true;\n },\n });\n config.projectName = nameResponse.projectName;\n } else {\n config.projectName = args.projectName;\n }\n\n // Database Selection\n if (!args.database) {\n const dbResponse = await prompts({\n type: 'select',\n name: 'database',\n message: 'Choisissez la base de données:',\n choices: databaseOptions,\n initial: 0,\n });\n config.database = dbResponse.database;\n } else {\n config.database = args.database;\n }\n\n // Theme Selection - only if themes are available\n if (!args.theme && themeOptions.length > 0) {\n const themeResponse = await prompts({\n type: 'select',\n name: 'theme',\n message: 'Choisissez un thème:',\n choices: themeOptions,\n initial: 0,\n });\n config.theme = themeResponse.theme;\n } else {\n config.theme = args.theme || 'default';\n }\n\n // Plugin Selection - only if plugins are available\n if ((!args.plugins || args.plugins.length === 0) && pluginOptions.length > 0) {\n const pluginResponse = await prompts({\n type: 'multiselect',\n name: 'plugins',\n message: 'Choisissez les plugins à installer (Espace pour sélectionner, Entrée pour valider):',\n choices: pluginOptions,\n instructions: false,\n });\n config.plugins = pluginResponse.plugins || [];\n } else {\n config.plugins = args.plugins || [];\n }\n\n // Site Configuration\n if (!args.siteName || !args.adminName || !args.adminEmail || !args.adminPassword) {\n console.log(chalk.bold('\\n📝 Configuration du site:\\n'));\n\n const siteResponse = await prompts([\n {\n type: 'text',\n name: 'siteName',\n message: 'Nom du site:',\n initial: config.siteName,\n },\n {\n type: 'text',\n name: 'adminName',\n message: 'Nom de l\\'administrateur:',\n initial: config.adminName,\n },\n {\n type: 'text',\n name: 'adminEmail',\n message: 'Email de l\\'administrateur:',\n initial: config.adminEmail,\n validate: (value: string) => {\n if (!value) return 'L\\'email est requis';\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) return 'Email invalide';\n return true;\n },\n },\n {\n type: 'password',\n name: 'adminPassword',\n message: 'Mot de passe administrateur:',\n validate: (value: string) => {\n if (!value || value.length < 6) return 'Le mot de passe doit contenir au moins 6 caractères';\n return true;\n },\n },\n ]);\n\n config.siteName = siteResponse.siteName || config.siteName;\n config.adminName = siteResponse.adminName || config.adminName;\n config.adminEmail = siteResponse.adminEmail || config.adminEmail;\n config.adminPassword = siteResponse.adminPassword || config.adminPassword;\n } else {\n config.siteName = args.siteName;\n config.adminName = args.adminName;\n config.adminEmail = args.adminEmail;\n config.adminPassword = args.adminPassword;\n }\n\n // Post-install options\n if (args.installDeps === undefined || args.runMigrations === undefined) {\n console.log(chalk.bold('\\n⚙️ Options d\\'installation:\\n'));\n\n const installResponse = await prompts([\n {\n type: 'confirm',\n name: 'installDeps',\n message: 'Installer les dépendances (composer & npm)?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'runMigrations',\n message: 'Exécuter les migrations et seeder la base de données?',\n initial: true,\n },\n ]);\n\n config.installDeps = installResponse.installDeps !== undefined ? installResponse.installDeps : true;\n config.runMigrations = installResponse.runMigrations !== undefined ? installResponse.runMigrations : true;\n } else {\n config.installDeps = args.installDeps;\n config.runMigrations = args.runMigrations;\n }\n\n return config;\n}\n\nasync function downloadProject(targetDir: string, spinner: ReturnType<typeof ora>): Promise<void> {\n spinner.start('Téléchargement d\\'ExilonCMS...');\n\n const emitter = degit('Exilon-Studios/ExilonCMS', {\n cache: false,\n force: true,\n verbose: false,\n });\n\n try {\n await emitter.clone(targetDir);\n spinner.succeed('ExilonCMS téléchargé avec succès');\n } catch (error) {\n spinner.fail('Erreur lors du téléchargement');\n throw error;\n }\n}\n\nasync function configureProject(config: ProjectConfig, targetDir: string, spinner: ReturnType<typeof ora>): Promise<void> {\n spinner.start('Configuration du projet...');\n\n try {\n // Configure .env file\n const envPath = path.join(targetDir, '.env');\n const envExamplePath = path.join(targetDir, '.env.example');\n\n if (await fs.pathExists(envExamplePath)) {\n let envContent = await fs.readFile(envExamplePath, 'utf-8');\n\n // Set database configuration\n if (config.database === 'sqlite') {\n envContent = envContent.replace(/DB_CONNECTION=.*/, 'DB_CONNECTION=sqlite');\n envContent = envContent.replace(/#DB_DATABASE=.*/, 'DB_DATABASE=' + path.join(targetDir, 'database', 'database.sqlite'));\n } else if (config.database === 'postgresql') {\n envContent = envContent.replace(/DB_CONNECTION=.*/, 'DB_CONNECTION=pgsql');\n envContent = envContent.replace(/DB_DATABASE=.*/, 'DB_DATABASE=exiloncms');\n envContent = envContent.replace(/DB_USERNAME=.*/, 'DB_USERNAME=postgres');\n } else if (config.database === 'mysql') {\n envContent = envContent.replace(/DB_CONNECTION=.*/, 'DB_CONNECTION=mysql');\n envContent = envContent.replace(/DB_DATABASE=.*/, 'DB_DATABASE=exiloncms');\n envContent = envContent.replace(/DB_USERNAME=.*/, 'DB_USERNAME=root');\n }\n\n // Set app name\n envContent = envContent.replace(/APP_NAME=.*/, `APP_NAME=\"${config.siteName}\"`);\n\n await fs.writeFile(envPath, envContent);\n }\n\n // Create SQLite database if selected\n if (config.database === 'sqlite') {\n const dbDir = path.join(targetDir, 'database');\n await fs.ensureDir(dbDir);\n const dbPath = path.join(dbDir, 'database.sqlite');\n if (!(await fs.pathExists(dbPath))) {\n await fs.writeFile(dbPath, '');\n }\n }\n\n // Create required directories\n const themesDir = path.join(targetDir, 'resources', 'themes');\n await fs.ensureDir(themesDir);\n\n const pluginsDir = path.join(targetDir, 'plugins');\n await fs.ensureDir(pluginsDir);\n\n // Generate APP_KEY\n spinner.text = 'Génération de la clé d\\'application...';\n await execaCommand('php artisan key:generate --force', { cwd: targetDir, stdio: 'inherit' });\n\n spinner.succeed('Projet configuré avec succès');\n } catch (error) {\n spinner.fail('Erreur lors de la configuration');\n throw error;\n }\n}\n\nasync function installDependencies(config: ProjectConfig, targetDir: string, spinner: ReturnType<typeof ora>): Promise<void> {\n if (!config.installDeps) {\n spinner.info('Installation des dépendances skipée');\n return;\n }\n\n // Composer - use update for fresh installs to handle lock file issues\n spinner.start('Installation des dépendances PHP (Composer)...');\n try {\n await execaCommand('composer update --no-interaction', { cwd: targetDir, stdio: 'inherit' });\n spinner.succeed('Dépendances PHP installées');\n } catch (error: any) {\n spinner.fail('Erreur lors de l\\'installation Composer');\n\n // Check if it's a missing PHP extension error\n const errorStr = error.toString() || '';\n if (errorStr.includes('ext-zip') || errorStr.includes('extension zip')) {\n console.log(chalk.red('\\n❌ Extension PHP zip manquante!\\n'));\n console.log(chalk.bold('Pour utiliser ExilonCMS, PHP doit avoir l\\'extension zip activée.\\n'));\n\n const isWindows = process.platform === 'win32';\n\n if (isWindows) {\n console.log(chalk.bold('Windows - Activer l\\'extension zip:\\n'));\n console.log(chalk.cyan('1. Trouvez votre fichier php.ini:'));\n console.log(chalk.gray(' php --ini'));\n console.log(chalk.gray(' Ou: C:\\\\php\\\\php.ini\\n'));\n\n console.log(chalk.cyan('2. Éditez php.ini et cherchez:'));\n console.log(chalk.gray(' ;extension=zip\\n'));\n console.log(chalk.gray(' Changez en:'));\n console.log(chalk.gray(' extension=zip\\n'));\n\n console.log(chalk.cyan('3. Sauvegardez et redémarrez votre terminal.\\n'));\n\n console.log(chalk.yellow('💡 Alternative: Utilisez PHP via XAMPP/WAMP qui inclut ces extensions.\\n'));\n console.log(chalk.gray('Télécharger XAMPP: https://www.apachefriends.org/download.html'));\n console.log(chalk.gray('Télécharger WAMP: https://www.wampserver.com/\\n'));\n } else {\n console.log(chalk.bold('Linux/macOS - Activer l\\'extension zip:\\n'));\n console.log(chalk.cyan('Ubuntu/Debian:'));\n console.log(chalk.gray(' sudo apt install php-zip\\n'));\n console.log(chalk.cyan('macOS:'));\n console.log(chalk.gray(' brew install php\\n'));\n }\n\n console.log(chalk.bold('💡 Après avoir activé l\\'extension zip, relancez ce CLI.\\n'));\n }\n\n throw error;\n }\n\n // NPM\n spinner.start('Installation des dépendances Node.js...');\n try {\n await execaCommand('npm install --silent', { cwd: targetDir });\n spinner.succeed('Dépendances Node.js installées');\n } catch (error) {\n spinner.fail('Erreur lors de l\\'installation NPM');\n throw error;\n }\n\n // Build assets\n spinner.start('Construction des assets...');\n try {\n await execaCommand('npm run build', { cwd: targetDir });\n spinner.succeed('Assets construits');\n } catch (error) {\n spinner.warn('Erreur lors du build des assets (non-critique)');\n }\n}\n\nasync function runMigrationsAndSeed(config: ProjectConfig, targetDir: string, spinner: ReturnType<typeof ora>): Promise<void> {\n if (!config.runMigrations) {\n spinner.info('Migrations skipées');\n return;\n }\n\n spinner.start('Exécution des migrations et seeder...');\n try {\n // For SQLite, we use migrate:fresh which is safe for fresh install\n const command = config.database === 'sqlite'\n ? 'php artisan migrate:fresh --seed --force'\n : 'php artisan migrate --seed --force';\n\n await execaCommand(command, {\n cwd: targetDir,\n stdio: 'inherit',\n });\n\n spinner.succeed('Base de données initialisée');\n } catch (error) {\n spinner.fail('Erreur lors des migrations');\n throw error;\n }\n}\n\nasync function createAdminUser(config: ProjectConfig, targetDir: string, spinner: ReturnType<typeof ora>): Promise<void> {\n spinner.start('Création de l\\'utilisateur admin...');\n try {\n await execaCommand(\n `php artisan user:create --admin --name=\"${config.adminName}\" --email=\"${config.adminEmail}\" --password=\"${config.adminPassword}\"`,\n { cwd: targetDir, stdio: 'inherit' }\n );\n spinner.succeed('Utilisateur admin créé');\n } catch (error) {\n spinner.warn('Erreur lors de la création de l\\'admin (peut-être déjà créé via seeder)');\n }\n}\n\n// Create custom admin seeder to override default credentials\nasync function createCustomAdminSeeder(config: ProjectConfig, targetDir: string): Promise<void> {\n const seederPath = path.join(targetDir, 'database/seeders/CustomAdminSeeder.php');\n const seederContent = `<?php\n\nnamespace Database\\\\Seeders;\n\nuse ExilonCMS\\\\Models\\\\User;\nuse ExilonCMS\\\\Models\\\\Role;\nuse ExilonCMS\\\\Models\\\\Permission;\nuse Illuminate\\\\Database\\\\Console\\\\Seeds\\\\WithoutModelEvents;\nuse Illuminate\\\\Database\\\\Seeder;\nuse Illuminate\\\\Support\\\\Facades\\\\Hash;\n\nclass CustomAdminSeeder extends Seeder\n{\n use WithoutModelEvents;\n\n public function run(): void\n {\n // Create admin role if it doesn't exist\n $adminRole = Role::firstOrCreate(\n ['name' => 'admin'],\n [\n 'color' => 'FF0000',\n 'is_admin' => true,\n 'power' => 100,\n ]\n );\n\n // Create admin user with custom credentials\n $admin = User::firstOrCreate(\n ['email' => '${config.adminEmail}'],\n [\n 'name' => '${config.adminName}',\n 'password' => Hash::make('${config.adminPassword}'),\n 'role_id' => $adminRole->id,\n 'email_verified_at' => now(),\n 'password_changed_at' => now(),\n ]\n );\n\n // Create all permissions for admin role\n if ($adminRole->permissions()->count() === 0) {\n foreach (Permission::permissions() as $permission) {\n Permission::create([\n 'permission' => $permission,\n 'role_id' => $adminRole->id,\n ]);\n }\n }\n }\n}\n`;\n\n await fs.writeFile(seederPath, seederContent);\n\n // Update DatabaseSeeder to use CustomAdminSeeder instead of AdminUserSeeder\n const databaseSeederPath = path.join(targetDir, 'database/seeders/DatabaseSeeder.php');\n let databaseSeederContent = await fs.readFile(databaseSeederPath, 'utf-8');\n\n // Replace AdminUserSeeder with CustomAdminSeeder in the call array\n databaseSeederContent = databaseSeederContent.replace(\n /AdminUserSeeder::class/,\n 'CustomAdminSeeder::class'\n );\n\n await fs.writeFile(databaseSeederPath, databaseSeederContent);\n}\n\n// Install plugins from marketplace\nasync function installPlugins(config: ProjectConfig, targetDir: string, registry: MarketplaceRegistry | null, spinner: ReturnType<typeof ora>): Promise<void> {\n if (config.plugins.length === 0) {\n return;\n }\n\n if (!registry) {\n spinner.warn('Marketplace non disponible, impossible d\\'installer les plugins');\n return;\n }\n\n for (const pluginId of config.plugins) {\n const plugin = registry.plugins.find(p => p.extension_id === pluginId);\n if (!plugin) {\n spinner.warn(`Plugin ${pluginId} non trouvé dans le marketplace`);\n continue;\n }\n\n spinner.start(`Installation du plugin ${plugin.name}...`);\n try {\n // Download plugin zip\n const pluginZipPath = path.join(targetDir, 'temp_plugin.zip');\n const response = await fetch(plugin.url);\n const buffer = await response.arrayBuffer();\n await fs.writeFile(pluginZipPath, Buffer.from(buffer));\n\n // Extract using platform-specific command\n const pluginsDir = path.join(targetDir, 'plugins');\n await fs.ensureDir(pluginsDir);\n\n // Detect platform and use appropriate unzip command\n const isWindows = process.platform === 'win32';\n\n if (isWindows) {\n // Use PowerShell's Expand-Archive on Windows\n await execaCommand(\n `powershell -Command \"Expand-Archive -Path '${pluginZipPath}' -DestinationPath '${pluginsDir}' -Force\"`,\n { cwd: targetDir }\n );\n } else {\n // Use unzip command on Linux/Mac\n await execaCommand(`unzip -o \"${pluginZipPath}\" -d \"${pluginsDir}\"`, { cwd: targetDir });\n }\n\n // Clean up\n await fs.remove(pluginZipPath);\n\n spinner.succeed(`Plugin ${plugin.name} installé`);\n } catch (error) {\n spinner.fail(`Erreur lors de l'installation du plugin ${plugin.name}`);\n console.error(error);\n }\n }\n}\n\nfunction printSuccessMessage(config: ProjectConfig, targetDir: string): void {\n console.log(chalk.bold('\\n✨ Installation terminée avec succès!\\n'));\n\n console.log(chalk.cyan(' Projet créé dans: ') + chalk.white(targetDir));\n console.log(chalk.cyan(' Base de données: ') + chalk.white(config.database));\n console.log(chalk.cyan(' Thème: ') + chalk.white(config.theme));\n\n if (config.plugins.length > 0) {\n console.log(chalk.cyan(' Plugins installés: ') + chalk.white(config.plugins.join(', ')));\n }\n\n console.log(chalk.bold('\\n🚀 Prochaines étapes:\\n'));\n\n console.log(` ${chalk.cyan('1.')} Aller dans le dossier du projet:`);\n console.log(` ${chalk.gray(`cd ${config.projectName}`)}\\n`);\n\n if (!config.installDeps) {\n console.log(` ${chalk.cyan('2.')} Installer les dépendances:`);\n console.log(` ${chalk.gray('composer install')}`);\n console.log(` ${chalk.gray('npm install')}`);\n console.log(` ${chalk.gray('npm run build')}\\n`);\n }\n\n if (!config.runMigrations) {\n console.log(` ${chalk.cyan('3.')} Configurer la base de données et lancer les migrations:`);\n if (config.database !== 'sqlite') {\n console.log(` ${chalk.yellow('⚠️ Configurez votre base de données dans .env d\\'abord')}`);\n }\n console.log(` ${chalk.gray('php artisan migrate:fresh --seed')}\\n`);\n }\n\n console.log(` ${chalk.cyan('4.')} Démarrer le serveur de développement:`);\n console.log(` ${chalk.gray('php artisan serve')}\\n`);\n\n if (config.database === 'sqlite') {\n console.log(` ${chalk.green('✓')} SQLite utilisé - aucune configuration de base de données nécessaire!\\n`);\n } else {\n console.log(` ${chalk.yellow('⚠️ ')} Configurez votre base de données ${config.database} dans ${chalk.gray('.env')}\\n`);\n }\n\n console.log(chalk.bold('📧 Identifiants admin:\\n'));\n console.log(` Email: ${chalk.cyan(config.adminEmail)}`);\n console.log(` Password: ${chalk.cyan(config.adminPassword)}\\n`);\n\n console.log(chalk.gray(' ' + '─'.repeat(60) + '\\n'));\n\n console.log(` ${chalk.cyan('Documentation:')} https://github.com/Exilon-Studios/ExilonCMS/wiki\\n`);\n}\n\nasync function createCommand(projectName: string, options: any): Promise<void> {\n const spinner = ora();\n\n try {\n // Check dependencies first\n console.log(chalk.bold('\\n🔍 Vérification des dépendances...\\n'));\n await checkDependencies(spinner);\n\n // Fetch marketplace registry\n const registry = await fetchMarketplaceRegistry();\n\n const config = await promptForConfig({\n projectName,\n database: options.database,\n theme: options.theme,\n plugins: options.plugins ? options.plugins.split(',') : [],\n siteName: options.siteName,\n adminName: options.adminName,\n adminEmail: options.adminEmail,\n adminPassword: options.adminPassword,\n installDeps: options.installDeps,\n runMigrations: options.runMigrations,\n }, registry);\n\n const targetDir = path.resolve(process.cwd(), config.projectName);\n\n // Check if directory exists\n if (await fs.pathExists(targetDir)) {\n const { overwrite } = await prompts({\n type: 'confirm',\n name: 'overwrite',\n message: `Le dossier ${config.projectName} existe déjà. Écraser?`,\n initial: false,\n });\n\n if (!overwrite) {\n console.log(chalk.yellow('\\nInstallation annulée.'));\n process.exit(0);\n }\n\n await fs.remove(targetDir);\n }\n\n // Download project\n await downloadProject(targetDir, spinner);\n\n // Install dependencies FIRST\n await installDependencies(config, targetDir, spinner);\n\n // Configure project (needs artisan which needs composer dependencies)\n await configureProject(config, targetDir, spinner);\n\n // Create custom admin seeder with user's credentials\n await createCustomAdminSeeder(config, targetDir);\n\n // Run migrations (will use custom admin seeder)\n await runMigrationsAndSeed(config, targetDir, spinner);\n\n // Install plugins from marketplace\n await installPlugins(config, targetDir, registry, spinner);\n\n // Print success message\n printSuccessMessage(config, targetDir);\n\n } catch (error: any) {\n if (error.message === 'user cancelled') {\n console.log(chalk.yellow('\\nInstallation annulée.'));\n process.exit(0);\n }\n\n console.error(chalk.red('\\n✖ Erreur:'), error.message);\n process.exit(1);\n }\n}\n\n// CLI Program\nconst program = new Command();\n\nprogram\n .name('exiloncms')\n .description('Create a new ExilonCMS project')\n .version(packageJson.version);\n\nprogram\n .command('create [project-name]')\n .description('Create a new ExilonCMS project')\n .option('-d, --database <type>', 'Database type (sqlite, postgresql, mysql)', 'sqlite')\n .option('-t, --theme <name>', 'Theme name', 'default')\n .option('-p, --plugins <list>', 'Comma-separated list of plugins')\n .option('--site-name <name>', 'Site name')\n .option('--admin-name <name>', 'Admin name')\n .option('--admin-email <email>', 'Admin email')\n .option('--admin-password <password>', 'Admin password')\n .option('--no-install-deps', 'Skip installing dependencies')\n .option('--no-run-migrations', 'Skip running migrations')\n .action(createCommand);\n\nprogram\n .command('new [project-name]')\n .description('Alias for create')\n .option('-d, --database <type>', 'Database type (sqlite, postgresql, mysql)', 'sqlite')\n .option('-t, --theme <name>', 'Theme name', 'default')\n .option('-p, --plugins <list>', 'Comma-separated list of plugins')\n .option('--site-name <name>', 'Site name')\n .option('--admin-name <name>', 'Admin name')\n .option('--admin-email <email>', 'Admin email')\n .option('--admin-password <password>', 'Admin password')\n .option('--no-install-deps', 'Skip installing dependencies')\n .option('--no-run-migrations', 'Skip running migrations')\n .action(createCommand);\n\nprogram.parse();\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport prompts from 'prompts';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { execaCommand } from 'execa';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport degit from 'degit';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst packageJson = await fs.readJson(path.join(__dirname, '../package.json'));\n\n// ASCII Art Banner\nconst banner = `\n${chalk.cyan('╔═══════════════════════════════════════════════════════════╗')}\n${chalk.cyan('║')} ${chalk.bold.white('ExilonCMS CLI')} ${chalk.gray(`v${packageJson.version}`)} ${' '.repeat(36)} ${chalk.cyan('║')}\n${chalk.cyan('║')} ${chalk.white('Create modern ExilonCMS projects with ease')} ${' '.repeat(24)} ${chalk.cyan('║')}\n${chalk.cyan('╚═══════════════════════════════════════════════════════════╝')}\n`;\n\n// Marketplace Registry URL\nconst MARKETPLACE_REGISTRY_URL = 'https://raw.githubusercontent.com/Exilon-Studios/ExilonCMS-marketplace/main/registry.json';\n\n// Marketplace Registry Types\ninterface MarketplacePlugin {\n id: number;\n extension_id: string;\n name: string;\n description: string;\n version: string;\n author: string;\n url: string;\n repo_url?: string;\n hash: string;\n}\n\ninterface MarketplaceTheme {\n id: number;\n extension_id: string;\n name: string;\n description: string;\n version: string;\n author: string;\n url: string;\n hash: string;\n}\n\ninterface MarketplaceRegistry {\n plugins: MarketplacePlugin[];\n themes: MarketplaceTheme[];\n games: any[];\n alerts: any[];\n}\n\n// Fetch marketplace registry\nasync function fetchMarketplaceRegistry(): Promise<MarketplaceRegistry | null> {\n const spinner = ora();\n try {\n spinner.start('Récupération du marketplace...');\n const response = await fetch(MARKETPLACE_REGISTRY_URL);\n if (!response.ok) {\n spinner.warn('Impossible de récupérer le marketplace, utilisation des options par défaut');\n return null;\n }\n const registry: MarketplaceRegistry = await response.json();\n spinner.succeed(`Marketplace connecté - ${registry.plugins.length} plugins, ${registry.themes.length} thèmes`);\n return registry;\n } catch (error) {\n spinner.warn('Impossible de connecter au marketplace, utilisation des options par défaut');\n return null;\n }\n}\n\n// Database options\nconst databaseOptions = [\n { title: 'SQLite (Recommandé - Pas de configuration)', value: 'sqlite', description: 'Base de données fichier, aucune configuration requise' },\n { title: 'PostgreSQL', value: 'postgresql', description: 'Base de données serveur, performante et robuste' },\n { title: 'MySQL', value: 'mysql', description: 'Base de données serveur, populaire et répandue' },\n];\n\ninterface ProjectConfig {\n projectName: string;\n database: string;\n theme: string;\n plugins: string[];\n siteName: string;\n adminName: string;\n adminEmail: string;\n adminPassword: string;\n installDeps: boolean;\n runMigrations: boolean;\n}\n\nfunction validateProjectName(name: string): boolean {\n return /^[a-zA-Z0-9_-]+$/.test(name);\n}\n\n// Check if a command exists on the system\nasync function checkCommandExists(command: string): Promise<boolean> {\n try {\n const isWindows = process.platform === 'win32';\n const checkCmd = isWindows ? `where ${command}` : `which ${command}`;\n await execaCommand(checkCmd, { stdio: 'pipe' });\n return true;\n } catch {\n return false;\n }\n}\n\n// Check PHP extensions\nasync function checkPHPExtensions(spinner: ReturnType<typeof ora>): Promise<void> {\n const requiredExtensions = ['zip', 'fileinfo', 'mbstring', 'pdo', 'ctype', 'json', 'tokenizer', 'xml'];\n\n spinner.start('Vérification des extensions PHP...');\n\n // Create a PHP script to check extensions\n const checkScript = `<?php\n$missing = [];\n$required = ${JSON.stringify(requiredExtensions)};\n\nforeach ($required as $ext) {\n if (!extension_loaded($ext)) {\n $missing[] = $ext;\n }\n}\n\nif (!empty($missing)) {\n echo 'MISSING:' . implode(',', $missing);\n exit(1);\n}\n\necho 'OK';\nexit(0);\n`;\n\n // Write to temp file\n const tempFile = path.join(process.cwd(), 'php_check.php');\n await fs.writeFile(tempFile, checkScript);\n\n try {\n // Execute PHP script\n const { stdout } = await execaCommand(`php \"${tempFile}\"`, { stdio: 'pipe' });\n\n // Clean up\n await fs.remove(tempFile);\n\n if (stdout.includes('OK')) {\n spinner.succeed('Toutes les extensions PHP sont installées');\n return;\n }\n } catch (execError: any) {\n // Clean up temp file even on error\n if (await fs.pathExists(tempFile)) {\n await fs.remove(tempFile);\n }\n\n const stdout = execError.stdout || '';\n\n if (stdout.includes('MISSING:')) {\n const missing = stdout.replace('MISSING:', '').trim().split(',');\n\n spinner.warn('Extensions PHP manquantes');\n\n console.log(chalk.red(`\\n❌ Extensions PHP manquantes: ${missing.join(', ')}!\\n`));\n console.log(chalk.bold('Pour utiliser ExilonCMS, PHP doit avoir ces extensions activées.\\n'));\n\n const isWindows = process.platform === 'win32';\n\n if (isWindows) {\n console.log(chalk.bold('Windows - Activer les extensions PHP:\\n'));\n\n console.log(chalk.cyan('1. Trouvez votre fichier php.ini:'));\n console.log(chalk.gray(' php --ini'));\n console.log(chalk.gray(' Ou: C:\\\\php\\\\php.ini\\n'));\n\n console.log(chalk.cyan('2. Éditez php.ini et cherchez ces lignes:'));\n for (const ext of missing) {\n console.log(chalk.gray(` ;extension=${ext}`));\n }\n console.log(chalk.gray(' Changez-les en:'));\n for (const ext of missing) {\n console.log(chalk.green(` extension=${ext}`));\n }\n console.log('');\n\n console.log(chalk.cyan('3. Sauvegardez et redémarrez votre terminal.\\n'));\n\n console.log(chalk.yellow('💡 Alternative: Utilisez PHP via XAMPP/WAMP qui inclut ces extensions.\\n'));\n console.log(chalk.gray('Télécharger XAMPP: https://www.apachefriends.org/download.html'));\n console.log(chalk.gray('Télécharger WAMP: https://www.wampserver.com/\\n'));\n\n console.log(chalk.yellow('⚠️ PHP installé via WinGet:'));\n console.log(chalk.gray(' Le PHP WinGet est souvent minimaliste. Considérez XAMPP/WAMP pour un environnement complet.\\n'));\n } else {\n console.log(chalk.bold('Linux/macOS - Activer les extensions PHP:\\n'));\n console.log(chalk.cyan('Ubuntu/Debian:'));\n const packages = missing.map(ext => `php-${ext}`).join(' ');\n console.log(chalk.gray(` sudo apt install ${packages}\\n`));\n console.log(chalk.cyan('macOS:'));\n console.log(chalk.gray(' brew install php\\n'));\n }\n\n console.log(chalk.bold('💡 Après avoir activé les extensions, relancez ce CLI.\\n'));\n\n throw new Error('Extensions PHP manquantes - Veuillez suivre les instructions ci-dessus');\n }\n\n // If it's another error, ignore for now (will be caught later)\n spinner.succeed('Vérification des extensions PHP terminée');\n }\n}\n\n// Check all required dependencies\nasync function checkDependencies(spinner: ReturnType<typeof ora>): Promise<void> {\n const requiredDeps = [\n { name: 'PHP', command: 'php', url: 'https://windows.php.net/download/' },\n { name: 'Composer', command: 'composer', url: 'https://getcomposer.org/download/', windowsExe: 'https://getcomposer.org/Composer-Setup.exe' },\n { name: 'Node.js', command: 'node', url: 'https://nodejs.org/' },\n { name: 'npm', command: 'npm', url: 'https://nodejs.org/' },\n ];\n\n const missing: typeof requiredDeps = [];\n\n for (const dep of requiredDeps) {\n const exists = await checkCommandExists(dep.command);\n if (!exists) {\n missing.push(dep);\n }\n }\n\n if (missing.length > 0) {\n console.log(chalk.bold('\\n⚠️ Dépendances manquantes:\\n'));\n\n for (const dep of missing) {\n console.log(chalk.red(` ❌ ${dep.name}`));\n }\n\n console.log(chalk.bold('\\n📋 Veuillez installer les dépendances manuellement:\\n'));\n\n const isWindows = process.platform === 'win32';\n\n if (isWindows) {\n console.log(chalk.bold('Windows - Instructions d\\'installation:\\n'));\n\n for (const dep of missing) {\n if (dep.name === 'Composer') {\n console.log(chalk.cyan(`${dep.name}:`));\n console.log(chalk.gray(` Téléchargez: ${dep.windowsExe}`));\n console.log(chalk.gray(` Ou visitez: ${dep.url}\\n`));\n console.log(chalk.yellow(` IMPORTANT: Après l'installation, fermez et rouvrez votre terminal.\\n`));\n } else if (dep.name === 'PHP') {\n console.log(chalk.cyan(`${dep.name}:`));\n console.log(chalk.gray(` Téléchargez PHP 8.2+: ${dep.url}`));\n console.log(chalk.gray(` Choisissez: VC15 x64 Non Thread Safe (NTS)\\n`));\n } else if (dep.name === 'Node.js') {\n console.log(chalk.cyan(`${dep.name}:`));\n console.log(chalk.gray(` Téléchargez LTS: ${dep.url}\\n`));\n }\n }\n } else {\n console.log(chalk.bold('Linux/macOS - Instructions d\\'installation:\\n'));\n\n for (const dep of missing) {\n console.log(chalk.cyan(`${dep.name}:`));\n console.log(chalk.gray(` Visitez: ${dep.url}\\n`));\n }\n\n console.log(chalk.gray('Ubuntu/Debian: sudo apt install php composer nodejs npm'));\n console.log(chalk.gray('macOS: brew install php composer node\\n'));\n }\n\n console.log(chalk.bold('💡 Après l\\'installation, relancez ce CLI.\\n'));\n\n throw new Error('Dépendances manquantes - Veuillez suivre les instructions ci-dessus');\n }\n\n spinner.succeed('Toutes les dépendances sont installées');\n}\n\nasync function promptForConfig(args: Partial<ProjectConfig> = {}, registry: MarketplaceRegistry | null): Promise<ProjectConfig> {\n console.log(banner);\n\n const config: ProjectConfig = {\n projectName: '',\n database: 'sqlite',\n theme: 'default',\n plugins: [],\n siteName: 'Mon Site ExilonCMS',\n adminName: 'Admin',\n adminEmail: 'admin@example.com',\n adminPassword: 'password',\n installDeps: true,\n runMigrations: true,\n };\n\n // Build theme options from registry or defaults\n const themeOptions = registry && registry.themes.length > 0\n ? [\n ...registry.themes.map(theme => ({\n title: `${theme.name} v${theme.version}`,\n value: theme.extension_id,\n description: `${theme.description} par ${theme.author}`,\n })),\n { title: 'Aucun thème (minimal)', value: 'none', description: 'Installation sans thème personnalisé' },\n ]\n : [\n { title: 'Thème par défaut', value: 'default', description: 'Thème par défaut d\\'ExilonCMS' },\n { title: 'Aucun thème (minimal)', value: 'none', description: 'Installation sans thème personnalisé' },\n ];\n\n // Build plugin options from registry or defaults\n const pluginOptions = registry && registry.plugins.length > 0\n ? registry.plugins.map(plugin => ({\n title: `${plugin.name} v${plugin.version}`,\n value: plugin.extension_id,\n description: plugin.description,\n }))\n : [];\n\n // Project Name\n if (!args.projectName) {\n const nameResponse = await prompts({\n type: 'text',\n name: 'projectName',\n message: 'Nom du projet:',\n initial: 'mon-site-exiloncms',\n validate: (value: string) => {\n if (!value) return 'Le nom du projet est requis';\n if (!validateProjectName(value)) return 'Le nom ne peut contenir que des lettres, chiffres, tirets et underscores';\n return true;\n },\n });\n config.projectName = nameResponse.projectName;\n } else {\n config.projectName = args.projectName;\n }\n\n // Database Selection\n if (!args.database) {\n const dbResponse = await prompts({\n type: 'select',\n name: 'database',\n message: 'Choisissez la base de données:',\n choices: databaseOptions,\n initial: 0,\n });\n config.database = dbResponse.database;\n } else {\n config.database = args.database;\n }\n\n // Theme Selection - only if themes are available\n if (!args.theme && themeOptions.length > 0) {\n const themeResponse = await prompts({\n type: 'select',\n name: 'theme',\n message: 'Choisissez un thème:',\n choices: themeOptions,\n initial: 0,\n });\n config.theme = themeResponse.theme;\n } else {\n config.theme = args.theme || 'default';\n }\n\n // Plugin Selection - only if plugins are available\n if ((!args.plugins || args.plugins.length === 0) && pluginOptions.length > 0) {\n const pluginResponse = await prompts({\n type: 'multiselect',\n name: 'plugins',\n message: 'Choisissez les plugins à installer (Espace pour sélectionner, Entrée pour valider):',\n choices: pluginOptions,\n instructions: false,\n });\n config.plugins = pluginResponse.plugins || [];\n } else {\n config.plugins = args.plugins || [];\n }\n\n // Site Configuration\n if (!args.siteName || !args.adminName || !args.adminEmail || !args.adminPassword) {\n console.log(chalk.bold('\\n📝 Configuration du site:\\n'));\n\n const siteResponse = await prompts([\n {\n type: 'text',\n name: 'siteName',\n message: 'Nom du site:',\n initial: config.siteName,\n },\n {\n type: 'text',\n name: 'adminName',\n message: 'Nom de l\\'administrateur:',\n initial: config.adminName,\n },\n {\n type: 'text',\n name: 'adminEmail',\n message: 'Email de l\\'administrateur:',\n initial: config.adminEmail,\n validate: (value: string) => {\n if (!value) return 'L\\'email est requis';\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) return 'Email invalide';\n return true;\n },\n },\n {\n type: 'password',\n name: 'adminPassword',\n message: 'Mot de passe administrateur:',\n validate: (value: string) => {\n if (!value || value.length < 6) return 'Le mot de passe doit contenir au moins 6 caractères';\n return true;\n },\n },\n ]);\n\n config.siteName = siteResponse.siteName || config.siteName;\n config.adminName = siteResponse.adminName || config.adminName;\n config.adminEmail = siteResponse.adminEmail || config.adminEmail;\n config.adminPassword = siteResponse.adminPassword || config.adminPassword;\n } else {\n config.siteName = args.siteName;\n config.adminName = args.adminName;\n config.adminEmail = args.adminEmail;\n config.adminPassword = args.adminPassword;\n }\n\n // Post-install options\n if (args.installDeps === undefined || args.runMigrations === undefined) {\n console.log(chalk.bold('\\n⚙️ Options d\\'installation:\\n'));\n\n const installResponse = await prompts([\n {\n type: 'confirm',\n name: 'installDeps',\n message: 'Installer les dépendances (composer & npm)?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'runMigrations',\n message: 'Exécuter les migrations et seeder la base de données?',\n initial: true,\n },\n ]);\n\n config.installDeps = installResponse.installDeps !== undefined ? installResponse.installDeps : true;\n config.runMigrations = installResponse.runMigrations !== undefined ? installResponse.runMigrations : true;\n } else {\n config.installDeps = args.installDeps;\n config.runMigrations = args.runMigrations;\n }\n\n return config;\n}\n\nasync function downloadProject(targetDir: string, spinner: ReturnType<typeof ora>): Promise<void> {\n spinner.start('Téléchargement d\\'ExilonCMS...');\n\n const emitter = degit('Exilon-Studios/ExilonCMS', {\n cache: false,\n force: true,\n verbose: false,\n });\n\n try {\n await emitter.clone(targetDir);\n spinner.succeed('ExilonCMS téléchargé avec succès');\n } catch (error) {\n spinner.fail('Erreur lors du téléchargement');\n throw error;\n }\n}\n\nasync function configureProject(config: ProjectConfig, targetDir: string, spinner: ReturnType<typeof ora>): Promise<void> {\n spinner.start('Configuration du projet...');\n\n try {\n // Configure .env file\n const envPath = path.join(targetDir, '.env');\n const envExamplePath = path.join(targetDir, '.env.example');\n\n if (await fs.pathExists(envExamplePath)) {\n let envContent = await fs.readFile(envExamplePath, 'utf-8');\n\n // Set database configuration\n if (config.database === 'sqlite') {\n envContent = envContent.replace(/DB_CONNECTION=.*/, 'DB_CONNECTION=sqlite');\n envContent = envContent.replace(/#DB_DATABASE=.*/, 'DB_DATABASE=' + path.join(targetDir, 'database', 'database.sqlite'));\n } else if (config.database === 'postgresql') {\n envContent = envContent.replace(/DB_CONNECTION=.*/, 'DB_CONNECTION=pgsql');\n envContent = envContent.replace(/DB_DATABASE=.*/, 'DB_DATABASE=exiloncms');\n envContent = envContent.replace(/DB_USERNAME=.*/, 'DB_USERNAME=postgres');\n } else if (config.database === 'mysql') {\n envContent = envContent.replace(/DB_CONNECTION=.*/, 'DB_CONNECTION=mysql');\n envContent = envContent.replace(/DB_DATABASE=.*/, 'DB_DATABASE=exiloncms');\n envContent = envContent.replace(/DB_USERNAME=.*/, 'DB_USERNAME=root');\n }\n\n // Set app name\n envContent = envContent.replace(/APP_NAME=.*/, `APP_NAME=\"${config.siteName}\"`);\n\n await fs.writeFile(envPath, envContent);\n }\n\n // Create SQLite database if selected\n if (config.database === 'sqlite') {\n const dbDir = path.join(targetDir, 'database');\n await fs.ensureDir(dbDir);\n const dbPath = path.join(dbDir, 'database.sqlite');\n if (!(await fs.pathExists(dbPath))) {\n await fs.writeFile(dbPath, '');\n }\n }\n\n // Create required directories\n const themesDir = path.join(targetDir, 'resources', 'themes');\n await fs.ensureDir(themesDir);\n\n const pluginsDir = path.join(targetDir, 'plugins');\n await fs.ensureDir(pluginsDir);\n\n // Generate APP_KEY\n spinner.text = 'Génération de la clé d\\'application...';\n await execaCommand('php artisan key:generate --force', { cwd: targetDir, stdio: 'inherit' });\n\n spinner.succeed('Projet configuré avec succès');\n } catch (error) {\n spinner.fail('Erreur lors de la configuration');\n throw error;\n }\n}\n\nasync function installDependencies(config: ProjectConfig, targetDir: string, spinner: ReturnType<typeof ora>): Promise<void> {\n if (!config.installDeps) {\n spinner.info('Installation des dépendances skipée');\n return;\n }\n\n // Composer - use update for fresh installs to handle lock file issues\n spinner.start('Installation des dépendances PHP (Composer)...');\n try {\n const { stdout, stderr } = await execaCommand('composer update --no-interaction', { cwd: targetDir });\n spinner.succeed('Dépendances PHP installées');\n } catch (error: any) {\n // Check if it's a missing PHP extension error\n // Combine error message, stdout and stderr for detection\n const errorStr = (error.toString() || '') + (error.stdout || '') + (error.stderr || '');\n\n // Collect missing extensions\n const missingExtensions: string[] = [];\n if (errorStr.includes('ext-zip') || errorStr.includes('extension zip')) {\n missingExtensions.push('zip');\n }\n if (errorStr.includes('ext-fileinfo') || errorStr.includes('extension fileinfo')) {\n missingExtensions.push('fileinfo');\n }\n if (errorStr.includes('ext-mbstring') || errorStr.includes('extension mbstring')) {\n missingExtensions.push('mbstring');\n }\n if (errorStr.includes('ext-pdo') || errorStr.includes('extension pdo')) {\n missingExtensions.push('pdo');\n }\n\n if (missingExtensions.length > 0) {\n spinner.fail('Extensions PHP manquantes');\n\n console.log(chalk.red(`\\n❌ Extensions PHP manquantes: ${missingExtensions.join(', ')}!\\n`));\n console.log(chalk.bold('Pour utiliser ExilonCMS, PHP doit avoir ces extensions activées.\\n'));\n\n const isWindows = process.platform === 'win32';\n\n if (isWindows) {\n console.log(chalk.bold('Windows - Activer les extensions PHP:\\n'));\n\n console.log(chalk.cyan('1. Trouvez votre fichier php.ini:'));\n console.log(chalk.gray(' php --ini'));\n console.log(chalk.gray(` Dans votre cas:\\n ${errorStr.match(/([A-Z]:\\\\[^[]+php\\.ini)/)?.[1] || 'C:\\\\php\\\\php.ini'}\\n`));\n\n console.log(chalk.cyan('2. Éditez php.ini et cherchez:'));\n for (const ext of missingExtensions) {\n console.log(chalk.gray(` ;extension=${ext}`));\n }\n console.log(chalk.gray(' Changez en:'));\n for (const ext of missingExtensions) {\n console.log(chalk.green(` extension=${ext}`));\n }\n console.log('');\n\n console.log(chalk.cyan('3. Sauvegardez et redémarrez votre terminal.\\n'));\n\n console.log(chalk.yellow('💡 Alternative: Utilisez PHP via XAMPP/WAMP qui inclut ces extensions.\\n'));\n console.log(chalk.gray('Télécharger XAMPP: https://www.apachefriends.org/download.html'));\n console.log(chalk.gray('Télécharger WAMP: https://www.wampserver.com/\\n'));\n\n console.log(chalk.yellow('⚠️ PHP installé via WinGet:'));\n console.log(chalk.gray(' Le PHP WinGet est souvent minimaliste. Considérez XAMPP/WAMP pour un environnement complet.\\n'));\n } else {\n console.log(chalk.bold('Linux/macOS - Activer les extensions PHP:\\n'));\n console.log(chalk.cyan('Ubuntu/Debian:'));\n const packages = missingExtensions.map(ext => `php-${ext}`).join(' ');\n console.log(chalk.gray(` sudo apt install ${packages}\\n`));\n console.log(chalk.cyan('macOS:'));\n console.log(chalk.gray(' brew install php\\n'));\n }\n\n console.log(chalk.bold('💡 Après avoir activé les extensions, relancez ce CLI.\\n'));\n\n // Exit cleanly without showing composer errors\n process.exit(1);\n }\n\n // For other errors, show the composer output\n spinner.fail('Erreur lors de l\\'installation Composer');\n console.error(errorStr);\n throw error;\n }\n\n // NPM\n spinner.start('Installation des dépendances Node.js...');\n try {\n await execaCommand('npm install --silent', { cwd: targetDir });\n spinner.succeed('Dépendances Node.js installées');\n } catch (error) {\n spinner.fail('Erreur lors de l\\'installation NPM');\n throw error;\n }\n\n // Build assets\n spinner.start('Construction des assets...');\n try {\n await execaCommand('npm run build', { cwd: targetDir });\n spinner.succeed('Assets construits');\n } catch (error) {\n spinner.warn('Erreur lors du build des assets (non-critique)');\n }\n}\n\nasync function runMigrationsAndSeed(config: ProjectConfig, targetDir: string, spinner: ReturnType<typeof ora>): Promise<void> {\n if (!config.runMigrations) {\n spinner.info('Migrations skipées');\n return;\n }\n\n spinner.start('Exécution des migrations et seeder...');\n try {\n // For SQLite, we use migrate:fresh which is safe for fresh install\n const command = config.database === 'sqlite'\n ? 'php artisan migrate:fresh --seed --force'\n : 'php artisan migrate --seed --force';\n\n await execaCommand(command, {\n cwd: targetDir,\n stdio: 'inherit',\n });\n\n spinner.succeed('Base de données initialisée');\n } catch (error) {\n spinner.fail('Erreur lors des migrations');\n throw error;\n }\n}\n\nasync function createAdminUser(config: ProjectConfig, targetDir: string, spinner: ReturnType<typeof ora>): Promise<void> {\n spinner.start('Création de l\\'utilisateur admin...');\n try {\n await execaCommand(\n `php artisan user:create --admin --name=\"${config.adminName}\" --email=\"${config.adminEmail}\" --password=\"${config.adminPassword}\"`,\n { cwd: targetDir, stdio: 'inherit' }\n );\n spinner.succeed('Utilisateur admin créé');\n } catch (error) {\n spinner.warn('Erreur lors de la création de l\\'admin (peut-être déjà créé via seeder)');\n }\n}\n\n// Create custom admin seeder to override default credentials\nasync function createCustomAdminSeeder(config: ProjectConfig, targetDir: string): Promise<void> {\n const seederPath = path.join(targetDir, 'database/seeders/CustomAdminSeeder.php');\n const seederContent = `<?php\n\nnamespace Database\\\\Seeders;\n\nuse ExilonCMS\\\\Models\\\\User;\nuse ExilonCMS\\\\Models\\\\Role;\nuse ExilonCMS\\\\Models\\\\Permission;\nuse Illuminate\\\\Database\\\\Console\\\\Seeds\\\\WithoutModelEvents;\nuse Illuminate\\\\Database\\\\Seeder;\nuse Illuminate\\\\Support\\\\Facades\\\\Hash;\n\nclass CustomAdminSeeder extends Seeder\n{\n use WithoutModelEvents;\n\n public function run(): void\n {\n // Create admin role if it doesn't exist\n $adminRole = Role::firstOrCreate(\n ['name' => 'admin'],\n [\n 'color' => 'FF0000',\n 'is_admin' => true,\n 'power' => 100,\n ]\n );\n\n // Create admin user with custom credentials\n $admin = User::firstOrCreate(\n ['email' => '${config.adminEmail}'],\n [\n 'name' => '${config.adminName}',\n 'password' => Hash::make('${config.adminPassword}'),\n 'role_id' => $adminRole->id,\n 'email_verified_at' => now(),\n 'password_changed_at' => now(),\n ]\n );\n\n // Create all permissions for admin role\n if ($adminRole->permissions()->count() === 0) {\n foreach (Permission::permissions() as $permission) {\n Permission::create([\n 'permission' => $permission,\n 'role_id' => $adminRole->id,\n ]);\n }\n }\n }\n}\n`;\n\n await fs.writeFile(seederPath, seederContent);\n\n // Update DatabaseSeeder to use CustomAdminSeeder instead of AdminUserSeeder\n const databaseSeederPath = path.join(targetDir, 'database/seeders/DatabaseSeeder.php');\n let databaseSeederContent = await fs.readFile(databaseSeederPath, 'utf-8');\n\n // Replace AdminUserSeeder with CustomAdminSeeder in the call array\n databaseSeederContent = databaseSeederContent.replace(\n /AdminUserSeeder::class/,\n 'CustomAdminSeeder::class'\n );\n\n await fs.writeFile(databaseSeederPath, databaseSeederContent);\n}\n\n// Install plugins from marketplace\nasync function installPlugins(config: ProjectConfig, targetDir: string, registry: MarketplaceRegistry | null, spinner: ReturnType<typeof ora>): Promise<void> {\n if (config.plugins.length === 0) {\n return;\n }\n\n if (!registry) {\n spinner.warn('Marketplace non disponible, impossible d\\'installer les plugins');\n return;\n }\n\n for (const pluginId of config.plugins) {\n const plugin = registry.plugins.find(p => p.extension_id === pluginId);\n if (!plugin) {\n spinner.warn(`Plugin ${pluginId} non trouvé dans le marketplace`);\n continue;\n }\n\n spinner.start(`Installation du plugin ${plugin.name}...`);\n try {\n // Download plugin zip\n const pluginZipPath = path.join(targetDir, 'temp_plugin.zip');\n const response = await fetch(plugin.url);\n const buffer = await response.arrayBuffer();\n await fs.writeFile(pluginZipPath, Buffer.from(buffer));\n\n // Extract using platform-specific command\n const pluginsDir = path.join(targetDir, 'plugins');\n await fs.ensureDir(pluginsDir);\n\n // Detect platform and use appropriate unzip command\n const isWindows = process.platform === 'win32';\n\n if (isWindows) {\n // Use PowerShell's Expand-Archive on Windows\n await execaCommand(\n `powershell -Command \"Expand-Archive -Path '${pluginZipPath}' -DestinationPath '${pluginsDir}' -Force\"`,\n { cwd: targetDir }\n );\n } else {\n // Use unzip command on Linux/Mac\n await execaCommand(`unzip -o \"${pluginZipPath}\" -d \"${pluginsDir}\"`, { cwd: targetDir });\n }\n\n // Clean up\n await fs.remove(pluginZipPath);\n\n spinner.succeed(`Plugin ${plugin.name} installé`);\n } catch (error) {\n spinner.fail(`Erreur lors de l'installation du plugin ${plugin.name}`);\n console.error(error);\n }\n }\n}\n\nfunction printSuccessMessage(config: ProjectConfig, targetDir: string): void {\n console.log(chalk.bold('\\n✨ Installation terminée avec succès!\\n'));\n\n console.log(chalk.cyan(' Projet créé dans: ') + chalk.white(targetDir));\n console.log(chalk.cyan(' Base de données: ') + chalk.white(config.database));\n console.log(chalk.cyan(' Thème: ') + chalk.white(config.theme));\n\n if (config.plugins.length > 0) {\n console.log(chalk.cyan(' Plugins installés: ') + chalk.white(config.plugins.join(', ')));\n }\n\n console.log(chalk.bold('\\n🚀 Prochaines étapes:\\n'));\n\n console.log(` ${chalk.cyan('1.')} Aller dans le dossier du projet:`);\n console.log(` ${chalk.gray(`cd ${config.projectName}`)}\\n`);\n\n if (!config.installDeps) {\n console.log(` ${chalk.cyan('2.')} Installer les dépendances:`);\n console.log(` ${chalk.gray('composer install')}`);\n console.log(` ${chalk.gray('npm install')}`);\n console.log(` ${chalk.gray('npm run build')}\\n`);\n }\n\n if (!config.runMigrations) {\n console.log(` ${chalk.cyan('3.')} Configurer la base de données et lancer les migrations:`);\n if (config.database !== 'sqlite') {\n console.log(` ${chalk.yellow('⚠️ Configurez votre base de données dans .env d\\'abord')}`);\n }\n console.log(` ${chalk.gray('php artisan migrate:fresh --seed')}\\n`);\n }\n\n console.log(` ${chalk.cyan('4.')} Démarrer le serveur de développement:`);\n console.log(` ${chalk.gray('php artisan serve')}\\n`);\n\n if (config.database === 'sqlite') {\n console.log(` ${chalk.green('✓')} SQLite utilisé - aucune configuration de base de données nécessaire!\\n`);\n } else {\n console.log(` ${chalk.yellow('⚠️ ')} Configurez votre base de données ${config.database} dans ${chalk.gray('.env')}\\n`);\n }\n\n console.log(chalk.bold('📧 Identifiants admin:\\n'));\n console.log(` Email: ${chalk.cyan(config.adminEmail)}`);\n console.log(` Password: ${chalk.cyan(config.adminPassword)}\\n`);\n\n console.log(chalk.gray(' ' + '─'.repeat(60) + '\\n'));\n\n console.log(` ${chalk.cyan('Documentation:')} https://github.com/Exilon-Studios/ExilonCMS/wiki\\n`);\n}\n\nasync function createCommand(projectName: string, options: any): Promise<void> {\n const spinner = ora();\n\n try {\n // Check dependencies first\n console.log(chalk.bold('\\n🔍 Vérification des dépendances...\\n'));\n await checkDependencies(spinner);\n\n // Check PHP extensions\n await checkPHPExtensions(spinner);\n\n // Fetch marketplace registry\n const registry = await fetchMarketplaceRegistry();\n\n const config = await promptForConfig({\n projectName,\n database: options.database,\n theme: options.theme,\n plugins: options.plugins ? options.plugins.split(',') : [],\n siteName: options.siteName,\n adminName: options.adminName,\n adminEmail: options.adminEmail,\n adminPassword: options.adminPassword,\n installDeps: options.installDeps,\n runMigrations: options.runMigrations,\n }, registry);\n\n const targetDir = path.resolve(process.cwd(), config.projectName);\n\n // Check if directory exists\n if (await fs.pathExists(targetDir)) {\n const { overwrite } = await prompts({\n type: 'confirm',\n name: 'overwrite',\n message: `Le dossier ${config.projectName} existe déjà. Écraser?`,\n initial: false,\n });\n\n if (!overwrite) {\n console.log(chalk.yellow('\\nInstallation annulée.'));\n process.exit(0);\n }\n\n await fs.remove(targetDir);\n }\n\n // Download project\n await downloadProject(targetDir, spinner);\n\n // Install dependencies FIRST\n await installDependencies(config, targetDir, spinner);\n\n // Configure project (needs artisan which needs composer dependencies)\n await configureProject(config, targetDir, spinner);\n\n // Create custom admin seeder with user's credentials\n await createCustomAdminSeeder(config, targetDir);\n\n // Run migrations (will use custom admin seeder)\n await runMigrationsAndSeed(config, targetDir, spinner);\n\n // Install plugins from marketplace\n await installPlugins(config, targetDir, registry, spinner);\n\n // Print success message\n printSuccessMessage(config, targetDir);\n\n } catch (error: any) {\n if (error.message === 'user cancelled') {\n console.log(chalk.yellow('\\nInstallation annulée.'));\n process.exit(0);\n }\n\n console.error(chalk.red('\\n✖ Erreur:'), error.message);\n process.exit(1);\n }\n}\n\n// CLI Program\nconst program = new Command();\n\nprogram\n .name('exiloncms')\n .description('Create a new ExilonCMS project')\n .version(packageJson.version);\n\nprogram\n .command('create [project-name]')\n .description('Create a new ExilonCMS project')\n .option('-d, --database <type>', 'Database type (sqlite, postgresql, mysql)', 'sqlite')\n .option('-t, --theme <name>', 'Theme name', 'default')\n .option('-p, --plugins <list>', 'Comma-separated list of plugins')\n .option('--site-name <name>', 'Site name')\n .option('--admin-name <name>', 'Admin name')\n .option('--admin-email <email>', 'Admin email')\n .option('--admin-password <password>', 'Admin password')\n .option('--no-install-deps', 'Skip installing dependencies')\n .option('--no-run-migrations', 'Skip running migrations')\n .action(createCommand);\n\nprogram\n .command('new [project-name]')\n .description('Alias for create')\n .option('-d, --database <type>', 'Database type (sqlite, postgresql, mysql)', 'sqlite')\n .option('-t, --theme <name>', 'Theme name', 'default')\n .option('-p, --plugins <list>', 'Comma-separated list of plugins')\n .option('--site-name <name>', 'Site name')\n .option('--admin-name <name>', 'Admin name')\n .option('--admin-email <email>', 'Admin email')\n .option('--admin-password <password>', 'Admin password')\n .option('--no-install-deps', 'Skip installing dependencies')\n .option('--no-run-migrations', 'Skip running migrations')\n .action(createCommand);\n\nprogram.parse();\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exiloncms/cli",
3
- "version": "1.1.2",
3
+ "version": "1.2.1",
4
4
  "description": "Interactive CLI to create new ExilonCMS projects",
5
5
  "type": "module",
6
6
  "bin": {