mango-cms 0.2.16 → 0.2.18

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
@@ -365,6 +365,7 @@ async function detectWebServer() {
365
365
  function generateNginxConfig(settings, buildPath) {
366
366
  const domain = settings.mangoDomain;
367
367
  const port = settings.port || 3002;
368
+ const frontPort = settings.frontPort || 3001;
368
369
 
369
370
  return `server {
370
371
  root ${buildPath};
@@ -392,7 +393,43 @@ function generateNginxConfig(settings, buildPath) {
392
393
  proxy_set_header X-Forwarded-Proto $scheme;
393
394
  proxy_pass http://localhost:${port};
394
395
  }
395
- }`;
396
+ }
397
+
398
+ server {
399
+ server_name ${settings.siteDomain};
400
+ root ${buildPath};
401
+ index index.html;
402
+
403
+ # Serve static files directly
404
+ location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf|json)$ {
405
+ expires 1y;
406
+ access_log off;
407
+ add_header Cache-Control "public";
408
+ try_files $uri =404;
409
+ }
410
+
411
+ ${settings.s3Bucket ? `location /s3/ {
412
+ proxy_pass https://${settings.s3Bucket}.s3.amazonaws.com/;
413
+ }
414
+ ` : ''}
415
+
416
+ location / {
417
+ try_files $uri $uri/ @fallback;
418
+ }
419
+
420
+ location @fallback {
421
+ proxy_http_version 1.1;
422
+ proxy_cache_bypass $http_upgrade;
423
+ proxy_set_header Upgrade $http_upgrade;
424
+ proxy_set_header Connection 'upgrade';
425
+ proxy_set_header Host $host;
426
+ proxy_set_header X-Real-IP $remote_addr;
427
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
428
+ proxy_set_header X-Forwarded-Proto $scheme;
429
+ proxy_pass http://localhost:${frontPort};
430
+ }
431
+ }
432
+ `;
396
433
  }
397
434
 
398
435
  // Helper function to generate apache config
@@ -425,7 +462,32 @@ function generateApacheConfig(settings, buildPath) {
425
462
 
426
463
  ErrorLog \${APACHE_LOG_DIR}/${domain}-error.log
427
464
  CustomLog \${APACHE_LOG_DIR}/${domain}-access.log combined
428
- </VirtualHost>`;
465
+ </VirtualHost>
466
+
467
+ <VirtualHost *:80>
468
+ ServerName ${settings.siteDomain}
469
+ DocumentRoot ${buildPath}
470
+ IndexIndex index.html
471
+
472
+ # Serve static files directly
473
+ <FilesMatch \.\.(?:js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf|json)$>
474
+ Header set Cache-Control "max-age=31536000"
475
+ </FilesMatch>
476
+
477
+ ${settings.s3Bucket ? `ProxyPass /s3/ https://${settings.s3Bucket}.s3.amazonaws.com/
478
+ ProxyPassReverse /s3/ https://${settings.s3Bucket}.s3.amazonaws.com/
479
+ ` : ''}
480
+
481
+ ProxyPass / http://localhost:${frontPort}/
482
+ ProxyPassReverse / http://localhost:${frontPort}/
483
+
484
+ RequestHeader set X-Forwarded-Proto "https"
485
+ RequestHeader set X-Forwarded-Port "443"
486
+
487
+ ErrorLog \${APACHE_LOG_DIR}/${settings.siteDomain}-error.log
488
+ CustomLog \${APACHE_LOG_DIR}/${settings.siteDomain}-access.log combined
489
+ </VirtualHost>
490
+ `;
429
491
  }
430
492
 
431
493
  // Helper function to configure web server
@@ -508,7 +570,7 @@ async function managePM2Process(settings) {
508
570
  execSync(`pm2 reload ${processName}`);
509
571
  } else {
510
572
  console.log(`Starting new PM2 process: ${processName}`);
511
- execSync(`pm2 start build/index.js --name ${processName}`);
573
+ execSync(`pm2 start index.js --name ${processName}`, { cwd: './build' });
512
574
  }
513
575
  } catch (error) {
514
576
  console.error('Error managing PM2 process:', error.message);
@@ -11,8 +11,8 @@ let startAutomations = function () {
11
11
 
12
12
  setInterval(() => {
13
13
 
14
- // Five hour timezone offset for DigitalOcean server
15
- let now = new Date(Date.now() - 1000 * 60 * 60 * 5)
14
+ // Optional timezone offset for server
15
+ // let now = new Date(Date.now() - 1000 * 60 * 60 * 5)
16
16
 
17
17
  let day = now.getDay()
18
18
  let weekday = days[day]
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "port": 6646,
3
+ "frontPort": 6645,
3
4
  "siteName": "Example",
4
5
  "siteDomain": "example.com",
5
6
  "mangoDomain": "api.example.com",
@@ -1,15 +1,17 @@
1
1
  const express = require('express');
2
2
  const fs = require('fs')
3
3
  const axios = require('axios')
4
- const settings = require('../../config/config/settings.json')
5
- const collections = require('../../config/config/.collections.json')
4
+ const settings = require('../mango/config/settings.json')
5
+ const collections = require('../mango/config/.collections.json')
6
6
 
7
- let port = 1337
7
+ let port = settings.frontPort
8
8
  let metaComment = '<!-- Inject Meta -->'
9
9
  let appPlaceholder = '<!--SSR-->'
10
10
 
11
11
  let serve = async function (req, res) {
12
12
 
13
+ let index = fs.readFileSync('./index.html', 'utf8')
14
+
13
15
  // Cookies
14
16
  let cookies
15
17
  const { headers: { cookie } } = req;
@@ -22,28 +24,27 @@ let serve = async function (req, res) {
22
24
  }
23
25
 
24
26
  // User Data Injection
25
- let index = fs.readFileSync('./index.html', 'utf8')
26
- let authorization = cookies?.Authorization
27
+ let authorization = req?.query?.token || cookies?.Authorization
27
28
  if (authorization) {
28
-
29
- let hash = authorization.split(':')[0]
30
29
  let userId = authorization.split(':')[1]
31
- let user = (await axios.get(`http://localhost:${settings.port}/members?search={"password.hash": "${hash}", "id": "${userId}"}`, { headers: { 'Authorization': authorization } }))
32
- user = user?.data?.response?.[0]
30
+ console.log('authorization', authorization)
31
+ console.log('userId', userId)
32
+ let user = await axios.get(`http://localhost:${settings.port}/members/${userId}`, { headers: { authorization } })
33
+ user = user?.data?.response
34
+ console.log('user', user)
33
35
  if (user) index = index.replace('window.user = null;', `window.user = ${JSON.stringify(user)};`)
34
-
35
36
  }
36
37
 
37
38
  // Define the collection and ID
38
39
  let collection = req.path.split('/')[1]
39
40
  let id = req.path.split('/')[2] ? req.path.split('/')[2] : null
40
41
 
41
- console.log('collection', collection)
42
- console.log('id', id)
42
+ // console.log('collection', collection)
43
+ // console.log('id', id)
43
44
 
44
45
  let entry = (await axios.get(`http://localhost:${settings.port}/${collection}/${id}`))?.data?.response
45
46
 
46
- console.log('entry', entry)
47
+ // console.log('entry', entry)
47
48
 
48
49
  if (!entry) return res.send(index)
49
50
 
@@ -60,14 +60,15 @@ let oldQuery = JSON.stringify(props.query || {})
60
60
  let inferedId = computed(() => props.id !== undefined ? props.id : props.query?.id || route?.params?.id || null )
61
61
  let searchingAlgolia = computed(() => !!props.algoliaSearch || !!props.algoliaFilters )
62
62
 
63
- let timer;
64
- let debounceInit = (...args) => {
65
- console.log('debouncing')
66
- if (active.value === false || props.disabled) return
67
- loading.value = true
68
- clearTimeout(timer);
69
- timer = setTimeout(() => { init.apply(this, args); }, props.debounce);
70
- };
63
+ let debounceInit = computed(() => {
64
+ let timer;
65
+ return (...args) => {
66
+ if (active.value === false || props.disabled) return
67
+ loading.value = true
68
+ clearTimeout(timer);
69
+ timer = setTimeout(() => { init.apply(this, args); }, props.debounce);
70
+ };
71
+ })
71
72
 
72
73
  watch(() => props.query, (n, o) => {
73
74
  let newQuery = JSON.stringify(n)
@@ -76,8 +77,8 @@ watch(() => props.query, (n, o) => {
76
77
 
77
78
  watch(inferedId, (n, o) => defer(null, null, 'id'))
78
79
  watch(() => props.collection, (n, o) => defer(null, null, 'collection'))
79
- watch(() => props.algoliaSearch, (n, o) => searchingAlgolia.value ? debounceInit() : init())
80
- watch(() => props.algoliaFilters, (n, o) => searchingAlgolia.value ? debounceInit() : init())
80
+ watch(() => props.algoliaSearch, (n, o) => searchingAlgolia.value ? debounceInit.value() : init())
81
+ watch(() => props.algoliaFilters, (n, o) => searchingAlgolia.value ? debounceInit.value() : init())
81
82
  watch(loading, (n, o) => emit('update:loading', loading.value))
82
83
  watch(data, () => {
83
84
  if (data?.value?.length && props.query?.limit && data?.value?.length < props.query?.limit) noneRemain.value = true
@@ -89,7 +90,7 @@ function defer(n,o,origin) {
89
90
  console.log('n,o,origin', n,o,origin)
90
91
  if (n == o && origin == 'query') return console.log(`they're the same...`)
91
92
  if (origin == 'query') oldQuery = n
92
- nextTick(() => debounceInit())
93
+ nextTick(() => debounceInit.value())
93
94
  }
94
95
 
95
96
  async function loadMore() {
@@ -110,6 +111,7 @@ async function loadMore() {
110
111
  } else {
111
112
  var nextPage = await Mango[inferedCollection.value](query)
112
113
  }
114
+ nextPage = nextPage?.response || nextPage
113
115
  if (nextPage.length) data.value = data.value.concat(nextPage)
114
116
  if (!nextPage.length || (query.limit && nextPage.length < query.limit)) noneRemain.value = true
115
117
  loadingPage.value = false
@@ -189,6 +191,10 @@ async function init() {
189
191
  if (id) data.value = await Mango[collection](id, query)
190
192
  else data.value = await Mango[collection](query)
191
193
 
194
+ if (data.value?.count) emit('totalResults', data.value.count)
195
+
196
+ data.value = data.value?.response || data.value
197
+
192
198
  emit('update:data', data.value)
193
199
  loading.value = false
194
200
 
@@ -24,34 +24,63 @@ if (process.env.NODE_ENV != 'production' && useDevAPI) {
24
24
  ws = `ws://localhost:${port}/graphql`
25
25
  }
26
26
 
27
+ function getQuery(params) {
28
+
29
+ if (params.search != undefined)
30
+ params.search = JSON.stringify(params.search);
31
+ if (params.fields != undefined)
32
+ params.fields = JSON.stringify(params.fields);
33
+ if (params.sort != undefined) params.sort = JSON.stringify(params.sort);
34
+
35
+ const query =
36
+ Object.keys(params)
37
+ .filter((key) => params[key] != undefined)
38
+ ?.map(
39
+ (key) =>
40
+ `${encodeURIComponent(key)}=${encodeURIComponent(
41
+ params[key]
42
+ )}`
43
+ )
44
+ ?.join("&") || "";
45
+
46
+ return query
47
+ }
48
+
27
49
  const Mango = collections.reduce((a, c) => {
28
50
 
29
- let runQuery = ({ limit, page, search, fields, id, sort, depthLimit } = {}) => {
51
+ let runQuery = ({ limit, page, search, fields, id, sort, depthLimit, verbose } = {}) => {
30
52
 
31
53
  let fullQuery
32
54
 
33
-
34
- const params = { limit, page, search, fields, sort, depthLimit }
35
-
36
- if (params.search != undefined) params.search = JSON.stringify(params.search)
37
- if (params.fields != undefined) params.fields = JSON.stringify(params.fields)
38
- if (params.sort != undefined) params.sort = JSON.stringify(params.sort)
39
-
40
- const query = Object.keys(params)
41
- .filter(key => params[key] != undefined)
42
- ?.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
43
- ?.join('&') || ''
44
- // console.log(query)
55
+ const query = getQuery({ limit, page, search, fields, sort, depthLimit, verbose })
45
56
 
46
57
  fullQuery = `${api}/${c.name}/${id || ''}?${query}`
47
58
 
48
59
  let Authorization = window.localStorage.getItem('token')
49
60
 
50
61
  return new Promise((resolve, reject) => {
51
- axios.get(fullQuery, { headers: { Authorization } })
52
- .then(response => resolve(response?.data?.response))
53
- .catch(e => reject(e))
54
- })
62
+ // If it's a local entry
63
+ if (id && !isNaN(id)) {
64
+ id = Number(id);
65
+ let request = window.indexedDB.open(c.name, 1);
66
+ request.onsuccess = (e) => {
67
+ let db = e.target.result;
68
+ let transaction = db.transaction([c.name], "readwrite");
69
+ let store = transaction.objectStore(c.name);
70
+ let entryRequest = store.get(id);
71
+ entryRequest.onsuccess = (e) => {
72
+ let result = entryRequest.result;
73
+ if (result) resolve(result);
74
+ else reject("No entry found");
75
+ };
76
+ };
77
+ } else {
78
+ axios
79
+ .get(fullQuery, { headers: { Authorization } })
80
+ .then((response) => resolve(verbose ? response?.data : response?.data?.response))
81
+ .catch((e) => reject(e));
82
+ }
83
+ });
55
84
 
56
85
  }
57
86
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mango-cms",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
4
4
  "main": "./index.js",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -25,10 +25,10 @@
25
25
  "dev": "NODE_OPTIONS='--trace-warnings' npx webpack --watch --mode development"
26
26
  },
27
27
  "peerDependencies": {
28
- "vue": "^3.0.0",
29
- "vue-router": "^4.0.0",
28
+ "algoliasearch": "^4.10.3",
30
29
  "axios": "^0.21.4",
31
- "algoliasearch": "^4.10.3"
30
+ "vue": "^3.0.0",
31
+ "vue-router": "^4.0.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@vitejs/plugin-vue": "^4.0.0",
@@ -92,16 +92,16 @@
92
92
  "stream": "^0.0.2",
93
93
  "subscriptions-transport-ws": "^0.9.18",
94
94
  "util": "^0.12.3",
95
- "uuid": "^8.3.2",
95
+ "uuid": "3.4.0",
96
96
  "web": "^0.0.2",
97
97
  "webpack": "^5.10.0",
98
98
  "webpack-cli": "^5.1.4",
99
99
  "webpack-node-externals": "^2.5.2"
100
100
  },
101
101
  "optionalDependencies": {
102
+ "bufferutil": "^4.0.8",
102
103
  "kerberos": "^2.0.0",
103
104
  "snappy": "^7.2.2",
104
- "bufferutil": "^4.0.8",
105
105
  "utf-8-validate": "^6.0.4"
106
106
  }
107
107
  }