@vulkano/core 1.17.0 → 1.17.2
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/bin/postinstall.js +448 -0
- package/database/mongodb.js +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Vulkano scaffold — runs after `npm install @vulkano/core`.
|
|
5
|
+
*
|
|
6
|
+
* If the project does not already have an `app/` or `vulkano/` directory,
|
|
7
|
+
* creates the minimal folder structure and config files needed to start.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const readline = require('readline');
|
|
13
|
+
|
|
14
|
+
// npm sets INIT_CWD to the directory where `npm install` was invoked.
|
|
15
|
+
// npm_config_local_prefix is the project root (directory containing node_modules).
|
|
16
|
+
// Fall back to __dirname-based resolution for non-npm invocations.
|
|
17
|
+
const coreRoot = path.resolve(__dirname, '..');
|
|
18
|
+
const projectRoot = process.env.INIT_CWD
|
|
19
|
+
|| process.env.npm_config_local_prefix
|
|
20
|
+
|| path.resolve(__dirname, '..', '..', '..', '..');
|
|
21
|
+
|
|
22
|
+
if (projectRoot === coreRoot) {
|
|
23
|
+
// Running `npm install` inside the core repo itself — nothing to scaffold
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const appDir = path.join(projectRoot, 'app');
|
|
28
|
+
const vulkanoDir = path.join(projectRoot, 'vulkano');
|
|
29
|
+
|
|
30
|
+
if (fs.existsSync(appDir) || fs.existsSync(vulkanoDir)) {
|
|
31
|
+
// Project already has a structure — do not touch it
|
|
32
|
+
process.exit(0);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ─────────────────────────────────────────────
|
|
36
|
+
// Scaffold
|
|
37
|
+
// ─────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
function scaffold() {
|
|
40
|
+
|
|
41
|
+
function write(relPath, content) {
|
|
42
|
+
const abs = path.join(appDir, relPath);
|
|
43
|
+
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
44
|
+
if (!fs.existsSync(abs)) {
|
|
45
|
+
fs.writeFileSync(abs, content, 'utf8');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function dir(relPath) {
|
|
50
|
+
const abs = path.join(appDir, relPath);
|
|
51
|
+
fs.mkdirSync(abs, { recursive: true });
|
|
52
|
+
const keep = path.join(abs, '.gitkeep');
|
|
53
|
+
if (!fs.existsSync(keep)) fs.writeFileSync(keep, '', 'utf8');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ─────────────────────────────────────────────
|
|
57
|
+
// app/config/bootstrap.js (required by Vulkano)
|
|
58
|
+
// ─────────────────────────────────────────────
|
|
59
|
+
write('config/bootstrap.js', `/**
|
|
60
|
+
* Bootstrap — called once the server is ready to start.
|
|
61
|
+
* @param {Function} cb Call cb() to finish startup
|
|
62
|
+
*/
|
|
63
|
+
module.exports = (cb) => {
|
|
64
|
+
|
|
65
|
+
// Start app
|
|
66
|
+
cb(() => {
|
|
67
|
+
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
`);
|
|
71
|
+
|
|
72
|
+
// ─────────────────────────────────────────────
|
|
73
|
+
// app/config/settings.js
|
|
74
|
+
// ─────────────────────────────────────────────
|
|
75
|
+
write('config/settings.js', `/**
|
|
76
|
+
* Application settings
|
|
77
|
+
*/
|
|
78
|
+
module.exports = {
|
|
79
|
+
|
|
80
|
+
// Server port (overridden by NODE_PORT / PORT env vars)
|
|
81
|
+
port: parseInt(process.env.PORT, 10) || 8000,
|
|
82
|
+
|
|
83
|
+
// Database connection — key must exist in app/config/connections.js
|
|
84
|
+
database: {
|
|
85
|
+
connection: 'default',
|
|
86
|
+
settings: {
|
|
87
|
+
strictQuery: false,
|
|
88
|
+
debug: false
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
};
|
|
93
|
+
`);
|
|
94
|
+
|
|
95
|
+
// ─────────────────────────────────────────────
|
|
96
|
+
// app/config/connections.js
|
|
97
|
+
// ─────────────────────────────────────────────
|
|
98
|
+
write('config/connections.js', `/**
|
|
99
|
+
* Database connections
|
|
100
|
+
* The key here is referenced from settings.js → database.connection
|
|
101
|
+
*/
|
|
102
|
+
module.exports = {
|
|
103
|
+
|
|
104
|
+
default: process.env.MONGO_URI || 'mongodb://localhost:27017/vulkano'
|
|
105
|
+
|
|
106
|
+
};
|
|
107
|
+
`);
|
|
108
|
+
|
|
109
|
+
// ─────────────────────────────────────────────
|
|
110
|
+
// app/config/routes.js
|
|
111
|
+
// ─────────────────────────────────────────────
|
|
112
|
+
write('config/routes.js', `/**
|
|
113
|
+
* Explicit routes (optional)
|
|
114
|
+
* Format: 'METHOD /path': 'ControllerName.action'
|
|
115
|
+
*
|
|
116
|
+
* Convention-based routes are auto-generated from controllers — no need
|
|
117
|
+
* to list them here.
|
|
118
|
+
*
|
|
119
|
+
* Example:
|
|
120
|
+
* - GET /users/ -> File: UsersController, Method: 'get': (req, res) => {}
|
|
121
|
+
* - GET /users/123 -> File: UsersController, Method: 'get :id': (req, res) => {}
|
|
122
|
+
* - POST /users/ -> File: UsersController, Method: 'post': (req, res) => {}
|
|
123
|
+
* - PUT /users/123 -> File: UsersController, Method: 'put :id': (req, res) => {}
|
|
124
|
+
* - DELETE /users/123 -> File: UsersController, Method: 'delete :id': (req, res) => {}
|
|
125
|
+
*
|
|
126
|
+
* But you can write your own routes manually
|
|
127
|
+
*
|
|
128
|
+
*/
|
|
129
|
+
module.exports = {
|
|
130
|
+
|
|
131
|
+
// 'GET /': 'HomeController.get'
|
|
132
|
+
|
|
133
|
+
};
|
|
134
|
+
`);
|
|
135
|
+
|
|
136
|
+
// ─────────────────────────────────────────────
|
|
137
|
+
// app/config/express/settings.js
|
|
138
|
+
// ─────────────────────────────────────────────
|
|
139
|
+
write('config/express/settings.js', `/**
|
|
140
|
+
* Express server settings
|
|
141
|
+
*/
|
|
142
|
+
module.exports = {
|
|
143
|
+
|
|
144
|
+
// Show "X-Powered-By" header
|
|
145
|
+
poweredBy: false,
|
|
146
|
+
|
|
147
|
+
// Request timeout in milliseconds
|
|
148
|
+
timeout: 120000,
|
|
149
|
+
|
|
150
|
+
// Folder to upload files
|
|
151
|
+
uploadPath: 'public/files',
|
|
152
|
+
|
|
153
|
+
// Number of proxy hops to trust for X-Forwarded-* headers.
|
|
154
|
+
// Use 1 when behind a single load balancer, true to trust all (less secure).
|
|
155
|
+
trustProxy: 1
|
|
156
|
+
|
|
157
|
+
};
|
|
158
|
+
`);
|
|
159
|
+
|
|
160
|
+
// ─────────────────────────────────────────────
|
|
161
|
+
// app/config/express/cors.js
|
|
162
|
+
// ─────────────────────────────────────────────
|
|
163
|
+
write('config/express/cors.js', `/**
|
|
164
|
+
* CORS configuration
|
|
165
|
+
*/
|
|
166
|
+
module.exports = {
|
|
167
|
+
|
|
168
|
+
// Enable CORS
|
|
169
|
+
enabled: false,
|
|
170
|
+
|
|
171
|
+
// Path where CORS headers are applied
|
|
172
|
+
path: '/',
|
|
173
|
+
|
|
174
|
+
// Allowed origin — use specific domains in production
|
|
175
|
+
origin: '*',
|
|
176
|
+
|
|
177
|
+
// Additional allowed request headers
|
|
178
|
+
headers: ['x-token-auth']
|
|
179
|
+
|
|
180
|
+
};
|
|
181
|
+
`);
|
|
182
|
+
|
|
183
|
+
// ─────────────────────────────────────────────
|
|
184
|
+
// app/config/express/jwt.js
|
|
185
|
+
// ─────────────────────────────────────────────
|
|
186
|
+
write('config/express/jwt.js', `/**
|
|
187
|
+
* JWT authentication middleware
|
|
188
|
+
*/
|
|
189
|
+
module.exports = {
|
|
190
|
+
|
|
191
|
+
//
|
|
192
|
+
// Enable JWT
|
|
193
|
+
// @type Boolean
|
|
194
|
+
//
|
|
195
|
+
enabled: false,
|
|
196
|
+
|
|
197
|
+
//
|
|
198
|
+
// Custom KEY
|
|
199
|
+
// You can use this https://api.wordpress.org/secret-key/1.1/salt/ to change key
|
|
200
|
+
// @type String
|
|
201
|
+
//
|
|
202
|
+
key: process.env.JWT_SECRET_KEY || '',
|
|
203
|
+
|
|
204
|
+
//
|
|
205
|
+
// header name via Request
|
|
206
|
+
// @type String
|
|
207
|
+
//
|
|
208
|
+
header: 'x-token-auth',
|
|
209
|
+
|
|
210
|
+
//
|
|
211
|
+
// Get token via url
|
|
212
|
+
// value: string
|
|
213
|
+
// @type String
|
|
214
|
+
//
|
|
215
|
+
queryParameter: 'token',
|
|
216
|
+
|
|
217
|
+
//
|
|
218
|
+
// Get token via cookie
|
|
219
|
+
// value: string
|
|
220
|
+
// @type String
|
|
221
|
+
//
|
|
222
|
+
cookieName: 'token',
|
|
223
|
+
|
|
224
|
+
//
|
|
225
|
+
// Path to make mandatory the token
|
|
226
|
+
// Example /api/
|
|
227
|
+
// @type String
|
|
228
|
+
//
|
|
229
|
+
path: '/api/',
|
|
230
|
+
|
|
231
|
+
//
|
|
232
|
+
// Path to ignore token request
|
|
233
|
+
// Example: ['/api/auth', '/api/auth/forgot', /^\\/api\\/events/i]
|
|
234
|
+
// you can see https://github.com/jfromaniello/express-unless to more examples
|
|
235
|
+
//
|
|
236
|
+
// To allow the enpoint to verify token replace the api path for /^\\/api\\/auth(?!\\/current)/i
|
|
237
|
+
//
|
|
238
|
+
// @type Array
|
|
239
|
+
//
|
|
240
|
+
ignore: [
|
|
241
|
+
'/api/',
|
|
242
|
+
/^\\/api\\/auth(?!\\/current)/i
|
|
243
|
+
]
|
|
244
|
+
|
|
245
|
+
};
|
|
246
|
+
`);
|
|
247
|
+
|
|
248
|
+
// ─────────────────────────────────────────────
|
|
249
|
+
// app/config/express/cookies.js
|
|
250
|
+
// ─────────────────────────────────────────────
|
|
251
|
+
write('config/express/cookies.js', `/**
|
|
252
|
+
* Cookie parser
|
|
253
|
+
*/
|
|
254
|
+
module.exports = {
|
|
255
|
+
|
|
256
|
+
//
|
|
257
|
+
// Enable Cookies
|
|
258
|
+
// @type Boolean
|
|
259
|
+
//
|
|
260
|
+
enabled: false,
|
|
261
|
+
|
|
262
|
+
// SECRET KEY to sign the cookie
|
|
263
|
+
// You can use this https://api.wordpress.org/secret-key/1.1/salt/ to change key
|
|
264
|
+
// @type String
|
|
265
|
+
secret: process.env.COOKIES_SECRET_KEY || ''
|
|
266
|
+
|
|
267
|
+
};
|
|
268
|
+
`);
|
|
269
|
+
|
|
270
|
+
// ─────────────────────────────────────────────
|
|
271
|
+
// app/config/encryption.js
|
|
272
|
+
// ─────────────────────────────────────────────
|
|
273
|
+
write('config/encryption.js', `/**
|
|
274
|
+
* Encryption settings (used by Encrypter)
|
|
275
|
+
*/
|
|
276
|
+
module.exports = {
|
|
277
|
+
|
|
278
|
+
// Secret encryption key — always set via environment variable
|
|
279
|
+
key: process.env.ENCRYPTION_KEY || '',
|
|
280
|
+
|
|
281
|
+
// Salt for key derivation (scrypt)
|
|
282
|
+
salt: process.env.ENCRYPTION_SALT || 'vulkano-salt-v1',
|
|
283
|
+
|
|
284
|
+
// Cipher algorithm
|
|
285
|
+
algorithm: process.env.ENCRYPTION_ALGORITHM || 'aes-256-cbc'
|
|
286
|
+
|
|
287
|
+
};
|
|
288
|
+
`);
|
|
289
|
+
|
|
290
|
+
// ─────────────────────────────────────────────
|
|
291
|
+
// app/controllers/HomeController.js
|
|
292
|
+
// ─────────────────────────────────────────────
|
|
293
|
+
write('controllers/HomeController.js', `/**
|
|
294
|
+
* HomeController
|
|
295
|
+
* Convention-based routes → GET /home/, GET /home/:id, POST /home/save, etc.
|
|
296
|
+
*
|
|
297
|
+
* To map GET / to this controller add to app/config/routes.js:
|
|
298
|
+
* 'GET /': 'HomeController.index'
|
|
299
|
+
*/
|
|
300
|
+
module.exports = {
|
|
301
|
+
|
|
302
|
+
// GET /home/
|
|
303
|
+
get(req, res) {
|
|
304
|
+
res.render('home/index.html');
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
};
|
|
308
|
+
`);
|
|
309
|
+
|
|
310
|
+
// ─────────────────────────────────────────────
|
|
311
|
+
// Empty placeholder directories
|
|
312
|
+
// ─────────────────────────────────────────────
|
|
313
|
+
dir('models');
|
|
314
|
+
dir('services');
|
|
315
|
+
dir('responses');
|
|
316
|
+
|
|
317
|
+
// ─────────────────────────────────────────────
|
|
318
|
+
// app/views structure
|
|
319
|
+
// ─────────────────────────────────────────────
|
|
320
|
+
dir('views/home');
|
|
321
|
+
dir('views/_shared/errors');
|
|
322
|
+
dir('views/_shared/templates');
|
|
323
|
+
|
|
324
|
+
write('views/_shared/templates/default.html', `<!DOCTYPE html>
|
|
325
|
+
<html lang="en">
|
|
326
|
+
<head>
|
|
327
|
+
<meta charset="UTF-8">
|
|
328
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
329
|
+
<title>{% block title %}Vulkano{% endblock %}</title>
|
|
330
|
+
<link rel="stylesheet" href="/css/app.css">
|
|
331
|
+
</head>
|
|
332
|
+
<body>
|
|
333
|
+
|
|
334
|
+
{% block content %}{% endblock %}
|
|
335
|
+
|
|
336
|
+
<script src="/js/app.js"></script>
|
|
337
|
+
</body>
|
|
338
|
+
</html>
|
|
339
|
+
`);
|
|
340
|
+
|
|
341
|
+
write('views/home/index.html', `{% extends "_shared/templates/default.html" %}
|
|
342
|
+
|
|
343
|
+
{% block title %}Home — Vulkano{% endblock %}
|
|
344
|
+
|
|
345
|
+
{% block content %}
|
|
346
|
+
<h1>Vulkano is running!</h1>
|
|
347
|
+
{% endblock %}
|
|
348
|
+
`);
|
|
349
|
+
|
|
350
|
+
write('views/_shared/errors/404.html', `<!DOCTYPE html>
|
|
351
|
+
<html lang="en">
|
|
352
|
+
<head>
|
|
353
|
+
<meta charset="UTF-8">
|
|
354
|
+
<title>404 Not Found</title>
|
|
355
|
+
</head>
|
|
356
|
+
<body>
|
|
357
|
+
<h1>404 — Page Not Found</h1>
|
|
358
|
+
</body>
|
|
359
|
+
</html>
|
|
360
|
+
`);
|
|
361
|
+
|
|
362
|
+
write('views/_shared/errors/500.html', `<!DOCTYPE html>
|
|
363
|
+
<html lang="en">
|
|
364
|
+
<head>
|
|
365
|
+
<meta charset="UTF-8">
|
|
366
|
+
<title>500 Server Error</title>
|
|
367
|
+
</head>
|
|
368
|
+
<body>
|
|
369
|
+
<h1>500 — Server Error</h1>
|
|
370
|
+
</body>
|
|
371
|
+
</html>
|
|
372
|
+
`);
|
|
373
|
+
|
|
374
|
+
// public/files for multer uploads
|
|
375
|
+
const publicFiles = path.join(projectRoot, 'public', 'files');
|
|
376
|
+
fs.mkdirSync(publicFiles, { recursive: true });
|
|
377
|
+
|
|
378
|
+
// public/css for css files
|
|
379
|
+
const publicCss = path.join(projectRoot, 'public', 'css');
|
|
380
|
+
fs.mkdirSync(publicCss, { recursive: true });
|
|
381
|
+
|
|
382
|
+
// public/js for js files
|
|
383
|
+
const publicJs = path.join(projectRoot, 'public', 'js');
|
|
384
|
+
fs.mkdirSync(publicJs, { recursive: true });
|
|
385
|
+
|
|
386
|
+
// public/img for image files
|
|
387
|
+
const publicImg = path.join(projectRoot, 'public', 'img');
|
|
388
|
+
fs.mkdirSync(publicImg, { recursive: true });
|
|
389
|
+
|
|
390
|
+
// public/fonts for font files
|
|
391
|
+
const publicFonts = path.join(projectRoot, 'public', 'fonts');
|
|
392
|
+
fs.mkdirSync(publicFonts, { recursive: true });
|
|
393
|
+
|
|
394
|
+
// .env example
|
|
395
|
+
const envExample = path.join(projectRoot, '.env');
|
|
396
|
+
if (!fs.existsSync(envExample)) {
|
|
397
|
+
fs.writeFileSync(envExample, [
|
|
398
|
+
'# Copy to .env and fill in your values',
|
|
399
|
+
'PORT=8000',
|
|
400
|
+
'MONGO_URI=',
|
|
401
|
+
'JWT_SECRET=',
|
|
402
|
+
'COOKIE_SECRET=',
|
|
403
|
+
'ENCRYPTION_KEY=',
|
|
404
|
+
'ENCRYPTION_SALT=salt',
|
|
405
|
+
'ENCRYPTION_ALGORITHM=aes-256-cbc',
|
|
406
|
+
''
|
|
407
|
+
].join('\n'), 'utf8');
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
console.log([
|
|
411
|
+
'',
|
|
412
|
+
' ✔ Vulkano scaffold created:',
|
|
413
|
+
' app/config/ ← settings, connections, routes, express, jwt…',
|
|
414
|
+
' app/controllers/ ← HomeController.js',
|
|
415
|
+
' app/models/ ← (empty — add your models here)',
|
|
416
|
+
' app/services/ ← (empty — add your services here)',
|
|
417
|
+
' app/views/ ← home/index.html, _shared/templates/default.html, errors/404, 500',
|
|
418
|
+
' public/css/ ← css files',
|
|
419
|
+
' public/js/ ← js files',
|
|
420
|
+
' public/img/ ← image files',
|
|
421
|
+
' public/fonts/ ← font files',
|
|
422
|
+
' .env ← fill in values',
|
|
423
|
+
'',
|
|
424
|
+
' Next steps:',
|
|
425
|
+
' 1. Set MONGO_URI, JWT_SECRET, etc.',
|
|
426
|
+
'',
|
|
427
|
+
].join('\n'));
|
|
428
|
+
|
|
429
|
+
} // end scaffold()
|
|
430
|
+
|
|
431
|
+
// ─────────────────────────────────────────────
|
|
432
|
+
// Prompt
|
|
433
|
+
// ─────────────────────────────────────────────
|
|
434
|
+
|
|
435
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
436
|
+
|
|
437
|
+
rl.question('\n 🌋 Vulkano: Would you like to scaffold a new project? (Y/n) ', (answer) => {
|
|
438
|
+
|
|
439
|
+
rl.close();
|
|
440
|
+
|
|
441
|
+
if (answer.trim().toLowerCase() === 'n') {
|
|
442
|
+
console.log('\n Skipped. You can scaffold manually at any time.\n');
|
|
443
|
+
process.exit(0);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
scaffold();
|
|
447
|
+
|
|
448
|
+
});
|
package/database/mongodb.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vulkano/core",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.2",
|
|
4
4
|
"description": "A MVC framework using Express 4",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Vulkano Team",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"scripts": {
|
|
12
12
|
"test": "jest",
|
|
13
13
|
"test:watch": "jest --watch",
|
|
14
|
-
"test:coverage": "jest --coverage"
|
|
14
|
+
"test:coverage": "jest --coverage",
|
|
15
|
+
"postinstall": "node bin/postinstall.js"
|
|
15
16
|
},
|
|
16
17
|
"preferGlobal": true,
|
|
17
18
|
"homepage": "https://github.com/vulkanojs/vulkano-core",
|
|
@@ -53,6 +54,7 @@
|
|
|
53
54
|
"nunjucks": "^3.2.4",
|
|
54
55
|
"redis": "^5.12.1",
|
|
55
56
|
"socket.io": "^4.8.1",
|
|
57
|
+
"socket.io-adapter": "^2.5.6",
|
|
56
58
|
"undici": "^6.25.0"
|
|
57
59
|
},
|
|
58
60
|
"devDependencies": {
|