millas 0.2.25 → 0.2.27
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/package.json +1 -1
- package/src/cli.js +0 -4
- package/src/commands/serve.js +15 -45
- package/src/container/Application.js +34 -1
- package/src/container/HttpServer.js +1 -1
- package/src/orm/model/Model.js +4 -0
- package/src/router/RouteEntry.js +18 -0
package/package.json
CHANGED
package/src/cli.js
CHANGED
package/src/commands/serve.js
CHANGED
|
@@ -8,40 +8,6 @@ const {fork} = require('child_process');
|
|
|
8
8
|
const chokidar = require('chokidar');
|
|
9
9
|
const patchConsole = require("../logger/patchConsole");
|
|
10
10
|
const Logger = require("../logger/internal");
|
|
11
|
-
// ── ASCII banner ───────────────────────────────────────────────────────────────
|
|
12
|
-
|
|
13
|
-
const BANNER_LINES = [
|
|
14
|
-
' ███╗ ███╗██╗██╗ ██╗ █████╗ ███████╗',
|
|
15
|
-
' ████╗ ████║██║██║ ██║ ██╔══██╗██╔════╝',
|
|
16
|
-
' ██╔████╔██║██║██║ ██║ ███████║███████╗',
|
|
17
|
-
' ██║╚██╔╝██║██║██║ ██║ ██╔══██║╚════██║',
|
|
18
|
-
' ██║ ╚═╝ ██║██║███████╗███████╗██║ ██║███████║',
|
|
19
|
-
' ╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚══════╝',
|
|
20
|
-
];
|
|
21
|
-
|
|
22
|
-
function printBanner(host, port) {
|
|
23
|
-
const env = process.env.NODE_ENV || 'development';
|
|
24
|
-
const ver = 'v' + (require('../../package.json').version || '0.1.0');
|
|
25
|
-
const url = `http://${host}:${port}`;
|
|
26
|
-
const hr = chalk.dim(' ' + '─'.repeat(54));
|
|
27
|
-
const envColour = env === 'production' ? chalk.red
|
|
28
|
-
: env === 'staging' ? chalk.yellow
|
|
29
|
-
: chalk.green;
|
|
30
|
-
|
|
31
|
-
process.stdout.write('\n');
|
|
32
|
-
for (const line of BANNER_LINES) {
|
|
33
|
-
process.stdout.write(chalk.bold.cyan(line) + '\n');
|
|
34
|
-
}
|
|
35
|
-
process.stdout.write('\n' + hr + '\n');
|
|
36
|
-
process.stdout.write(
|
|
37
|
-
' ' + chalk.dim(ver.padEnd(8)) +
|
|
38
|
-
chalk.dim('│') + ' ' + envColour('⬤ ' + env) + ' ' +
|
|
39
|
-
chalk.dim('│') + ' ' + chalk.bold.white(url) + '\n'
|
|
40
|
-
);
|
|
41
|
-
process.stdout.write(hr + '\n\n');
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// ── Constants ─────────────────────────────────────────────────────────────────
|
|
45
11
|
|
|
46
12
|
const WATCH_DIRS = ['app', 'routes', 'config', 'bootstrap', 'providers', 'middleware'];
|
|
47
13
|
const WATCH_EXTS = new Set(['.js', '.mjs', '.cjs', '.json', '.njk', '.env']);
|
|
@@ -81,11 +47,14 @@ class HotReloader {
|
|
|
81
47
|
extra["MILLAS_START_UP"] = true
|
|
82
48
|
this._initialised = true
|
|
83
49
|
}
|
|
50
|
+
|
|
84
51
|
this._child = fork(this._bootstrap, [], {
|
|
85
52
|
env: {
|
|
86
53
|
...extra,
|
|
87
54
|
MILLAS_CHILD: '1',
|
|
88
55
|
DEBUG: process.env.APP_DEBUG,
|
|
56
|
+
MILLAS_HOST: process.env.MILLAS_HOST,
|
|
57
|
+
MILLAS_PORT: process.env.MILLAS_PORT,
|
|
89
58
|
},
|
|
90
59
|
stdio: 'inherit',
|
|
91
60
|
});
|
|
@@ -199,7 +168,7 @@ module.exports = function (program) {
|
|
|
199
168
|
.command('serve')
|
|
200
169
|
.description('Start the development server with hot reload')
|
|
201
170
|
.option('-p, --port <port>', 'Port to listen on')
|
|
202
|
-
.option('-h, --host <host>', 'Host to bind to'
|
|
171
|
+
.option('-h, --host <host>', 'Host to bind to')
|
|
203
172
|
.option('--no-reload', 'Disable hot reload (run once, like production)')
|
|
204
173
|
.action((options) => {
|
|
205
174
|
|
|
@@ -214,18 +183,19 @@ module.exports = function (program) {
|
|
|
214
183
|
process.exit(1);
|
|
215
184
|
}
|
|
216
185
|
|
|
217
|
-
const publicPort = parseInt(options.port ||process.env.APP_PORT, 10)
|
|
218
|
-
const publicHost = options.host
|
|
186
|
+
const publicPort = parseInt(options.port ||process.env.APP_PORT, 10);
|
|
187
|
+
const publicHost = options.host;
|
|
219
188
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
189
|
+
const env = Object.fromEntries(
|
|
190
|
+
Object.entries({
|
|
191
|
+
NODE_ENV: process.env.APP_ENV,
|
|
192
|
+
MILLERS_NODE_ENV: true,
|
|
193
|
+
MILLAS_HOST: publicHost,
|
|
194
|
+
MILLAS_PORT: String(publicPort),
|
|
195
|
+
}).filter(([, v]) => v !== undefined)
|
|
196
|
+
);
|
|
226
197
|
|
|
227
|
-
|
|
228
|
-
printBanner(publicHost, publicPort);
|
|
198
|
+
Object.assign(process.env, env)
|
|
229
199
|
|
|
230
200
|
if (options.reload !== false) {
|
|
231
201
|
new HotReloader(appBootstrap, publicPort, publicHost).start();
|
|
@@ -174,7 +174,7 @@ class Application {
|
|
|
174
174
|
|| parseInt(process.env.MILLAS_INTERNAL_PORT, 10)
|
|
175
175
|
|| parseInt(process.env.APP_PORT, 10)
|
|
176
176
|
|| 3000;
|
|
177
|
-
const _host = host ||
|
|
177
|
+
const _host = host || 'localhost';
|
|
178
178
|
|
|
179
179
|
await this._adapter.listen(_port, _host);
|
|
180
180
|
|
|
@@ -190,7 +190,9 @@ class Application {
|
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
_printStartupLog(host, port) {
|
|
193
|
+
|
|
193
194
|
const chalk = _tryChalk();
|
|
195
|
+
printBanner(host,port,chalk)
|
|
194
196
|
const routeCount = this._route.list().length;
|
|
195
197
|
const url = `http://${host}:${port}`;
|
|
196
198
|
|
|
@@ -344,4 +346,35 @@ function _tryChalk() {
|
|
|
344
346
|
p.white = id;
|
|
345
347
|
return p;
|
|
346
348
|
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const BANNER_LINES = [
|
|
352
|
+
' ███╗ ███╗██╗██╗ ██╗ █████╗ ███████╗',
|
|
353
|
+
' ████╗ ████║██║██║ ██║ ██╔══██╗██╔════╝',
|
|
354
|
+
' ██╔████╔██║██║██║ ██║ ███████║███████╗',
|
|
355
|
+
' ██║╚██╔╝██║██║██║ ██║ ██╔══██║╚════██║',
|
|
356
|
+
' ██║ ╚═╝ ██║██║███████╗███████╗██║ ██║███████║',
|
|
357
|
+
' ╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚══════╝',
|
|
358
|
+
];
|
|
359
|
+
|
|
360
|
+
function printBanner(host, port,chalk) {
|
|
361
|
+
const env = process.env.NODE_ENV || 'development';
|
|
362
|
+
const ver = 'v' + (require('../../package.json').version || '0.1.0');
|
|
363
|
+
const url = `http://${host}:${port}`;
|
|
364
|
+
const hr = chalk.dim(' ' + '─'.repeat(54));
|
|
365
|
+
const envColour = env === 'production' ? chalk.red
|
|
366
|
+
: env === 'staging' ? chalk.yellow
|
|
367
|
+
: chalk.green;
|
|
368
|
+
|
|
369
|
+
process.stdout.write('\n');
|
|
370
|
+
for (const line of BANNER_LINES) {
|
|
371
|
+
process.stdout.write(chalk.bold.cyan(line) + '\n');
|
|
372
|
+
}
|
|
373
|
+
process.stdout.write('\n' + hr + '\n');
|
|
374
|
+
process.stdout.write(
|
|
375
|
+
' ' + chalk.dim(ver.padEnd(8)) +
|
|
376
|
+
chalk.dim('│') + ' ' + envColour('⬤ ' + env) + ' ' +
|
|
377
|
+
chalk.dim('│') + ' ' + chalk.bold.white(url) + '\n'
|
|
378
|
+
);
|
|
379
|
+
process.stdout.write(hr + '\n\n');
|
|
347
380
|
}
|
package/src/orm/model/Model.js
CHANGED
|
@@ -569,6 +569,10 @@ class Model {
|
|
|
569
569
|
return new QueryBuilder(this._db(), this).select(...cols);
|
|
570
570
|
}
|
|
571
571
|
|
|
572
|
+
static selectRaw(sql, bindings = []) {
|
|
573
|
+
return new QueryBuilder(this._db(), this).selectRaw(sql, bindings);
|
|
574
|
+
}
|
|
575
|
+
|
|
572
576
|
static distinct(...cols) {
|
|
573
577
|
return new QueryBuilder(this._db(), this).distinct(...cols);
|
|
574
578
|
}
|
package/src/router/RouteEntry.js
CHANGED
|
@@ -78,6 +78,12 @@ class RouteEntry {
|
|
|
78
78
|
* Add extra middleware to this specific route after registration.
|
|
79
79
|
* Middleware aliases are appended to the existing list.
|
|
80
80
|
*
|
|
81
|
+
* Supports Laravel-style parameters:
|
|
82
|
+
* .middleware('auth')
|
|
83
|
+
* .middleware(['auth', 'throttle'])
|
|
84
|
+
* .middleware('verifyAction:payment_method_delete')
|
|
85
|
+
* .middleware(['auth', 'verifyAction:payment_method_delete'])
|
|
86
|
+
*
|
|
81
87
|
* @param {string|string[]} middleware
|
|
82
88
|
* @returns {RouteEntry}
|
|
83
89
|
*/
|
|
@@ -86,6 +92,18 @@ class RouteEntry {
|
|
|
86
92
|
this._entry.middleware = [...(this._entry.middleware || []), ...list];
|
|
87
93
|
return this;
|
|
88
94
|
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Set route name (Laravel-style).
|
|
98
|
+
* Route.get('/users', UserController, 'index').name('users.index')
|
|
99
|
+
*
|
|
100
|
+
* @param {string} name
|
|
101
|
+
* @returns {RouteEntry}
|
|
102
|
+
*/
|
|
103
|
+
name(name) {
|
|
104
|
+
this._entry.name = name;
|
|
105
|
+
return this;
|
|
106
|
+
}
|
|
89
107
|
}
|
|
90
108
|
|
|
91
109
|
module.exports = RouteEntry;
|