@vulkano/core 1.1.0 → 1.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/app.js +47 -24
- package/bootstrap/express.js +82 -0
- package/bootstrap/server.js +91 -272
- package/bootstrap/views.js +27 -0
- package/controllers/ScaffoldController.js +29 -2
- package/controllers/controllers.js +4 -2
- package/package.json +1 -1
package/app.js
CHANGED
|
@@ -164,18 +164,41 @@ const colors = {
|
|
|
164
164
|
|
|
165
165
|
function startVulkano() {
|
|
166
166
|
|
|
167
|
+
const appName = appPkg.name.toUpperCase().split('-').join(' ');
|
|
168
|
+
const appVersion = appPkg.version;
|
|
169
|
+
const author = appPkg.author || pkg.author;
|
|
170
|
+
|
|
171
|
+
const lineWidth = 38;
|
|
172
|
+
|
|
173
|
+
const showCenteredText = (text) => {
|
|
174
|
+
|
|
175
|
+
const colSize = (lineWidth / 2) - 3;
|
|
176
|
+
const textLength = (text || '').length;
|
|
177
|
+
const textLeftSize = Math.trunc(textLength / 2);
|
|
178
|
+
const textRightSize = textLength - textLeftSize;
|
|
179
|
+
|
|
180
|
+
const textPaddingLeft = ''.padStart( colSize - textLeftSize, ' ');
|
|
181
|
+
const textPaddingRight = ''.padEnd( colSize - textRightSize, ' ');
|
|
182
|
+
const textCentered = `${textPaddingLeft}${text}${textPaddingRight}`;
|
|
183
|
+
|
|
184
|
+
return textCentered;
|
|
185
|
+
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const cutLine = '-'.padEnd(lineWidth, '-');
|
|
189
|
+
|
|
167
190
|
console.log('');
|
|
191
|
+
console.log(`${colors.fg.magenta}${cutLine}`, colors.reset);
|
|
168
192
|
console.log('');
|
|
169
|
-
console.log(
|
|
170
|
-
console.log(
|
|
171
|
-
console.log(colors.fg.cyan,
|
|
172
|
-
console.log(colors.fg.cyan, ` APP VERSION ${appPkg.version}`, colors.reset);
|
|
173
|
-
console.log(colors.fg.cyan, ` @VULKANO/CORE ${pkg.version}`, colors.reset);
|
|
193
|
+
console.log(colors.fg.cyan, showCenteredText('🌋'), colors.reset);
|
|
194
|
+
console.log(colors.fg.cyan, showCenteredText(`${appName} ${appVersion}`), colors.reset);
|
|
195
|
+
console.log(colors.fg.cyan, showCenteredText(`${pkg.name} ${pkg.version}`.toUpperCase()), colors.reset);
|
|
174
196
|
console.log('');
|
|
175
|
-
console.log(colors.fg.blue, '🔗
|
|
176
|
-
console.log(colors.fg.cyan, '☕
|
|
197
|
+
console.log(colors.fg.blue, '🔗 github.com/vulkanojs/vulkano', colors.reset);
|
|
198
|
+
console.log(colors.fg.cyan, '☕ buymeacoffee.com/argordmel', colors.reset);
|
|
177
199
|
console.log('');
|
|
178
|
-
console.log(
|
|
200
|
+
console.log(` Author: ${colors.fg.green}${author}${colors.reset}`);
|
|
201
|
+
console.log(`${colors.fg.magenta}${cutLine}`, colors.reset);
|
|
179
202
|
|
|
180
203
|
// Routes
|
|
181
204
|
app.routes = controllers;
|
|
@@ -219,18 +242,23 @@ function startVulkano() {
|
|
|
219
242
|
connection
|
|
220
243
|
} = database || {};
|
|
221
244
|
|
|
245
|
+
const showColumn = (text, titleLength) => {
|
|
246
|
+
const txt = `${text.padEnd( 16 - titleLength, ' ')}`;
|
|
247
|
+
return txt;
|
|
248
|
+
};
|
|
249
|
+
|
|
222
250
|
const connectionToShow = connection && process.env.MONGO_URI ? 'MONGO_URI' : connection;
|
|
223
251
|
|
|
224
252
|
const serverConfig = [];
|
|
225
253
|
|
|
226
254
|
const nodeVersion = process.version.match(/^v(\d+\.\d+\.\d+)/)[1];
|
|
227
|
-
const portText = String(app.
|
|
228
|
-
const socketText =
|
|
229
|
-
const redisText =
|
|
255
|
+
const portText = String(app.vulkano.get('port') || 8000);
|
|
256
|
+
const socketText = sockets.enabled ? 'YES' : 'NO';
|
|
257
|
+
const redisText = redis && redis.enabled ? 'YES' : 'NO';
|
|
230
258
|
|
|
231
|
-
serverConfig.push(` PORT: ${colors.fg.green}${portText}${colors.reset}`);
|
|
259
|
+
serverConfig.push(` PORT: ${colors.fg.green}${showColumn(portText, 7)}${colors.reset}`);
|
|
232
260
|
serverConfig.push(' | ');
|
|
233
|
-
serverConfig.push(` ENV: ${app.PRODUCTION ? colors.fg.red : colors.fg.green}${NODE_ENV}${colors.reset}`);
|
|
261
|
+
serverConfig.push(` ENV: ${app.PRODUCTION ? colors.fg.red : colors.fg.green}${showColumn(NODE_ENV, 0)}${colors.reset}`);
|
|
234
262
|
|
|
235
263
|
console.log(serverConfig.join(''));
|
|
236
264
|
|
|
@@ -238,29 +266,24 @@ function startVulkano() {
|
|
|
238
266
|
const totalHeapSizeGb = (totalHeapSize / 1024 / 1024 / 1024).toFixed(2);
|
|
239
267
|
|
|
240
268
|
const nodeConfig = [];
|
|
241
|
-
nodeConfig.push(` NODE: ${colors.fg.green}${nodeVersion}${colors.reset}`);
|
|
269
|
+
nodeConfig.push(` NODE: ${colors.fg.green}${showColumn(nodeVersion, 7)}${colors.reset}`);
|
|
242
270
|
nodeConfig.push(' | ');
|
|
243
271
|
nodeConfig.push(' MAX MEM: ', `${colors.fg.green}${totalHeapSizeGb} GB${colors.reset}`);
|
|
244
272
|
console.log(nodeConfig.join(''));
|
|
245
273
|
|
|
246
274
|
const startUpConfig = [];
|
|
247
|
-
startUpConfig.push(' SOCKETS: ', `${colors.fg.green}${socketText}${colors.reset}`);
|
|
275
|
+
startUpConfig.push(' SOCKETS: ', `${colors.fg.green}${showColumn(socketText, 10)}${colors.reset}`);
|
|
248
276
|
startUpConfig.push(' | ');
|
|
249
|
-
startUpConfig.push(` STARTUP: ${colors.fg.green}${moment(moment().diff(global.START_TIME)).format('
|
|
277
|
+
startUpConfig.push(` STARTUP: ${colors.fg.green}${moment(moment().diff(global.START_TIME)).format('s.SSS')}s${colors.reset}`);
|
|
250
278
|
console.log(startUpConfig.join(''));
|
|
251
279
|
|
|
252
280
|
const dbConfig = [];
|
|
253
|
-
|
|
254
|
-
dbConfig.push(' REDIS: ', `${colors.fg.green}${redisText}${colors.reset}`);
|
|
255
|
-
} else {
|
|
256
|
-
dbConfig.push(' REDIS: ', `${colors.fg.green}${redisText}${colors.reset}`);
|
|
257
|
-
}
|
|
258
|
-
|
|
281
|
+
dbConfig.push(' REDIS: ', `${colors.fg.green}${showColumn(redisText, 8)}${colors.reset}`);
|
|
259
282
|
dbConfig.push(' | ');
|
|
260
|
-
dbConfig.push(' DB: ', connection ? `${colors.fg.green}${connectionToShow}${colors.reset}` : `${colors.fg.blue}
|
|
283
|
+
dbConfig.push(' DB: ', connection ? `${colors.fg.green}${connectionToShow}${colors.reset}` : `${colors.fg.blue}NO DATABASE${colors.reset}`);
|
|
261
284
|
console.log(dbConfig.join(''));
|
|
262
285
|
|
|
263
|
-
console.log(`${colors.fg.magenta}
|
|
286
|
+
console.log(`${colors.fg.magenta}${cutLine}`, colors.reset);
|
|
264
287
|
|
|
265
288
|
// Run custom callback after init vulkano
|
|
266
289
|
if (callbackAfterInitVulkano && typeof callbackAfterInitVulkano === 'function') {
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const merge = require('deepmerge');
|
|
2
|
+
|
|
3
|
+
module.exports = function getExpressConfiguration() {
|
|
4
|
+
|
|
5
|
+
// Common config by filename
|
|
6
|
+
const {
|
|
7
|
+
cors,
|
|
8
|
+
jwt,
|
|
9
|
+
settings,
|
|
10
|
+
cookies,
|
|
11
|
+
// Folder express config files
|
|
12
|
+
express: expressServerConfig
|
|
13
|
+
} = app.config || {};
|
|
14
|
+
|
|
15
|
+
// express config by file in settings.js
|
|
16
|
+
const {
|
|
17
|
+
port: expressUserPort,
|
|
18
|
+
express: expressConfigInSettings
|
|
19
|
+
} = settings || {};
|
|
20
|
+
|
|
21
|
+
// express config by file in app/config/express/settings.js
|
|
22
|
+
const {
|
|
23
|
+
settings: expressGeneralSettings
|
|
24
|
+
} = expressServerConfig || {};
|
|
25
|
+
|
|
26
|
+
// express port via file in app/config/express/settings.js
|
|
27
|
+
const {
|
|
28
|
+
port: expressSettingsPort
|
|
29
|
+
} = expressGeneralSettings || {};
|
|
30
|
+
|
|
31
|
+
const {
|
|
32
|
+
NODE_PORT: ENV_NODE_PORT,
|
|
33
|
+
PORT: ENV_PORT
|
|
34
|
+
} = process.env || {};
|
|
35
|
+
|
|
36
|
+
// Express default configuration
|
|
37
|
+
const expressDefaultConfig = {
|
|
38
|
+
timeout: 120000,
|
|
39
|
+
poweredBy: false,
|
|
40
|
+
port: ENV_NODE_PORT || ENV_PORT || expressUserPort || expressSettingsPort || 8000,
|
|
41
|
+
cors: {},
|
|
42
|
+
cookies: {},
|
|
43
|
+
jwt: {},
|
|
44
|
+
multer: {
|
|
45
|
+
dest: 'public/files'
|
|
46
|
+
},
|
|
47
|
+
morgan: {
|
|
48
|
+
format: 'dev',
|
|
49
|
+
skip: ((req, res) => res.statusCode < 400)
|
|
50
|
+
},
|
|
51
|
+
compression: {},
|
|
52
|
+
json: {},
|
|
53
|
+
urlencoded: {
|
|
54
|
+
extended: true
|
|
55
|
+
},
|
|
56
|
+
helmet: {
|
|
57
|
+
contentSecurityPolicy: false,
|
|
58
|
+
crossOriginEmbedderPolicy: false
|
|
59
|
+
},
|
|
60
|
+
frameguard: null
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Merge all express configuration: config/file.js, config/express/file.js, config/settings.js
|
|
64
|
+
const expressConfig = merge.all([
|
|
65
|
+
{
|
|
66
|
+
cookies,
|
|
67
|
+
jwt,
|
|
68
|
+
cors
|
|
69
|
+
},
|
|
70
|
+
expressDefaultConfig || {},
|
|
71
|
+
expressServerConfig || {},
|
|
72
|
+
expressGeneralSettings || {},
|
|
73
|
+
expressConfigInSettings || {},
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
if (expressConfig && expressConfig.settings) {
|
|
77
|
+
delete expressConfig.settings;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return expressConfig;
|
|
81
|
+
|
|
82
|
+
};
|
package/bootstrap/server.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
const express = require('express');
|
|
6
6
|
const frameguard = require('frameguard');
|
|
7
|
-
const { Server } = require('socket.io');
|
|
7
|
+
// const { Server } = require('socket.io');
|
|
8
8
|
const nunjucks = require('nunjucks');
|
|
9
9
|
const morgan = require('morgan');
|
|
10
10
|
const compression = require('compression');
|
|
@@ -13,9 +13,8 @@ const helmet = require('helmet');
|
|
|
13
13
|
const timeout = require('connect-timeout');
|
|
14
14
|
const useragent = require('express-useragent');
|
|
15
15
|
const cookieParser = require('cookie-parser');
|
|
16
|
-
const
|
|
17
|
-
const {
|
|
18
|
-
const { createAdapter } = require('@socket.io/redis-adapter');
|
|
16
|
+
// const { createClient } = require('redis');
|
|
17
|
+
// const { createAdapter } = require('@socket.io/redis-adapter');
|
|
19
18
|
|
|
20
19
|
// Include all api controllers
|
|
21
20
|
const AllControllers = require('include-all')({
|
|
@@ -24,111 +23,31 @@ const AllControllers = require('include-all')({
|
|
|
24
23
|
optional: true
|
|
25
24
|
});
|
|
26
25
|
|
|
26
|
+
const viewsConfig = require('./views');
|
|
27
|
+
|
|
27
28
|
const responses = require('./responses');
|
|
28
29
|
|
|
29
30
|
const JWT = require('../libs/Jwt');
|
|
30
31
|
|
|
32
|
+
const expressConfig = require('./express')();
|
|
33
|
+
|
|
31
34
|
module.exports = {
|
|
32
35
|
|
|
33
36
|
routes: {},
|
|
34
37
|
|
|
35
|
-
start: function loadServerApplication(cb) {
|
|
38
|
+
start: async function loadServerApplication(cb) {
|
|
36
39
|
|
|
37
40
|
const jwtMiddleware = JWT;
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
const {
|
|
41
|
-
cors,
|
|
42
|
-
jwt,
|
|
43
|
-
settings,
|
|
44
|
-
sockets,
|
|
45
|
-
cookies,
|
|
46
|
-
redis,
|
|
47
|
-
// Folder express config files
|
|
48
|
-
express: expressServerConfig
|
|
49
|
-
} = app.config || {};
|
|
50
|
-
|
|
51
|
-
// express config by file in settings.js
|
|
52
|
-
const {
|
|
53
|
-
port: expressUserPort,
|
|
54
|
-
express: expressConfigInSettings
|
|
55
|
-
} = settings || {};
|
|
56
|
-
|
|
57
|
-
// express config by file in app/config/express/settings.js
|
|
58
|
-
const {
|
|
59
|
-
settings: expressGeneralSettings
|
|
60
|
-
} = expressServerConfig || {};
|
|
61
|
-
|
|
62
|
-
// express port via file in app/config/express/settings.js
|
|
63
|
-
const {
|
|
64
|
-
port: expressSettingsPort
|
|
65
|
-
} = expressGeneralSettings || {};
|
|
66
|
-
|
|
67
|
-
const {
|
|
68
|
-
NODE_PORT: ENV_NODE_PORT,
|
|
69
|
-
PORT: ENV_PORT
|
|
70
|
-
} = process.env || {};
|
|
71
|
-
|
|
72
|
-
// Express default configuration
|
|
73
|
-
const expressDefaultConfig = {
|
|
74
|
-
timeout: 120000,
|
|
75
|
-
poweredBy: false,
|
|
76
|
-
port: ENV_NODE_PORT || ENV_PORT || expressUserPort || expressSettingsPort || 8000,
|
|
77
|
-
cors: {},
|
|
78
|
-
cookies: {},
|
|
79
|
-
jwt: {},
|
|
80
|
-
multer: {
|
|
81
|
-
dest: 'public/files'
|
|
82
|
-
},
|
|
83
|
-
morgan: {
|
|
84
|
-
format: 'dev',
|
|
85
|
-
skip: ((req, res) => res.statusCode < 400)
|
|
86
|
-
},
|
|
87
|
-
compression: {},
|
|
88
|
-
json: {},
|
|
89
|
-
urlencoded: {
|
|
90
|
-
extended: true
|
|
91
|
-
},
|
|
92
|
-
helmet: {
|
|
93
|
-
contentSecurityPolicy: false,
|
|
94
|
-
crossOriginEmbedderPolicy: false
|
|
95
|
-
},
|
|
96
|
-
frameguard: null
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
// Merge all express configuration: config/file.js, config/express/file.js, config/settings.js
|
|
100
|
-
const expressConfig = merge.all([
|
|
101
|
-
{
|
|
102
|
-
cookies,
|
|
103
|
-
jwt,
|
|
104
|
-
cors
|
|
105
|
-
},
|
|
106
|
-
expressDefaultConfig || {},
|
|
107
|
-
expressServerConfig || {},
|
|
108
|
-
expressGeneralSettings || {},
|
|
109
|
-
expressConfigInSettings || {},
|
|
110
|
-
]);
|
|
111
|
-
|
|
112
|
-
if (expressConfig && expressConfig.settings) {
|
|
113
|
-
delete expressConfig.settings;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const views = app.server.views || {};
|
|
117
|
-
|
|
118
|
-
// Middleware
|
|
119
|
-
const middleware = app.config.middleware || ((req, res, next) => {
|
|
120
|
-
next();
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
const server = express();
|
|
42
|
+
const vulkano = express();
|
|
124
43
|
|
|
125
44
|
// Settings
|
|
126
|
-
|
|
45
|
+
vulkano.enable('trust proxy');
|
|
127
46
|
|
|
128
47
|
// ---------------
|
|
129
48
|
// PORT - File: app/config/express/settings.js
|
|
130
49
|
// ---------------
|
|
131
|
-
|
|
50
|
+
vulkano.set('port', expressConfig.port);
|
|
132
51
|
|
|
133
52
|
// ---------------
|
|
134
53
|
// MULTER - File: app/config/express/multer.js
|
|
@@ -138,17 +57,17 @@ module.exports = {
|
|
|
138
57
|
// ---------------
|
|
139
58
|
// MORGAN - File: app/config/express/morgan.js
|
|
140
59
|
// ---------------
|
|
141
|
-
|
|
60
|
+
vulkano.use(morgan(expressConfig.morgan.format, expressConfig.morgan));
|
|
142
61
|
|
|
143
62
|
// ---------------
|
|
144
63
|
// USER AGENT
|
|
145
64
|
// ---------------
|
|
146
|
-
|
|
65
|
+
vulkano.use(useragent.express());
|
|
147
66
|
|
|
148
67
|
// ---------------
|
|
149
68
|
// COMPRESSION - File: app/config/express/compression.js
|
|
150
69
|
// ---------------
|
|
151
|
-
|
|
70
|
+
vulkano.use(compression( expressConfig.compression || {} ));
|
|
152
71
|
|
|
153
72
|
// ---------------
|
|
154
73
|
// COOKIES - File: app/config/express/cookies.js
|
|
@@ -158,33 +77,28 @@ module.exports = {
|
|
|
158
77
|
if (!cookiesSecretKey) {
|
|
159
78
|
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.');
|
|
160
79
|
}
|
|
161
|
-
|
|
80
|
+
vulkano.use(cookieParser(cookiesSecretKey));
|
|
162
81
|
}
|
|
163
82
|
|
|
164
83
|
// ---------------
|
|
165
84
|
// EXPRESS JSON - File: app/config/express/json.js
|
|
166
85
|
// ---------------
|
|
167
|
-
|
|
86
|
+
vulkano.use(express.json(expressConfig.json));
|
|
168
87
|
|
|
169
88
|
// ---------------
|
|
170
89
|
// EXPRESS FORM DATA - File: app/config/express/urlencoded.js
|
|
171
90
|
// ---------------
|
|
172
|
-
|
|
91
|
+
vulkano.use(express.urlencoded(expressConfig.urlencoded));
|
|
173
92
|
|
|
174
93
|
// ---------------
|
|
175
94
|
// HELMET - File: app/config/express/helmet.js
|
|
176
95
|
// ---------------
|
|
177
|
-
|
|
96
|
+
vulkano.use(helmet(expressConfig.helmet));
|
|
178
97
|
|
|
179
98
|
// ---------------
|
|
180
99
|
// RESPONSES
|
|
181
100
|
// ---------------
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
// ---------------
|
|
185
|
-
// PUBLIC PATH - File: app/config/settings.js
|
|
186
|
-
// ---------------
|
|
187
|
-
server.use(express.static(PUBLIC_PATH));
|
|
101
|
+
vulkano.use(responses);
|
|
188
102
|
|
|
189
103
|
// ---------------
|
|
190
104
|
// FRAMEGUARD - File: app/config/express/frameguard.js
|
|
@@ -192,17 +106,17 @@ module.exports = {
|
|
|
192
106
|
if (expressConfig.frameguard) {
|
|
193
107
|
if (Array.isArray(expressConfig.frameguard)) {
|
|
194
108
|
expressConfig.frameguard.forEach( (frame) => {
|
|
195
|
-
|
|
109
|
+
vulkano.use(frameguard(frame));
|
|
196
110
|
});
|
|
197
111
|
} else {
|
|
198
|
-
|
|
112
|
+
vulkano.use(frameguard(expressConfig.frameguard));
|
|
199
113
|
}
|
|
200
114
|
}
|
|
201
115
|
|
|
202
116
|
// ---------------
|
|
203
117
|
// PROTOCOL & POWERED BY - File: app/config/settings.js
|
|
204
118
|
// ---------------
|
|
205
|
-
|
|
119
|
+
vulkano.use( (req, res, next) => {
|
|
206
120
|
|
|
207
121
|
const proto = req.secure ? 'https' : 'http';
|
|
208
122
|
const forwarded = req.headers['x-forwaded-proto'] || null;
|
|
@@ -220,7 +134,7 @@ module.exports = {
|
|
|
220
134
|
// ---------------
|
|
221
135
|
// REQUEST OPTIONS - File: app/config/express/cors.js
|
|
222
136
|
// ---------------
|
|
223
|
-
|
|
137
|
+
vulkano.options('*', (req, res) => {
|
|
224
138
|
|
|
225
139
|
// ---------------
|
|
226
140
|
// CORS
|
|
@@ -244,8 +158,9 @@ module.exports = {
|
|
|
244
158
|
// ---------------
|
|
245
159
|
// TIMEOUT - File: app/config/settings.js
|
|
246
160
|
// ---------------
|
|
247
|
-
|
|
248
|
-
|
|
161
|
+
vulkano.use(timeout( expressConfig.timeout || 120000 ));
|
|
162
|
+
|
|
163
|
+
vulkano.use( (req, res, next) => {
|
|
249
164
|
if (!req.timedout) {
|
|
250
165
|
next();
|
|
251
166
|
}
|
|
@@ -263,12 +178,12 @@ module.exports = {
|
|
|
263
178
|
}
|
|
264
179
|
|
|
265
180
|
// JWT (secret key)
|
|
266
|
-
|
|
181
|
+
vulkano.use(expressConfig.jwt.path || '*', jwtMiddleware.init().unless({
|
|
267
182
|
path: expressConfig.jwt.ignore || []
|
|
268
183
|
}));
|
|
269
184
|
|
|
270
185
|
// JWT Handler error
|
|
271
|
-
|
|
186
|
+
vulkano.use((err, req, res, next) => {
|
|
272
187
|
if (err && err.name === 'UnauthorizedError') {
|
|
273
188
|
res.status(401).jsonp({ success: false, error: 'Invalid token' });
|
|
274
189
|
} else {
|
|
@@ -283,7 +198,7 @@ module.exports = {
|
|
|
283
198
|
// ---------------
|
|
284
199
|
if (expressConfig.cors && expressConfig.cors.enabled) {
|
|
285
200
|
|
|
286
|
-
|
|
201
|
+
vulkano.use(expressConfig.cors.path, (req, res, next) => {
|
|
287
202
|
|
|
288
203
|
// Enable CORS.
|
|
289
204
|
let tmpCorsHeaders = ['X-Requested-With', 'X-HTTP-Method-Override', 'Content-Type', 'Accept'];
|
|
@@ -306,13 +221,26 @@ module.exports = {
|
|
|
306
221
|
// ---------------
|
|
307
222
|
// VIEWS
|
|
308
223
|
// ---------------
|
|
309
|
-
server.set('views', views.path);
|
|
310
224
|
|
|
311
|
-
const
|
|
312
|
-
|
|
225
|
+
const views = {
|
|
226
|
+
...viewsConfig,
|
|
227
|
+
...(app.server.views || {})
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
vulkano.set('views', views.path);
|
|
231
|
+
|
|
232
|
+
const {
|
|
233
|
+
settings: nunjucksSettingsUser
|
|
234
|
+
} = views || {};
|
|
235
|
+
|
|
236
|
+
const nunjucksSettings = {
|
|
313
237
|
autoescape: true,
|
|
314
|
-
watch: !app.PRODUCTION
|
|
315
|
-
|
|
238
|
+
watch: !app.PRODUCTION,
|
|
239
|
+
...(nunjucksSettingsUser || {}),
|
|
240
|
+
express: vulkano
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const envNunjucks = nunjucks.configure(views.path, nunjucksSettings);
|
|
316
244
|
|
|
317
245
|
app.server.views._engine = envNunjucks;
|
|
318
246
|
|
|
@@ -326,6 +254,14 @@ module.exports = {
|
|
|
326
254
|
});
|
|
327
255
|
}
|
|
328
256
|
|
|
257
|
+
if (views.helpers && Array.isArray(views.helpers)) {
|
|
258
|
+
views.helpers.forEach((helper) => {
|
|
259
|
+
Object.keys(helper || []).forEach((i) => {
|
|
260
|
+
envNunjucks.addGlobal(i, helper[i]);
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
329
265
|
if (views.filters && Array.isArray(views.filters)) {
|
|
330
266
|
views.filters.forEach((filter) => {
|
|
331
267
|
Object.keys(filter || []).forEach((i) => {
|
|
@@ -342,6 +278,27 @@ module.exports = {
|
|
|
342
278
|
});
|
|
343
279
|
}
|
|
344
280
|
|
|
281
|
+
app.nunjucks = nunjucks;
|
|
282
|
+
|
|
283
|
+
// ---------------
|
|
284
|
+
// Middlewares
|
|
285
|
+
// ---------------
|
|
286
|
+
|
|
287
|
+
// Middleware File (compatibility)
|
|
288
|
+
const middleware = app.config.middleware || ((req, res, next) => {
|
|
289
|
+
next();
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
// Middleware Folder
|
|
293
|
+
const middlewares = app.config.middlewares || {};
|
|
294
|
+
|
|
295
|
+
Object.keys(middlewares).forEach( (item) => {
|
|
296
|
+
const middlewareFunction = middlewares[item];
|
|
297
|
+
if (typeof middlewareFunction === 'function') {
|
|
298
|
+
vulkano.use(middlewareFunction);
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
|
|
345
302
|
// ---------------
|
|
346
303
|
// ROUTES
|
|
347
304
|
// ---------------
|
|
@@ -372,9 +329,9 @@ module.exports = {
|
|
|
372
329
|
handler = routes[route];
|
|
373
330
|
|
|
374
331
|
if (method === 'post') {
|
|
375
|
-
|
|
332
|
+
vulkano[method](pathToRoute, upload.any(), middleware, handler);
|
|
376
333
|
} else {
|
|
377
|
-
|
|
334
|
+
vulkano[method](pathToRoute, middleware, handler);
|
|
378
335
|
}
|
|
379
336
|
|
|
380
337
|
});
|
|
@@ -422,9 +379,9 @@ module.exports = {
|
|
|
422
379
|
|
|
423
380
|
if (toExecute) {
|
|
424
381
|
if (option === 'post') {
|
|
425
|
-
|
|
382
|
+
vulkano[option](pathToRun || '/', upload.any(), middleware, toExecute);
|
|
426
383
|
} else {
|
|
427
|
-
|
|
384
|
+
vulkano[option](pathToRun || '/', middleware, toExecute);
|
|
428
385
|
}
|
|
429
386
|
} else {
|
|
430
387
|
console.error('\x1b[31mError:', 'Controller not found in', (module) ? `${module}.${controller}.${action}` : `${controller}.${action}`, '\x1b[0m');
|
|
@@ -432,10 +389,12 @@ module.exports = {
|
|
|
432
389
|
|
|
433
390
|
});
|
|
434
391
|
|
|
392
|
+
const server = await vulkano.listen(expressConfig.port);
|
|
393
|
+
|
|
435
394
|
// ---------------
|
|
436
395
|
// ERROR 404
|
|
437
396
|
// ---------------
|
|
438
|
-
|
|
397
|
+
vulkano.use((req, res) => {
|
|
439
398
|
if (+res.statusCode >= 500 && +res.statusCode < 600) {
|
|
440
399
|
throw new Error();
|
|
441
400
|
}
|
|
@@ -445,14 +404,14 @@ module.exports = {
|
|
|
445
404
|
// ---------------
|
|
446
405
|
// ERROR 5XX
|
|
447
406
|
// ---------------
|
|
448
|
-
|
|
407
|
+
vulkano.use((err, req, res) => {
|
|
449
408
|
const status = err.status || res.statusCode || 500;
|
|
450
409
|
res.status(status);
|
|
451
410
|
if (!res.xhr) {
|
|
452
411
|
if (+status > 400 && +status < 500) {
|
|
453
|
-
res.render(`${
|
|
412
|
+
res.render(`${vulkano.get('views')}/_shared/errors/404.html`, { content: err.stack });
|
|
454
413
|
} else {
|
|
455
|
-
res.render(`${
|
|
414
|
+
res.render(`${vulkano.get('views')}/_shared/errors/500.html`, { content: err.stack });
|
|
456
415
|
}
|
|
457
416
|
} else {
|
|
458
417
|
res.jsonp({
|
|
@@ -464,154 +423,14 @@ module.exports = {
|
|
|
464
423
|
});
|
|
465
424
|
|
|
466
425
|
// ---------------
|
|
467
|
-
//
|
|
426
|
+
// PUBLIC PATH - File: app/config/settings.js
|
|
468
427
|
// ---------------
|
|
469
|
-
|
|
428
|
+
vulkano.use(express.static(PUBLIC_PATH));
|
|
470
429
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
pingInterval: +sockets.interval || 2000,
|
|
474
|
-
transports: sockets.transports || ['websocket', 'polling']
|
|
475
|
-
};
|
|
430
|
+
app.vulkano = vulkano;
|
|
431
|
+
app.server = server;
|
|
476
432
|
|
|
477
|
-
|
|
478
|
-
if (typeof sockets.cors === 'function') {
|
|
479
|
-
socketProps.allowRequest = sockets.cors;
|
|
480
|
-
} else if (typeof sockets.cors === 'string') {
|
|
481
|
-
socketProps.cors = sockets.cors || '';
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
if (sockets.redis && !redis.enabled) {
|
|
486
|
-
throw new Error('Enable the Redis config "app/config/redis.js" to connect the sockets');
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
const io = new Server(server.listen(expressConfig.port), socketProps);
|
|
490
|
-
|
|
491
|
-
let pubClient = null;
|
|
492
|
-
let subClient = null;
|
|
493
|
-
|
|
494
|
-
if (sockets.redis) {
|
|
495
|
-
|
|
496
|
-
const propsToRedis = {
|
|
497
|
-
host: redis.host,
|
|
498
|
-
port: redis.port
|
|
499
|
-
};
|
|
500
|
-
|
|
501
|
-
if (redis.password) {
|
|
502
|
-
propsToRedis.password = redis.password;
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
pubClient = createClient(propsToRedis);
|
|
506
|
-
subClient = pubClient.duplicate();
|
|
507
|
-
|
|
508
|
-
io.adapter(createAdapter(pubClient, subClient));
|
|
509
|
-
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
Promise
|
|
513
|
-
.all([
|
|
514
|
-
(sockets.redis ? pubClient.connect() : null),
|
|
515
|
-
(sockets.redis ? subClient.connect() : null)
|
|
516
|
-
])
|
|
517
|
-
.then(() => {
|
|
518
|
-
|
|
519
|
-
io.on('connection', (socket) => {
|
|
520
|
-
|
|
521
|
-
if ( typeof sockets.onConnect === 'function') {
|
|
522
|
-
sockets.onConnect(socket);
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
const socketEvents = sockets.events || {};
|
|
526
|
-
|
|
527
|
-
Object.keys(socketEvents).forEach( (i) => {
|
|
528
|
-
|
|
529
|
-
const checkPath = socketEvents[i] || '';
|
|
530
|
-
|
|
531
|
-
let toExecute = null;
|
|
532
|
-
let module = null;
|
|
533
|
-
let controller = null;
|
|
534
|
-
let action = null;
|
|
535
|
-
|
|
536
|
-
if (typeof checkPath === 'function') {
|
|
537
|
-
|
|
538
|
-
toExecute = checkPath;
|
|
539
|
-
|
|
540
|
-
} else {
|
|
541
|
-
|
|
542
|
-
const fullPath = checkPath.split('.');
|
|
543
|
-
|
|
544
|
-
if (fullPath.length > 2) { // Has folder
|
|
545
|
-
|
|
546
|
-
[
|
|
547
|
-
module,
|
|
548
|
-
controller,
|
|
549
|
-
action
|
|
550
|
-
] = fullPath;
|
|
551
|
-
|
|
552
|
-
} else {
|
|
553
|
-
|
|
554
|
-
[
|
|
555
|
-
controller,
|
|
556
|
-
action
|
|
557
|
-
] = fullPath;
|
|
558
|
-
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
try {
|
|
562
|
-
toExecute = module
|
|
563
|
-
? (AllControllers[module][controller][action])
|
|
564
|
-
: AllControllers[controller][action];
|
|
565
|
-
} catch (e) {
|
|
566
|
-
toExecute = null;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
if (toExecute) {
|
|
572
|
-
socket.on(i, (body) => {
|
|
573
|
-
toExecute({ socket, body: body || {} });
|
|
574
|
-
});
|
|
575
|
-
} else {
|
|
576
|
-
console.error('\x1b[31mError:', 'Controller not found in', (module) ? `${module}.${controller}.${action}` : `${controller}.${action}`, '\x1b[0m', 'to socket event', i);
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
});
|
|
580
|
-
|
|
581
|
-
server.set('socket', socket);
|
|
582
|
-
app.socket = socket;
|
|
583
|
-
|
|
584
|
-
});
|
|
585
|
-
|
|
586
|
-
// next line is the money
|
|
587
|
-
global.io = io;
|
|
588
|
-
server.set('socketio', io);
|
|
589
|
-
|
|
590
|
-
// middleware
|
|
591
|
-
if (sockets.middleware) {
|
|
592
|
-
io.use(sockets.middleware);
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
app.server = server;
|
|
596
|
-
|
|
597
|
-
cb();
|
|
598
|
-
|
|
599
|
-
});
|
|
600
|
-
|
|
601
|
-
return;
|
|
602
|
-
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
// ---------------
|
|
606
|
-
// START SERVER
|
|
607
|
-
// ---------------
|
|
608
|
-
server.listen(server.get('port'), () => {
|
|
609
|
-
app.server = {
|
|
610
|
-
...app.server,
|
|
611
|
-
...server
|
|
612
|
-
};
|
|
613
|
-
cb();
|
|
614
|
-
});
|
|
433
|
+
cb();
|
|
615
434
|
|
|
616
435
|
}
|
|
617
436
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
3
|
+
// Include all filters
|
|
4
|
+
const appFilters = require('include-all')({
|
|
5
|
+
dirname: path.join(APP_PATH, 'config/views/filters'),
|
|
6
|
+
filter: /(.+)\.js$/,
|
|
7
|
+
optional: true
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
// Include all helpers
|
|
11
|
+
const appHelpers = require('include-all')({
|
|
12
|
+
dirname: path.join(APP_PATH, 'config/views/helpers'),
|
|
13
|
+
filter: /(.+)\.js$/,
|
|
14
|
+
optional: true
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
module.exports = {
|
|
18
|
+
|
|
19
|
+
path: path.join(APP_PATH, 'views'),
|
|
20
|
+
|
|
21
|
+
engine: 'nunjucks',
|
|
22
|
+
|
|
23
|
+
filters: [appFilters || {}],
|
|
24
|
+
|
|
25
|
+
helpers: [appHelpers || {}]
|
|
26
|
+
|
|
27
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module.exports = (modelName) => {
|
|
1
|
+
module.exports = (modelName, allowedMethods) => {
|
|
2
2
|
|
|
3
3
|
const {
|
|
4
4
|
config
|
|
@@ -51,7 +51,7 @@ module.exports = (modelName) => {
|
|
|
51
51
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
const allMethods = {
|
|
55
55
|
|
|
56
56
|
get(req, res) {
|
|
57
57
|
|
|
@@ -105,4 +105,31 @@ module.exports = (modelName) => {
|
|
|
105
105
|
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
+
if (allowedMethods) {
|
|
109
|
+
|
|
110
|
+
const tempAllowedMethods = Array.isArray(allowedMethods)
|
|
111
|
+
? allowedMethods.map( (m) => m.toLowerCase() )
|
|
112
|
+
: allowedMethods.split(',').map( (m) => m.trim().toLowerCase() );
|
|
113
|
+
|
|
114
|
+
if (!tempAllowedMethods.includes('post')) {
|
|
115
|
+
delete allMethods.post;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!tempAllowedMethods.includes('get')) {
|
|
119
|
+
delete allMethods.get;
|
|
120
|
+
delete allMethods['get :id'];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (!tempAllowedMethods.includes('put')) {
|
|
124
|
+
delete allMethods['put :id'];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (!tempAllowedMethods.includes('delete')) {
|
|
128
|
+
delete allMethods['delete :id'];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return allMethods;
|
|
134
|
+
|
|
108
135
|
};
|
|
@@ -22,12 +22,13 @@ module.exports = function loadControllersApplication() {
|
|
|
22
22
|
|
|
23
23
|
const {
|
|
24
24
|
scaffold,
|
|
25
|
+
allowedMethods,
|
|
25
26
|
model
|
|
26
27
|
} = current;
|
|
27
28
|
|
|
28
29
|
if (scaffold && model) {
|
|
29
30
|
|
|
30
|
-
const scaffoldingCurrent = scaffoldController(model);
|
|
31
|
+
const scaffoldingCurrent = scaffoldController(model, allowedMethods);
|
|
31
32
|
|
|
32
33
|
Object.keys(scaffoldingCurrent).forEach( (m) => {
|
|
33
34
|
|
|
@@ -61,12 +62,13 @@ module.exports = function loadControllersApplication() {
|
|
|
61
62
|
|
|
62
63
|
const {
|
|
63
64
|
scaffold: subcurrentScaffold,
|
|
65
|
+
allowedMethods: subAllowedMethods,
|
|
64
66
|
model: subcurrentModel
|
|
65
67
|
} = subcurrent || {};
|
|
66
68
|
|
|
67
69
|
if (subcurrentScaffold && subcurrentModel) {
|
|
68
70
|
|
|
69
|
-
const scaffoldingSubcurrent = scaffoldController(subcurrentModel);
|
|
71
|
+
const scaffoldingSubcurrent = scaffoldController(subcurrentModel, subAllowedMethods);
|
|
70
72
|
|
|
71
73
|
Object.keys(scaffoldingSubcurrent).forEach( (m) => {
|
|
72
74
|
|