@vulkano/core 1.4.0 → 1.5.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.
@@ -1,3 +1,5 @@
1
+ /* global mongoose */
2
+
1
3
  /**
2
4
  * Server.js
3
5
  */
@@ -13,8 +15,10 @@ const helmet = require('helmet');
13
15
  const timeout = require('connect-timeout');
14
16
  const useragent = require('express-useragent');
15
17
  const cookieParser = require('cookie-parser');
16
- const { createClient } = require('redis');
17
- const { createAdapter } = require('@socket.io/redis-adapter');
18
+ const { createClient: socketRedis } = require('redis');
19
+ const socketMongoose = require('mongoose');
20
+ const { createAdapter: socketRedisAdapter } = require('@socket.io/redis-adapter');
21
+ const { createAdapter: socketMongoAdapter } = require('@socket.io/mongo-adapter');
18
22
 
19
23
  // Include all api controllers
20
24
  const AllControllers = require('include-all')({
@@ -35,568 +39,663 @@ const expressConfig = require('./express')();
35
39
  // Express Responses
36
40
  const responses = require('./responses');
37
41
 
38
- module.exports = {
42
+ module.exports = function loadServer() {
39
43
 
40
- routes: {},
44
+ return {
41
45
 
42
- start: async function loadServerApplication(cb) {
46
+ routes: {},
43
47
 
44
- // Get ENV Vars
45
- const {
46
- JWT_SECRET_KEY,
47
- COOKIES_SECRET_KEY
48
- } = process.env || {};
48
+ start: async function startServerApplication(cb) {
49
49
 
50
- const vulkano = express();
50
+ // Get ENV Vars
51
+ const {
52
+ JWT_SECRET_KEY,
53
+ COOKIES_SECRET_KEY
54
+ } = process.env || {};
51
55
 
52
- // Settings
53
- vulkano.enable('trust proxy');
56
+ const vulkano = express();
54
57
 
55
- // ---------------
56
- // PORT - File: app/config/express/settings.js
57
- // ---------------
58
- vulkano.set('port', expressConfig.port);
58
+ // Settings
59
+ vulkano.enable('trust proxy');
59
60
 
60
- // ---------------
61
- // MULTER - File: app/config/express/multer.js
62
- // ---------------
63
- const upload = multer(expressConfig.multer);
61
+ // ---------------
62
+ // PORT - File: app/config/express/settings.js
63
+ // ---------------
64
+ vulkano.set('port', expressConfig.port);
64
65
 
65
- // ---------------
66
- // MORGAN - File: app/config/express/morgan.js
67
- // ---------------
68
- vulkano.use(morgan(expressConfig.morgan.format, expressConfig.morgan));
66
+ // ---------------
67
+ // MULTER - File: app/config/express/multer.js
68
+ // ---------------
69
+ const upload = multer(expressConfig.multer);
69
70
 
70
- // ---------------
71
- // USER AGENT
72
- // ---------------
73
- vulkano.use(useragent.express());
71
+ // ---------------
72
+ // MORGAN - File: app/config/express/morgan.js
73
+ // ---------------
74
+ vulkano.use(morgan(expressConfig.morgan.format, expressConfig.morgan));
74
75
 
75
- // ---------------
76
- // COMPRESSION - File: app/config/express/compression.js
77
- // ---------------
78
- vulkano.use(compression( expressConfig.compression || {} ));
76
+ // ---------------
77
+ // USER AGENT
78
+ // ---------------
79
+ vulkano.use(useragent.express());
79
80
 
80
- // ---------------
81
- // COOKIES - File: app/config/express/cookies.js
82
- // ---------------
83
- if (expressConfig.cookies && expressConfig.cookies.enabled) {
84
- const cookiesSecretKey = COOKIES_SECRET_KEY || expressConfig.cookies.key || expressConfig.cookies.secret || '';
85
- if (!cookiesSecretKey) {
86
- console.log(' \x1b[33mWARNING\x1b[0m: Set the secret key in the config/express/cookie.js file or COOKIES_SECRET_KEY in the .env file.');
87
- }
88
- vulkano.use(cookieParser(cookiesSecretKey));
89
- }
81
+ // ---------------
82
+ // COMPRESSION - File: app/config/express/compression.js
83
+ // ---------------
84
+ vulkano.use(compression( expressConfig.compression || {} ));
90
85
 
91
- // ---------------
92
- // EXPRESS JSON - File: app/config/express/json.js
93
- // ---------------
94
- vulkano.use(express.json(expressConfig.json));
95
-
96
- // ---------------
97
- // EXPRESS FORM DATA - File: app/config/express/urlencoded.js
98
- // ---------------
99
- vulkano.use(express.urlencoded(expressConfig.urlencoded));
100
-
101
- // ---------------
102
- // HELMET - File: app/config/express/helmet.js
103
- // ---------------
104
- vulkano.use(helmet(expressConfig.helmet));
105
-
106
- // ---------------
107
- // RESPONSES
108
- // ---------------
109
- vulkano.use(responses);
110
-
111
- // ---------------
112
- // FRAMEGUARD - File: app/config/express/frameguard.js
113
- // ---------------
114
- if (expressConfig.frameguard) {
115
- if (Array.isArray(expressConfig.frameguard)) {
116
- expressConfig.frameguard.forEach( (frame) => {
117
- vulkano.use(frameguard(frame));
118
- });
119
- } else {
120
- vulkano.use(frameguard(expressConfig.frameguard));
86
+ // ---------------
87
+ // COOKIES - File: app/config/express/cookies.js
88
+ // ---------------
89
+ if (expressConfig.cookies && expressConfig.cookies.enabled) {
90
+ const cookiesSecretKey = COOKIES_SECRET_KEY || expressConfig.cookies.key || expressConfig.cookies.secret || '';
91
+ if (!cookiesSecretKey) {
92
+ console.log(' \x1b[33mWARNING\x1b[0m: Set the secret key in the config/express/cookie.js file or COOKIES_SECRET_KEY in the .env file.');
93
+ }
94
+ vulkano.use(cookieParser(cookiesSecretKey));
121
95
  }
122
- }
123
-
124
- // ---------------
125
- // PROTOCOL & POWERED BY - File: app/config/settings.js
126
- // ---------------
127
- vulkano.use( (req, res, next) => {
128
96
 
129
- const proto = req.secure ? 'https' : 'http';
130
- const forwarded = req.headers['x-forwaded-proto'] || null;
131
- const currentProtocol = (forwarded || proto).split('://')[0];
132
- req.protocol = currentProtocol;
133
-
134
- if (expressConfig.poweredBy) {
135
- res.setHeader('X-Powered-By', expressConfig.poweredBy);
136
- }
97
+ // ---------------
98
+ // EXPRESS JSON - File: app/config/express/json.js
99
+ // ---------------
100
+ vulkano.use(express.json(expressConfig.json));
137
101
 
138
- next();
102
+ // ---------------
103
+ // EXPRESS FORM DATA - File: app/config/express/urlencoded.js
104
+ // ---------------
105
+ vulkano.use(express.urlencoded(expressConfig.urlencoded));
139
106
 
140
- });
107
+ // ---------------
108
+ // HELMET - File: app/config/express/helmet.js
109
+ // ---------------
110
+ vulkano.use(helmet(expressConfig.helmet));
141
111
 
142
- // ---------------
143
- // REQUEST OPTIONS - File: app/config/express/cors.js
144
- // ---------------
145
- vulkano.options('*', (req, res) => {
112
+ // ---------------
113
+ // RESPONSES
114
+ // ---------------
115
+ vulkano.use(responses);
146
116
 
147
117
  // ---------------
148
- // CORS
118
+ // FRAMEGUARD - File: app/config/express/frameguard.js
149
119
  // ---------------
150
- if (expressConfig.cors && expressConfig.cors.enabled) {
151
- let tmpCustomHeaders = ['X-Requested-With', 'X-HTTP-Method-Override', 'Content-Type', 'Accept'];
152
- tmpCustomHeaders = tmpCustomHeaders.concat(expressConfig.cors.headers || []);
153
- res.header('Access-Control-Allow-Origin', expressConfig.cors.origin);
154
- res.header('Access-Control-Allow-Headers', tmpCustomHeaders.join(', '));
155
- } else {
156
- res.header('Access-Control-Allow-Origin', '*');
157
- res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
120
+ if (expressConfig.frameguard) {
121
+ if (Array.isArray(expressConfig.frameguard)) {
122
+ expressConfig.frameguard.forEach( (frame) => {
123
+ vulkano.use(frameguard(frame));
124
+ });
125
+ } else {
126
+ vulkano.use(frameguard(expressConfig.frameguard));
127
+ }
158
128
  }
159
- res.header('Allow', 'GET,PUT,POST,DELETE,OPTIONS');
160
- res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
161
129
 
162
- res.status(200).end();
130
+ // ---------------
131
+ // PROTOCOL & POWERED BY - File: app/config/settings.js
132
+ // ---------------
133
+ vulkano.use( (req, res, next) => {
163
134
 
164
- });
135
+ const proto = req.secure ? 'https' : 'http';
136
+ const forwarded = req.headers['x-forwaded-proto'] || null;
137
+ const currentProtocol = (forwarded || proto).split('://')[0];
138
+ req.protocol = currentProtocol;
165
139
 
166
- // ---------------
167
- // TIMEOUT - File: app/config/settings.js
168
- // ---------------
169
- vulkano.use(timeout( expressConfig.timeout || 120000 ));
140
+ if (expressConfig.poweredBy) {
141
+ res.setHeader('X-Powered-By', expressConfig.poweredBy);
142
+ }
170
143
 
171
- vulkano.use( (req, res, next) => {
172
- if (!req.timedout) {
173
144
  next();
174
- }
175
- });
176
145
 
177
- // ---------------
178
- // JWT - File: app/config/express/jwt.js
179
- // ---------------
180
- if (expressConfig.jwt && expressConfig.jwt.enabled) {
146
+ });
181
147
 
182
- const jwtSecretKey = JWT_SECRET_KEY || expressConfig.jwt.key || expressConfig.jwt.secret || '';
183
- if (!jwtSecretKey) {
184
- console.log(' \x1b[41mERROR\x1b[0m: Can not get key in config/express/jwt.js file or JWT_SECRET_KEY in .env file');
185
- return;
186
- }
148
+ // ---------------
149
+ // REQUEST OPTIONS - File: app/config/express/cors.js
150
+ // ---------------
151
+ vulkano.options('*', (req, res) => {
152
+
153
+ // ---------------
154
+ // CORS
155
+ // ---------------
156
+ if (expressConfig.cors && expressConfig.cors.enabled) {
157
+ let tmpCustomHeaders = ['X-Requested-With', 'X-HTTP-Method-Override', 'Content-Type', 'Accept'];
158
+ tmpCustomHeaders = tmpCustomHeaders.concat(expressConfig.cors.headers || []);
159
+ res.header('Access-Control-Allow-Origin', expressConfig.cors.origin);
160
+ res.header('Access-Control-Allow-Headers', tmpCustomHeaders.join(', '));
161
+ } else {
162
+ res.header('Access-Control-Allow-Origin', '*');
163
+ res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
164
+ }
165
+ res.header('Allow', 'GET,PUT,POST,DELETE,OPTIONS');
166
+ res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
187
167
 
188
- // JWT (secret key)
189
- vulkano.use(expressConfig.jwt.path || '*', jwtMiddleware.init().unless({
190
- path: expressConfig.jwt.ignore || []
191
- }));
168
+ res.status(200).end();
192
169
 
193
- // JWT Handler error
194
- vulkano.use((err, req, res, next) => {
195
- if (err && err.name === 'UnauthorizedError') {
196
- res.status(401).jsonp({ success: false, error: 'Invalid token' });
197
- } else {
170
+ });
171
+
172
+ // ---------------
173
+ // TIMEOUT - File: app/config/settings.js
174
+ // ---------------
175
+ vulkano.use(timeout( expressConfig.timeout || 120000 ));
176
+
177
+ vulkano.use( (req, res, next) => {
178
+ if (!req.timedout) {
198
179
  next();
199
180
  }
200
181
  });
201
182
 
202
- }
183
+ // ---------------
184
+ // JWT - File: app/config/express/jwt.js
185
+ // ---------------
186
+ if (expressConfig.jwt && expressConfig.jwt.enabled) {
203
187
 
204
- // ---------------
205
- // CORS - File: app/config/express/cors.js
206
- // ---------------
207
- if (expressConfig.cors && expressConfig.cors.enabled) {
188
+ const jwtSecretKey = JWT_SECRET_KEY || expressConfig.jwt.key || expressConfig.jwt.secret || '';
189
+ if (!jwtSecretKey) {
190
+ console.log(' \x1b[41mERROR\x1b[0m: Can not get key in config/express/jwt.js file or JWT_SECRET_KEY in .env file');
191
+ return;
192
+ }
208
193
 
209
- vulkano.use(expressConfig.cors.path, (req, res, next) => {
194
+ // JWT (secret key)
195
+ vulkano.use(expressConfig.jwt.path || '*', jwtMiddleware.init().unless({
196
+ path: expressConfig.jwt.ignore || []
197
+ }));
198
+
199
+ // JWT Handler error
200
+ vulkano.use((err, req, res, next) => {
201
+ if (err && err.name === 'UnauthorizedError') {
202
+ res.status(401).jsonp({ success: false, error: 'Invalid token' });
203
+ } else {
204
+ next();
205
+ }
206
+ });
210
207
 
211
- // Enable CORS.
212
- let tmpCorsHeaders = ['X-Requested-With', 'X-HTTP-Method-Override', 'Content-Type', 'Accept'];
213
- tmpCorsHeaders = tmpCorsHeaders.concat(expressConfig.cors.headers || []);
208
+ }
214
209
 
215
- res.header('Access-Control-Allow-Origin', expressConfig.cors.origin);
216
- res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
217
- res.header('Access-Control-Allow-Headers', tmpCorsHeaders.join(', '));
210
+ // ---------------
211
+ // CORS - File: app/config/express/cors.js
212
+ // ---------------
213
+ if (expressConfig.cors && expressConfig.cors.enabled) {
218
214
 
219
- // Disable CACHE in API resources.
220
- res.header('Cache-Control', 'no-cache, no-store, must-revalidate'); // HTTP 1.1.
221
- res.header('Pragma', 'no-cache'); // HTTP 1.0.
222
- res.header('Expires', '0'); // Proxies.
215
+ vulkano.use(expressConfig.cors.path, (req, res, next) => {
223
216
 
224
- next();
217
+ // Enable CORS.
218
+ let tmpCorsHeaders = ['X-Requested-With', 'X-HTTP-Method-Override', 'Content-Type', 'Accept'];
219
+ tmpCorsHeaders = tmpCorsHeaders.concat(expressConfig.cors.headers || []);
225
220
 
226
- });
227
- }
221
+ res.header('Access-Control-Allow-Origin', expressConfig.cors.origin);
222
+ res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
223
+ res.header('Access-Control-Allow-Headers', tmpCorsHeaders.join(', '));
224
+
225
+ // Disable CACHE in API resources.
226
+ res.header('Cache-Control', 'no-cache, no-store, must-revalidate'); // HTTP 1.1.
227
+ res.header('Pragma', 'no-cache'); // HTTP 1.0.
228
+ res.header('Expires', '0'); // Proxies.
229
+
230
+ next();
231
+
232
+ });
233
+ }
228
234
 
229
- // ---------------
230
- // VIEWS
231
- // ---------------
235
+ // ---------------
236
+ // VIEWS
237
+ // ---------------
232
238
 
233
- const views = {
234
- ...viewsConfig,
235
- ...(app.server.views || {})
236
- };
239
+ const views = {
240
+ ...viewsConfig,
241
+ ...(app.server.views || {})
242
+ };
237
243
 
238
- vulkano.set('views', views.path);
244
+ vulkano.set('views', views.path);
239
245
 
240
- const {
241
- settings: nunjucksSettingsUser
242
- } = views || {};
246
+ const {
247
+ settings: nunjucksSettingsUser
248
+ } = views || {};
243
249
 
244
- const nunjucksSettings = {
245
- autoescape: true,
246
- watch: !app.PRODUCTION,
247
- ...(nunjucksSettingsUser || {}),
248
- express: vulkano
249
- };
250
+ const nunjucksSettings = {
251
+ autoescape: true,
252
+ watch: !app.PRODUCTION,
253
+ ...(nunjucksSettingsUser || {}),
254
+ express: vulkano
255
+ };
250
256
 
251
- const envNunjucks = nunjucks.configure(views.path, nunjucksSettings);
257
+ const envNunjucks = nunjucks.configure(views.path, nunjucksSettings);
252
258
 
253
- app.server.views._engine = envNunjucks;
259
+ app.server.views._engine = envNunjucks;
254
260
 
255
- envNunjucks.addGlobal('app', app);
261
+ envNunjucks.addGlobal('app', app);
256
262
 
257
- if (views.globals && Array.isArray(views.globals)) {
258
- views.globals.forEach((global) => {
259
- Object.keys(global || []).forEach((i) => {
260
- envNunjucks.addGlobal(i, global[i]);
263
+ if (views.globals && Array.isArray(views.globals)) {
264
+ views.globals.forEach((global) => {
265
+ Object.keys(global || []).forEach((i) => {
266
+ envNunjucks.addGlobal(i, global[i]);
267
+ });
261
268
  });
262
- });
263
- }
269
+ }
264
270
 
265
- if (views.helpers && Array.isArray(views.helpers)) {
266
- views.helpers.forEach((helper) => {
267
- Object.keys(helper || []).forEach((i) => {
268
- envNunjucks.addGlobal(i, helper[i]);
271
+ if (views.helpers && Array.isArray(views.helpers)) {
272
+ views.helpers.forEach((helper) => {
273
+ Object.keys(helper || []).forEach((i) => {
274
+ envNunjucks.addGlobal(i, helper[i]);
275
+ });
269
276
  });
270
- });
271
- }
277
+ }
272
278
 
273
- if (views.filters && Array.isArray(views.filters)) {
274
- views.filters.forEach((filter) => {
275
- Object.keys(filter || []).forEach((i) => {
276
- envNunjucks.addFilter(i, filter[i]);
279
+ if (views.filters && Array.isArray(views.filters)) {
280
+ views.filters.forEach((filter) => {
281
+ Object.keys(filter || []).forEach((i) => {
282
+ envNunjucks.addFilter(i, filter[i]);
283
+ });
277
284
  });
278
- });
279
- }
285
+ }
280
286
 
281
- if (views.extensions && Array.isArray(views.extensions)) {
282
- views.extensions.forEach((extension) => {
283
- Object.keys(extension || []).forEach((i) => {
284
- envNunjucks.addExtension(i, extension[i]);
287
+ if (views.extensions && Array.isArray(views.extensions)) {
288
+ views.extensions.forEach((extension) => {
289
+ Object.keys(extension || []).forEach((i) => {
290
+ envNunjucks.addExtension(i, extension[i]);
291
+ });
285
292
  });
286
- });
287
- }
293
+ }
288
294
 
289
- app.nunjucks = nunjucks;
295
+ app.nunjucks = nunjucks;
296
+
297
+ // ---------------
298
+ // Middlewares
299
+ // ---------------
290
300
 
291
- // ---------------
292
- // Middlewares
293
- // ---------------
301
+ // Middleware File (compatibility)
302
+ const middleware = app.config.middleware || ((req, res, next) => {
303
+ next();
304
+ });
294
305
 
295
- // Middleware File (compatibility)
296
- const middleware = app.config.middleware || ((req, res, next) => {
297
- next();
298
- });
306
+ // Middleware Folder
307
+ const middlewares = app.config.middlewares || {};
299
308
 
300
- // Middleware Folder
301
- const middlewares = app.config.middlewares || {};
309
+ Object.keys(middlewares).forEach( (item) => {
310
+ const middlewareFunction = middlewares[item];
311
+ if (typeof middlewareFunction === 'function') {
312
+ vulkano.use(middlewareFunction);
313
+ }
314
+ });
302
315
 
303
- Object.keys(middlewares).forEach( (item) => {
304
- const middlewareFunction = middlewares[item];
305
- if (typeof middlewareFunction === 'function') {
306
- vulkano.use(middlewareFunction);
316
+ // ---------------
317
+ // PUBLIC PATH - File: app/config/settings.js
318
+ // (if are using Vite)
319
+ // ---------------
320
+ if (!app.viteProxy) {
321
+ vulkano.use(express.static(PUBLIC_PATH));
307
322
  }
308
- });
309
-
310
- // ---------------
311
- // PUBLIC PATH - File: app/config/settings.js
312
- // (if are using Vite)
313
- // ---------------
314
- if (!app.viteProxy) {
315
- vulkano.use(express.static(PUBLIC_PATH));
316
- }
317
323
 
318
- // ---------------
319
- // ROUTES
320
- // ---------------
324
+ // ---------------
325
+ // ROUTES
326
+ // ---------------
321
327
 
322
- const {
323
- routes
324
- } = app;
328
+ const {
329
+ routes
330
+ } = app;
325
331
 
326
- let method;
327
- let pathToRoute;
328
- let handler;
332
+ let method;
333
+ let pathToRoute;
334
+ let handler;
329
335
 
330
- Object.keys(routes).forEach((route) => {
336
+ Object.keys(routes).forEach((route) => {
331
337
 
332
- const parts = route.split(' ');
338
+ const parts = route.split(' ');
333
339
 
334
- const [
335
- methodToRun,
336
- pathToRun
337
- ] = parts;
340
+ const [
341
+ methodToRun,
342
+ pathToRun
343
+ ] = parts;
338
344
 
339
- method = methodToRun;
345
+ method = methodToRun;
340
346
 
341
- if (pathToRun) {
342
- pathToRoute = pathToRun;
343
- }
347
+ if (pathToRun) {
348
+ pathToRoute = pathToRun;
349
+ }
344
350
 
345
- handler = routes[route];
351
+ handler = routes[route];
346
352
 
347
- if (method === 'post') {
348
- vulkano[method](pathToRoute, upload.any(), middleware, handler);
349
- } else {
350
- vulkano[method](pathToRoute, middleware, handler);
351
- }
353
+ if (method === 'post') {
354
+ vulkano[method](pathToRoute, upload.any(), middleware, handler);
355
+ } else {
356
+ vulkano[method](pathToRoute, middleware, handler);
357
+ }
352
358
 
353
- });
359
+ });
354
360
 
355
- Object.keys(this.routes || {}).forEach((i) => {
361
+ Object.keys(this.routes || {}).forEach((i) => {
356
362
 
357
- const fullPath = this.routes[i].split('.');
363
+ const fullPath = this.routes[i].split('.');
358
364
 
359
- const [
360
- moduleToRun,
361
- controllerToRun,
362
- actionToRun
363
- ] = fullPath;
365
+ const [
366
+ moduleToRun,
367
+ controllerToRun,
368
+ actionToRun
369
+ ] = fullPath;
364
370
 
365
- let module;
366
- let controller;
367
- let action;
371
+ let module;
372
+ let controller;
373
+ let action;
368
374
 
369
- if (actionToRun) { // Has folder
370
- module = moduleToRun;
371
- controller = controllerToRun;
372
- action = actionToRun;
373
- } else {
374
- module = null;
375
- controller = moduleToRun;
376
- action = controllerToRun;
377
- }
375
+ if (actionToRun) { // Has folder
376
+ module = moduleToRun;
377
+ controller = controllerToRun;
378
+ action = actionToRun;
379
+ } else {
380
+ module = null;
381
+ controller = moduleToRun;
382
+ action = controllerToRun;
383
+ }
378
384
 
379
- const parts = i.split(' ');
380
- const pathToRun = parts.pop();
381
- let option = (parts[0] !== undefined) ? parts[0].toLowerCase() : 'get';
382
- if (option !== 'get' && option !== 'post' && option !== 'put' && option !== 'delete') {
383
- option = 'get';
384
- }
385
+ const parts = i.split(' ');
386
+ const pathToRun = parts.pop();
387
+ let option = (parts[0] !== undefined) ? parts[0].toLowerCase() : 'get';
388
+ if (option !== 'get' && option !== 'post' && option !== 'put' && option !== 'delete') {
389
+ option = 'get';
390
+ }
385
391
 
386
- let toExecute = null;
392
+ let toExecute = null;
387
393
 
388
- try {
389
- toExecute = module
390
- ? (AllControllers[module][controller][action])
391
- : AllControllers[controller][action];
392
- } catch (e) {
393
- toExecute = null;
394
- }
394
+ try {
395
+ toExecute = module
396
+ ? (AllControllers[module][controller][action])
397
+ : AllControllers[controller][action];
398
+ } catch (e) {
399
+ toExecute = null;
400
+ }
395
401
 
396
- if (toExecute) {
397
- if (option === 'post') {
398
- vulkano[option](pathToRun || '/', upload.any(), middleware, toExecute);
402
+ if (toExecute) {
403
+ if (option === 'post') {
404
+ vulkano[option](pathToRun || '/', upload.any(), middleware, toExecute);
405
+ } else {
406
+ vulkano[option](pathToRun || '/', middleware, toExecute);
407
+ }
399
408
  } else {
400
- vulkano[option](pathToRun || '/', middleware, toExecute);
409
+ console.error('\x1b[31mError:', 'Controller not found in', (module) ? `${module}.${controller}.${action}` : `${controller}.${action}`, '\x1b[0m');
401
410
  }
402
- } else {
403
- console.error('\x1b[31mError:', 'Controller not found in', (module) ? `${module}.${controller}.${action}` : `${controller}.${action}`, '\x1b[0m');
404
- }
405
411
 
406
- });
412
+ });
413
+
414
+ const server = await vulkano.listen(expressConfig.port);
407
415
 
408
- const server = await vulkano.listen(expressConfig.port);
416
+ // ---------------
417
+ // ERROR 404
418
+ // ---------------
419
+ vulkano.use((req, res) => {
420
+ if (+res.statusCode >= 500 && +res.statusCode < 600) {
421
+ throw new Error();
422
+ }
423
+ res.status(404).render(`${views.path}/_shared/errors/404.html`);
424
+ });
409
425
 
410
- // ---------------
411
- // ERROR 404
412
- // ---------------
413
- vulkano.use((req, res) => {
414
- if (+res.statusCode >= 500 && +res.statusCode < 600) {
415
- throw new Error();
416
- }
417
- res.status(404).render(`${views.path}/_shared/errors/404.html`);
418
- });
419
-
420
- // ---------------
421
- // ERROR 5XX
422
- // ---------------
423
- vulkano.use((err, req, res) => {
424
- const status = err.status || res.statusCode || 500;
425
- res.status(status);
426
- if (!res.xhr) {
427
- if (+status > 400 && +status < 500) {
428
- res.render(`${vulkano.get('views')}/_shared/errors/404.html`, { content: err.stack });
426
+ // ---------------
427
+ // ERROR 5XX
428
+ // ---------------
429
+ vulkano.use((err, req, res) => {
430
+ const status = err.status || res.statusCode || 500;
431
+ res.status(status);
432
+ if (!res.xhr) {
433
+ if (+status > 400 && +status < 500) {
434
+ res.render(`${vulkano.get('views')}/_shared/errors/404.html`, { content: err.stack });
435
+ } else {
436
+ res.render(`${vulkano.get('views')}/_shared/errors/500.html`, { content: err.stack });
437
+ }
429
438
  } else {
430
- res.render(`${vulkano.get('views')}/_shared/errors/500.html`, { content: err.stack });
439
+ res.jsonp({
440
+ success: false,
441
+ error: err.message || err.error || err.invalidAttributes || err.toString() || 'Object Not Found',
442
+ data: (app.PRODUCTION) ? {} : (err.stack || {})
443
+ });
431
444
  }
432
- } else {
433
- res.jsonp({
434
- success: false,
435
- error: err.message || err.error || err.invalidAttributes || err.toString() || 'Object Not Found',
436
- data: (app.PRODUCTION) ? {} : (err.stack || {})
437
- });
445
+ });
446
+
447
+ // ---------------
448
+ // PUBLIC PATH
449
+ // (if not are using Vite)
450
+ // ---------------
451
+ if (app.viteProxy) {
452
+ vulkano.use(express.static(PUBLIC_PATH));
438
453
  }
439
- });
440
-
441
- // ---------------
442
- // PUBLIC PATH
443
- // (if not are using Vite)
444
- // ---------------
445
- if (app.viteProxy) {
446
- vulkano.use(express.static(PUBLIC_PATH));
447
- }
448
454
 
449
- app.vulkano = vulkano;
450
- app.server = server;
455
+ app.vulkano = vulkano;
456
+ app.server = server;
451
457
 
452
- // ---------------
453
- // SOCKETS
454
- // ---------------
455
- const {
456
- sockets,
457
- redis
458
- } = expressConfig || {};
458
+ // ---------------
459
+ // SOCKETS
460
+ // ---------------
461
+ const {
462
+ sockets
463
+ } = expressConfig || {};
459
464
 
460
- if (!sockets || (sockets && !sockets.enabled)) {
461
- cb();
462
- return;
463
- }
465
+ if (!sockets || (sockets && !sockets.enabled)) {
466
+ cb();
467
+ return;
468
+ }
469
+
470
+ const {
471
+ config: socketsConfig
472
+ } = sockets;
473
+
474
+ const socketProps = {
475
+ ...(socketsConfig || {}),
476
+ pingTimeout: +socketsConfig.timeout || 4000,
477
+ pingInterval: +socketsConfig.interval || 2000,
478
+ transports: socketsConfig.transports || ['websocket', 'polling']
479
+ };
464
480
 
465
- const socketProps = {
466
- pingTimeout: +sockets.timeout || 4000,
467
- pingInterval: +sockets.interval || 2000,
468
- transports: sockets.transports || ['websocket', 'polling']
469
- };
470
-
471
- if (sockets.cors) {
472
- if (typeof sockets.cors === 'function') {
473
- socketProps.allowRequest = sockets.cors;
474
- } else if (typeof sockets.cors === 'string') {
475
- socketProps.cors = sockets.cors || '';
481
+ if (sockets.cors) {
482
+ if (typeof sockets.cors === 'function') {
483
+ socketProps.allowRequest = sockets.cors;
484
+ } else if (typeof sockets.cors === 'string') {
485
+ socketProps.cors = sockets.cors || '';
486
+ }
476
487
  }
477
- }
478
488
 
479
- if (sockets.redis && !redis.enabled) {
480
- throw new Error('Enable the Redis config "app/config/redis.js" to connect the sockets');
481
- }
489
+ const {
490
+ adapter
491
+ } = sockets;
482
492
 
483
- const io = new Server(server, socketProps);
493
+ const {
494
+ redis: redisAdapter,
495
+ mongodb: mongodbAdapter
496
+ } = sockets.adapters || {};
484
497
 
485
- let pubClient = null;
486
- let subClient = null;
498
+ if ( String(adapter).toLocaleLowerCase() === 'redis') {
487
499
 
488
- if (sockets.redis) {
500
+ const {
501
+ host,
502
+ port
503
+ } = redisAdapter || {};
489
504
 
490
- if (sockets.transports.includes('polling')) {
491
- throw new Error('To enable Sockets with Redis support, the transports must be set ¨websocket¨ only');
492
- }
505
+ if (!host || !port) {
506
+ throw new Error('Unable to connect to Redis. File: "app/config/sockets/adapters/redis.js" to connect the sockets');
507
+ }
493
508
 
494
- const propsToRedis = {
495
- host: redis.host,
496
- port: redis.port
497
- };
509
+ if (socketProps.transports.includes('polling')) {
510
+ throw new Error('To enable Sockets with Redis support, the transports must be set ¨websocket¨ only');
511
+ }
512
+
513
+ } else if ( String(adapter).toLocaleLowerCase() === 'mongodb') {
514
+
515
+ // if (socketProps.transports.includes('polling')) {
516
+ // eslint-disable-next-line max-len
517
+ // console.log('To enable Sockets with MongoDB support the transports must be set to ["websocket"] only');
518
+ // }
498
519
 
499
- if (redis.password) {
500
- propsToRedis.password = redis.password;
501
520
  }
502
521
 
503
- pubClient = createClient(propsToRedis);
504
- subClient = pubClient.duplicate();
522
+ const io = new Server(server, socketProps);
505
523
 
506
- io.adapter(createAdapter(pubClient, subClient));
524
+ let pubClient = null;
525
+ let subClient = null;
507
526
 
508
- }
527
+ if ( String(adapter).toLocaleLowerCase() === 'redis') {
528
+
529
+ const propsToRedis = {
530
+ host: redisAdapter.host,
531
+ port: redisAdapter.port
532
+ };
533
+
534
+ if (redisAdapter.password) {
535
+ propsToRedis.password = redisAdapter.password;
536
+ }
537
+
538
+ pubClient = socketRedis(propsToRedis);
539
+ subClient = pubClient.duplicate();
540
+
541
+ io.adapter(socketRedisAdapter(pubClient, subClient));
542
+
543
+ } else if ( String(adapter).toLocaleLowerCase() === 'mongodb') {
544
+
545
+ const {
546
+ settings: socketsMongoSettings
547
+ } = mongodbAdapter || {};
548
+
549
+ const socketsConnection = String(process.env.SOCKETS_MONGO_URI || mongodbAdapter.connection || '').trim();
550
+ let socketsDatabase = String(process.env.SOCKETS_MONGO_DATABASE || mongodbAdapter.database || '').trim();
551
+ const socketsCollection = String(process.env.SOCKETS_MONGO_COLLECTION || mongodbAdapter.collection || 'socket.io-adapter-events').trim();
552
+
553
+ let socketsMongoCollection = null;
509
554
 
510
- Promise
511
- .all([
512
- (sockets.redis ? pubClient.connect() : null),
513
- (sockets.redis ? subClient.connect() : null)
514
- ])
515
- .then(() => {
555
+ try {
516
556
 
517
- io.on('connection', (socket) => {
557
+ let mongoClientDB = null;
558
+
559
+ // if not has a mongo conection try to create it
560
+ if (!mongoose.connection.readyState) {
561
+
562
+ if (!socketsConnection) {
563
+ throw new Error('Unable to connecto to the database for SocketIO. Please check the env var SOCKETS_MONGO_URI and try again.');
564
+ }
565
+
566
+ const socketMongooseConnection = await socketMongoose.connect(socketsConnection);
567
+ mongoClientDB = socketMongooseConnection.connection.getClient();
568
+
569
+ } else {
570
+
571
+ // Get current connection
572
+ mongoClientDB = mongoose.connection.getClient();
573
+ socketsDatabase = mongoose.connection.db.s.namespace.db;
574
+
575
+ // SOCKETS_MONGO_URI
576
+ if (socketsConnection !== mongoClientDB.s.url) {
577
+
578
+ const socketMongoInstance = new socketMongoose.Mongoose();
579
+
580
+ const socketMongooseConnection = await socketMongoInstance.connect(socketsConnection);
581
+ mongoClientDB = socketMongooseConnection.connection.getClient();
582
+ socketsDatabase = socketMongoInstance.connection.db.s.namespace.db;
583
+
584
+ }
518
585
 
519
- if ( typeof sockets.onConnect === 'function') {
520
- sockets.onConnect(socket);
521
586
  }
522
587
 
523
- const socketEvents = sockets.events || {};
588
+ socketsMongoCollection = mongoClientDB.db(socketsDatabase).collection(socketsCollection);
524
589
 
525
- Object.keys(socketEvents).forEach( (i) => {
590
+ const propsToMongoCollection = {
591
+ expireAfterSeconds: 3600,
592
+ background: true,
593
+ ...(socketsMongoSettings || {})
594
+ };
526
595
 
527
- const checkPath = socketEvents[i] || '';
596
+ socketsMongoCollection.createIndex({ createdAt: 1 }, propsToMongoCollection);
528
597
 
529
- let toExecute = null;
530
- let module = null;
531
- let controller = null;
532
- let action = null;
598
+ } catch (err) {
599
+ console.log(err);
600
+ throw new Error('To enable Sockets with MongoDB support. Check the connection.');
601
+ }
533
602
 
534
- if (typeof checkPath === 'function') {
603
+ io.adapter(socketMongoAdapter(socketsMongoCollection, { addCreatedAtField: true }));
535
604
 
536
- toExecute = checkPath;
605
+ }
606
+
607
+ Promise
608
+ .all([
609
+ (sockets.redis ? pubClient.connect() : null),
610
+ (sockets.redis ? subClient.connect() : null)
611
+ ])
612
+ .then(() => {
613
+
614
+ io.on('connection', (socket) => {
615
+
616
+ if ( typeof sockets.onConnect === 'function') {
617
+ sockets.onConnect(socket);
618
+ }
619
+
620
+ const socketEvents = sockets.events || sockets.routes || {};
537
621
 
538
- } else {
622
+ Object.keys(socketEvents).forEach( (i) => {
539
623
 
540
- const fullPath = checkPath.split('.');
624
+ const checkPath = socketEvents[i] || '';
541
625
 
542
- if (fullPath.length > 2) { // Has folder
626
+ let toExecute = null;
627
+ let module = null;
628
+ let controller = null;
629
+ let action = null;
543
630
 
544
- [
545
- module,
546
- controller,
547
- action
548
- ] = fullPath;
631
+ if (typeof checkPath === 'function') {
632
+
633
+ toExecute = checkPath;
549
634
 
550
635
  } else {
551
636
 
552
- [
553
- controller,
554
- action
555
- ] = fullPath;
637
+ const fullPath = checkPath.split('.');
638
+
639
+ if (fullPath.length > 2) { // Has folder
640
+
641
+ [
642
+ module,
643
+ controller,
644
+ action
645
+ ] = fullPath;
646
+
647
+ } else {
648
+
649
+ [
650
+ controller,
651
+ action
652
+ ] = fullPath;
653
+
654
+ }
655
+
656
+ try {
657
+ toExecute = module
658
+ ? (AllControllers[module][controller][action])
659
+ : AllControllers[controller][action];
660
+ } catch (e) {
661
+ toExecute = null;
662
+ }
556
663
 
557
664
  }
558
665
 
559
- try {
560
- toExecute = module
561
- ? (AllControllers[module][controller][action])
562
- : AllControllers[controller][action];
563
- } catch (e) {
564
- toExecute = null;
666
+ if (toExecute) {
667
+ socket.on(i, (body) => {
668
+ toExecute({ socket, body: body || {} });
669
+ });
670
+ } else {
671
+ console.error('\x1b[31mError:', 'Controller not found in', (module) ? `${module}.${controller}.${action}` : `${controller}.${action}`, '\x1b[0m', 'to socket event', i);
565
672
  }
566
673
 
567
- }
674
+ });
568
675
 
569
- if (toExecute) {
570
- socket.on(i, (body) => {
571
- toExecute({ socket, body: body || {} });
572
- });
573
- } else {
574
- console.error('\x1b[31mError:', 'Controller not found in', (module) ? `${module}.${controller}.${action}` : `${controller}.${action}`, '\x1b[0m', 'to socket event', i);
575
- }
676
+ vulkano.set('socket', socket);
677
+ app.socket = socket;
576
678
 
577
679
  });
578
680
 
579
- vulkano.set('socket', socket);
580
- app.socket = socket;
581
-
582
- });
681
+ // next line is the money
682
+ global.io = io;
683
+ vulkano.set('socketio', io);
583
684
 
584
- // next line is the money
585
- global.io = io;
586
- vulkano.set('socketio', io);
685
+ // middleware
686
+ if (sockets.middleware && typeof sockets.middleware === 'function') {
687
+ io.use(sockets.middleware);
688
+ }
587
689
 
588
- // middleware
589
- if (sockets.middleware && typeof sockets.middleware === 'function') {
590
- io.use(sockets.middleware);
591
- }
690
+ // override vulkano
691
+ app.vulkano = vulkano;
592
692
 
593
- // override vulkano
594
- app.vulkano = vulkano;
693
+ cb();
595
694
 
596
- cb();
695
+ });
597
696
 
598
- });
697
+ }
599
698
 
600
- }
699
+ };
601
700
 
602
701
  };