mango-cms 0.2.5 → 0.2.6

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.
Files changed (2) hide show
  1. package/cli.js +251 -28
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -252,41 +252,264 @@ program
252
252
  .description('Start the Mango CMS in watch mode')
253
253
  .action(async () => {
254
254
  try {
255
- // Check system dependencies first
256
- await checkSystemDependencies();
255
+ await startMangoCMS();
256
+ } catch (error) {
257
+ console.error('Error starting Mango CMS:', error.message);
258
+ process.exit(1);
259
+ }
260
+ });
257
261
 
258
- // Check for license in settings.json
259
- const settingsPath = path.join(process.cwd(), 'mango/config/settings.json');
260
- await ensureLicenseExists(settingsPath);
262
+ program
263
+ .command('dev')
264
+ .description('Start the Mango CMS in watch mode (alias for start)')
265
+ .action(async () => {
266
+ try {
267
+ await startMangoCMS();
268
+ } catch (error) {
269
+ console.error('Error starting Mango CMS:', error.message);
270
+ process.exit(1);
271
+ }
272
+ });
261
273
 
262
- // Ensure src exists
263
- await ensureSrcExists(__dirname);
274
+ // Helper function for starting Mango CMS
275
+ async function startMangoCMS() {
276
+ try {
277
+ // Check system dependencies first
278
+ await checkSystemDependencies();
264
279
 
265
- // Path to @mango-cms/core inside node_modules
266
- const cmsPackagePath = path.resolve(__dirname);
267
- // User's project root (where they run "mango start")
268
- const userProjectRoot = process.cwd();
280
+ // Check for license in settings.json
281
+ const settingsPath = path.join(process.cwd(), 'mango/config/settings.json');
282
+ await ensureLicenseExists(settingsPath);
269
283
 
270
- console.log(`Starting Mango CMS...`);
271
- console.log(`CMS package located at: ${cmsPackagePath}`);
272
- console.log(`Running in context of: ${userProjectRoot}`);
284
+ // Ensure src exists
285
+ await ensureSrcExists(__dirname);
273
286
 
274
- // Run Webpack with the config from @mango-cms/core, but in the user's project context
275
- const webpackConfigPath = path.join(cmsPackagePath, 'webpack.config.js');
276
- execSync(
277
- `npx webpack --config "${webpackConfigPath}" --watch --mode development`,
278
- {
279
- cwd: cmsPackagePath,
280
- stdio: 'inherit',
281
- env: {
282
- ...process.env,
283
- MANGO_ROOT: cmsPackagePath,
284
- PROJECT_ROOT: userProjectRoot
285
- }
287
+ // Path to @mango-cms/core inside node_modules
288
+ const cmsPackagePath = path.resolve(__dirname);
289
+ // User's project root (where they run "mango start")
290
+ const userProjectRoot = process.cwd();
291
+
292
+ console.log(`Starting Mango CMS...`);
293
+ console.log(`CMS package located at: ${cmsPackagePath}`);
294
+ console.log(`Running in context of: ${userProjectRoot}`);
295
+
296
+ // Run Webpack with the config from @mango-cms/core, but in the user's project context
297
+ const webpackConfigPath = path.join(cmsPackagePath, 'webpack.config.js');
298
+ execSync(
299
+ `npx webpack --config "${webpackConfigPath}" --watch --mode development`,
300
+ {
301
+ cwd: cmsPackagePath,
302
+ stdio: 'inherit',
303
+ env: {
304
+ ...process.env,
305
+ MANGO_ROOT: cmsPackagePath,
306
+ PROJECT_ROOT: userProjectRoot
286
307
  }
287
- );
308
+ }
309
+ );
310
+ } catch (error) {
311
+ console.error('Error starting Mango CMS:', error.message);
312
+ process.exit(1);
313
+ }
314
+ }
315
+
316
+ // Helper function to detect web server (nginx or apache)
317
+ async function detectWebServer() {
318
+ try {
319
+ // Try nginx first
320
+ execSync('nginx -v', { stdio: 'ignore' });
321
+ return 'nginx';
322
+ } catch (error) {
323
+ try {
324
+ // Try apache next
325
+ execSync('apachectl -v', { stdio: 'ignore' });
326
+ return 'apache';
288
327
  } catch (error) {
289
- console.error('Error starting Mango CMS:', error.message);
328
+ return null;
329
+ }
330
+ }
331
+ }
332
+
333
+ // Helper function to generate nginx config
334
+ function generateNginxConfig(settings, buildPath) {
335
+ const domain = settings.mangoDomain;
336
+ const port = settings.port || 3002;
337
+
338
+ return `server {
339
+ root ${buildPath};
340
+ server_name ${domain};
341
+
342
+ client_max_body_size 50M;
343
+
344
+ location /tmp {
345
+ root ${buildPath};
346
+ }
347
+
348
+ ${settings.s3Bucket ? `location /s3/ {
349
+ proxy_pass https://${settings.s3Bucket}.s3.amazonaws.com/;
350
+ }
351
+ ` : ''}
352
+
353
+ location / {
354
+ proxy_http_version 1.1;
355
+ proxy_cache_bypass $http_upgrade;
356
+ proxy_set_header Upgrade $http_upgrade;
357
+ proxy_set_header Connection 'upgrade';
358
+ proxy_set_header Host $host;
359
+ proxy_set_header X-Real-IP $remote_addr;
360
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
361
+ proxy_set_header X-Forwarded-Proto $scheme;
362
+ proxy_pass http://localhost:${port};
363
+ }
364
+ }`;
365
+ }
366
+
367
+ // Helper function to generate apache config
368
+ function generateApacheConfig(settings, buildPath) {
369
+ const domain = settings.mangoDomain;
370
+ const port = settings.port || 3002;
371
+
372
+ return `<VirtualHost *:80>
373
+ ServerName ${domain}
374
+ DocumentRoot ${buildPath}
375
+
376
+ ProxyRequests Off
377
+ ProxyPreserveHost On
378
+
379
+ <Directory ${buildPath}>
380
+ Options Indexes FollowSymLinks
381
+ AllowOverride All
382
+ Require all granted
383
+ </Directory>
384
+
385
+ ${settings.s3Bucket ? `ProxyPass /s3/ https://${settings.s3Bucket}.s3.amazonaws.com/
386
+ ProxyPassReverse /s3/ https://${settings.s3Bucket}.s3.amazonaws.com/
387
+ ` : ''}
388
+
389
+ ProxyPass / http://localhost:${port}/
390
+ ProxyPassReverse / http://localhost:${port}/
391
+
392
+ RequestHeader set X-Forwarded-Proto "https"
393
+ RequestHeader set X-Forwarded-Port "443"
394
+
395
+ ErrorLog \${APACHE_LOG_DIR}/${domain}-error.log
396
+ CustomLog \${APACHE_LOG_DIR}/${domain}-access.log combined
397
+ </VirtualHost>`;
398
+ }
399
+
400
+ // Helper function to configure web server
401
+ async function configureWebServer(settings, buildPath) {
402
+ let webServer = await detectWebServer();
403
+
404
+ if (!webServer) {
405
+ const { server } = await inquirer.prompt([
406
+ {
407
+ type: 'list',
408
+ name: 'server',
409
+ message: 'Which web server would you like to use?',
410
+ choices: ['nginx', 'apache']
411
+ }
412
+ ]);
413
+ webServer = server;
414
+ }
415
+
416
+ const config = webServer === 'nginx' ?
417
+ generateNginxConfig(settings, buildPath) :
418
+ generateApacheConfig(settings, buildPath);
419
+
420
+ const configPath = webServer === 'nginx' ?
421
+ `/etc/nginx/sites-available/${settings.siteName.toLowerCase()}` :
422
+ `/etc/apache2/sites-available/${settings.siteName.toLowerCase()}.conf`;
423
+
424
+ try {
425
+ // Write config file
426
+ fs.writeFileSync(configPath, config);
427
+ console.log(`Created ${webServer} configuration at ${configPath}`);
428
+
429
+ if (webServer === 'nginx') {
430
+ // Create symlink if it doesn't exist
431
+ const enabledPath = `/etc/nginx/sites-enabled/${settings.siteName.toLowerCase()}`;
432
+ if (!fs.existsSync(enabledPath)) {
433
+ execSync(`sudo ln -s ${configPath} ${enabledPath}`);
434
+ }
435
+ // Test and reload nginx
436
+ execSync('sudo nginx -t');
437
+ execSync('sudo systemctl reload nginx');
438
+ } else {
439
+ // Enable site and reload apache
440
+ execSync(`sudo a2ensite ${settings.siteName.toLowerCase()}`);
441
+ execSync('sudo systemctl reload apache2');
442
+ }
443
+
444
+ console.log(`${webServer} configuration has been updated and service reloaded`);
445
+ } catch (error) {
446
+ console.error(`Error configuring ${webServer}:`, error.message);
447
+ throw error;
448
+ }
449
+ }
450
+
451
+ // Helper function to check if PM2 is installed
452
+ async function checkPM2() {
453
+ try {
454
+ execSync('pm2 -v', { stdio: 'ignore' });
455
+ return true;
456
+ } catch (error) {
457
+ console.error('PM2 is not installed. Please install it using: npm install -g pm2');
458
+ return false;
459
+ }
460
+ }
461
+
462
+ // Helper function to manage PM2 process
463
+ async function managePM2Process(settings) {
464
+ const processName = `${settings.siteName.toLowerCase()}-mango`;
465
+
466
+ try {
467
+ // Check if process exists
468
+ const processListOutput = execSync('pm2 list --mini', { encoding: 'utf8' });
469
+ const processExists = processListOutput.includes(processName);
470
+
471
+ if (processExists) {
472
+ console.log(`Reloading PM2 process: ${processName}`);
473
+ execSync(`pm2 reload ${processName}`);
474
+ } else {
475
+ console.log(`Starting new PM2 process: ${processName}`);
476
+ execSync(`pm2 start build/index.js --name ${processName}`);
477
+ }
478
+ } catch (error) {
479
+ console.error('Error managing PM2 process:', error.message);
480
+ throw error;
481
+ }
482
+ }
483
+
484
+ program
485
+ .command('deploy')
486
+ .description('Build and deploy Mango CMS using PM2')
487
+ .action(async () => {
488
+ try {
489
+ const configPath = path.join(process.cwd(), 'default/mango/config/settings.json');
490
+ const settings = JSON.parse(fs.readFileSync(configPath, 'utf8'));
491
+
492
+ // Run build command
493
+ console.log('Building Mango CMS...');
494
+ execSync('npm run mango build', { stdio: 'inherit' });
495
+
496
+ // Check if PM2 is installed
497
+ if (await checkPM2()) {
498
+ await managePM2Process(settings);
499
+
500
+ // Configure web server
501
+ const buildPath = path.join(process.cwd(), 'build');
502
+ try {
503
+ await configureWebServer(settings, buildPath);
504
+ } catch (error) {
505
+ console.warn('Warning: Could not configure web server:', error.message);
506
+ console.warn('You may need to configure your web server manually.');
507
+ }
508
+
509
+ console.log('Deployment completed successfully!');
510
+ }
511
+ } catch (error) {
512
+ console.error('Deployment failed:', error.message);
290
513
  process.exit(1);
291
514
  }
292
515
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mango-cms",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "main": "./index.js",
5
5
  "exports": {
6
6
  ".": "./index.js",