@morojs/moro 1.6.2 → 1.6.3
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/dist/core/http/http-server.js +12 -9
- package/dist/core/http/http-server.js.map +1 -1
- package/dist/core/http/uws-http-server.js +1 -1
- package/dist/core/http/uws-http-server.js.map +1 -1
- package/dist/core/middleware/built-in/auth/core.d.ts +78 -0
- package/dist/core/middleware/built-in/auth/core.js +358 -0
- package/dist/core/middleware/built-in/auth/core.js.map +1 -0
- package/dist/core/middleware/built-in/{auth-helpers.js → auth/helpers.js} +1 -1
- package/dist/core/middleware/built-in/auth/helpers.js.map +1 -0
- package/dist/core/middleware/built-in/auth/hook.d.ts +30 -0
- package/dist/core/middleware/built-in/auth/hook.js +99 -0
- package/dist/core/middleware/built-in/auth/hook.js.map +1 -0
- package/dist/core/middleware/built-in/auth/index.d.ts +7 -0
- package/dist/core/middleware/built-in/auth/index.js +15 -0
- package/dist/core/middleware/built-in/auth/index.js.map +1 -0
- package/dist/core/middleware/built-in/{jwt-helpers.js → auth/jwt-helpers.js} +1 -1
- package/dist/core/middleware/built-in/auth/jwt-helpers.js.map +1 -0
- package/dist/core/middleware/built-in/auth/middleware.d.ts +23 -0
- package/dist/core/middleware/built-in/auth/middleware.js +71 -0
- package/dist/core/middleware/built-in/auth/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/{auth-providers.d.ts → auth/providers.d.ts} +1 -1
- package/dist/core/middleware/built-in/{auth-providers.js → auth/providers.js} +1 -1
- package/dist/core/middleware/built-in/auth/providers.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/file.d.ts +1 -1
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/file.js +1 -1
- package/dist/core/middleware/built-in/cache/adapters/cache/file.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/index.d.ts +1 -1
- package/dist/core/middleware/built-in/cache/adapters/cache/index.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/memory.d.ts +1 -1
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/memory.js +1 -1
- package/dist/core/middleware/built-in/cache/adapters/cache/memory.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/redis.d.ts +1 -1
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/redis.js +2 -2
- package/dist/core/middleware/built-in/cache/adapters/cache/redis.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cache/adapters}/index.d.ts +0 -2
- package/{src/core/middleware/built-in/adapters/index.ts → dist/core/middleware/built-in/cache/adapters/index.js} +1 -3
- package/dist/core/middleware/built-in/cache/adapters/index.js.map +1 -0
- package/dist/core/middleware/built-in/cache/core.d.ts +37 -0
- package/dist/core/middleware/built-in/cache/core.js +87 -0
- package/dist/core/middleware/built-in/cache/core.js.map +1 -0
- package/dist/core/middleware/built-in/cache/hook.d.ts +20 -0
- package/dist/core/middleware/built-in/{cache.js → cache/hook.js} +22 -5
- package/dist/core/middleware/built-in/cache/hook.js.map +1 -0
- package/dist/core/middleware/built-in/cache/index.d.ts +3 -0
- package/dist/core/middleware/built-in/cache/index.js +9 -0
- package/dist/core/middleware/built-in/cache/index.js.map +1 -0
- package/dist/core/middleware/built-in/cache/middleware.d.ts +17 -0
- package/dist/core/middleware/built-in/cache/middleware.js +44 -0
- package/dist/core/middleware/built-in/cache/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/azure.d.ts +1 -1
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/azure.js +1 -1
- package/dist/core/middleware/built-in/cdn/adapters/cdn/azure.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/cloudflare.d.ts +1 -1
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/cloudflare.js +1 -1
- package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudflare.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/cloudfront.d.ts +1 -1
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/cloudfront.js +2 -2
- package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudfront.js.map +1 -0
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/index.d.ts +1 -1
- package/dist/core/middleware/built-in/cdn/adapters/cdn/index.js.map +1 -0
- package/dist/core/middleware/built-in/cdn/adapters/index.d.ts +2 -0
- package/dist/core/middleware/built-in/{adapters → cdn/adapters}/index.js +0 -2
- package/dist/core/middleware/built-in/cdn/adapters/index.js.map +1 -0
- package/dist/core/middleware/built-in/cdn/core.d.ts +43 -0
- package/dist/core/middleware/built-in/cdn/core.js +144 -0
- package/dist/core/middleware/built-in/cdn/core.js.map +1 -0
- package/dist/core/middleware/built-in/cdn/hook.d.ts +22 -0
- package/dist/core/middleware/built-in/cdn/hook.js +70 -0
- package/dist/core/middleware/built-in/cdn/hook.js.map +1 -0
- package/dist/core/middleware/built-in/cdn/index.d.ts +5 -0
- package/dist/core/middleware/built-in/cdn/index.js +11 -0
- package/dist/core/middleware/built-in/cdn/index.js.map +1 -0
- package/dist/core/middleware/built-in/cdn/middleware.d.ts +21 -0
- package/dist/core/middleware/built-in/cdn/middleware.js +52 -0
- package/dist/core/middleware/built-in/cdn/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/cookie/core.d.ts +37 -0
- package/dist/core/middleware/built-in/cookie/core.js +83 -0
- package/dist/core/middleware/built-in/cookie/core.js.map +1 -0
- package/dist/core/middleware/built-in/cookie/hook.d.ts +20 -0
- package/dist/core/middleware/built-in/cookie/hook.js +47 -0
- package/dist/core/middleware/built-in/cookie/hook.js.map +1 -0
- package/dist/core/middleware/built-in/cookie/index.d.ts +3 -0
- package/dist/core/middleware/built-in/cookie/index.js +9 -0
- package/dist/core/middleware/built-in/cookie/index.js.map +1 -0
- package/dist/core/middleware/built-in/cookie/middleware.d.ts +17 -0
- package/dist/core/middleware/built-in/cookie/middleware.js +36 -0
- package/dist/core/middleware/built-in/cookie/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/cors/core.d.ts +23 -0
- package/dist/core/middleware/built-in/cors/core.js +51 -0
- package/dist/core/middleware/built-in/cors/core.js.map +1 -0
- package/dist/core/middleware/built-in/cors/hook.d.ts +17 -0
- package/dist/core/middleware/built-in/cors/hook.js +37 -0
- package/dist/core/middleware/built-in/cors/hook.js.map +1 -0
- package/dist/core/middleware/built-in/cors/index.d.ts +3 -0
- package/dist/core/middleware/built-in/cors/index.js +9 -0
- package/dist/core/middleware/built-in/cors/index.js.map +1 -0
- package/dist/core/middleware/built-in/cors/middleware.d.ts +16 -0
- package/dist/core/middleware/built-in/cors/middleware.js +22 -0
- package/dist/core/middleware/built-in/cors/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/csp/core.d.ts +45 -0
- package/dist/core/middleware/built-in/csp/core.js +88 -0
- package/dist/core/middleware/built-in/csp/core.js.map +1 -0
- package/dist/core/middleware/built-in/csp/hook.d.ts +22 -0
- package/dist/core/middleware/built-in/csp/hook.js +47 -0
- package/dist/core/middleware/built-in/csp/hook.js.map +1 -0
- package/dist/core/middleware/built-in/csp/index.d.ts +3 -0
- package/dist/core/middleware/built-in/csp/index.js +9 -0
- package/dist/core/middleware/built-in/csp/index.js.map +1 -0
- package/dist/core/middleware/built-in/csp/middleware.d.ts +19 -0
- package/dist/core/middleware/built-in/csp/middleware.js +29 -0
- package/dist/core/middleware/built-in/csp/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/csrf/core.d.ts +28 -0
- package/dist/core/middleware/built-in/csrf/core.js +69 -0
- package/dist/core/middleware/built-in/csrf/core.js.map +1 -0
- package/dist/core/middleware/built-in/csrf/hook.d.ts +17 -0
- package/dist/core/middleware/built-in/csrf/hook.js +45 -0
- package/dist/core/middleware/built-in/csrf/hook.js.map +1 -0
- package/dist/core/middleware/built-in/csrf/index.d.ts +3 -0
- package/dist/core/middleware/built-in/csrf/index.js +9 -0
- package/dist/core/middleware/built-in/csrf/index.js.map +1 -0
- package/dist/core/middleware/built-in/csrf/middleware.d.ts +16 -0
- package/dist/core/middleware/built-in/csrf/middleware.js +34 -0
- package/dist/core/middleware/built-in/csrf/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/error-tracker/index.d.ts +1 -0
- package/dist/core/middleware/built-in/error-tracker/index.js +4 -0
- package/dist/core/middleware/built-in/error-tracker/index.js.map +1 -0
- package/dist/core/middleware/built-in/error-tracker/middleware.d.ts +12 -0
- package/dist/core/middleware/built-in/{error-tracker.js → error-tracker/middleware.js} +14 -3
- package/dist/core/middleware/built-in/error-tracker/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/index.d.ts +25 -59
- package/dist/core/middleware/built-in/index.js +31 -31
- package/dist/core/middleware/built-in/index.js.map +1 -1
- package/dist/core/middleware/built-in/performance-monitor/index.d.ts +1 -0
- package/dist/core/middleware/built-in/performance-monitor/index.js +4 -0
- package/dist/core/middleware/built-in/performance-monitor/index.js.map +1 -0
- package/dist/core/middleware/built-in/performance-monitor/middleware.d.ts +12 -0
- package/dist/core/middleware/built-in/{performance-monitor.js → performance-monitor/middleware.js} +14 -3
- package/dist/core/middleware/built-in/performance-monitor/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/rate-limit/core.d.ts +33 -0
- package/dist/core/middleware/built-in/rate-limit/core.js +86 -0
- package/dist/core/middleware/built-in/rate-limit/core.js.map +1 -0
- package/dist/core/middleware/built-in/rate-limit/hook.d.ts +20 -0
- package/dist/core/middleware/built-in/{rate-limit.js → rate-limit/hook.js} +22 -16
- package/dist/core/middleware/built-in/rate-limit/hook.js.map +1 -0
- package/dist/core/middleware/built-in/rate-limit/index.d.ts +3 -0
- package/dist/core/middleware/built-in/rate-limit/index.js +9 -0
- package/dist/core/middleware/built-in/rate-limit/index.js.map +1 -0
- package/dist/core/middleware/built-in/rate-limit/middleware.d.ts +16 -0
- package/dist/core/middleware/built-in/rate-limit/middleware.js +35 -0
- package/dist/core/middleware/built-in/rate-limit/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/request-logger/index.d.ts +1 -0
- package/dist/core/middleware/built-in/request-logger/index.js +4 -0
- package/dist/core/middleware/built-in/request-logger/index.js.map +1 -0
- package/dist/core/middleware/built-in/request-logger/middleware.d.ts +12 -0
- package/dist/core/middleware/built-in/{request-logger.js → request-logger/middleware.js} +14 -3
- package/dist/core/middleware/built-in/request-logger/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/session/core.d.ts +73 -0
- package/dist/core/middleware/built-in/session/core.js +227 -0
- package/dist/core/middleware/built-in/session/core.js.map +1 -0
- package/dist/core/middleware/built-in/session/hook.d.ts +17 -0
- package/dist/core/middleware/built-in/session/hook.js +53 -0
- package/dist/core/middleware/built-in/session/hook.js.map +1 -0
- package/dist/core/middleware/built-in/session/index.d.ts +3 -0
- package/dist/core/middleware/built-in/session/index.js +9 -0
- package/dist/core/middleware/built-in/session/index.js.map +1 -0
- package/dist/core/middleware/built-in/session/middleware.d.ts +17 -0
- package/dist/core/middleware/built-in/session/middleware.js +38 -0
- package/dist/core/middleware/built-in/session/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/sse/core.d.ts +44 -0
- package/dist/core/middleware/built-in/sse/core.js +117 -0
- package/dist/core/middleware/built-in/sse/core.js.map +1 -0
- package/dist/core/middleware/built-in/sse/hook.d.ts +18 -0
- package/dist/core/middleware/built-in/sse/hook.js +60 -0
- package/dist/core/middleware/built-in/sse/hook.js.map +1 -0
- package/dist/core/middleware/built-in/sse/index.d.ts +3 -0
- package/dist/core/middleware/built-in/sse/index.js +9 -0
- package/dist/core/middleware/built-in/sse/index.js.map +1 -0
- package/dist/core/middleware/built-in/sse/middleware.d.ts +18 -0
- package/dist/core/middleware/built-in/sse/middleware.js +43 -0
- package/dist/core/middleware/built-in/sse/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/validation/core.d.ts +23 -0
- package/dist/core/middleware/built-in/validation/core.js +93 -0
- package/dist/core/middleware/built-in/validation/core.js.map +1 -0
- package/dist/core/middleware/built-in/validation/hook.d.ts +13 -0
- package/dist/core/middleware/built-in/{validation.js → validation/hook.js} +14 -3
- package/dist/core/middleware/built-in/validation/hook.js.map +1 -0
- package/dist/core/middleware/built-in/validation/index.d.ts +3 -0
- package/dist/core/middleware/built-in/validation/index.js +9 -0
- package/dist/core/middleware/built-in/validation/index.js.map +1 -0
- package/dist/core/middleware/built-in/validation/middleware.d.ts +16 -0
- package/dist/core/middleware/built-in/validation/middleware.js +27 -0
- package/dist/core/middleware/built-in/validation/middleware.js.map +1 -0
- package/dist/core/middleware/index.js +6 -0
- package/dist/core/middleware/index.js.map +1 -1
- package/dist/core/routing/unified-router.d.ts +4 -20
- package/dist/core/routing/unified-router.js +61 -106
- package/dist/core/routing/unified-router.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/moro.js +12 -18
- package/dist/moro.js.map +1 -1
- package/dist/types/hooks.d.ts +3 -0
- package/package.json +2 -6
- package/dist/core/middleware/built-in/adapters/cache/file.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cache/index.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cache/memory.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cache/redis.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cdn/azure.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/cdn/index.js.map +0 -1
- package/dist/core/middleware/built-in/adapters/index.js.map +0 -1
- package/dist/core/middleware/built-in/auth-helpers.js.map +0 -1
- package/dist/core/middleware/built-in/auth-providers.js.map +0 -1
- package/dist/core/middleware/built-in/auth.d.ts +0 -30
- package/dist/core/middleware/built-in/auth.js +0 -348
- package/dist/core/middleware/built-in/auth.js.map +0 -1
- package/dist/core/middleware/built-in/cache.d.ts +0 -3
- package/dist/core/middleware/built-in/cache.js.map +0 -1
- package/dist/core/middleware/built-in/cdn.d.ts +0 -3
- package/dist/core/middleware/built-in/cdn.js +0 -109
- package/dist/core/middleware/built-in/cdn.js.map +0 -1
- package/dist/core/middleware/built-in/cookie.d.ts +0 -14
- package/dist/core/middleware/built-in/cookie.js +0 -64
- package/dist/core/middleware/built-in/cookie.js.map +0 -1
- package/dist/core/middleware/built-in/cors.d.ts +0 -2
- package/dist/core/middleware/built-in/cors.js +0 -25
- package/dist/core/middleware/built-in/cors.js.map +0 -1
- package/dist/core/middleware/built-in/csp.d.ts +0 -22
- package/dist/core/middleware/built-in/csp.js +0 -68
- package/dist/core/middleware/built-in/csp.js.map +0 -1
- package/dist/core/middleware/built-in/csrf.d.ts +0 -9
- package/dist/core/middleware/built-in/csrf.js +0 -60
- package/dist/core/middleware/built-in/csrf.js.map +0 -1
- package/dist/core/middleware/built-in/error-tracker.d.ts +0 -1
- package/dist/core/middleware/built-in/error-tracker.js.map +0 -1
- package/dist/core/middleware/built-in/jwt-helpers.js.map +0 -1
- package/dist/core/middleware/built-in/performance-monitor.d.ts +0 -1
- package/dist/core/middleware/built-in/performance-monitor.js.map +0 -1
- package/dist/core/middleware/built-in/rate-limit.d.ts +0 -6
- package/dist/core/middleware/built-in/rate-limit.js.map +0 -1
- package/dist/core/middleware/built-in/request-logger.d.ts +0 -1
- package/dist/core/middleware/built-in/request-logger.js.map +0 -1
- package/dist/core/middleware/built-in/session.d.ts +0 -41
- package/dist/core/middleware/built-in/session.js +0 -205
- package/dist/core/middleware/built-in/session.js.map +0 -1
- package/dist/core/middleware/built-in/sse.d.ts +0 -6
- package/dist/core/middleware/built-in/sse.js +0 -69
- package/dist/core/middleware/built-in/sse.js.map +0 -1
- package/dist/core/middleware/built-in/validation.d.ts +0 -2
- package/dist/core/middleware/built-in/validation.js.map +0 -1
- package/jest.config.mjs +0 -41
- package/src/core/auth/README.md +0 -339
- package/src/core/auth/morojs-adapter.ts +0 -415
- package/src/core/config/config-manager.ts +0 -133
- package/src/core/config/config-sources.ts +0 -600
- package/src/core/config/config-validator.ts +0 -1116
- package/src/core/config/file-loader.ts +0 -150
- package/src/core/config/index.ts +0 -109
- package/src/core/config/schema.ts +0 -164
- package/src/core/config/utils.ts +0 -244
- package/src/core/database/README.md +0 -238
- package/src/core/database/adapters/drizzle.ts +0 -415
- package/src/core/database/adapters/index.ts +0 -42
- package/src/core/database/adapters/mongodb.ts +0 -317
- package/src/core/database/adapters/mysql.ts +0 -235
- package/src/core/database/adapters/postgresql.ts +0 -226
- package/src/core/database/adapters/redis.ts +0 -379
- package/src/core/database/adapters/sqlite.ts +0 -263
- package/src/core/database/index.ts +0 -3
- package/src/core/docs/index.ts +0 -231
- package/src/core/docs/openapi-generator.ts +0 -576
- package/src/core/docs/schema-to-openapi.ts +0 -145
- package/src/core/docs/simple-docs.ts +0 -295
- package/src/core/docs/swagger-ui.ts +0 -354
- package/src/core/docs/zod-to-openapi.ts +0 -532
- package/src/core/events/event-bus.ts +0 -231
- package/src/core/events/index.ts +0 -12
- package/src/core/framework.ts +0 -885
- package/src/core/http/http-server.ts +0 -1847
- package/src/core/http/index.ts +0 -7
- package/src/core/http/uws-http-server.ts +0 -591
- package/src/core/logger/filters.ts +0 -153
- package/src/core/logger/index.ts +0 -21
- package/src/core/logger/logger.ts +0 -1033
- package/src/core/logger/outputs.ts +0 -132
- package/src/core/middleware/built-in/adapters/cache/file.ts +0 -104
- package/src/core/middleware/built-in/adapters/cache/index.ts +0 -23
- package/src/core/middleware/built-in/adapters/cache/memory.ts +0 -73
- package/src/core/middleware/built-in/adapters/cache/redis.ts +0 -114
- package/src/core/middleware/built-in/adapters/cdn/azure.ts +0 -60
- package/src/core/middleware/built-in/adapters/cdn/cloudflare.ts +0 -83
- package/src/core/middleware/built-in/adapters/cdn/cloudfront.ts +0 -94
- package/src/core/middleware/built-in/adapters/cdn/index.ts +0 -23
- package/src/core/middleware/built-in/auth-helpers.ts +0 -401
- package/src/core/middleware/built-in/auth-providers.ts +0 -480
- package/src/core/middleware/built-in/auth.ts +0 -410
- package/src/core/middleware/built-in/cache.ts +0 -213
- package/src/core/middleware/built-in/cdn.ts +0 -124
- package/src/core/middleware/built-in/cookie.ts +0 -85
- package/src/core/middleware/built-in/cors.ts +0 -38
- package/src/core/middleware/built-in/csp.ts +0 -101
- package/src/core/middleware/built-in/csrf.ts +0 -82
- package/src/core/middleware/built-in/error-tracker.ts +0 -16
- package/src/core/middleware/built-in/index.ts +0 -87
- package/src/core/middleware/built-in/jwt-helpers.ts +0 -243
- package/src/core/middleware/built-in/performance-monitor.ts +0 -25
- package/src/core/middleware/built-in/rate-limit.ts +0 -60
- package/src/core/middleware/built-in/request-logger.ts +0 -16
- package/src/core/middleware/built-in/session.ts +0 -287
- package/src/core/middleware/built-in/sse.ts +0 -88
- package/src/core/middleware/built-in/validation.ts +0 -33
- package/src/core/middleware/index.ts +0 -177
- package/src/core/modules/auto-discovery.ts +0 -726
- package/src/core/modules/index.ts +0 -3
- package/src/core/modules/modules.ts +0 -135
- package/src/core/networking/adapters/index.ts +0 -17
- package/src/core/networking/adapters/socketio-adapter.ts +0 -254
- package/src/core/networking/adapters/uws-adapter.ts +0 -619
- package/src/core/networking/adapters/ws-adapter.ts +0 -429
- package/src/core/networking/index.ts +0 -4
- package/src/core/networking/service-discovery.ts +0 -303
- package/src/core/networking/websocket-adapter.ts +0 -217
- package/src/core/networking/websocket-manager.ts +0 -308
- package/src/core/pooling/object-pool-manager.ts +0 -630
- package/src/core/routing/app-integration.ts +0 -164
- package/src/core/routing/index.ts +0 -261
- package/src/core/routing/path-matcher.ts +0 -222
- package/src/core/routing/router.ts +0 -97
- package/src/core/routing/unified-router.ts +0 -870
- package/src/core/runtime/aws-lambda-adapter.ts +0 -147
- package/src/core/runtime/base-adapter.ts +0 -130
- package/src/core/runtime/cloudflare-workers-adapter.ts +0 -152
- package/src/core/runtime/index.ts +0 -62
- package/src/core/runtime/node-adapter.ts +0 -202
- package/src/core/runtime/vercel-edge-adapter.ts +0 -114
- package/src/core/utilities/circuit-breaker.ts +0 -46
- package/src/core/utilities/container.ts +0 -736
- package/src/core/utilities/hooks.ts +0 -142
- package/src/core/utilities/index.ts +0 -17
- package/src/core/utilities/package-utils.ts +0 -59
- package/src/core/validation/adapters.ts +0 -147
- package/src/core/validation/index.ts +0 -258
- package/src/core/validation/schema-interface.ts +0 -100
- package/src/index.ts +0 -233
- package/src/moro.ts +0 -1728
- package/src/types/auth.ts +0 -440
- package/src/types/cache.ts +0 -38
- package/src/types/cdn.ts +0 -22
- package/src/types/config.ts +0 -229
- package/src/types/core.ts +0 -58
- package/src/types/database.ts +0 -32
- package/src/types/discovery.ts +0 -7
- package/src/types/events.ts +0 -82
- package/src/types/hooks.ts +0 -47
- package/src/types/http.ts +0 -89
- package/src/types/logger.ts +0 -102
- package/src/types/module.ts +0 -99
- package/src/types/runtime.ts +0 -76
- package/src/types/session.ts +0 -89
- package/tsconfig.json +0 -23
- /package/dist/core/middleware/built-in/{auth-helpers.d.ts → auth/helpers.d.ts} +0 -0
- /package/dist/core/middleware/built-in/{jwt-helpers.d.ts → auth/jwt-helpers.d.ts} +0 -0
- /package/dist/core/middleware/built-in/{adapters → cache/adapters}/cache/index.js +0 -0
- /package/dist/core/middleware/built-in/{adapters → cdn/adapters}/cdn/index.js +0 -0
package/src/core/framework.ts
DELETED
|
@@ -1,885 +0,0 @@
|
|
|
1
|
-
// Core Moro Framework with Pluggable WebSocket Adapters
|
|
2
|
-
import { createServer, Server } from 'http';
|
|
3
|
-
import {
|
|
4
|
-
createSecureServer as createHttp2SecureServer,
|
|
5
|
-
createServer as createHttp2Server,
|
|
6
|
-
} from 'http2';
|
|
7
|
-
import { EventEmitter } from 'events';
|
|
8
|
-
import { MoroHttpServer, HttpRequest, HttpResponse, middleware } from './http/index.js';
|
|
9
|
-
import { UWebSocketsHttpServer } from './http/uws-http-server.js';
|
|
10
|
-
import { Router } from './routing/router.js';
|
|
11
|
-
import { Container } from './utilities/container.js';
|
|
12
|
-
import { ModuleLoader } from './modules/index.js';
|
|
13
|
-
import { WebSocketManager } from './networking/websocket-manager.js';
|
|
14
|
-
import { CircuitBreaker } from './utilities/circuit-breaker.js';
|
|
15
|
-
import { isPackageAvailable } from './utilities/package-utils.js';
|
|
16
|
-
import { MoroEventBus } from './events/index.js';
|
|
17
|
-
import { createFrameworkLogger, logger as globalLogger } from './logger/index.js';
|
|
18
|
-
import { ModuleConfig, InternalRouteDefinition } from '../types/module.js';
|
|
19
|
-
import { LogLevel, LoggerOptions } from '../types/logger.js';
|
|
20
|
-
import { MoroOptions as CoreMoroOptions } from '../types/core.js';
|
|
21
|
-
import { WebSocketAdapter, WebSocketAdapterOptions } from './networking/websocket-adapter.js';
|
|
22
|
-
|
|
23
|
-
// Extended MoroOptions that includes both core options and framework-specific options
|
|
24
|
-
export interface MoroOptions extends CoreMoroOptions {
|
|
25
|
-
http2?: boolean;
|
|
26
|
-
https?: {
|
|
27
|
-
key: string | Buffer;
|
|
28
|
-
cert: string | Buffer;
|
|
29
|
-
ca?: string | Buffer;
|
|
30
|
-
};
|
|
31
|
-
websocket?:
|
|
32
|
-
| {
|
|
33
|
-
enabled?: boolean;
|
|
34
|
-
adapter?: WebSocketAdapter;
|
|
35
|
-
compression?: boolean;
|
|
36
|
-
customIdGenerator?: () => string;
|
|
37
|
-
options?: WebSocketAdapterOptions;
|
|
38
|
-
}
|
|
39
|
-
| false;
|
|
40
|
-
config?: any; // Full configuration object
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export class Moro extends EventEmitter {
|
|
44
|
-
private httpServer: MoroHttpServer | UWebSocketsHttpServer;
|
|
45
|
-
private server: Server | any; // HTTP/2 server type or uWebSockets app
|
|
46
|
-
private websocketAdapter?: WebSocketAdapter;
|
|
47
|
-
private container: Container;
|
|
48
|
-
private moduleLoader: ModuleLoader;
|
|
49
|
-
private websocketManager?: WebSocketManager;
|
|
50
|
-
private circuitBreakers = new Map<string, CircuitBreaker>();
|
|
51
|
-
private rateLimiters = new Map<string, Map<string, { count: number; resetTime: number }>>();
|
|
52
|
-
// Enterprise-grade event system
|
|
53
|
-
private eventBus: MoroEventBus;
|
|
54
|
-
// Framework logger
|
|
55
|
-
private logger: any;
|
|
56
|
-
private options: MoroOptions;
|
|
57
|
-
private config: any;
|
|
58
|
-
private usingUWebSockets = false;
|
|
59
|
-
// WebSocket initialization promise to handle async adapter detection
|
|
60
|
-
private websocketSetupPromise: Promise<void> | null = null;
|
|
61
|
-
|
|
62
|
-
constructor(options: MoroOptions = {}) {
|
|
63
|
-
super();
|
|
64
|
-
this.options = options;
|
|
65
|
-
this.config = options.config || {};
|
|
66
|
-
|
|
67
|
-
// Configure global logger based on options
|
|
68
|
-
if (options.logger !== undefined) {
|
|
69
|
-
if (options.logger === false) {
|
|
70
|
-
// Disable logging by setting level to fatal (highest level)
|
|
71
|
-
globalLogger.setLevel('fatal');
|
|
72
|
-
} else if (typeof options.logger === 'object') {
|
|
73
|
-
// Configure logger with provided options
|
|
74
|
-
if (options.logger.level) {
|
|
75
|
-
globalLogger.setLevel(options.logger.level);
|
|
76
|
-
}
|
|
77
|
-
// Additional logger options can be configured here in the future
|
|
78
|
-
// For now, we focus on the level setting which is the most common need
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Initialize framework logger after global configuration
|
|
83
|
-
this.logger = createFrameworkLogger('Core');
|
|
84
|
-
|
|
85
|
-
// Check if uWebSockets should be used for HTTP and WebSocket
|
|
86
|
-
const useUWebSockets = this.config.server?.useUWebSockets || false;
|
|
87
|
-
|
|
88
|
-
if (useUWebSockets) {
|
|
89
|
-
try {
|
|
90
|
-
// Try to use uWebSockets for high performance HTTP and WebSocket
|
|
91
|
-
const sslOptions = this.config.server?.ssl || options.https;
|
|
92
|
-
this.httpServer = new UWebSocketsHttpServer({ ssl: sslOptions });
|
|
93
|
-
this.server = (this.httpServer as UWebSocketsHttpServer).getApp();
|
|
94
|
-
this.usingUWebSockets = true;
|
|
95
|
-
this.logger.info('uWebSockets HTTP+WebSocket server created', 'ServerInit');
|
|
96
|
-
} catch (error) {
|
|
97
|
-
// Fallback to standard HTTP/1.1 if uWebSockets fails to load
|
|
98
|
-
this.logger.warn(
|
|
99
|
-
'uWebSockets failed to initialize, falling back to Node.js http.Server. ' +
|
|
100
|
-
'Error: ' +
|
|
101
|
-
(error instanceof Error ? error.message : String(error)),
|
|
102
|
-
'ServerInit'
|
|
103
|
-
);
|
|
104
|
-
this.usingUWebSockets = false;
|
|
105
|
-
this.httpServer = new MoroHttpServer();
|
|
106
|
-
this.server = (this.httpServer as MoroHttpServer).getServer();
|
|
107
|
-
}
|
|
108
|
-
} else if (options.http2) {
|
|
109
|
-
// Use HTTP/2
|
|
110
|
-
this.httpServer = new MoroHttpServer();
|
|
111
|
-
|
|
112
|
-
if (options.https) {
|
|
113
|
-
this.server = createHttp2SecureServer(options.https);
|
|
114
|
-
} else {
|
|
115
|
-
this.server = createHttp2Server();
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Handle HTTP/2 streams manually
|
|
119
|
-
this.server.on('stream', (stream: any, headers: any) => {
|
|
120
|
-
// Convert HTTP/2 stream to HTTP/1.1-like request/response
|
|
121
|
-
const req = stream as any;
|
|
122
|
-
const res = stream as any;
|
|
123
|
-
req.url = headers[':path'];
|
|
124
|
-
req.method = headers[':method'];
|
|
125
|
-
req.headers = headers;
|
|
126
|
-
(this.httpServer as MoroHttpServer)['handleRequest'](req, res);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
this.logger.info('HTTP/2 server created', 'ServerInit');
|
|
130
|
-
} else {
|
|
131
|
-
// Use standard HTTP/1.1
|
|
132
|
-
this.httpServer = new MoroHttpServer();
|
|
133
|
-
this.server = (this.httpServer as MoroHttpServer).getServer();
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
this.container = new Container();
|
|
137
|
-
this.moduleLoader = new ModuleLoader(this.container);
|
|
138
|
-
|
|
139
|
-
// Setup WebSocket adapter if enabled in config OR options
|
|
140
|
-
if (
|
|
141
|
-
this.config.websocket.enabled ||
|
|
142
|
-
(options.websocket && typeof options.websocket === 'object')
|
|
143
|
-
) {
|
|
144
|
-
// Store the promise so we can await it before using websockets
|
|
145
|
-
this.websocketSetupPromise = this.setupWebSockets(options.websocket || {});
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Initialize enterprise event bus
|
|
149
|
-
this.eventBus = new MoroEventBus({
|
|
150
|
-
maxListeners: 200,
|
|
151
|
-
enableMetrics: true,
|
|
152
|
-
isolation: 'module',
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
// Register event bus in DI container as factory
|
|
156
|
-
this.container.register('eventBus', () => this.eventBus);
|
|
157
|
-
|
|
158
|
-
this.setupCore();
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Middleware support
|
|
162
|
-
use(middleware: any): this {
|
|
163
|
-
this.httpServer.use(middleware);
|
|
164
|
-
return this;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
private setupCore() {
|
|
168
|
-
// PERFORMANCE FIX: Only apply middleware if enabled in config OR options
|
|
169
|
-
|
|
170
|
-
// Security middleware - check config enabled property OR options.security.*.enabled === true
|
|
171
|
-
if (this.config.security.helmet.enabled || this.options.security?.helmet?.enabled === true) {
|
|
172
|
-
this.httpServer.use(middleware.helmet());
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (this.config.security.cors.enabled || this.options.security?.cors?.enabled === true) {
|
|
176
|
-
const corsOptions =
|
|
177
|
-
typeof this.options.cors === 'object'
|
|
178
|
-
? this.options.cors
|
|
179
|
-
: this.config.security.cors
|
|
180
|
-
? this.config.security.cors
|
|
181
|
-
: {};
|
|
182
|
-
this.httpServer.use(middleware.cors(corsOptions));
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Performance middleware - check config enabled property OR options.performance.*.enabled === true
|
|
186
|
-
if (
|
|
187
|
-
this.config.performance.compression.enabled ||
|
|
188
|
-
this.options.performance?.compression?.enabled === true
|
|
189
|
-
) {
|
|
190
|
-
const compressionOptions =
|
|
191
|
-
typeof this.options.compression === 'object'
|
|
192
|
-
? this.options.compression
|
|
193
|
-
: this.config.performance.compression
|
|
194
|
-
? this.config.performance.compression
|
|
195
|
-
: {};
|
|
196
|
-
this.httpServer.use(middleware.compression(compressionOptions));
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Body size middleware - always enabled with configurable limit
|
|
200
|
-
this.httpServer.use(middleware.bodySize({ limit: this.config.server.bodySizeLimit }));
|
|
201
|
-
|
|
202
|
-
// Configure request tracking (ID generation) in HTTP server
|
|
203
|
-
if (this.httpServer.setRequestTracking) {
|
|
204
|
-
this.httpServer.setRequestTracking(this.config.server.requestTracking.enabled);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Request logging middleware - separate from request tracking (ID generation)
|
|
208
|
-
if (this.config.server.requestLogging.enabled) {
|
|
209
|
-
this.httpServer.use(this.requestLoggingMiddleware());
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Error boundary middleware - configurable but recommended to keep enabled
|
|
213
|
-
if (this.config.server.errorBoundary.enabled) {
|
|
214
|
-
this.httpServer.use(this.errorBoundaryMiddleware());
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Setup WebSocket adapter and manager
|
|
220
|
-
*/
|
|
221
|
-
private async setupWebSockets(wsConfig: any): Promise<void> {
|
|
222
|
-
try {
|
|
223
|
-
// If using uWebSockets HTTP server, automatically use uWebSockets for WebSocket too
|
|
224
|
-
if (this.usingUWebSockets) {
|
|
225
|
-
const { UWebSocketsAdapter } = await import('./networking/adapters/index.js');
|
|
226
|
-
this.websocketAdapter = new UWebSocketsAdapter();
|
|
227
|
-
|
|
228
|
-
// For uWebSockets, we need to integrate with the existing app
|
|
229
|
-
const uwsHttpServer = this.httpServer as UWebSocketsHttpServer;
|
|
230
|
-
await this.websocketAdapter.initialize(uwsHttpServer.getApp(), wsConfig.options);
|
|
231
|
-
|
|
232
|
-
this.logger.info(
|
|
233
|
-
'uWebSockets adapter initialized (integrated with HTTP server)',
|
|
234
|
-
'WebSocketSetup'
|
|
235
|
-
);
|
|
236
|
-
} else {
|
|
237
|
-
// Use provided adapter or try to auto-detect
|
|
238
|
-
if (wsConfig.adapter) {
|
|
239
|
-
this.websocketAdapter = wsConfig.adapter;
|
|
240
|
-
} else {
|
|
241
|
-
this.websocketAdapter = (await this.detectWebSocketAdapter()) || undefined;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
if (this.websocketAdapter) {
|
|
245
|
-
await this.websocketAdapter.initialize(this.server, wsConfig.options);
|
|
246
|
-
|
|
247
|
-
this.logger.info(
|
|
248
|
-
`WebSocket adapter initialized: ${this.websocketAdapter.getAdapterName()}`,
|
|
249
|
-
'WebSocketSetup'
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// Configure adapter features (if adapter was created)
|
|
255
|
-
if (this.websocketAdapter) {
|
|
256
|
-
this.websocketManager = new WebSocketManager(this.websocketAdapter, this.container);
|
|
257
|
-
|
|
258
|
-
if (wsConfig.compression) {
|
|
259
|
-
this.websocketAdapter.setCompression(true);
|
|
260
|
-
}
|
|
261
|
-
if (wsConfig.customIdGenerator) {
|
|
262
|
-
this.websocketAdapter.setCustomIdGenerator(wsConfig.customIdGenerator);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
} catch (error) {
|
|
266
|
-
this.logger.warn(
|
|
267
|
-
'WebSocket setup failed, continuing without WebSocket support',
|
|
268
|
-
'WebSocketSetup',
|
|
269
|
-
{ error: error instanceof Error ? error.message : String(error) }
|
|
270
|
-
);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Auto-detect available WebSocket adapter
|
|
276
|
-
* Tests if the library is actually installed by checking require.resolve
|
|
277
|
-
*/
|
|
278
|
-
private async detectWebSocketAdapter(): Promise<WebSocketAdapter | null> {
|
|
279
|
-
// Check if adapter is specified in config
|
|
280
|
-
if (this.config.websocket?.adapter) {
|
|
281
|
-
const adapterType = this.config.websocket.adapter;
|
|
282
|
-
|
|
283
|
-
if (adapterType === 'uws' && isPackageAvailable('uWebSockets.js')) {
|
|
284
|
-
try {
|
|
285
|
-
const { UWebSocketsAdapter } = await import('./networking/adapters/index.js');
|
|
286
|
-
return new UWebSocketsAdapter();
|
|
287
|
-
} catch {
|
|
288
|
-
this.logger.warn('uWebSockets.js specified but failed to load', 'AdapterDetection');
|
|
289
|
-
}
|
|
290
|
-
} else if (adapterType === 'socket.io' && isPackageAvailable('socket.io')) {
|
|
291
|
-
try {
|
|
292
|
-
const { SocketIOAdapter } = await import('./networking/adapters/index.js');
|
|
293
|
-
return new SocketIOAdapter();
|
|
294
|
-
} catch {
|
|
295
|
-
this.logger.warn('socket.io specified but failed to load', 'AdapterDetection');
|
|
296
|
-
}
|
|
297
|
-
} else if (adapterType === 'ws' && isPackageAvailable('ws')) {
|
|
298
|
-
try {
|
|
299
|
-
const { WSAdapter } = await import('./networking/adapters/index.js');
|
|
300
|
-
return new WSAdapter();
|
|
301
|
-
} catch {
|
|
302
|
-
this.logger.warn('ws specified but failed to load', 'AdapterDetection');
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// Auto-detect: Try uWebSockets.js first (highest performance)
|
|
308
|
-
if (isPackageAvailable('uWebSockets.js')) {
|
|
309
|
-
try {
|
|
310
|
-
const { UWebSocketsAdapter } = await import('./networking/adapters/index.js');
|
|
311
|
-
this.logger.debug('uWebSockets.js detected and loaded', 'AdapterDetection');
|
|
312
|
-
return new UWebSocketsAdapter();
|
|
313
|
-
} catch {
|
|
314
|
-
// Failed to load adapter
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// Try socket.io second
|
|
319
|
-
if (isPackageAvailable('socket.io')) {
|
|
320
|
-
try {
|
|
321
|
-
const { SocketIOAdapter } = await import('./networking/adapters/index.js');
|
|
322
|
-
this.logger.debug('socket.io detected and loaded', 'AdapterDetection');
|
|
323
|
-
return new SocketIOAdapter();
|
|
324
|
-
} catch {
|
|
325
|
-
// Failed to load adapter
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Try native ws library last
|
|
330
|
-
if (isPackageAvailable('ws')) {
|
|
331
|
-
try {
|
|
332
|
-
const { WSAdapter } = await import('./networking/adapters/index.js');
|
|
333
|
-
this.logger.debug('ws detected and loaded', 'AdapterDetection');
|
|
334
|
-
return new WSAdapter();
|
|
335
|
-
} catch {
|
|
336
|
-
// Failed to load adapter
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
this.logger.warn(
|
|
341
|
-
'No WebSocket adapter found. Install uWebSockets.js, socket.io, or ws for WebSocket support',
|
|
342
|
-
'AdapterDetection'
|
|
343
|
-
);
|
|
344
|
-
return null;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
private requestLoggingMiddleware() {
|
|
348
|
-
return (req: HttpRequest, res: HttpResponse, next: () => void) => {
|
|
349
|
-
const startTime = Date.now();
|
|
350
|
-
|
|
351
|
-
res.on('finish', () => {
|
|
352
|
-
const duration = Date.now() - startTime;
|
|
353
|
-
// Include request ID in log if request tracking is enabled
|
|
354
|
-
const idPart = req.requestId ? ` [${req.requestId}]` : '';
|
|
355
|
-
this.logger.info(`${req.method} ${req.path} - ${res.statusCode} - ${duration}ms${idPart}`);
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
next();
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
private errorBoundaryMiddleware() {
|
|
363
|
-
return async (req: HttpRequest, res: HttpResponse, next: () => void) => {
|
|
364
|
-
try {
|
|
365
|
-
next();
|
|
366
|
-
} catch (error: any) {
|
|
367
|
-
this.logger.error('Error:', error.message, error.stack);
|
|
368
|
-
|
|
369
|
-
if (!res.headersSent) {
|
|
370
|
-
res.status(500).json({
|
|
371
|
-
success: false,
|
|
372
|
-
error: 'Internal server error',
|
|
373
|
-
requestId: req.requestId,
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
// Public API for adding middleware
|
|
381
|
-
addMiddleware(middleware: any) {
|
|
382
|
-
this.httpServer.use(middleware);
|
|
383
|
-
this.emit('middleware:added', { middleware });
|
|
384
|
-
return this;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// Public API for database registration
|
|
388
|
-
registerDatabase(adapter: any) {
|
|
389
|
-
this.container.register('database', () => adapter, true);
|
|
390
|
-
this.emit('database:registered', { adapter });
|
|
391
|
-
return this;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
// Public API for accessing HTTP server
|
|
395
|
-
getHttpServer() {
|
|
396
|
-
return this.httpServer;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// Public API for accessing Socket.IO server
|
|
400
|
-
/**
|
|
401
|
-
* Get WebSocket adapter (for backward compatibility)
|
|
402
|
-
* @deprecated Use getWebSocketAdapter() instead
|
|
403
|
-
*/
|
|
404
|
-
getIOServer() {
|
|
405
|
-
if (!this.websocketAdapter) {
|
|
406
|
-
throw new Error(
|
|
407
|
-
'WebSocket adapter not available. Install socket.io or configure a WebSocket adapter.'
|
|
408
|
-
);
|
|
409
|
-
}
|
|
410
|
-
return this.websocketAdapter;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
* Get the WebSocket adapter
|
|
415
|
-
*/
|
|
416
|
-
getWebSocketAdapter(): WebSocketAdapter | undefined {
|
|
417
|
-
return this.websocketAdapter;
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
/**
|
|
421
|
-
* Ensure WebSocket setup is complete (for async adapter detection)
|
|
422
|
-
*/
|
|
423
|
-
async ensureWebSocketReady(): Promise<void> {
|
|
424
|
-
if (this.websocketSetupPromise) {
|
|
425
|
-
await this.websocketSetupPromise;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
/**
|
|
430
|
-
* Get the WebSocket manager
|
|
431
|
-
*/
|
|
432
|
-
getWebSocketManager(): WebSocketManager | undefined {
|
|
433
|
-
return this.websocketManager;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
async loadModule(moduleConfig: ModuleConfig): Promise<void> {
|
|
437
|
-
this.logger.info(
|
|
438
|
-
`Loading module: ${moduleConfig.name}@${moduleConfig.version}`,
|
|
439
|
-
'ModuleLoader'
|
|
440
|
-
);
|
|
441
|
-
|
|
442
|
-
// Create module event bus once during module loading
|
|
443
|
-
const moduleEventBus = this.eventBus.createModuleBus(moduleConfig.name);
|
|
444
|
-
|
|
445
|
-
// Register services in DI container
|
|
446
|
-
this.registerServices(moduleConfig);
|
|
447
|
-
|
|
448
|
-
// Create module router with resilience patterns
|
|
449
|
-
const router = await this.createModuleRouter(moduleConfig, moduleEventBus);
|
|
450
|
-
|
|
451
|
-
// Setup WebSocket handlers
|
|
452
|
-
if (moduleConfig.websockets) {
|
|
453
|
-
await this.setupWebSocketHandlers(moduleConfig);
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
// Mount with versioning
|
|
457
|
-
this.logger.debug(`Module version before basePath: "${moduleConfig.version}"`, 'ModuleLoader');
|
|
458
|
-
const basePath = `/api/v${moduleConfig.version}/${moduleConfig.name}`;
|
|
459
|
-
this.logger.debug(`Generated basePath: "${basePath}"`, 'ModuleLoader');
|
|
460
|
-
this.mountRouter(basePath, router);
|
|
461
|
-
|
|
462
|
-
this.logger.info(`Module loaded: ${moduleConfig.name}`, 'ModuleLoader');
|
|
463
|
-
this.emit('moduleLoaded', moduleConfig.name);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
private registerServices(config: ModuleConfig): void {
|
|
467
|
-
if (!config.services) return;
|
|
468
|
-
|
|
469
|
-
for (const service of config.services) {
|
|
470
|
-
const factory = () => {
|
|
471
|
-
const dependencies = (service.dependencies || []).map(dep => this.container.resolve(dep));
|
|
472
|
-
return new service.implementation(...dependencies);
|
|
473
|
-
};
|
|
474
|
-
|
|
475
|
-
this.container.register(service.name, factory, service.singleton || false);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
// Register functional route handlers if they exist
|
|
479
|
-
if (config.routeHandlers) {
|
|
480
|
-
for (const [name, handler] of Object.entries(config.routeHandlers)) {
|
|
481
|
-
this.container.register(name, () => handler, false);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
// Register functional socket handlers if they exist
|
|
486
|
-
if (config.socketHandlers) {
|
|
487
|
-
for (const [name, handler] of Object.entries(config.socketHandlers)) {
|
|
488
|
-
this.container.register(name, () => handler, false);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
private async createModuleRouter(config: ModuleConfig, moduleEventBus: any): Promise<Router> {
|
|
494
|
-
const router = new Router();
|
|
495
|
-
|
|
496
|
-
this.logger.debug(`Creating router for module: ${config.name}`, 'Router');
|
|
497
|
-
this.logger.debug(`Module has ${config.routes?.length || 0} routes`, 'Router');
|
|
498
|
-
|
|
499
|
-
if (!config.routes) return router;
|
|
500
|
-
|
|
501
|
-
for (const route of config.routes) {
|
|
502
|
-
this.logger.debug(
|
|
503
|
-
`Adding route: ${route.method} ${route.path} -> ${route.handler}`,
|
|
504
|
-
'Router'
|
|
505
|
-
);
|
|
506
|
-
const handler = await this.createResilientHandler(route, config, moduleEventBus);
|
|
507
|
-
const method = route.method.toLowerCase() as keyof Router;
|
|
508
|
-
|
|
509
|
-
// Add route to router
|
|
510
|
-
(router[method] as Function)(route.path, handler);
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
this.logger.debug(`Router created with ${router.getRoutes().length} total routes`, 'Router');
|
|
514
|
-
return router;
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
private async createResilientHandler(
|
|
518
|
-
route: InternalRouteDefinition,
|
|
519
|
-
config: ModuleConfig,
|
|
520
|
-
moduleEventBus: any
|
|
521
|
-
) {
|
|
522
|
-
const handlerKey = `${config.name}.${route.handler}`;
|
|
523
|
-
|
|
524
|
-
return async (req: HttpRequest, res: HttpResponse) => {
|
|
525
|
-
const requestId = req.headers['x-request-id'] || Math.random().toString(36);
|
|
526
|
-
|
|
527
|
-
try {
|
|
528
|
-
// Try to get functional handler first, then fall back to service-based
|
|
529
|
-
let handler;
|
|
530
|
-
let useEnhancedReq = false;
|
|
531
|
-
|
|
532
|
-
if (config.routeHandlers && config.routeHandlers[route.handler]) {
|
|
533
|
-
// New functional handler
|
|
534
|
-
handler = config.routeHandlers[route.handler];
|
|
535
|
-
useEnhancedReq = true;
|
|
536
|
-
this.logger.debug(`Using functional handler: ${route.handler}`, 'Handler', {
|
|
537
|
-
availableHandlers: Object.keys(config.routeHandlers || {}),
|
|
538
|
-
});
|
|
539
|
-
} else if (this.container.has(config.name)) {
|
|
540
|
-
// Old service-based handler
|
|
541
|
-
const service = this.container.resolve(config.name) as any;
|
|
542
|
-
handler = service[route.handler];
|
|
543
|
-
this.logger.debug(`Using service handler: ${config.name}.${route.handler}`, 'Handler');
|
|
544
|
-
} else {
|
|
545
|
-
this.logger.error(`No handler found for route ${route.method} ${route.path}`, 'Handler', {
|
|
546
|
-
routeHandlers: Object.keys(config.routeHandlers || {}),
|
|
547
|
-
containerHasModule: this.container.has(config.name),
|
|
548
|
-
});
|
|
549
|
-
throw new Error(`Handler ${route.handler} not found for module ${config.name}`);
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
if (!handler || typeof handler !== 'function') {
|
|
553
|
-
throw new Error(`Handler ${route.handler} is not a function`);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// Check authentication if auth configuration is provided
|
|
557
|
-
if ((route as any).auth) {
|
|
558
|
-
const auth = (req as any).auth;
|
|
559
|
-
const authConfig = (route as any).auth;
|
|
560
|
-
|
|
561
|
-
if (!auth) {
|
|
562
|
-
res.status(401);
|
|
563
|
-
res.json({
|
|
564
|
-
success: false,
|
|
565
|
-
error: 'Authentication required',
|
|
566
|
-
message: 'You must be logged in to access this resource',
|
|
567
|
-
});
|
|
568
|
-
return;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// Check authentication requirement (default is required unless optional: true)
|
|
572
|
-
if (!authConfig.optional && !auth.isAuthenticated) {
|
|
573
|
-
res.status(401);
|
|
574
|
-
res.json({
|
|
575
|
-
success: false,
|
|
576
|
-
error: 'Authentication required',
|
|
577
|
-
message: 'You must be logged in to access this resource',
|
|
578
|
-
});
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
// Skip further checks if not authenticated but optional
|
|
583
|
-
if (!auth.isAuthenticated && authConfig.optional) {
|
|
584
|
-
// Continue to handler
|
|
585
|
-
} else if (auth.isAuthenticated) {
|
|
586
|
-
const user = auth.user;
|
|
587
|
-
|
|
588
|
-
// Check roles if specified
|
|
589
|
-
if (authConfig.roles && authConfig.roles.length > 0) {
|
|
590
|
-
const userRoles = user?.roles || [];
|
|
591
|
-
const hasRole = authConfig.roles.some((role: string) => userRoles.includes(role));
|
|
592
|
-
|
|
593
|
-
if (!hasRole) {
|
|
594
|
-
res.status(403);
|
|
595
|
-
res.json({
|
|
596
|
-
success: false,
|
|
597
|
-
error: 'Insufficient permissions',
|
|
598
|
-
message: `Required roles: ${authConfig.roles.join(', ')}`,
|
|
599
|
-
userRoles,
|
|
600
|
-
});
|
|
601
|
-
return;
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
// Check permissions if specified
|
|
606
|
-
if (authConfig.permissions && authConfig.permissions.length > 0) {
|
|
607
|
-
const userPermissions = user?.permissions || [];
|
|
608
|
-
const hasPermission = authConfig.permissions.every((permission: string) =>
|
|
609
|
-
userPermissions.includes(permission)
|
|
610
|
-
);
|
|
611
|
-
|
|
612
|
-
if (!hasPermission) {
|
|
613
|
-
res.status(403);
|
|
614
|
-
res.json({
|
|
615
|
-
success: false,
|
|
616
|
-
error: 'Insufficient permissions',
|
|
617
|
-
message: `Required permissions: ${authConfig.permissions.join(', ')}`,
|
|
618
|
-
userPermissions,
|
|
619
|
-
});
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
// Validate request if validation schema is provided
|
|
627
|
-
if (route.validation) {
|
|
628
|
-
try {
|
|
629
|
-
// Validate body
|
|
630
|
-
if (route.validation.body && req.body !== undefined) {
|
|
631
|
-
req.body = route.validation.body.parse(req.body);
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
// Validate query
|
|
635
|
-
if (route.validation.query && req.query !== undefined) {
|
|
636
|
-
req.query = route.validation.query.parse(req.query);
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
// Validate params
|
|
640
|
-
if (route.validation.params && req.params !== undefined) {
|
|
641
|
-
req.params = route.validation.params.parse(req.params);
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
// Validate headers
|
|
645
|
-
if (route.validation.headers && req.headers !== undefined) {
|
|
646
|
-
req.headers = route.validation.headers.parse(req.headers);
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
this.logger.debug('Module route validation passed', 'ModuleValidation', {
|
|
650
|
-
route: `${route.method} ${route.path}`,
|
|
651
|
-
module: config.name,
|
|
652
|
-
});
|
|
653
|
-
} catch (validationError: any) {
|
|
654
|
-
if (validationError.issues) {
|
|
655
|
-
this.logger.debug('Module route validation failed', 'ModuleValidation', {
|
|
656
|
-
route: `${route.method} ${route.path}`,
|
|
657
|
-
module: config.name,
|
|
658
|
-
errors: validationError.issues.length,
|
|
659
|
-
});
|
|
660
|
-
|
|
661
|
-
res.status(400).json({
|
|
662
|
-
success: false,
|
|
663
|
-
error: 'Validation failed',
|
|
664
|
-
details: validationError.issues.map((issue: any) => ({
|
|
665
|
-
field: issue.path.length > 0 ? issue.path.join('.') : 'request',
|
|
666
|
-
message: issue.message,
|
|
667
|
-
code: issue.code,
|
|
668
|
-
})),
|
|
669
|
-
requestId,
|
|
670
|
-
});
|
|
671
|
-
return;
|
|
672
|
-
}
|
|
673
|
-
throw validationError;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
// Prepare request object based on handler type
|
|
678
|
-
let requestToUse: any = req;
|
|
679
|
-
if (useEnhancedReq) {
|
|
680
|
-
// Use the pre-created module event bus
|
|
681
|
-
requestToUse = {
|
|
682
|
-
...req,
|
|
683
|
-
database: this.container.has('database')
|
|
684
|
-
? this.container.resolve('database')
|
|
685
|
-
: undefined,
|
|
686
|
-
events: moduleEventBus, // Use pre-created event bus
|
|
687
|
-
app: {
|
|
688
|
-
get: (key: string) => (key === 'io' ? this.websocketAdapter : undefined),
|
|
689
|
-
},
|
|
690
|
-
};
|
|
691
|
-
this.logger.debug(`Database available: ${!!requestToUse.database}`, 'Handler', {
|
|
692
|
-
moduleId: config.name,
|
|
693
|
-
});
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
// Execute with circuit breaker
|
|
697
|
-
const circuitBreaker = this.getCircuitBreaker(handlerKey);
|
|
698
|
-
const result = await circuitBreaker.execute(() => handler(requestToUse, res));
|
|
699
|
-
|
|
700
|
-
// For functional handlers, ensure the response is sent
|
|
701
|
-
if (useEnhancedReq && result !== undefined && result !== null && !res.headersSent) {
|
|
702
|
-
this.logger.debug(`Sending functional handler result`, 'Handler', {
|
|
703
|
-
result,
|
|
704
|
-
});
|
|
705
|
-
res.json(result);
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
return result;
|
|
709
|
-
} catch (error: any) {
|
|
710
|
-
this.logger.error(`Route handler error [${requestId}]: ${error.message}`, 'Handler', {
|
|
711
|
-
requestId,
|
|
712
|
-
handlerKey,
|
|
713
|
-
stack: error.stack,
|
|
714
|
-
});
|
|
715
|
-
if (!res.headersSent) {
|
|
716
|
-
res.status(500).json({
|
|
717
|
-
success: false,
|
|
718
|
-
error: 'Internal server error',
|
|
719
|
-
requestId,
|
|
720
|
-
});
|
|
721
|
-
}
|
|
722
|
-
throw error;
|
|
723
|
-
}
|
|
724
|
-
};
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
private mountRouter(basePath: string, router: Router): void {
|
|
728
|
-
this.logger.debug(`Mounting router for basePath: ${basePath}`, 'Router');
|
|
729
|
-
|
|
730
|
-
// Enterprise-grade middleware integration with performance optimization
|
|
731
|
-
// IMPORTANT: Module middleware runs AFTER user middleware (like auth) to ensure proper order
|
|
732
|
-
this.httpServer.use(async (req: HttpRequest, res: HttpResponse, next: () => void) => {
|
|
733
|
-
if (req.path.startsWith(basePath)) {
|
|
734
|
-
this.logger.debug(`Module middleware handling: ${req.method} ${req.path}`, 'Middleware', {
|
|
735
|
-
basePath,
|
|
736
|
-
});
|
|
737
|
-
|
|
738
|
-
// Mark this request as being handled by a module
|
|
739
|
-
(req as any).__moduleBasePath = basePath;
|
|
740
|
-
(req as any).__moduleRouter = router;
|
|
741
|
-
|
|
742
|
-
// Continue to next middleware (including auth) first
|
|
743
|
-
next();
|
|
744
|
-
} else {
|
|
745
|
-
next();
|
|
746
|
-
}
|
|
747
|
-
});
|
|
748
|
-
|
|
749
|
-
this.logger.info(`Router mounted for ${basePath}`, 'Router');
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
private finalModuleHandlerSetup = false;
|
|
753
|
-
|
|
754
|
-
// Setup final module handler that runs after all user middleware
|
|
755
|
-
setupFinalModuleHandler(): void {
|
|
756
|
-
// Prevent duplicate setup
|
|
757
|
-
if (this.finalModuleHandlerSetup) {
|
|
758
|
-
this.logger.debug('Final module handler already set up, skipping', 'ModuleSystem');
|
|
759
|
-
return;
|
|
760
|
-
}
|
|
761
|
-
this.finalModuleHandlerSetup = true;
|
|
762
|
-
|
|
763
|
-
this.logger.info(
|
|
764
|
-
'Setting up final module handler to run after user middleware',
|
|
765
|
-
'ModuleSystem'
|
|
766
|
-
);
|
|
767
|
-
|
|
768
|
-
this.httpServer.use(async (req: HttpRequest, res: HttpResponse, next: () => void) => {
|
|
769
|
-
// Check if this request was marked for module handling
|
|
770
|
-
const moduleBasePath = (req as any).__moduleBasePath;
|
|
771
|
-
const moduleRouter = (req as any).__moduleRouter;
|
|
772
|
-
|
|
773
|
-
if (moduleBasePath && moduleRouter && !res.headersSent) {
|
|
774
|
-
this.logger.debug(`Final module handler processing: ${req.method} ${req.path}`, 'Router');
|
|
775
|
-
|
|
776
|
-
try {
|
|
777
|
-
const handled = await moduleRouter.handle(req, res, moduleBasePath);
|
|
778
|
-
this.logger.debug(`Route handled by module: ${handled}`, 'Router');
|
|
779
|
-
|
|
780
|
-
if (!handled) {
|
|
781
|
-
next(); // Let other middleware handle it
|
|
782
|
-
}
|
|
783
|
-
// If handled, the router already sent the response, so don't call next()
|
|
784
|
-
} catch (error) {
|
|
785
|
-
this.logger.error('Module router error', 'Router', {
|
|
786
|
-
error: error instanceof Error ? error.message : String(error),
|
|
787
|
-
});
|
|
788
|
-
if (!res.headersSent) {
|
|
789
|
-
res.status(500).json({ success: false, error: 'Internal server error' });
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
} else {
|
|
793
|
-
next();
|
|
794
|
-
}
|
|
795
|
-
});
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
private async setupWebSocketHandlers(config: ModuleConfig): Promise<void> {
|
|
799
|
-
if (!this.websocketAdapter || !this.websocketManager) {
|
|
800
|
-
this.logger.warn(
|
|
801
|
-
`Module ${config.name} defines WebSocket handlers but no WebSocket adapter is available`,
|
|
802
|
-
'WebSocketSetup'
|
|
803
|
-
);
|
|
804
|
-
return;
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
const namespace = this.websocketAdapter.createNamespace(`/${config.name}`);
|
|
808
|
-
|
|
809
|
-
for (const wsConfig of config.websockets || []) {
|
|
810
|
-
await this.websocketManager.registerHandler(namespace, wsConfig, config);
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
private checkRateLimit(
|
|
815
|
-
identifier: string,
|
|
816
|
-
rateLimit: { requests: number; window: number }
|
|
817
|
-
): boolean {
|
|
818
|
-
if (!this.rateLimiters.has(identifier)) {
|
|
819
|
-
this.rateLimiters.set(identifier, new Map());
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
const handlerLimiter = this.rateLimiters.get(identifier)!;
|
|
823
|
-
const now = Date.now();
|
|
824
|
-
const limit = handlerLimiter.get(identifier);
|
|
825
|
-
|
|
826
|
-
if (!limit || now > limit.resetTime) {
|
|
827
|
-
handlerLimiter.set(identifier, {
|
|
828
|
-
count: 1,
|
|
829
|
-
resetTime: now + rateLimit.window,
|
|
830
|
-
});
|
|
831
|
-
return true;
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
if (limit.count >= rateLimit.requests) {
|
|
835
|
-
return false;
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
limit.count++;
|
|
839
|
-
return true;
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
private getCircuitBreaker(key: string): CircuitBreaker {
|
|
843
|
-
if (!this.circuitBreakers.has(key)) {
|
|
844
|
-
this.circuitBreakers.set(
|
|
845
|
-
key,
|
|
846
|
-
new CircuitBreaker({
|
|
847
|
-
failureThreshold: 5,
|
|
848
|
-
resetTimeout: 30000,
|
|
849
|
-
monitoringPeriod: 10000,
|
|
850
|
-
})
|
|
851
|
-
);
|
|
852
|
-
}
|
|
853
|
-
return this.circuitBreakers.get(key)!;
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
listen(port: number, callback?: () => void): void;
|
|
857
|
-
listen(port: number, host: string, callback?: () => void): void;
|
|
858
|
-
listen(port: number, host?: string | (() => void), callback?: () => void): void {
|
|
859
|
-
if (typeof host === 'function') {
|
|
860
|
-
this.httpServer.listen(port, host);
|
|
861
|
-
} else if (host) {
|
|
862
|
-
this.httpServer.listen(port, host, callback);
|
|
863
|
-
} else {
|
|
864
|
-
this.httpServer.listen(port, callback);
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
// Compatibility method for existing controllers
|
|
869
|
-
set(key: string, value: any): void {
|
|
870
|
-
if (key === 'io') {
|
|
871
|
-
// Deprecated: Use websocket adapter instead
|
|
872
|
-
this.logger.warn(
|
|
873
|
-
'Setting io instance is deprecated. Use websocket adapter configuration.',
|
|
874
|
-
'Deprecated'
|
|
875
|
-
);
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
get(key: string): any {
|
|
880
|
-
if (key === 'io') {
|
|
881
|
-
return this.websocketAdapter;
|
|
882
|
-
}
|
|
883
|
-
return undefined;
|
|
884
|
-
}
|
|
885
|
-
}
|