millas 0.2.12-beta → 0.2.12-beta-1
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 +3 -16
- package/src/auth/Auth.js +13 -8
- package/src/auth/AuthController.js +3 -1
- package/src/auth/AuthUser.js +98 -0
- package/src/cli.js +1 -1
- package/src/commands/serve.js +81 -110
- package/src/container/AppInitializer.js +158 -0
- package/src/container/Application.js +278 -253
- package/src/container/HttpServer.js +156 -0
- package/src/container/MillasApp.js +23 -280
- package/src/container/MillasConfig.js +163 -0
- package/src/core/auth.js +9 -0
- package/src/core/db.js +8 -0
- package/src/core/foundation.js +67 -0
- package/src/core/http.js +11 -0
- package/src/core/mail.js +6 -0
- package/src/core/queue.js +7 -0
- package/src/core/validation.js +29 -0
- package/src/facades/Admin.js +1 -1
- package/src/facades/Auth.js +22 -39
- package/src/facades/Cache.js +21 -10
- package/src/facades/Database.js +1 -1
- package/src/facades/Events.js +18 -17
- package/src/facades/Facade.js +197 -0
- package/src/facades/Http.js +42 -45
- package/src/facades/Log.js +25 -49
- package/src/facades/Mail.js +27 -32
- package/src/facades/Queue.js +22 -15
- package/src/facades/Storage.js +18 -10
- package/src/facades/Url.js +53 -0
- package/src/http/HttpClient.js +673 -0
- package/src/http/ResponseDispatcher.js +18 -111
- package/src/http/UrlGenerator.js +375 -0
- package/src/http/WelcomePage.js +273 -0
- package/src/http/adapters/ExpressAdapter.js +315 -0
- package/src/http/adapters/HttpAdapter.js +168 -0
- package/src/http/adapters/index.js +9 -0
- package/src/index.js +5 -144
- package/src/logger/formatters/PrettyFormatter.js +15 -5
- package/src/logger/internal.js +2 -2
- package/src/logger/patchConsole.js +91 -81
- package/src/middleware/MiddlewareRegistry.js +62 -82
- package/src/orm/migration/ModelInspector.js +339 -340
- package/src/providers/AuthServiceProvider.js +9 -5
- package/src/providers/CacheStorageServiceProvider.js +3 -1
- package/src/providers/EventServiceProvider.js +2 -1
- package/src/providers/LogServiceProvider.js +3 -2
- package/src/providers/MailServiceProvider.js +3 -2
- package/src/providers/QueueServiceProvider.js +3 -2
- package/src/router/Router.js +119 -152
- package/src/scaffold/templates.js +8 -7
- package/src/facades/Validation.js +0 -69
|
@@ -16,7 +16,8 @@ const RoleMiddleware = require('../auth/RoleMiddleware');
|
|
|
16
16
|
*/
|
|
17
17
|
class AuthServiceProvider extends ServiceProvider {
|
|
18
18
|
register(container) {
|
|
19
|
-
container.instance('Auth',
|
|
19
|
+
container.instance('Auth', Auth);
|
|
20
|
+
container.alias('auth', 'Auth');
|
|
20
21
|
container.instance('AuthMiddleware', AuthMiddleware);
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -32,11 +33,14 @@ class AuthServiceProvider extends ServiceProvider {
|
|
|
32
33
|
};
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
// Load the User model if
|
|
36
|
-
|
|
36
|
+
// Load the app's User model if it exists.
|
|
37
|
+
// Falls back to the built-in AuthUser so Auth always has a model to work with.
|
|
38
|
+
let UserModel;
|
|
37
39
|
try {
|
|
38
40
|
UserModel = require(process.cwd() + '/app/models/User');
|
|
39
|
-
} catch {
|
|
41
|
+
} catch {
|
|
42
|
+
UserModel = require('../auth/AuthUser');
|
|
43
|
+
}
|
|
40
44
|
|
|
41
45
|
// Configure the Auth singleton
|
|
42
46
|
Auth.configure(authConfig, UserModel);
|
|
@@ -50,4 +54,4 @@ class AuthServiceProvider extends ServiceProvider {
|
|
|
50
54
|
}
|
|
51
55
|
}
|
|
52
56
|
|
|
53
|
-
module.exports = AuthServiceProvider;
|
|
57
|
+
module.exports = AuthServiceProvider;
|
|
@@ -12,6 +12,7 @@ const Storage = require('../storage/Storage');
|
|
|
12
12
|
class CacheServiceProvider extends ServiceProvider {
|
|
13
13
|
register(container) {
|
|
14
14
|
container.instance('Cache', Cache);
|
|
15
|
+
container.alias('cache', 'Cache');
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
async boot() {
|
|
@@ -41,6 +42,7 @@ class CacheServiceProvider extends ServiceProvider {
|
|
|
41
42
|
class StorageServiceProvider extends ServiceProvider {
|
|
42
43
|
register(container) {
|
|
43
44
|
container.instance('Storage', Storage);
|
|
45
|
+
container.alias('storage', 'Storage');
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
async boot() {
|
|
@@ -68,4 +70,4 @@ class StorageServiceProvider extends ServiceProvider {
|
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
module.exports = { CacheServiceProvider, StorageServiceProvider };
|
|
73
|
+
module.exports = { CacheServiceProvider, StorageServiceProvider };
|
|
@@ -19,6 +19,7 @@ const { emit } = require('../events/EventEmitter');
|
|
|
19
19
|
class EventServiceProvider extends ServiceProvider {
|
|
20
20
|
register(container) {
|
|
21
21
|
container.instance('EventEmitter', EventEmitter);
|
|
22
|
+
container.alias('events', 'EventEmitter');
|
|
22
23
|
container.instance('emit', emit);
|
|
23
24
|
}
|
|
24
25
|
|
|
@@ -31,4 +32,4 @@ class EventServiceProvider extends ServiceProvider {
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
module.exports = EventServiceProvider;
|
|
35
|
+
module.exports = EventServiceProvider;
|
|
@@ -39,8 +39,9 @@ const patchConsole = require('../logger/patchConsole');
|
|
|
39
39
|
*/
|
|
40
40
|
class LogServiceProvider extends ServiceProvider {
|
|
41
41
|
register(container) {
|
|
42
|
-
container.instance('Log',
|
|
43
|
-
container.instance('Logger',
|
|
42
|
+
container.instance('Log', Log);
|
|
43
|
+
container.instance('Logger', Logger);
|
|
44
|
+
container.alias('log', 'Log');
|
|
44
45
|
container.instance('MillasLog', MillasLog);
|
|
45
46
|
}
|
|
46
47
|
|
|
@@ -19,7 +19,8 @@ const MailMessage = require('../mail/MailMessage');
|
|
|
19
19
|
*/
|
|
20
20
|
class MailServiceProvider extends ServiceProvider {
|
|
21
21
|
register(container) {
|
|
22
|
-
container.instance('Mail',
|
|
22
|
+
container.instance('Mail', Mail);
|
|
23
|
+
container.alias('mail', 'Mail');
|
|
23
24
|
container.instance('MailMessage', MailMessage);
|
|
24
25
|
}
|
|
25
26
|
|
|
@@ -48,4 +49,4 @@ class MailServiceProvider extends ServiceProvider {
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
module.exports = MailServiceProvider;
|
|
52
|
+
module.exports = MailServiceProvider;
|
|
@@ -21,7 +21,8 @@ const { dispatch } = require('../queue/Queue');
|
|
|
21
21
|
*/
|
|
22
22
|
class QueueServiceProvider extends ServiceProvider {
|
|
23
23
|
register(container) {
|
|
24
|
-
container.instance('Queue',
|
|
24
|
+
container.instance('Queue', Queue);
|
|
25
|
+
container.alias('queue', 'Queue');
|
|
25
26
|
container.instance('dispatch', dispatch);
|
|
26
27
|
}
|
|
27
28
|
|
|
@@ -49,4 +50,4 @@ class QueueServiceProvider extends ServiceProvider {
|
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
module.exports = QueueServiceProvider;
|
|
53
|
+
module.exports = QueueServiceProvider;
|
package/src/router/Router.js
CHANGED
|
@@ -1,211 +1,178 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Router
|
|
5
|
+
*
|
|
6
|
+
* Bridges the Millas RouteRegistry to any HttpAdapter.
|
|
7
|
+
* Zero knowledge of Express (or any HTTP engine) — it only calls
|
|
8
|
+
* the adapter interface defined in HttpAdapter.js.
|
|
9
|
+
*
|
|
10
|
+
* Responsibilities:
|
|
11
|
+
* - Resolve route handlers from the RouteRegistry
|
|
12
|
+
* - Resolve middleware aliases from the MiddlewareRegistry
|
|
13
|
+
* - Ask the adapter to mount each route
|
|
14
|
+
* - Ask the adapter to mount the welcome page, 404, and error handler
|
|
15
|
+
*/
|
|
10
16
|
class Router {
|
|
11
17
|
/**
|
|
12
|
-
* @param {
|
|
13
|
-
* @param {RouteRegistry}
|
|
14
|
-
* @param {MiddlewareRegistry}
|
|
15
|
-
* @param {Container|null}
|
|
18
|
+
* @param {import('../http/adapters/HttpAdapter')} adapter
|
|
19
|
+
* @param {import('./RouteRegistry')} registry
|
|
20
|
+
* @param {import('./MiddlewareRegistry')} middlewareRegistry
|
|
21
|
+
* @param {import('../container/Container')|null} container
|
|
16
22
|
*/
|
|
17
|
-
constructor(
|
|
18
|
-
this.
|
|
23
|
+
constructor(adapter, registry, middlewareRegistry, container = null) {
|
|
24
|
+
this._adapter = adapter;
|
|
19
25
|
this._registry = registry;
|
|
20
|
-
this._mw = middlewareRegistry
|
|
26
|
+
this._mw = middlewareRegistry;
|
|
21
27
|
this._container = container;
|
|
22
28
|
}
|
|
23
29
|
|
|
30
|
+
// ── Public API ─────────────────────────────────────────────────────────────
|
|
31
|
+
|
|
24
32
|
/**
|
|
25
|
-
*
|
|
26
|
-
* Does NOT add
|
|
27
|
-
*
|
|
33
|
+
* Mount all registered routes onto the adapter.
|
|
34
|
+
* Does NOT add fallbacks — call mountFallbacks() after all routes
|
|
35
|
+
* and any extra middleware (e.g. Admin panel) have been added.
|
|
28
36
|
*/
|
|
29
37
|
mountRoutes() {
|
|
30
|
-
const
|
|
31
|
-
for (const route of routes) {
|
|
38
|
+
for (const route of this._registry.all()) {
|
|
32
39
|
this._bindRoute(route);
|
|
33
40
|
}
|
|
34
41
|
return this;
|
|
35
42
|
}
|
|
36
43
|
|
|
37
44
|
/**
|
|
38
|
-
*
|
|
39
|
-
* Must be called LAST — after all routes and admin
|
|
45
|
+
* Mount the 404 + error handlers.
|
|
46
|
+
* Must be called LAST — after all routes and the admin panel.
|
|
40
47
|
*/
|
|
41
48
|
mountFallbacks() {
|
|
42
|
-
this.
|
|
43
|
-
this.
|
|
49
|
+
this._maybeInjectWelcome();
|
|
50
|
+
this._adapter.mountNotFound();
|
|
51
|
+
this._adapter.mountErrorHandler();
|
|
44
52
|
return this;
|
|
45
53
|
}
|
|
46
54
|
|
|
47
55
|
/**
|
|
48
|
-
*
|
|
49
|
-
* AND add 404/error handlers (original behaviour).
|
|
56
|
+
* Mount routes + fallbacks in one call.
|
|
50
57
|
*/
|
|
51
58
|
mount() {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
this
|
|
57
|
-
this._app.use(ErrorRenderer.handler());
|
|
59
|
+
this.mountRoutes();
|
|
60
|
+
this._maybeInjectWelcome();
|
|
61
|
+
this._adapter.mountNotFound();
|
|
62
|
+
this._adapter.mountErrorHandler();
|
|
63
|
+
return this;
|
|
58
64
|
}
|
|
59
65
|
|
|
60
|
-
//
|
|
66
|
+
// ── Private ────────────────────────────────────────────────────────────────
|
|
61
67
|
|
|
62
68
|
_bindRoute(route) {
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
const middlewareHandlers = this._resolveMiddleware(route.middleware || []);
|
|
70
|
+
const terminalHandler = this._resolveTerminalHandler(
|
|
71
|
+
route.handler,
|
|
72
|
+
route.method,
|
|
73
|
+
route.verb,
|
|
74
|
+
route.path,
|
|
75
|
+
route.name
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
this._adapter.mountRoute(route.verb, route.path, [
|
|
79
|
+
...middlewareHandlers,
|
|
80
|
+
terminalHandler,
|
|
81
|
+
]);
|
|
70
82
|
}
|
|
71
83
|
|
|
72
84
|
_resolveMiddleware(list) {
|
|
73
85
|
return list.map(alias => {
|
|
74
86
|
try {
|
|
75
|
-
return this._mw.resolve(alias);
|
|
87
|
+
return this._mw.resolve(alias, this._adapter, this._container);
|
|
76
88
|
} catch (err) {
|
|
77
|
-
console.warn(`[Millas]
|
|
78
|
-
return (
|
|
89
|
+
console.warn(`[Millas] Middleware warning: ${err.message} — skipping.`);
|
|
90
|
+
return this._mw.resolvePassthrough(this._adapter);
|
|
79
91
|
}
|
|
80
92
|
});
|
|
81
93
|
}
|
|
82
94
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
95
|
+
_resolveTerminalHandler(handler, method, verb, path, routeName) {
|
|
96
|
+
const kernelFn = this._extractKernelFn(handler, method);
|
|
97
|
+
const displayName = this._buildDisplayName(handler, method, verb, path, routeName);
|
|
98
|
+
return this._adapter.wrapKernelHandler(kernelFn, displayName, this._container);
|
|
99
|
+
}
|
|
86
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Pull the actual function out of the handler definition.
|
|
103
|
+
* Three forms:
|
|
104
|
+
* 1. Bare function/arrow: Route.get('/', () => jsonify({}))
|
|
105
|
+
* 2. Controller class + method: Route.get('/', UserController, 'index')
|
|
106
|
+
* 3. Controller instance + method: Route.get('/', controllerInstance, 'index')
|
|
107
|
+
*/
|
|
108
|
+
_extractKernelFn(handler, method) {
|
|
87
109
|
if (typeof handler === 'function' && !method) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
: null;
|
|
93
|
-
} else if (typeof handler === 'function' && typeof method === 'string') {
|
|
110
|
+
return handler;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (typeof handler === 'function' && typeof method === 'string') {
|
|
94
114
|
const instance = new handler();
|
|
95
115
|
if (typeof instance[method] !== 'function') {
|
|
96
|
-
throw new Error(
|
|
116
|
+
throw new Error(
|
|
117
|
+
`Method "${method}" not found on controller "${handler.name}".`
|
|
118
|
+
);
|
|
97
119
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
120
|
+
return instance[method].bind(instance);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (typeof handler === 'object' && handler !== null && typeof method === 'string') {
|
|
101
124
|
if (typeof handler[method] !== 'function') {
|
|
102
125
|
throw new Error(`Method "${method}" not found on handler object.`);
|
|
103
126
|
}
|
|
104
|
-
|
|
105
|
-
inferredName = `${handler.constructor?.name || 'Controller'}.${method}`;
|
|
106
|
-
} else if (typeof handler === 'function') {
|
|
107
|
-
fn = handler;
|
|
108
|
-
inferredName = handler.name && handler.name !== 'anonymous' ? handler.name : null;
|
|
109
|
-
} else {
|
|
110
|
-
throw new Error(`Invalid route handler: ${JSON.stringify(handler)}`);
|
|
127
|
+
return handler[method].bind(handler);
|
|
111
128
|
}
|
|
112
129
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// 3. Named function (async function getUsers)
|
|
117
|
-
// 4. Route signature (GET /users/:id)
|
|
118
|
-
const displayName = routeName
|
|
119
|
-
|| inferredName
|
|
120
|
-
|| (verb && path ? `${verb.toUpperCase()} ${path}` : 'anonymous');
|
|
130
|
+
if (typeof handler === 'function') {
|
|
131
|
+
return handler;
|
|
132
|
+
}
|
|
121
133
|
|
|
122
|
-
|
|
134
|
+
throw new Error(`Invalid route handler: ${JSON.stringify(handler)}`);
|
|
123
135
|
}
|
|
124
136
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const trackedNext = (...args) => {
|
|
143
|
-
nextCalled = true;
|
|
144
|
-
expressNext(...args);
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
new Promise((resolve, reject) => {
|
|
148
|
-
try {
|
|
149
|
-
resolve(fn(ctx, trackedNext));
|
|
150
|
-
} catch (err) {
|
|
151
|
-
reject(err);
|
|
152
|
-
}
|
|
153
|
-
})
|
|
154
|
-
.then(value => {
|
|
155
|
-
if (nextCalled) return;
|
|
156
|
-
if (expressRes.headersSent) return;
|
|
157
|
-
|
|
158
|
-
if (value === undefined || value === null) {
|
|
159
|
-
const err = Object.assign(
|
|
160
|
-
new Error(
|
|
161
|
-
`The route handler "${fnName}" did not return a response.\n` +
|
|
162
|
-
`Return a MillasResponse or a plain value:\n\n` +
|
|
163
|
-
` return jsonify({ ok: true })\n` +
|
|
164
|
-
` return { ok: true } // auto-wrapped\n` +
|
|
165
|
-
` return 'Hello world' // auto-wrapped\n` +
|
|
166
|
-
` return redirect('/login')\n` +
|
|
167
|
-
` return view('home', { data })`
|
|
168
|
-
),
|
|
169
|
-
{ status: 500, statusCode: 500 }
|
|
170
|
-
);
|
|
171
|
-
return expressNext(err);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (value instanceof Error) return expressNext(value);
|
|
175
|
-
|
|
176
|
-
try {
|
|
177
|
-
const response = MillasResponse.isResponse(value)
|
|
178
|
-
? value
|
|
179
|
-
: ResponseDispatcher.autoWrap(value);
|
|
180
|
-
ResponseDispatcher.dispatch(response, expressRes);
|
|
181
|
-
} catch (dispatchErr) {
|
|
182
|
-
expressNext(dispatchErr);
|
|
183
|
-
}
|
|
184
|
-
})
|
|
185
|
-
.catch(expressNext);
|
|
186
|
-
};
|
|
137
|
+
_buildDisplayName(handler, method, verb, path, routeName) {
|
|
138
|
+
if (routeName) return routeName;
|
|
139
|
+
|
|
140
|
+
if (typeof handler === 'function' && method) {
|
|
141
|
+
return `${handler.name}.${method}`;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (
|
|
145
|
+
typeof handler === 'function' &&
|
|
146
|
+
handler.name &&
|
|
147
|
+
handler.name !== 'anonymous' &&
|
|
148
|
+
handler.name !== ''
|
|
149
|
+
) {
|
|
150
|
+
return handler.name;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return verb && path ? `${verb.toUpperCase()} ${path}` : 'anonymous';
|
|
187
154
|
}
|
|
188
155
|
|
|
189
156
|
/**
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
* 2. Return values are automatically sent as a response — so developers
|
|
194
|
-
* can write handlers without touching req/res at all:
|
|
195
|
-
*
|
|
196
|
-
* Route.get('/', () => ({ status: 'ok' }))
|
|
197
|
-
* Route.get('/hello', () => 'Hello world')
|
|
198
|
-
* Route.get('/user', async () => await User.find(1))
|
|
199
|
-
* Route.get('/ping', (req, res) => res.json({ pong: true })) // still works
|
|
200
|
-
*
|
|
201
|
-
* Return value rules:
|
|
202
|
-
* string → res.send(value)
|
|
203
|
-
* number → res.json(value) (rarely useful but safe)
|
|
204
|
-
* object/array → res.json(value)
|
|
205
|
-
* null/undefined → do nothing (handler called res itself, or next())
|
|
206
|
-
* Error → next(value)
|
|
157
|
+
* If no user-defined GET / route exists, ask the adapter to serve
|
|
158
|
+
* a developer-friendly welcome page.
|
|
159
|
+
* Only active outside production — silently skipped in prod.
|
|
207
160
|
*/
|
|
208
|
-
|
|
161
|
+
_maybeInjectWelcome() {
|
|
162
|
+
if (process.env.NODE_ENV === 'production') return;
|
|
163
|
+
|
|
164
|
+
const hasRoot = this._registry.all().some(
|
|
165
|
+
r => r.verb === 'GET' && (r.path === '/' || r.path === '')
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
if (!hasRoot) {
|
|
169
|
+
let version = '';
|
|
170
|
+
try { version = require('../../package.json').version; } catch {}
|
|
171
|
+
this._adapter.mountWelcome(
|
|
172
|
+
this._adapter.makeWelcomeHandler(version)
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
209
176
|
}
|
|
210
177
|
|
|
211
|
-
module.exports = Router;
|
|
178
|
+
module.exports = Router;
|
|
@@ -12,6 +12,8 @@ function getProjectFiles(projectName) {
|
|
|
12
12
|
scripts: {
|
|
13
13
|
start: 'node bootstrap/app.js',
|
|
14
14
|
dev: 'millas serve',
|
|
15
|
+
makemigrations: 'millas makemigration',
|
|
16
|
+
migrate: 'millas migrate',
|
|
15
17
|
serve: 'millas serve',
|
|
16
18
|
},
|
|
17
19
|
dependencies: {
|
|
@@ -88,18 +90,17 @@ module.exports = {
|
|
|
88
90
|
|
|
89
91
|
require('dotenv').config();
|
|
90
92
|
|
|
91
|
-
const {
|
|
93
|
+
const { Millas } = require('millas');
|
|
92
94
|
const AppServiceProvider = require('../providers/AppServiceProvider');
|
|
93
95
|
|
|
94
|
-
|
|
96
|
+
module.exports = Millas.config()
|
|
95
97
|
.providers([AppServiceProvider])
|
|
96
98
|
.routes(Route => {
|
|
97
99
|
require('../routes/web')(Route);
|
|
98
100
|
require('../routes/api')(Route);
|
|
99
101
|
})
|
|
100
|
-
.withAdmin()
|
|
101
|
-
|
|
102
|
-
module.exports = app.start();
|
|
102
|
+
.withAdmin()
|
|
103
|
+
.create();
|
|
103
104
|
`,
|
|
104
105
|
|
|
105
106
|
// ─── routes/web.js ────────────────────────────────────────────
|
|
@@ -242,7 +243,7 @@ module.exports = {
|
|
|
242
243
|
// ─── providers/AppServiceProvider.js ──────────────────────────
|
|
243
244
|
'providers/AppServiceProvider.js': `'use strict';
|
|
244
245
|
|
|
245
|
-
const { ServiceProvider } = require('millas');
|
|
246
|
+
const { ServiceProvider } = require('millas/core/foundation');
|
|
246
247
|
|
|
247
248
|
/**
|
|
248
249
|
* AppServiceProvider
|
|
@@ -326,4 +327,4 @@ providers/ # Service providers
|
|
|
326
327
|
};
|
|
327
328
|
}
|
|
328
329
|
|
|
329
|
-
module.exports = { getProjectFiles };
|
|
330
|
+
module.exports = { getProjectFiles };
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* millas/facades/Validation
|
|
5
|
-
*
|
|
6
|
-
* Field validators and schema runner.
|
|
7
|
-
*
|
|
8
|
-
* const { string, email, number, boolean, date, array, object, file, Validator }
|
|
9
|
-
* = require('millas/facades/Validation');
|
|
10
|
-
*
|
|
11
|
-
* Route.post('/register', async ({ body }) => {
|
|
12
|
-
* const data = await body.validate({
|
|
13
|
-
* name: string('Must be text').required('Name is required').min(2).max(100),
|
|
14
|
-
* email: email().required(),
|
|
15
|
-
* age: number().optional().min(0).max(120),
|
|
16
|
-
* password: string().required().min(8).confirmed(),
|
|
17
|
-
* role: string().oneOf(['admin','user']).default('user'),
|
|
18
|
-
* tags: array().of(string().required()).optional(),
|
|
19
|
-
* address: object({
|
|
20
|
-
* city: string().required(),
|
|
21
|
-
* zip: string().matches(/^\d{5}$/, 'Invalid ZIP'),
|
|
22
|
-
* }).optional(),
|
|
23
|
-
* avatar: file().optional().image().maxSize('2mb'),
|
|
24
|
-
* });
|
|
25
|
-
* return jsonify(await User.create(data), { status: 201 });
|
|
26
|
-
* });
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
const {
|
|
30
|
-
Validator,
|
|
31
|
-
BaseValidator,
|
|
32
|
-
StringValidator,
|
|
33
|
-
EmailValidator,
|
|
34
|
-
NumberValidator,
|
|
35
|
-
BooleanValidator,
|
|
36
|
-
DateValidator,
|
|
37
|
-
ArrayValidator,
|
|
38
|
-
ObjectValidator,
|
|
39
|
-
FileValidator,
|
|
40
|
-
string,
|
|
41
|
-
email,
|
|
42
|
-
number,
|
|
43
|
-
boolean,
|
|
44
|
-
date,
|
|
45
|
-
array,
|
|
46
|
-
} = require('../index');
|
|
47
|
-
|
|
48
|
-
const { object, file } = require('../validation/Validator');
|
|
49
|
-
|
|
50
|
-
module.exports = {
|
|
51
|
-
Validator,
|
|
52
|
-
BaseValidator,
|
|
53
|
-
StringValidator,
|
|
54
|
-
EmailValidator,
|
|
55
|
-
NumberValidator,
|
|
56
|
-
BooleanValidator,
|
|
57
|
-
DateValidator,
|
|
58
|
-
ArrayValidator,
|
|
59
|
-
ObjectValidator,
|
|
60
|
-
FileValidator,
|
|
61
|
-
string,
|
|
62
|
-
email,
|
|
63
|
-
number,
|
|
64
|
-
boolean,
|
|
65
|
-
date,
|
|
66
|
-
array,
|
|
67
|
-
object,
|
|
68
|
-
file,
|
|
69
|
-
};
|