@morojs/moro 1.0.0 → 1.0.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/README.md +1 -1
- package/dist/core/config/index.d.ts +5 -5
- package/dist/core/config/index.js +1 -1
- package/dist/core/config/index.js.map +1 -1
- package/dist/core/config/loader.d.ts +1 -1
- package/dist/core/config/loader.js +58 -82
- package/dist/core/config/loader.js.map +1 -1
- package/dist/core/config/schema.d.ts +1 -1
- package/dist/core/config/schema.js +52 -111
- package/dist/core/config/schema.js.map +1 -1
- package/dist/core/config/utils.d.ts +2 -2
- package/dist/core/config/utils.js +18 -18
- package/dist/core/config/utils.js.map +1 -1
- package/dist/core/database/adapters/drizzle.d.ts +1 -1
- package/dist/core/database/adapters/drizzle.js +39 -55
- package/dist/core/database/adapters/drizzle.js.map +1 -1
- package/dist/core/database/adapters/index.d.ts +7 -7
- package/dist/core/database/adapters/index.js +11 -11
- package/dist/core/database/adapters/index.js.map +1 -1
- package/dist/core/database/adapters/mongodb.d.ts +1 -1
- package/dist/core/database/adapters/mongodb.js +19 -23
- package/dist/core/database/adapters/mongodb.js.map +1 -1
- package/dist/core/database/adapters/mysql.d.ts +1 -1
- package/dist/core/database/adapters/mysql.js +31 -27
- package/dist/core/database/adapters/mysql.js.map +1 -1
- package/dist/core/database/adapters/postgresql.d.ts +1 -1
- package/dist/core/database/adapters/postgresql.js +27 -35
- package/dist/core/database/adapters/postgresql.js.map +1 -1
- package/dist/core/database/adapters/redis.d.ts +1 -1
- package/dist/core/database/adapters/redis.js +24 -24
- package/dist/core/database/adapters/redis.js.map +1 -1
- package/dist/core/database/adapters/sqlite.d.ts +1 -1
- package/dist/core/database/adapters/sqlite.js +36 -36
- package/dist/core/database/adapters/sqlite.js.map +1 -1
- package/dist/core/database/index.d.ts +2 -2
- package/dist/core/docs/index.d.ts +7 -7
- package/dist/core/docs/index.js +13 -15
- package/dist/core/docs/index.js.map +1 -1
- package/dist/core/docs/openapi-generator.d.ts +5 -5
- package/dist/core/docs/openapi-generator.js +93 -94
- package/dist/core/docs/openapi-generator.js.map +1 -1
- package/dist/core/docs/simple-docs.d.ts +1 -1
- package/dist/core/docs/simple-docs.js +25 -28
- package/dist/core/docs/simple-docs.js.map +1 -1
- package/dist/core/docs/swagger-ui.d.ts +2 -2
- package/dist/core/docs/swagger-ui.js +46 -51
- package/dist/core/docs/swagger-ui.js.map +1 -1
- package/dist/core/docs/zod-to-openapi.d.ts +1 -1
- package/dist/core/docs/zod-to-openapi.js +115 -125
- package/dist/core/docs/zod-to-openapi.js.map +1 -1
- package/dist/core/events/event-bus.d.ts +1 -1
- package/dist/core/events/event-bus.js +15 -21
- package/dist/core/events/event-bus.js.map +1 -1
- package/dist/core/events/index.d.ts +2 -2
- package/dist/core/framework.d.ts +5 -5
- package/dist/core/framework.js +55 -60
- package/dist/core/framework.js.map +1 -1
- package/dist/core/http/http-server.d.ts +2 -2
- package/dist/core/http/http-server.js +228 -261
- package/dist/core/http/http-server.js.map +1 -1
- package/dist/core/http/index.d.ts +3 -3
- package/dist/core/http/router.d.ts +1 -1
- package/dist/core/http/router.js +15 -17
- package/dist/core/http/router.js.map +1 -1
- package/dist/core/logger/filters.d.ts +1 -1
- package/dist/core/logger/filters.js +16 -16
- package/dist/core/logger/filters.js.map +1 -1
- package/dist/core/logger/index.d.ts +3 -3
- package/dist/core/logger/logger.d.ts +1 -1
- package/dist/core/logger/logger.js +48 -59
- package/dist/core/logger/logger.js.map +1 -1
- package/dist/core/logger/outputs.d.ts +4 -4
- package/dist/core/logger/outputs.js +16 -20
- package/dist/core/logger/outputs.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cache/file.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cache/file.js +19 -19
- package/dist/core/middleware/built-in/adapters/cache/file.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cache/index.d.ts +4 -4
- package/dist/core/middleware/built-in/adapters/cache/index.js +3 -3
- package/dist/core/middleware/built-in/adapters/cache/index.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cache/memory.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cache/memory.js +5 -5
- package/dist/core/middleware/built-in/adapters/cache/memory.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cache/redis.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cache/redis.js +18 -18
- package/dist/core/middleware/built-in/adapters/cache/redis.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/azure.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/azure.js +8 -8
- package/dist/core/middleware/built-in/adapters/cdn/azure.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js +14 -14
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js +13 -15
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/index.d.ts +4 -4
- package/dist/core/middleware/built-in/adapters/cdn/index.js +3 -3
- package/dist/core/middleware/built-in/adapters/index.d.ts +4 -4
- package/dist/core/middleware/built-in/auth.d.ts +1 -1
- package/dist/core/middleware/built-in/auth.js +14 -14
- package/dist/core/middleware/built-in/cache.d.ts +2 -2
- package/dist/core/middleware/built-in/cache.js +43 -45
- package/dist/core/middleware/built-in/cache.js.map +1 -1
- package/dist/core/middleware/built-in/cdn.d.ts +2 -2
- package/dist/core/middleware/built-in/cdn.js +27 -29
- package/dist/core/middleware/built-in/cdn.js.map +1 -1
- package/dist/core/middleware/built-in/cookie.d.ts +2 -2
- package/dist/core/middleware/built-in/cookie.js +17 -17
- package/dist/core/middleware/built-in/cookie.js.map +1 -1
- package/dist/core/middleware/built-in/cors.d.ts +1 -1
- package/dist/core/middleware/built-in/cors.js +13 -13
- package/dist/core/middleware/built-in/csp.d.ts +1 -1
- package/dist/core/middleware/built-in/csp.js +22 -25
- package/dist/core/middleware/built-in/csp.js.map +1 -1
- package/dist/core/middleware/built-in/csrf.d.ts +1 -1
- package/dist/core/middleware/built-in/csrf.js +21 -24
- package/dist/core/middleware/built-in/csrf.js.map +1 -1
- package/dist/core/middleware/built-in/error-tracker.js +2 -2
- package/dist/core/middleware/built-in/index.d.ts +14 -14
- package/dist/core/middleware/built-in/performance-monitor.js +2 -2
- package/dist/core/middleware/built-in/rate-limit.d.ts +1 -1
- package/dist/core/middleware/built-in/rate-limit.js +12 -12
- package/dist/core/middleware/built-in/request-logger.js.map +1 -1
- package/dist/core/middleware/built-in/session.d.ts +5 -5
- package/dist/core/middleware/built-in/session.js +35 -38
- package/dist/core/middleware/built-in/session.js.map +1 -1
- package/dist/core/middleware/built-in/sse.d.ts +1 -1
- package/dist/core/middleware/built-in/sse.js +20 -22
- package/dist/core/middleware/built-in/sse.js.map +1 -1
- package/dist/core/middleware/built-in/validation.d.ts +1 -1
- package/dist/core/middleware/built-in/validation.js +13 -13
- package/dist/core/middleware/index.d.ts +5 -5
- package/dist/core/middleware/index.js +16 -16
- package/dist/core/middleware/index.js.map +1 -1
- package/dist/core/modules/auto-discovery.d.ts +2 -2
- package/dist/core/modules/auto-discovery.js +12 -13
- package/dist/core/modules/auto-discovery.js.map +1 -1
- package/dist/core/modules/index.d.ts +2 -2
- package/dist/core/modules/index.js.map +1 -1
- package/dist/core/modules/modules.d.ts +3 -3
- package/dist/core/modules/modules.js +3 -6
- package/dist/core/modules/modules.js.map +1 -1
- package/dist/core/networking/index.d.ts +2 -2
- package/dist/core/networking/index.js.map +1 -1
- package/dist/core/networking/service-discovery.d.ts +2 -2
- package/dist/core/networking/service-discovery.js +27 -27
- package/dist/core/networking/service-discovery.js.map +1 -1
- package/dist/core/networking/websocket-manager.d.ts +3 -3
- package/dist/core/networking/websocket-manager.js +15 -16
- package/dist/core/networking/websocket-manager.js.map +1 -1
- package/dist/core/routing/app-integration.d.ts +2 -2
- package/dist/core/routing/app-integration.js +13 -13
- package/dist/core/routing/app-integration.js.map +1 -1
- package/dist/core/routing/index.d.ts +3 -3
- package/dist/core/routing/index.js +43 -52
- package/dist/core/routing/index.js.map +1 -1
- package/dist/core/runtime/aws-lambda-adapter.d.ts +3 -3
- package/dist/core/runtime/aws-lambda-adapter.js +14 -16
- package/dist/core/runtime/aws-lambda-adapter.js.map +1 -1
- package/dist/core/runtime/base-adapter.d.ts +2 -2
- package/dist/core/runtime/base-adapter.js +11 -12
- package/dist/core/runtime/base-adapter.js.map +1 -1
- package/dist/core/runtime/cloudflare-workers-adapter.d.ts +3 -3
- package/dist/core/runtime/cloudflare-workers-adapter.js +20 -21
- package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -1
- package/dist/core/runtime/index.d.ts +9 -9
- package/dist/core/runtime/index.js +4 -4
- package/dist/core/runtime/index.js.map +1 -1
- package/dist/core/runtime/node-adapter.d.ts +5 -5
- package/dist/core/runtime/node-adapter.js +35 -35
- package/dist/core/runtime/node-adapter.js.map +1 -1
- package/dist/core/runtime/vercel-edge-adapter.d.ts +3 -3
- package/dist/core/runtime/vercel-edge-adapter.js +12 -15
- package/dist/core/runtime/vercel-edge-adapter.js.map +1 -1
- package/dist/core/utilities/circuit-breaker.js +6 -6
- package/dist/core/utilities/container.d.ts +1 -1
- package/dist/core/utilities/container.js +17 -22
- package/dist/core/utilities/container.js.map +1 -1
- package/dist/core/utilities/hooks.d.ts +3 -3
- package/dist/core/utilities/hooks.js +11 -11
- package/dist/core/utilities/hooks.js.map +1 -1
- package/dist/core/utilities/index.d.ts +4 -4
- package/dist/core/validation/index.d.ts +3 -3
- package/dist/core/validation/index.js +15 -15
- package/dist/core/validation/index.js.map +1 -1
- package/dist/index.d.ts +31 -30
- package/dist/index.js +28 -1
- package/dist/index.js.map +1 -1
- package/dist/moro.d.ts +14 -14
- package/dist/moro.js +79 -88
- package/dist/moro.js.map +1 -1
- package/dist/types/cache.d.ts +1 -1
- package/dist/types/core.d.ts +2 -2
- package/dist/types/events.d.ts +19 -19
- package/dist/types/hooks.d.ts +1 -1
- package/dist/types/http.d.ts +2 -2
- package/dist/types/logger.d.ts +3 -3
- package/dist/types/module.d.ts +2 -2
- package/dist/types/runtime.d.ts +2 -2
- package/dist/types/session.d.ts +4 -4
- package/package.json +180 -164
- package/src/core/config/index.ts +7 -9
- package/src/core/config/loader.ts +86 -158
- package/src/core/config/schema.ts +59 -122
- package/src/core/config/utils.ts +27 -45
- package/src/core/database/adapters/drizzle.ts +53 -75
- package/src/core/database/adapters/index.ts +26 -29
- package/src/core/database/adapters/mongodb.ts +31 -54
- package/src/core/database/adapters/mysql.ts +40 -50
- package/src/core/database/adapters/postgresql.ts +32 -42
- package/src/core/database/adapters/redis.ts +31 -36
- package/src/core/database/adapters/sqlite.ts +43 -51
- package/src/core/database/index.ts +2 -2
- package/src/core/docs/index.ts +25 -39
- package/src/core/docs/openapi-generator.ts +104 -117
- package/src/core/docs/simple-docs.ts +29 -39
- package/src/core/docs/swagger-ui.ts +57 -76
- package/src/core/docs/zod-to-openapi.ts +121 -153
- package/src/core/events/event-bus.ts +22 -45
- package/src/core/events/index.ts +2 -2
- package/src/core/framework.ts +119 -197
- package/src/core/http/http-server.ts +260 -360
- package/src/core/http/index.ts +3 -8
- package/src/core/http/router.ts +19 -31
- package/src/core/logger/filters.ts +19 -22
- package/src/core/logger/index.ts +3 -3
- package/src/core/logger/logger.ts +59 -100
- package/src/core/logger/outputs.ts +23 -27
- package/src/core/middleware/built-in/adapters/cache/file.ts +21 -23
- package/src/core/middleware/built-in/adapters/cache/index.ts +11 -14
- package/src/core/middleware/built-in/adapters/cache/memory.ts +7 -7
- package/src/core/middleware/built-in/adapters/cache/redis.ts +21 -24
- package/src/core/middleware/built-in/adapters/cdn/azure.ts +10 -18
- package/src/core/middleware/built-in/adapters/cdn/cloudflare.ts +19 -36
- package/src/core/middleware/built-in/adapters/cdn/cloudfront.ts +17 -26
- package/src/core/middleware/built-in/adapters/cdn/index.ts +10 -10
- package/src/core/middleware/built-in/adapters/index.ts +4 -4
- package/src/core/middleware/built-in/auth.ts +16 -16
- package/src/core/middleware/built-in/cache.ts +50 -67
- package/src/core/middleware/built-in/cdn.ts +34 -61
- package/src/core/middleware/built-in/cookie.ts +23 -28
- package/src/core/middleware/built-in/cors.ts +17 -17
- package/src/core/middleware/built-in/csp.ts +25 -31
- package/src/core/middleware/built-in/csrf.ts +24 -29
- package/src/core/middleware/built-in/error-tracker.ts +3 -3
- package/src/core/middleware/built-in/index.ts +28 -28
- package/src/core/middleware/built-in/performance-monitor.ts +4 -4
- package/src/core/middleware/built-in/rate-limit.ts +15 -15
- package/src/core/middleware/built-in/request-logger.ts +1 -3
- package/src/core/middleware/built-in/session.ts +47 -70
- package/src/core/middleware/built-in/sse.ts +23 -28
- package/src/core/middleware/built-in/validation.ts +15 -15
- package/src/core/middleware/index.ts +26 -37
- package/src/core/modules/auto-discovery.ts +21 -31
- package/src/core/modules/index.ts +2 -5
- package/src/core/modules/modules.ts +11 -20
- package/src/core/networking/index.ts +2 -6
- package/src/core/networking/service-discovery.ts +41 -61
- package/src/core/networking/websocket-manager.ts +27 -36
- package/src/core/routing/app-integration.ts +19 -32
- package/src/core/routing/index.ts +57 -88
- package/src/core/runtime/aws-lambda-adapter.ts +20 -30
- package/src/core/runtime/base-adapter.ts +17 -27
- package/src/core/runtime/cloudflare-workers-adapter.ts +28 -42
- package/src/core/runtime/index.ts +21 -33
- package/src/core/runtime/node-adapter.ts +59 -73
- package/src/core/runtime/vercel-edge-adapter.ts +18 -29
- package/src/core/utilities/circuit-breaker.ts +7 -7
- package/src/core/utilities/container.ts +52 -89
- package/src/core/utilities/hooks.ts +17 -23
- package/src/core/utilities/index.ts +4 -4
- package/src/core/validation/index.ts +25 -51
- package/src/index.ts +58 -60
- package/src/moro.ts +119 -191
- package/src/types/cache.ts +1 -1
- package/src/types/core.ts +2 -2
- package/src/types/database.ts +2 -10
- package/src/types/events.ts +23 -31
- package/src/types/hooks.ts +1 -1
- package/src/types/http.ts +5 -8
- package/src/types/logger.ts +7 -23
- package/src/types/module.ts +2 -2
- package/src/types/runtime.ts +6 -21
- package/src/types/session.ts +4 -4
package/src/core/framework.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
// src/core/framework.ts
|
|
2
|
-
import { createServer, Server } from
|
|
2
|
+
import { createServer, Server } from 'http';
|
|
3
3
|
import {
|
|
4
4
|
createSecureServer as createHttp2SecureServer,
|
|
5
5
|
createServer as createHttp2Server,
|
|
6
|
-
} from
|
|
7
|
-
import { Server as SocketIOServer } from
|
|
8
|
-
import { EventEmitter } from
|
|
9
|
-
import { MoroHttpServer, HttpRequest, HttpResponse, middleware } from
|
|
10
|
-
import { Router } from
|
|
11
|
-
import { Container } from
|
|
12
|
-
import { ModuleLoader } from
|
|
13
|
-
import { WebSocketManager } from
|
|
14
|
-
import { CircuitBreaker } from
|
|
15
|
-
import { MoroEventBus } from
|
|
16
|
-
import { createFrameworkLogger, logger as globalLogger } from
|
|
17
|
-
import { ModuleConfig, InternalRouteDefinition } from
|
|
18
|
-
import { LogLevel, LoggerOptions } from
|
|
6
|
+
} from 'http2';
|
|
7
|
+
import { Server as SocketIOServer } from 'socket.io';
|
|
8
|
+
import { EventEmitter } from 'events';
|
|
9
|
+
import { MoroHttpServer, HttpRequest, HttpResponse, middleware } from './http';
|
|
10
|
+
import { Router } from './http';
|
|
11
|
+
import { Container } from './utilities';
|
|
12
|
+
import { ModuleLoader } from './modules';
|
|
13
|
+
import { WebSocketManager } from './networking';
|
|
14
|
+
import { CircuitBreaker } from './utilities';
|
|
15
|
+
import { MoroEventBus } from './events';
|
|
16
|
+
import { createFrameworkLogger, logger as globalLogger } from './logger';
|
|
17
|
+
import { ModuleConfig, InternalRouteDefinition } from '../types/module';
|
|
18
|
+
import { LogLevel, LoggerOptions } from '../types/logger';
|
|
19
19
|
|
|
20
20
|
export interface MoroOptions {
|
|
21
21
|
http2?: boolean;
|
|
@@ -43,10 +43,7 @@ export class Moro extends EventEmitter {
|
|
|
43
43
|
private moduleLoader: ModuleLoader;
|
|
44
44
|
private websocketManager: WebSocketManager;
|
|
45
45
|
private circuitBreakers = new Map<string, CircuitBreaker>();
|
|
46
|
-
private rateLimiters = new Map<
|
|
47
|
-
string,
|
|
48
|
-
Map<string, { count: number; resetTime: number }>
|
|
49
|
-
>();
|
|
46
|
+
private rateLimiters = new Map<string, Map<string, { count: number; resetTime: number }>>();
|
|
50
47
|
private ioInstance: SocketIOServer;
|
|
51
48
|
// Enterprise-grade event system
|
|
52
49
|
private eventBus: MoroEventBus;
|
|
@@ -62,8 +59,8 @@ export class Moro extends EventEmitter {
|
|
|
62
59
|
if (options.logger !== undefined) {
|
|
63
60
|
if (options.logger === false) {
|
|
64
61
|
// Disable logging by setting level to fatal (highest level)
|
|
65
|
-
globalLogger.setLevel(
|
|
66
|
-
} else if (typeof options.logger ===
|
|
62
|
+
globalLogger.setLevel('fatal');
|
|
63
|
+
} else if (typeof options.logger === 'object') {
|
|
67
64
|
// Configure logger with provided options
|
|
68
65
|
if (options.logger.level) {
|
|
69
66
|
globalLogger.setLevel(options.logger.level);
|
|
@@ -74,7 +71,7 @@ export class Moro extends EventEmitter {
|
|
|
74
71
|
}
|
|
75
72
|
|
|
76
73
|
// Initialize framework logger after global configuration
|
|
77
|
-
this.logger = createFrameworkLogger(
|
|
74
|
+
this.logger = createFrameworkLogger('Core');
|
|
78
75
|
|
|
79
76
|
this.httpServer = new MoroHttpServer();
|
|
80
77
|
|
|
@@ -87,24 +84,24 @@ export class Moro extends EventEmitter {
|
|
|
87
84
|
}
|
|
88
85
|
|
|
89
86
|
// Handle HTTP/2 streams manually
|
|
90
|
-
this.server.on(
|
|
87
|
+
this.server.on('stream', (stream: any, headers: any) => {
|
|
91
88
|
// Convert HTTP/2 stream to HTTP/1.1-like request/response
|
|
92
89
|
const req = stream as any;
|
|
93
90
|
const res = stream as any;
|
|
94
|
-
req.url = headers[
|
|
95
|
-
req.method = headers[
|
|
91
|
+
req.url = headers[':path'];
|
|
92
|
+
req.method = headers[':method'];
|
|
96
93
|
req.headers = headers;
|
|
97
|
-
this.httpServer[
|
|
94
|
+
this.httpServer['handleRequest'](req, res);
|
|
98
95
|
});
|
|
99
96
|
|
|
100
|
-
this.logger.info(
|
|
97
|
+
this.logger.info('HTTP/2 server created', 'ServerInit');
|
|
101
98
|
} else {
|
|
102
99
|
this.server = this.httpServer.getServer();
|
|
103
100
|
}
|
|
104
101
|
|
|
105
102
|
this.io = new SocketIOServer(this.server, {
|
|
106
|
-
cors: { origin:
|
|
107
|
-
path:
|
|
103
|
+
cors: { origin: '*' },
|
|
104
|
+
path: '/socket.io/',
|
|
108
105
|
});
|
|
109
106
|
|
|
110
107
|
this.ioInstance = this.io;
|
|
@@ -114,9 +111,7 @@ export class Moro extends EventEmitter {
|
|
|
114
111
|
|
|
115
112
|
// Configure WebSocket advanced features
|
|
116
113
|
if (options.websocket?.customIdGenerator) {
|
|
117
|
-
this.websocketManager.setCustomIdGenerator(
|
|
118
|
-
options.websocket.customIdGenerator,
|
|
119
|
-
);
|
|
114
|
+
this.websocketManager.setCustomIdGenerator(options.websocket.customIdGenerator);
|
|
120
115
|
}
|
|
121
116
|
|
|
122
117
|
if (options.websocket?.compression) {
|
|
@@ -127,11 +122,11 @@ export class Moro extends EventEmitter {
|
|
|
127
122
|
this.eventBus = new MoroEventBus({
|
|
128
123
|
maxListeners: 200,
|
|
129
124
|
enableMetrics: true,
|
|
130
|
-
isolation:
|
|
125
|
+
isolation: 'module',
|
|
131
126
|
});
|
|
132
127
|
|
|
133
128
|
// Register event bus in DI container as factory
|
|
134
|
-
this.container.register(
|
|
129
|
+
this.container.register('eventBus', () => this.eventBus);
|
|
135
130
|
|
|
136
131
|
this.setupCore();
|
|
137
132
|
}
|
|
@@ -149,7 +144,7 @@ export class Moro extends EventEmitter {
|
|
|
149
144
|
|
|
150
145
|
// Performance middleware
|
|
151
146
|
this.httpServer.use(middleware.compression());
|
|
152
|
-
this.httpServer.use(middleware.bodySize({ limit:
|
|
147
|
+
this.httpServer.use(middleware.bodySize({ limit: '10mb' }));
|
|
153
148
|
|
|
154
149
|
// Request tracking middleware
|
|
155
150
|
this.httpServer.use(this.requestTrackingMiddleware());
|
|
@@ -162,10 +157,10 @@ export class Moro extends EventEmitter {
|
|
|
162
157
|
return (req: HttpRequest, res: HttpResponse, next: () => void) => {
|
|
163
158
|
const startTime = Date.now();
|
|
164
159
|
|
|
165
|
-
res.on(
|
|
160
|
+
res.on('finish', () => {
|
|
166
161
|
const duration = Date.now() - startTime;
|
|
167
162
|
this.logger.info(
|
|
168
|
-
`${req.method} ${req.path} - ${res.statusCode} - ${duration}ms [${req.requestId}]
|
|
163
|
+
`${req.method} ${req.path} - ${res.statusCode} - ${duration}ms [${req.requestId}]`
|
|
169
164
|
);
|
|
170
165
|
});
|
|
171
166
|
|
|
@@ -178,12 +173,12 @@ export class Moro extends EventEmitter {
|
|
|
178
173
|
try {
|
|
179
174
|
next();
|
|
180
175
|
} catch (error: any) {
|
|
181
|
-
this.logger.error(
|
|
176
|
+
this.logger.error('Error:', error.message, error.stack);
|
|
182
177
|
|
|
183
178
|
if (!res.headersSent) {
|
|
184
179
|
res.status(500).json({
|
|
185
180
|
success: false,
|
|
186
|
-
error:
|
|
181
|
+
error: 'Internal server error',
|
|
187
182
|
requestId: req.requestId,
|
|
188
183
|
});
|
|
189
184
|
}
|
|
@@ -194,14 +189,14 @@ export class Moro extends EventEmitter {
|
|
|
194
189
|
// Public API for adding middleware
|
|
195
190
|
addMiddleware(middleware: any) {
|
|
196
191
|
this.httpServer.use(middleware);
|
|
197
|
-
this.emit(
|
|
192
|
+
this.emit('middleware:added', { middleware });
|
|
198
193
|
return this;
|
|
199
194
|
}
|
|
200
195
|
|
|
201
196
|
// Public API for database registration
|
|
202
197
|
registerDatabase(adapter: any) {
|
|
203
|
-
this.container.register(
|
|
204
|
-
this.emit(
|
|
198
|
+
this.container.register('database', () => adapter, true);
|
|
199
|
+
this.emit('database:registered', { adapter });
|
|
205
200
|
return this;
|
|
206
201
|
}
|
|
207
202
|
|
|
@@ -218,7 +213,7 @@ export class Moro extends EventEmitter {
|
|
|
218
213
|
async loadModule(moduleConfig: ModuleConfig): Promise<void> {
|
|
219
214
|
this.logger.info(
|
|
220
215
|
`Loading module: ${moduleConfig.name}@${moduleConfig.version}`,
|
|
221
|
-
|
|
216
|
+
'ModuleLoader'
|
|
222
217
|
);
|
|
223
218
|
|
|
224
219
|
// Create module event bus once during module loading
|
|
@@ -236,16 +231,13 @@ export class Moro extends EventEmitter {
|
|
|
236
231
|
}
|
|
237
232
|
|
|
238
233
|
// Mount with versioning
|
|
239
|
-
this.logger.debug(
|
|
240
|
-
`Module version before basePath: "${moduleConfig.version}"`,
|
|
241
|
-
"ModuleLoader",
|
|
242
|
-
);
|
|
234
|
+
this.logger.debug(`Module version before basePath: "${moduleConfig.version}"`, 'ModuleLoader');
|
|
243
235
|
const basePath = `/api/v${moduleConfig.version}/${moduleConfig.name}`;
|
|
244
|
-
this.logger.debug(`Generated basePath: "${basePath}"`,
|
|
236
|
+
this.logger.debug(`Generated basePath: "${basePath}"`, 'ModuleLoader');
|
|
245
237
|
this.mountRouter(basePath, router);
|
|
246
238
|
|
|
247
|
-
this.logger.info(`Module loaded: ${moduleConfig.name}`,
|
|
248
|
-
this.emit(
|
|
239
|
+
this.logger.info(`Module loaded: ${moduleConfig.name}`, 'ModuleLoader');
|
|
240
|
+
this.emit('moduleLoaded', moduleConfig.name);
|
|
249
241
|
}
|
|
250
242
|
|
|
251
243
|
private registerServices(config: ModuleConfig): void {
|
|
@@ -253,17 +245,11 @@ export class Moro extends EventEmitter {
|
|
|
253
245
|
|
|
254
246
|
for (const service of config.services) {
|
|
255
247
|
const factory = () => {
|
|
256
|
-
const dependencies = (service.dependencies || []).map((dep)
|
|
257
|
-
this.container.resolve(dep),
|
|
258
|
-
);
|
|
248
|
+
const dependencies = (service.dependencies || []).map(dep => this.container.resolve(dep));
|
|
259
249
|
return new service.implementation(...dependencies);
|
|
260
250
|
};
|
|
261
251
|
|
|
262
|
-
this.container.register(
|
|
263
|
-
service.name,
|
|
264
|
-
factory,
|
|
265
|
-
service.singleton || false,
|
|
266
|
-
);
|
|
252
|
+
this.container.register(service.name, factory, service.singleton || false);
|
|
267
253
|
}
|
|
268
254
|
|
|
269
255
|
// Register functional route handlers if they exist
|
|
@@ -281,53 +267,39 @@ export class Moro extends EventEmitter {
|
|
|
281
267
|
}
|
|
282
268
|
}
|
|
283
269
|
|
|
284
|
-
private async createModuleRouter(
|
|
285
|
-
config: ModuleConfig,
|
|
286
|
-
moduleEventBus: any,
|
|
287
|
-
): Promise<Router> {
|
|
270
|
+
private async createModuleRouter(config: ModuleConfig, moduleEventBus: any): Promise<Router> {
|
|
288
271
|
const router = new Router();
|
|
289
272
|
|
|
290
|
-
this.logger.debug(`Creating router for module: ${config.name}`,
|
|
291
|
-
this.logger.debug(
|
|
292
|
-
`Module has ${config.routes?.length || 0} routes`,
|
|
293
|
-
"Router",
|
|
294
|
-
);
|
|
273
|
+
this.logger.debug(`Creating router for module: ${config.name}`, 'Router');
|
|
274
|
+
this.logger.debug(`Module has ${config.routes?.length || 0} routes`, 'Router');
|
|
295
275
|
|
|
296
276
|
if (!config.routes) return router;
|
|
297
277
|
|
|
298
278
|
for (const route of config.routes) {
|
|
299
279
|
this.logger.debug(
|
|
300
280
|
`Adding route: ${route.method} ${route.path} -> ${route.handler}`,
|
|
301
|
-
|
|
302
|
-
);
|
|
303
|
-
const handler = await this.createResilientHandler(
|
|
304
|
-
route,
|
|
305
|
-
config,
|
|
306
|
-
moduleEventBus,
|
|
281
|
+
'Router'
|
|
307
282
|
);
|
|
283
|
+
const handler = await this.createResilientHandler(route, config, moduleEventBus);
|
|
308
284
|
const method = route.method.toLowerCase() as keyof Router;
|
|
309
285
|
|
|
310
286
|
// Add route to router
|
|
311
287
|
(router[method] as Function)(route.path, handler);
|
|
312
288
|
}
|
|
313
289
|
|
|
314
|
-
this.logger.debug(
|
|
315
|
-
`Router created with ${router.getRoutes().length} total routes`,
|
|
316
|
-
"Router",
|
|
317
|
-
);
|
|
290
|
+
this.logger.debug(`Router created with ${router.getRoutes().length} total routes`, 'Router');
|
|
318
291
|
return router;
|
|
319
292
|
}
|
|
320
293
|
|
|
321
294
|
private async createResilientHandler(
|
|
322
295
|
route: InternalRouteDefinition,
|
|
323
296
|
config: ModuleConfig,
|
|
324
|
-
moduleEventBus: any
|
|
297
|
+
moduleEventBus: any
|
|
325
298
|
) {
|
|
326
299
|
const handlerKey = `${config.name}.${route.handler}`;
|
|
327
300
|
|
|
328
301
|
return async (req: HttpRequest, res: HttpResponse) => {
|
|
329
|
-
const requestId =
|
|
330
|
-
req.headers["x-request-id"] || Math.random().toString(36);
|
|
302
|
+
const requestId = req.headers['x-request-id'] || Math.random().toString(36);
|
|
331
303
|
|
|
332
304
|
try {
|
|
333
305
|
// Try to get functional handler first, then fall back to service-based
|
|
@@ -338,36 +310,23 @@ export class Moro extends EventEmitter {
|
|
|
338
310
|
// New functional handler
|
|
339
311
|
handler = config.routeHandlers[route.handler];
|
|
340
312
|
useEnhancedReq = true;
|
|
341
|
-
this.logger.debug(
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
{
|
|
345
|
-
availableHandlers: Object.keys(config.routeHandlers || {}),
|
|
346
|
-
},
|
|
347
|
-
);
|
|
313
|
+
this.logger.debug(`Using functional handler: ${route.handler}`, 'Handler', {
|
|
314
|
+
availableHandlers: Object.keys(config.routeHandlers || {}),
|
|
315
|
+
});
|
|
348
316
|
} else if (this.container.has(config.name)) {
|
|
349
317
|
// Old service-based handler
|
|
350
318
|
const service = this.container.resolve(config.name) as any;
|
|
351
319
|
handler = service[route.handler];
|
|
352
|
-
this.logger.debug(
|
|
353
|
-
`Using service handler: ${config.name}.${route.handler}`,
|
|
354
|
-
"Handler",
|
|
355
|
-
);
|
|
320
|
+
this.logger.debug(`Using service handler: ${config.name}.${route.handler}`, 'Handler');
|
|
356
321
|
} else {
|
|
357
|
-
this.logger.error(
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
containerHasModule: this.container.has(config.name),
|
|
363
|
-
},
|
|
364
|
-
);
|
|
365
|
-
throw new Error(
|
|
366
|
-
`Handler ${route.handler} not found for module ${config.name}`,
|
|
367
|
-
);
|
|
322
|
+
this.logger.error(`No handler found for route ${route.method} ${route.path}`, 'Handler', {
|
|
323
|
+
routeHandlers: Object.keys(config.routeHandlers || {}),
|
|
324
|
+
containerHasModule: this.container.has(config.name),
|
|
325
|
+
});
|
|
326
|
+
throw new Error(`Handler ${route.handler} not found for module ${config.name}`);
|
|
368
327
|
}
|
|
369
328
|
|
|
370
|
-
if (!handler || typeof handler !==
|
|
329
|
+
if (!handler || typeof handler !== 'function') {
|
|
371
330
|
throw new Error(`Handler ${route.handler} is not a function`);
|
|
372
331
|
}
|
|
373
332
|
|
|
@@ -394,32 +353,23 @@ export class Moro extends EventEmitter {
|
|
|
394
353
|
req.headers = route.validation.headers.parse(req.headers);
|
|
395
354
|
}
|
|
396
355
|
|
|
397
|
-
this.logger.debug(
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
route: `${route.method} ${route.path}`,
|
|
402
|
-
module: config.name,
|
|
403
|
-
},
|
|
404
|
-
);
|
|
356
|
+
this.logger.debug('Module route validation passed', 'ModuleValidation', {
|
|
357
|
+
route: `${route.method} ${route.path}`,
|
|
358
|
+
module: config.name,
|
|
359
|
+
});
|
|
405
360
|
} catch (validationError: any) {
|
|
406
361
|
if (validationError.issues) {
|
|
407
|
-
this.logger.debug(
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
module: config.name,
|
|
413
|
-
errors: validationError.issues.length,
|
|
414
|
-
},
|
|
415
|
-
);
|
|
362
|
+
this.logger.debug('Module route validation failed', 'ModuleValidation', {
|
|
363
|
+
route: `${route.method} ${route.path}`,
|
|
364
|
+
module: config.name,
|
|
365
|
+
errors: validationError.issues.length,
|
|
366
|
+
});
|
|
416
367
|
|
|
417
368
|
res.status(400).json({
|
|
418
369
|
success: false,
|
|
419
|
-
error:
|
|
370
|
+
error: 'Validation failed',
|
|
420
371
|
details: validationError.issues.map((issue: any) => ({
|
|
421
|
-
field:
|
|
422
|
-
issue.path.length > 0 ? issue.path.join(".") : "request",
|
|
372
|
+
field: issue.path.length > 0 ? issue.path.join('.') : 'request',
|
|
423
373
|
message: issue.message,
|
|
424
374
|
code: issue.code,
|
|
425
375
|
})),
|
|
@@ -437,38 +387,26 @@ export class Moro extends EventEmitter {
|
|
|
437
387
|
// Use the pre-created module event bus
|
|
438
388
|
requestToUse = {
|
|
439
389
|
...req,
|
|
440
|
-
database: this.container.has(
|
|
441
|
-
? this.container.resolve(
|
|
390
|
+
database: this.container.has('database')
|
|
391
|
+
? this.container.resolve('database')
|
|
442
392
|
: undefined,
|
|
443
393
|
events: moduleEventBus, // Use pre-created event bus
|
|
444
394
|
app: {
|
|
445
|
-
get: (key: string) =>
|
|
446
|
-
key === "io" ? this.ioInstance : undefined,
|
|
395
|
+
get: (key: string) => (key === 'io' ? this.ioInstance : undefined),
|
|
447
396
|
},
|
|
448
397
|
};
|
|
449
|
-
this.logger.debug(
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
{
|
|
453
|
-
moduleId: config.name,
|
|
454
|
-
},
|
|
455
|
-
);
|
|
398
|
+
this.logger.debug(`Database available: ${!!requestToUse.database}`, 'Handler', {
|
|
399
|
+
moduleId: config.name,
|
|
400
|
+
});
|
|
456
401
|
}
|
|
457
402
|
|
|
458
403
|
// Execute with circuit breaker
|
|
459
404
|
const circuitBreaker = this.getCircuitBreaker(handlerKey);
|
|
460
|
-
const result = await circuitBreaker.execute(() =>
|
|
461
|
-
handler(requestToUse, res),
|
|
462
|
-
);
|
|
405
|
+
const result = await circuitBreaker.execute(() => handler(requestToUse, res));
|
|
463
406
|
|
|
464
407
|
// For functional handlers, ensure the response is sent
|
|
465
|
-
if (
|
|
466
|
-
|
|
467
|
-
result !== undefined &&
|
|
468
|
-
result !== null &&
|
|
469
|
-
!res.headersSent
|
|
470
|
-
) {
|
|
471
|
-
this.logger.debug(`Sending functional handler result`, "Handler", {
|
|
408
|
+
if (useEnhancedReq && result !== undefined && result !== null && !res.headersSent) {
|
|
409
|
+
this.logger.debug(`Sending functional handler result`, 'Handler', {
|
|
472
410
|
result,
|
|
473
411
|
});
|
|
474
412
|
res.json(result);
|
|
@@ -476,19 +414,15 @@ export class Moro extends EventEmitter {
|
|
|
476
414
|
|
|
477
415
|
return result;
|
|
478
416
|
} catch (error: any) {
|
|
479
|
-
this.logger.error(
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
handlerKey,
|
|
485
|
-
stack: error.stack,
|
|
486
|
-
},
|
|
487
|
-
);
|
|
417
|
+
this.logger.error(`Route handler error [${requestId}]: ${error.message}`, 'Handler', {
|
|
418
|
+
requestId,
|
|
419
|
+
handlerKey,
|
|
420
|
+
stack: error.stack,
|
|
421
|
+
});
|
|
488
422
|
if (!res.headersSent) {
|
|
489
423
|
res.status(500).json({
|
|
490
424
|
success: false,
|
|
491
|
-
error:
|
|
425
|
+
error: 'Internal server error',
|
|
492
426
|
requestId,
|
|
493
427
|
});
|
|
494
428
|
}
|
|
@@ -498,45 +432,37 @@ export class Moro extends EventEmitter {
|
|
|
498
432
|
}
|
|
499
433
|
|
|
500
434
|
private mountRouter(basePath: string, router: Router): void {
|
|
501
|
-
this.logger.debug(`Mounting router for basePath: ${basePath}`,
|
|
435
|
+
this.logger.debug(`Mounting router for basePath: ${basePath}`, 'Router');
|
|
502
436
|
|
|
503
437
|
// Enterprise-grade middleware integration with performance optimization
|
|
504
|
-
this.httpServer.use(
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
this.logger.error("Router error", "Router", {
|
|
525
|
-
error: error instanceof Error ? error.message : String(error),
|
|
526
|
-
});
|
|
527
|
-
if (!res.headersSent) {
|
|
528
|
-
res
|
|
529
|
-
.status(500)
|
|
530
|
-
.json({ success: false, error: "Internal server error" });
|
|
531
|
-
}
|
|
438
|
+
this.httpServer.use(async (req: HttpRequest, res: HttpResponse, next: () => void) => {
|
|
439
|
+
if (req.path.startsWith(basePath)) {
|
|
440
|
+
this.logger.debug(`Module middleware handling: ${req.method} ${req.path}`, 'Middleware', {
|
|
441
|
+
basePath,
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
try {
|
|
445
|
+
const handled = await router.handle(req, res, basePath);
|
|
446
|
+
this.logger.debug(`Route handled: ${handled}`, 'Router');
|
|
447
|
+
|
|
448
|
+
if (!handled) {
|
|
449
|
+
next(); // Let other middleware handle it
|
|
450
|
+
}
|
|
451
|
+
// If handled, the router already sent the response, so don't call next()
|
|
452
|
+
} catch (error) {
|
|
453
|
+
this.logger.error('Router error', 'Router', {
|
|
454
|
+
error: error instanceof Error ? error.message : String(error),
|
|
455
|
+
});
|
|
456
|
+
if (!res.headersSent) {
|
|
457
|
+
res.status(500).json({ success: false, error: 'Internal server error' });
|
|
532
458
|
}
|
|
533
|
-
} else {
|
|
534
|
-
next();
|
|
535
459
|
}
|
|
536
|
-
}
|
|
537
|
-
|
|
460
|
+
} else {
|
|
461
|
+
next();
|
|
462
|
+
}
|
|
463
|
+
});
|
|
538
464
|
|
|
539
|
-
this.logger.info(`Router mounted for ${basePath}`,
|
|
465
|
+
this.logger.info(`Router mounted for ${basePath}`, 'Router');
|
|
540
466
|
}
|
|
541
467
|
|
|
542
468
|
private async setupWebSocketHandlers(config: ModuleConfig): Promise<void> {
|
|
@@ -549,7 +475,7 @@ export class Moro extends EventEmitter {
|
|
|
549
475
|
|
|
550
476
|
private checkRateLimit(
|
|
551
477
|
identifier: string,
|
|
552
|
-
rateLimit: { requests: number; window: number }
|
|
478
|
+
rateLimit: { requests: number; window: number }
|
|
553
479
|
): boolean {
|
|
554
480
|
if (!this.rateLimiters.has(identifier)) {
|
|
555
481
|
this.rateLimiters.set(identifier, new Map());
|
|
@@ -583,7 +509,7 @@ export class Moro extends EventEmitter {
|
|
|
583
509
|
failureThreshold: 5,
|
|
584
510
|
resetTimeout: 30000,
|
|
585
511
|
monitoringPeriod: 10000,
|
|
586
|
-
})
|
|
512
|
+
})
|
|
587
513
|
);
|
|
588
514
|
}
|
|
589
515
|
return this.circuitBreakers.get(key)!;
|
|
@@ -591,12 +517,8 @@ export class Moro extends EventEmitter {
|
|
|
591
517
|
|
|
592
518
|
listen(port: number, callback?: () => void): void;
|
|
593
519
|
listen(port: number, host: string, callback?: () => void): void;
|
|
594
|
-
listen(
|
|
595
|
-
|
|
596
|
-
host?: string | (() => void),
|
|
597
|
-
callback?: () => void,
|
|
598
|
-
): void {
|
|
599
|
-
if (typeof host === "function") {
|
|
520
|
+
listen(port: number, host?: string | (() => void), callback?: () => void): void {
|
|
521
|
+
if (typeof host === 'function') {
|
|
600
522
|
this.httpServer.listen(port, host);
|
|
601
523
|
} else if (host) {
|
|
602
524
|
this.httpServer.listen(port, host, callback);
|
|
@@ -607,13 +529,13 @@ export class Moro extends EventEmitter {
|
|
|
607
529
|
|
|
608
530
|
// Compatibility method for existing controllers
|
|
609
531
|
set(key: string, value: any): void {
|
|
610
|
-
if (key ===
|
|
532
|
+
if (key === 'io') {
|
|
611
533
|
this.ioInstance = value;
|
|
612
534
|
}
|
|
613
535
|
}
|
|
614
536
|
|
|
615
537
|
get(key: string): any {
|
|
616
|
-
if (key ===
|
|
538
|
+
if (key === 'io') {
|
|
617
539
|
return this.ioInstance;
|
|
618
540
|
}
|
|
619
541
|
return undefined;
|