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