millas 0.2.12-beta → 0.2.12-beta-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/package.json +3 -16
- package/src/admin/ActivityLog.js +153 -52
- package/src/admin/Admin.js +400 -167
- package/src/admin/AdminAuth.js +213 -98
- package/src/admin/FormGenerator.js +372 -0
- package/src/admin/HookRegistry.js +256 -0
- package/src/admin/QueryEngine.js +263 -0
- package/src/admin/ViewContext.js +309 -0
- package/src/admin/WidgetRegistry.js +406 -0
- package/src/admin/index.js +17 -0
- package/src/admin/resources/AdminResource.js +383 -97
- package/src/admin/static/admin.css +1341 -0
- package/src/admin/static/date-picker.css +157 -0
- package/src/admin/static/date-picker.js +316 -0
- package/src/admin/static/json-editor.css +649 -0
- package/src/admin/static/json-editor.js +1429 -0
- package/src/admin/static/ui.js +1044 -0
- package/src/admin/views/layouts/base.njk +65 -1013
- package/src/admin/views/pages/detail.njk +40 -16
- package/src/admin/views/pages/form.njk +47 -599
- package/src/admin/views/pages/list.njk +145 -62
- package/src/admin/views/partials/form-field.njk +53 -0
- package/src/admin/views/partials/form-footer.njk +28 -0
- package/src/admin/views/partials/form-readonly.njk +114 -0
- package/src/admin/views/partials/form-scripts.njk +476 -0
- package/src/admin/views/partials/form-widget.njk +296 -0
- package/src/admin/views/partials/json-dialog.njk +80 -0
- package/src/admin/views/partials/json-editor.njk +37 -0
- package/src/admin.zip +0 -0
- package/src/auth/Auth.js +31 -10
- package/src/auth/AuthController.js +3 -1
- package/src/auth/AuthUser.js +119 -0
- package/src/cli.js +4 -2
- package/src/commands/createsuperuser.js +254 -0
- package/src/commands/lang.js +589 -0
- package/src/commands/migrate.js +154 -81
- package/src/commands/serve.js +82 -110
- package/src/container/AppInitializer.js +215 -0
- package/src/container/Application.js +278 -253
- package/src/container/HttpServer.js +156 -0
- package/src/container/MillasApp.js +29 -279
- package/src/container/MillasConfig.js +192 -0
- package/src/core/admin.js +5 -0
- package/src/core/auth.js +9 -0
- package/src/core/db.js +9 -0
- package/src/core/foundation.js +59 -0
- package/src/core/http.js +11 -0
- package/src/core/lang.js +1 -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/i18n/I18nServiceProvider.js +91 -0
- package/src/i18n/Translator.js +635 -0
- package/src/i18n/defaults.js +122 -0
- package/src/i18n/index.js +164 -0
- package/src/i18n/locales/en.js +55 -0
- package/src/i18n/locales/sw.js +48 -0
- package/src/index.js +5 -144
- package/src/logger/formatters/PrettyFormatter.js +103 -57
- package/src/logger/internal.js +2 -2
- package/src/logger/patchConsole.js +91 -81
- package/src/middleware/MiddlewareRegistry.js +62 -82
- package/src/migrations/system/0001_users.js +21 -0
- package/src/migrations/system/0002_admin_log.js +25 -0
- package/src/migrations/system/0003_sessions.js +23 -0
- package/src/orm/fields/index.js +210 -188
- package/src/orm/migration/DefaultValueParser.js +325 -0
- package/src/orm/migration/InteractiveResolver.js +191 -0
- package/src/orm/migration/Makemigrations.js +312 -0
- package/src/orm/migration/MigrationGraph.js +227 -0
- package/src/orm/migration/MigrationRunner.js +202 -108
- package/src/orm/migration/MigrationWriter.js +463 -0
- package/src/orm/migration/ModelInspector.js +412 -344
- package/src/orm/migration/ModelScanner.js +225 -0
- package/src/orm/migration/ProjectState.js +213 -0
- package/src/orm/migration/RenameDetector.js +175 -0
- package/src/orm/migration/SchemaBuilder.js +8 -81
- package/src/orm/migration/operations/base.js +57 -0
- package/src/orm/migration/operations/column.js +191 -0
- package/src/orm/migration/operations/fields.js +252 -0
- package/src/orm/migration/operations/index.js +55 -0
- package/src/orm/migration/operations/models.js +152 -0
- package/src/orm/migration/operations/registry.js +131 -0
- package/src/orm/migration/operations/special.js +51 -0
- package/src/orm/migration/utils.js +208 -0
- package/src/orm/model/Model.js +81 -13
- package/src/providers/AdminServiceProvider.js +66 -9
- package/src/providers/AuthServiceProvider.js +46 -7
- package/src/providers/CacheStorageServiceProvider.js +5 -3
- package/src/providers/DatabaseServiceProvider.js +3 -2
- package/src/providers/EventServiceProvider.js +2 -1
- package/src/providers/LogServiceProvider.js +7 -3
- package/src/providers/MailServiceProvider.js +4 -3
- package/src/providers/QueueServiceProvider.js +4 -3
- package/src/router/Router.js +119 -152
- package/src/scaffold/templates.js +83 -26
- package/src/facades/Validation.js +0 -69
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* HttpAdapter
|
|
5
|
+
*
|
|
6
|
+
* Abstract interface between the Millas kernel and any underlying HTTP engine.
|
|
7
|
+
* The kernel never imports Express (or Fastify, or Hono) directly — it only
|
|
8
|
+
* calls the methods defined here.
|
|
9
|
+
*
|
|
10
|
+
* To add a new HTTP engine, create a class that extends HttpAdapter and
|
|
11
|
+
* implements every method. The kernel works unchanged.
|
|
12
|
+
*
|
|
13
|
+
* ── Implemented by ───────────────────────────────────────────────────────────
|
|
14
|
+
*
|
|
15
|
+
* ExpressAdapter (default, ships with Millas)
|
|
16
|
+
* FastifyAdapter (future)
|
|
17
|
+
* HonoAdapter (future)
|
|
18
|
+
*
|
|
19
|
+
* ── Lifecycle ────────────────────────────────────────────────────────────────
|
|
20
|
+
*
|
|
21
|
+
* 1. adapter.applyBodyParsers() — JSON + urlencoded
|
|
22
|
+
* 2. adapter.applyMiddleware(fn) — any raw adapter-level middleware
|
|
23
|
+
* 3. adapter.mountRoute(verb, path, handlers) — register app routes
|
|
24
|
+
* 4. adapter.mountWelcome(handler) — optional dev welcome page
|
|
25
|
+
* 5. adapter.mountNotFound() — 404 handler
|
|
26
|
+
* 6. adapter.mountErrorHandler() — global error handler
|
|
27
|
+
* 7. await adapter.listen(port, host) — start accepting connections
|
|
28
|
+
* 8. adapter.close() — graceful shutdown
|
|
29
|
+
*/
|
|
30
|
+
class HttpAdapter {
|
|
31
|
+
|
|
32
|
+
// ── Setup ──────────────────────────────────────────────────────────────────
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Apply JSON + urlencoded body parsers.
|
|
36
|
+
* Called once during bootstrap, before any routes are mounted.
|
|
37
|
+
*/
|
|
38
|
+
applyBodyParsers() {
|
|
39
|
+
throw new Error(`${this.constructor.name} must implement applyBodyParsers()`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Apply a single raw middleware function at the adapter level.
|
|
44
|
+
* Used for things like helmet(), compression() that are engine-specific.
|
|
45
|
+
*
|
|
46
|
+
* @param {Function} fn — adapter-native middleware function
|
|
47
|
+
*/
|
|
48
|
+
applyMiddleware(fn) {
|
|
49
|
+
throw new Error(`${this.constructor.name} must implement applyMiddleware(fn)`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ── Route mounting ─────────────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Register a route handler.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} verb — 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS'
|
|
58
|
+
* @param {string} path — e.g. '/users/:id'
|
|
59
|
+
* @param {Function[]} handlers — [middleware..., terminalHandler]
|
|
60
|
+
* Each handler is a Millas kernel handler
|
|
61
|
+
* (expressReq, expressRes, expressNext) already
|
|
62
|
+
* converted by the adapter's wrapKernelHandler().
|
|
63
|
+
*/
|
|
64
|
+
mountRoute(verb, path, handlers) {
|
|
65
|
+
throw new Error(`${this.constructor.name} must implement mountRoute(verb, path, handlers)`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Mount the dev welcome page for GET /.
|
|
70
|
+
* Only called when no user route covers GET /.
|
|
71
|
+
*
|
|
72
|
+
* @param {Function} handler — adapter-native handler function
|
|
73
|
+
*/
|
|
74
|
+
mountWelcome(handler) {
|
|
75
|
+
throw new Error(`${this.constructor.name} must implement mountWelcome(handler)`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Mount the 404 fallback handler.
|
|
80
|
+
* Must be called AFTER all routes and mountWelcome().
|
|
81
|
+
*/
|
|
82
|
+
mountNotFound() {
|
|
83
|
+
throw new Error(`${this.constructor.name} must implement mountNotFound()`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Mount the global error handler.
|
|
88
|
+
* Must be called LAST — after mountNotFound().
|
|
89
|
+
*/
|
|
90
|
+
mountErrorHandler() {
|
|
91
|
+
throw new Error(`${this.constructor.name} must implement mountErrorHandler()`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ── Request / Response bridge ──────────────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Wrap a Millas kernel handler function into an adapter-native handler.
|
|
98
|
+
*
|
|
99
|
+
* The kernel handler signature is:
|
|
100
|
+
* (millaCtx: RequestContext, trackedNext: Function) => Promise<MillasResponse>
|
|
101
|
+
*
|
|
102
|
+
* The adapter wraps this into whatever its native handler signature is,
|
|
103
|
+
* e.g. (req, res, next) for Express.
|
|
104
|
+
*
|
|
105
|
+
* @param {Function} kernelFn
|
|
106
|
+
* @param {string} displayName — for error messages
|
|
107
|
+
* @param {object} container — DI container
|
|
108
|
+
* @returns {Function} adapter-native handler
|
|
109
|
+
*/
|
|
110
|
+
wrapKernelHandler(kernelFn, displayName, container) {
|
|
111
|
+
throw new Error(`${this.constructor.name} must implement wrapKernelHandler()`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Wrap a Millas middleware instance into an adapter-native handler.
|
|
116
|
+
*
|
|
117
|
+
* @param {object} instance — Millas Middleware instance with handle(ctx, next)
|
|
118
|
+
* @param {object} container — DI container
|
|
119
|
+
* @returns {Function} adapter-native handler
|
|
120
|
+
*/
|
|
121
|
+
wrapMiddleware(instance, container) {
|
|
122
|
+
throw new Error(`${this.constructor.name} must implement wrapMiddleware()`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Dispatch a MillasResponse to the underlying engine's response object.
|
|
127
|
+
*
|
|
128
|
+
* @param {MillasResponse} response
|
|
129
|
+
* @param {*} nativeRes — e.g. Express res
|
|
130
|
+
*/
|
|
131
|
+
dispatch(response, nativeRes) {
|
|
132
|
+
throw new Error(`${this.constructor.name} must implement dispatch(response, nativeRes)`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// ── Server lifecycle ───────────────────────────────────────────────────────
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Start listening on port/host.
|
|
139
|
+
* Returns a Promise that resolves once the server is bound.
|
|
140
|
+
*
|
|
141
|
+
* @param {number} port
|
|
142
|
+
* @param {string} host
|
|
143
|
+
* @returns {Promise<void>}
|
|
144
|
+
*/
|
|
145
|
+
listen(port, host) {
|
|
146
|
+
throw new Error(`${this.constructor.name} must implement listen(port, host)`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Gracefully close the server.
|
|
151
|
+
* Returns a Promise that resolves once all connections are drained.
|
|
152
|
+
*
|
|
153
|
+
* @returns {Promise<void>}
|
|
154
|
+
*/
|
|
155
|
+
close() {
|
|
156
|
+
throw new Error(`${this.constructor.name} must implement close()`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* The name of this adapter, used in logs and error messages.
|
|
161
|
+
* @returns {string}
|
|
162
|
+
*/
|
|
163
|
+
get name() {
|
|
164
|
+
return this.constructor.name;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
module.exports = HttpAdapter;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const ServiceProvider = require('../providers/ServiceProvider');
|
|
6
|
+
const Translator = require('./Translator');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* I18nServiceProvider
|
|
10
|
+
*
|
|
11
|
+
* Boots the translation system and registers the Trans singleton
|
|
12
|
+
* into the DI container.
|
|
13
|
+
*
|
|
14
|
+
* ── Setup in bootstrap/app.js ─────────────────────────────────────────────
|
|
15
|
+
*
|
|
16
|
+
* const { Millas } = require('millas');
|
|
17
|
+
* const I18nServiceProvider = require('millas/src/i18n/I18nServiceProvider');
|
|
18
|
+
*
|
|
19
|
+
* module.exports = Millas.config()
|
|
20
|
+
* .providers([I18nServiceProvider, AppServiceProvider])
|
|
21
|
+
* .create();
|
|
22
|
+
*
|
|
23
|
+
* ── config/app.js ─────────────────────────────────────────────────────────
|
|
24
|
+
*
|
|
25
|
+
* module.exports = {
|
|
26
|
+
* locale: 'en', // default locale
|
|
27
|
+
* fallback: 'en', // fallback when translation missing
|
|
28
|
+
* };
|
|
29
|
+
*
|
|
30
|
+
* ── lang/ directory ───────────────────────────────────────────────────────
|
|
31
|
+
*
|
|
32
|
+
* Place translation files at <basePath>/lang/:
|
|
33
|
+
*
|
|
34
|
+
* lang/
|
|
35
|
+
* en.js ← source language
|
|
36
|
+
* sw.js ← Swahili
|
|
37
|
+
* fr.js ← French
|
|
38
|
+
*
|
|
39
|
+
* ── Route-level locale switching ──────────────────────────────────────────
|
|
40
|
+
*
|
|
41
|
+
* Use the built-in middleware to auto-detect locale from requests:
|
|
42
|
+
*
|
|
43
|
+
* const { Trans } = require('millas/src/i18n');
|
|
44
|
+
* app.use(Trans.middleware());
|
|
45
|
+
*
|
|
46
|
+
* Or manually in a route:
|
|
47
|
+
* Trans.setLocale('sw');
|
|
48
|
+
*/
|
|
49
|
+
class I18nServiceProvider extends ServiceProvider {
|
|
50
|
+
|
|
51
|
+
register(container) {
|
|
52
|
+
// Register the Trans singleton into the DI container
|
|
53
|
+
const trans = require('./index').Trans;
|
|
54
|
+
container.instance('trans', trans);
|
|
55
|
+
container.instance('Trans', trans);
|
|
56
|
+
container.alias('i18n', 'trans');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async boot(container, app) {
|
|
60
|
+
const basePath = container.make('basePath') || process.cwd();
|
|
61
|
+
const trans = container.make('trans');
|
|
62
|
+
|
|
63
|
+
// Load config/app.js for locale settings
|
|
64
|
+
let locale = 'en';
|
|
65
|
+
let fallback = 'en';
|
|
66
|
+
let warnMissing = process.env.NODE_ENV !== 'production';
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const appConfig = require(path.join(basePath, 'config/app'));
|
|
70
|
+
if (appConfig.locale) locale = appConfig.locale;
|
|
71
|
+
if (appConfig.fallback) fallback = appConfig.fallback;
|
|
72
|
+
} catch { /* config/app.js not found or no locale keys */ }
|
|
73
|
+
|
|
74
|
+
// Lang path: <basePath>/lang/
|
|
75
|
+
const langPath = path.join(basePath, 'lang');
|
|
76
|
+
|
|
77
|
+
trans.configure({ locale, fallback, langPath, warnMissing });
|
|
78
|
+
|
|
79
|
+
// Log available locales on startup in debug mode
|
|
80
|
+
if (process.env.DEBUG || process.env.NODE_ENV === 'development') {
|
|
81
|
+
const available = trans.availableLocales();
|
|
82
|
+
if (available.length > 0 && !(available.length === 1 && available[0] === 'en')) {
|
|
83
|
+
process.stdout.write(
|
|
84
|
+
`[i18n] Locale: ${locale} | Fallback: ${fallback} | Available: ${available.join(', ')}\n`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = I18nServiceProvider;
|