mango-cms 0.2.50 → 0.3.0

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/cli.js CHANGED
@@ -1,13 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { Command } = require('commander');
4
- const { execSync, spawn } = require('child_process');
5
- const path = require('path');
6
- const inquirer = require('inquirer');
7
- const fs = require('fs-extra');
8
- const axios = require('axios');
9
- const AdmZip = require('adm-zip');
10
- const { addHosts, removeHosts } = require('./lib/hosts-manager');
3
+ import { Command } from 'commander';
4
+ import { execSync, spawn } from 'child_process';
5
+ import path from 'path';
6
+ import { fileURLToPath } from 'url';
7
+ import inquirer from 'inquirer';
8
+ import fs from 'fs-extra';
9
+ import axios from 'axios';
10
+ import AdmZip from 'adm-zip';
11
+ import { addHosts, removeHosts } from './lib/hosts-manager.js';
12
+ import os from 'os';
13
+
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = path.dirname(__filename);
11
16
 
12
17
  const program = new Command();
13
18
 
@@ -332,20 +337,47 @@ async function startMangoCMS() {
332
337
  console.log(`CMS package located at: ${cmsPackagePath}`);
333
338
  console.log(`Running in context of: ${userProjectRoot}`);
334
339
 
335
- // Run Webpack with the config from @mango-cms/core, but in the user's project context
336
- const webpackConfigPath = path.join(cmsPackagePath, 'webpack.config.js');
337
- execSync(
338
- `npx webpack --config "${webpackConfigPath}" --watch --mode development`,
339
- {
340
- cwd: cmsPackagePath,
341
- stdio: 'inherit',
342
- env: {
343
- ...process.env,
344
- MANGO_ROOT: cmsPackagePath,
345
- PROJECT_ROOT: userProjectRoot
346
- }
340
+ const viteConfigPath = path.join(cmsPackagePath, 'vite.config.js');
341
+ const buildDir = path.join(userProjectRoot, 'build');
342
+
343
+ // Start Vite build in watch mode
344
+ const viteProcess = spawn('npx', ['vite', 'build', '--watch', '--mode', 'development'], {
345
+ cwd: cmsPackagePath,
346
+ stdio: 'inherit',
347
+ env: {
348
+ ...process.env,
349
+ MANGO_ROOT: cmsPackagePath,
350
+ PROJECT_ROOT: userProjectRoot
351
+ }
352
+ });
353
+
354
+ // Give Vite a moment to do the initial build
355
+ await new Promise(resolve => setTimeout(resolve, 3000));
356
+
357
+ // Start nodemon to watch the build output and restart the server
358
+ const nodemonProcess = spawn('npx', ['nodemon', '--watch', buildDir, '--ext', 'js', path.join(buildDir, 'index.js')], {
359
+ cwd: userProjectRoot,
360
+ stdio: 'inherit',
361
+ env: {
362
+ ...process.env,
363
+ MANGO_ROOT: cmsPackagePath,
364
+ PROJECT_ROOT: userProjectRoot
347
365
  }
348
- );
366
+ });
367
+
368
+ // Handle process termination
369
+ process.on('SIGINT', () => {
370
+ viteProcess.kill();
371
+ nodemonProcess.kill();
372
+ process.exit(0);
373
+ });
374
+
375
+ process.on('SIGTERM', () => {
376
+ viteProcess.kill();
377
+ nodemonProcess.kill();
378
+ process.exit(0);
379
+ });
380
+
349
381
  } catch (error) {
350
382
  console.error('Error starting Mango CMS:', error.message);
351
383
  process.exit(1);
@@ -409,7 +441,7 @@ server {
409
441
  index index.html;
410
442
 
411
443
  # Serve static files directly if they exist
412
- location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf|json|html)$ {
444
+ location ~* \\.(?:js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf|json|html)$ {
413
445
  expires 1y;
414
446
  access_log off;
415
447
  add_header Cache-Control "public";
@@ -445,6 +477,7 @@ server {
445
477
  function generateApacheConfig(settings, buildPath) {
446
478
  const domain = settings.mangoDomain;
447
479
  const port = settings.port || 3002;
480
+ const frontPort = settings.frontPort || 3001;
448
481
 
449
482
  return `<VirtualHost *:80>
450
483
  ServerName ${domain}
@@ -479,7 +512,7 @@ function generateApacheConfig(settings, buildPath) {
479
512
  IndexIndex index.html
480
513
 
481
514
  # Serve static files directly
482
- <FilesMatch \.\.(?:js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf|json)$>
515
+ <FilesMatch \\.\\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf|json)$>
483
516
  Header set Cache-Control "max-age=31536000"
484
517
  </FilesMatch>
485
518
 
@@ -653,10 +686,9 @@ program
653
686
  console.log(`CMS package located at: ${cmsPackagePath}`);
654
687
  console.log(`Building in context of: ${userProjectRoot}`);
655
688
 
656
- // Run Webpack with the config from @mango-cms/core in production mode
657
- const webpackConfigPath = path.join(cmsPackagePath, 'webpack.config.js');
689
+ // Run Vite build in production mode
658
690
  execSync(
659
- `npx webpack --config "${webpackConfigPath}" --mode production`,
691
+ `npx vite build --mode production`,
660
692
  {
661
693
  cwd: cmsPackagePath,
662
694
  stdio: 'inherit',
@@ -705,7 +737,7 @@ program
705
737
  console.log(`Using server IP: ${serverIp}`);
706
738
  console.log(`Using database: ${database}`);
707
739
 
708
- const downloadsDir = path.join(require('os').homedir(), 'Downloads');
740
+ const downloadsDir = path.join(os.homedir(), 'Downloads');
709
741
  const dumpZip = path.join(downloadsDir, 'dump.zip');
710
742
  const dumpDir = path.join(downloadsDir, 'dump');
711
743
 
@@ -13,7 +13,6 @@
13
13
  "dependencies": {
14
14
  "@headlessui/vue": "^1.6.7",
15
15
  "@mapbox/mapbox-gl-geocoder": "^5.0.0",
16
- "@sweetalert2/theme-dark": "^5.0.10",
17
16
  "@tinymce/tinymce-vue": "^4",
18
17
  "@vitejs/plugin-vue": "^5.2.3",
19
18
  "@vueup/vue-quill": "^1.0.0-beta.7",
@@ -25,9 +24,8 @@
25
24
  "dayjs": "^1.10.7",
26
25
  "express": "^4.18.1",
27
26
  "google-maps": "^4.3.3",
28
- "mango-cms": "^0.2.50",
27
+ "mango-cms": "^0.3.0",
29
28
  "mapbox-gl": "^2.7.0",
30
- "sweetalert2": "^11.4.0",
31
29
  "vite": "^6.2.2",
32
30
  "vue": "^3.2.37",
33
31
  "vue-router": "4",
@@ -57,6 +57,7 @@ export default defineConfig({
57
57
  ],
58
58
  server: {
59
59
  host: '0.0.0.0',
60
+ allowedHosts: ['.mango'],
60
61
  // When running behind mango proxy, configure HMR to use the proxy domain
61
62
  // VITE_DEV_PROXY is set to api.{slug}.mango; derive frontend domain by stripping "api." prefix
62
63
  ...(process.env.VITE_DEV_PROXY?.startsWith('api.') ? {
package/lib/dev-proxy.js CHANGED
@@ -9,9 +9,9 @@
9
9
  * Usage: node lib/dev-proxy.js <frontDomain> <apiDomain> <frontPort> <backendPort> [pidPath]
10
10
  */
11
11
 
12
- const http = require('http');
13
- const httpProxy = require('http-proxy');
14
- const fs = require('fs');
12
+ import http from 'http';
13
+ import httpProxy from 'http-proxy';
14
+ import fs from 'fs';
15
15
 
16
16
  const frontDomain = process.argv[2];
17
17
  const apiDomain = process.argv[3];
@@ -3,13 +3,13 @@
3
3
  * Lines are tagged with "# mango-proxy" for easy cleanup.
4
4
  */
5
5
 
6
- const fs = require('fs');
7
- const { execSync } = require('child_process');
6
+ import fs from 'fs';
7
+ import { execSync } from 'child_process';
8
8
 
9
9
  const HOSTS_FILE = '/etc/hosts';
10
10
  const TAG = '# mango-proxy';
11
11
 
12
- function addHosts(domains) {
12
+ export function addHosts(domains) {
13
13
  const hostsContent = fs.readFileSync(HOSTS_FILE, 'utf8');
14
14
  const newDomains = domains.filter(d => !hostsContent.includes(d));
15
15
 
@@ -29,7 +29,7 @@ function addHosts(domains) {
29
29
  }
30
30
  }
31
31
 
32
- function removeHosts() {
32
+ export function removeHosts() {
33
33
  try {
34
34
  const hostsContent = fs.readFileSync(HOSTS_FILE, 'utf8');
35
35
  const lines = hostsContent.split('\n');
@@ -49,5 +49,3 @@ function removeHosts() {
49
49
  console.error('Failed to clean /etc/hosts:', err.message);
50
50
  }
51
51
  }
52
-
53
- module.exports = { addHosts, removeHosts };
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "mango-cms",
3
- "version": "0.2.50",
3
+ "version": "0.3.0",
4
+ "type": "module",
4
5
  "main": "./index.js",
5
6
  "exports": {
6
7
  ".": "./index.js",
@@ -9,7 +10,7 @@
9
10
  "files": [
10
11
  "index.js",
11
12
  "cli.js",
12
- "webpack.config.js",
13
+ "vite.config.js",
13
14
  "lib/**/*",
14
15
  "default/**/*",
15
16
  "!default/node_modules/**"
@@ -21,9 +22,9 @@
21
22
  },
22
23
  "scripts": {
23
24
  "postinstall": "",
24
- "build": "npx webpack",
25
- "watch": "NODE_OPTIONS='--trace-warnings' npx webpack --watch --mode development",
26
- "dev": "NODE_OPTIONS='--trace-warnings' npx webpack --watch --mode development"
25
+ "build": "vite build",
26
+ "watch": "vite build --watch",
27
+ "dev": "vite build --watch"
27
28
  },
28
29
  "peerDependencies": {
29
30
  "algoliasearch": "^4.10.3",
@@ -38,9 +39,6 @@
38
39
  "dependencies": {
39
40
  "@aws-sdk/client-s3": "^3.423.0",
40
41
  "@aws-sdk/lib-storage": "^3.423.0",
41
- "@babel/core": "^7.12.9",
42
- "@babel/plugin-transform-runtime": "^7.12.1",
43
- "@babel/preset-env": "^7.12.7",
44
42
  "@sentry/node": "^7.85.0",
45
43
  "@sentry/profiling-node": "^1.2.6",
46
44
  "adm-zip": "^0.5.16",
@@ -50,16 +48,16 @@
50
48
  "archiver": "^7.0.1",
51
49
  "aws-sdk": "^2.1469.0",
52
50
  "axios": "^0.21.4",
53
- "babel-loader": "^8.2.2",
54
- "babel-plugin-source-map-support": "^2.1.3",
55
51
  "cli-progress": "^3.12.0",
56
52
  "connect-multiparty": "^2.2.0",
53
+ "connect-redis": "7",
57
54
  "cors": "^2.8.5",
58
55
  "country-state-city": "^3.2.1",
59
56
  "crypto": "^1.0.1",
60
57
  "dayjs": "^1.11.6",
61
58
  "dotenv": "^8.2.0",
62
59
  "express": "^4.17.1",
60
+ "express-session": "^1.19.0",
63
61
  "fast-csv": "^5.0.5",
64
62
  "fs-extra": "^11.3.0",
65
63
  "get-audio-duration": "^3.1.0",
@@ -84,12 +82,11 @@
84
82
  "multer": "^1.4.2",
85
83
  "node-lame": "^1.3.2",
86
84
  "node-zip": "^1.1.1",
87
- "nodemon-webpack-plugin": "^4.3.2",
85
+ "nodemon": "^3.0.0",
88
86
  "openai": "^5.15.0",
89
87
  "pack": "^2.2.0",
90
88
  "parse-html-text-content": "^1.1.1",
91
89
  "redis": "^4.7.0",
92
- "require-all": "^3.0.0",
93
90
  "resend": "^6.3.0",
94
91
  "sharp": "^0.32.1",
95
92
  "socket.io": "^4.8.0",
@@ -100,10 +97,7 @@
100
97
  "subscriptions-transport-ws": "^0.9.18",
101
98
  "util": "^0.12.3",
102
99
  "uuid": "3.4.0",
103
- "web": "^0.0.2",
104
- "webpack": "^5.10.0",
105
- "webpack-cli": "^5.1.4",
106
- "webpack-node-externals": "^2.5.2"
100
+ "web": "^0.0.2"
107
101
  },
108
102
  "optionalDependencies": {
109
103
  "bufferutil": "^4.0.8",
package/vite.config.js ADDED
@@ -0,0 +1,76 @@
1
+ import { defineConfig } from 'vite'
2
+ import { fileURLToPath } from 'url'
3
+ import path from 'path'
4
+ import fs from 'fs'
5
+ import { builtinModules } from 'module'
6
+
7
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
8
+
9
+ export default defineConfig(({ mode }) => {
10
+ process.env.PROJECT_ROOT = process.env.PROJECT_ROOT || process.cwd()
11
+ process.env.MANGO_ROOT = process.env.MANGO_ROOT || __dirname
12
+
13
+ const mangoRoot = process.env.MANGO_ROOT
14
+ let userProjectRoot = process.env.PROJECT_ROOT
15
+
16
+ const legacyMode = userProjectRoot === mangoRoot
17
+ if (legacyMode) {
18
+ userProjectRoot = path.join(__dirname, '..')
19
+ process.env.PROJECT_ROOT = userProjectRoot
20
+ }
21
+
22
+ // Determine config directory - prefer 'mango' over 'config' (legacy)
23
+ let configDir = 'mango'
24
+ if (!fs.existsSync(path.join(userProjectRoot, 'mango')) && fs.existsSync(path.join(userProjectRoot, 'config'))) {
25
+ configDir = 'config'
26
+ }
27
+ process.env.CONFIG_ROOT = path.join(userProjectRoot, configDir)
28
+
29
+ const buildPath = legacyMode ? mangoRoot : userProjectRoot
30
+
31
+ console.log('Vite config:', {
32
+ PROJECT_ROOT: process.env.PROJECT_ROOT,
33
+ MANGO_ROOT: mangoRoot,
34
+ CONFIG_ROOT: process.env.CONFIG_ROOT,
35
+ legacyMode,
36
+ buildPath
37
+ })
38
+
39
+ return {
40
+ build: {
41
+ ssr: path.resolve(mangoRoot, 'src/main.js'),
42
+ outDir: path.resolve(buildPath, 'build'),
43
+ emptyOutDir: true,
44
+ sourcemap: 'inline',
45
+ minify: mode === 'production',
46
+ rollupOptions: {
47
+ output: {
48
+ entryFileNames: 'index.js',
49
+ format: 'esm'
50
+ }
51
+ }
52
+ },
53
+ resolve: {
54
+ alias: {
55
+ '@mango': path.resolve(userProjectRoot, configDir),
56
+ '@cms': path.resolve(mangoRoot, 'src/cms'),
57
+ '@config': path.resolve(userProjectRoot, configDir),
58
+ '@settings': path.resolve(userProjectRoot, configDir, 'config/settings.json'),
59
+ '@fields': path.resolve(mangoRoot, 'src/cms/1. build/fields'),
60
+ '@mongo': path.resolve(mangoRoot, 'src/cms/1. build/libraries/mongo'),
61
+ '@query': path.resolve(mangoRoot, 'src/cms/1. build/libraries/mongo'),
62
+ '@helpers': path.resolve(mangoRoot, 'src/cms/1. build/helpers'),
63
+ '@main': path.resolve(mangoRoot, 'src/cms/2. process/0. main')
64
+ }
65
+ },
66
+ ssr: {
67
+ external: [...builtinModules, ...builtinModules.map(m => `node:${m}`)],
68
+ noExternal: []
69
+ },
70
+ define: {
71
+ 'process.env.MANGO_ROOT': JSON.stringify(mangoRoot),
72
+ 'process.env.PROJECT_ROOT': JSON.stringify(process.env.PROJECT_ROOT),
73
+ 'process.env.CONFIG_ROOT': JSON.stringify(process.env.CONFIG_ROOT)
74
+ }
75
+ }
76
+ })
package/webpack.config.js DELETED
@@ -1,65 +0,0 @@
1
- const path = require('path');
2
- const webpack = require('webpack');
3
- const nodeExternals = require('webpack-node-externals');
4
- const NodemonPlugin = require('nodemon-webpack-plugin');
5
-
6
-
7
- // Get the user's project root from the execution context (passed via CLI or fallback to cwd)
8
- process.env.PROJECT_ROOT = process.env.PROJECT_ROOT || process.cwd();
9
- process.env.MANGO_ROOT = process.env.MANGO_ROOT || __dirname;
10
- let moduleLocation = process.env.PROJECT_ROOT
11
-
12
- let legacyMode = process.env.PROJECT_ROOT == process.env.MANGO_ROOT
13
- if (legacyMode) {
14
- moduleLocation = __dirname
15
- process.env.PROJECT_ROOT = path.join(__dirname, '..')
16
- }
17
- process.env.CONFIG_ROOT = process.env.PROJECT_ROOT + (legacyMode ? '/config' : '/mango')
18
- console.log('env', process.env.PROJECT_ROOT, process.env.MANGO_ROOT, legacyMode, path.resolve(moduleLocation, 'node_modules'))
19
-
20
- const userProjectRoot = process.env.PROJECT_ROOT
21
- const mangoRoot = process.env.MANGO_ROOT
22
- const buildPath = legacyMode ? mangoRoot : userProjectRoot
23
-
24
- console.log('moduleLocation', moduleLocation, process.env.CONFIG_ROOT)
25
-
26
- module.exports = {
27
- mode: 'production',
28
- resolve: {
29
- alias: {
30
-
31
- '@mango$': path.resolve(mangoRoot, 'src/cms/exports'),
32
- '@mango': path.resolve(userProjectRoot, legacyMode ? 'config' : 'mango'),
33
-
34
- '@cms': path.resolve(mangoRoot, 'src/cms'),
35
- '@config': path.resolve(userProjectRoot, legacyMode ? 'config' : 'mango'),
36
- '@settings': path.resolve(userProjectRoot, legacyMode ? 'config/config/settings.json' : 'mango/config/settings.json'),
37
- '@fields': path.resolve(mangoRoot, 'src/cms/1. build/fields'),
38
- '@mongo': path.resolve(mangoRoot, 'src/cms/1. build/libraries/mongo'),
39
- '@query': path.resolve(mangoRoot, 'src/cms/1. build/libraries/mongo'),
40
- '@helpers': path.resolve(mangoRoot, 'src/cms/1. build/helpers'),
41
- '@main': path.resolve(mangoRoot, 'src/cms/2. process/0. main'),
42
- },
43
- },
44
- devtool: 'inline-source-map',
45
- entry: {
46
- server: path.resolve(mangoRoot, 'src/main.js'), // Entry point in @mango-cms/core
47
- },
48
- output: {
49
- path: path.resolve(buildPath, 'build'), // Change to build in mango directory
50
- filename: 'index.js',
51
- },
52
- target: 'node',
53
- plugins: [new NodemonPlugin()],
54
- node: {
55
- __dirname: false,
56
- __filename: false,
57
- },
58
- externals: [
59
- nodeExternals(),
60
- // Also check for externals in the mango package
61
- nodeExternals({
62
- modulesDir: path.resolve(moduleLocation, 'node_modules')
63
- })
64
- ],
65
- };