@morojs/moro 1.6.1 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -256
- package/dist/core/auth/morojs-adapter.js +20 -20
- package/dist/core/auth/morojs-adapter.js.map +1 -1
- package/dist/core/config/config-manager.d.ts +44 -0
- package/dist/core/config/config-manager.js +104 -0
- package/dist/core/config/config-manager.js.map +1 -0
- package/dist/core/config/config-sources.d.ts +21 -0
- package/dist/core/config/config-sources.js +503 -0
- package/dist/core/config/config-sources.js.map +1 -0
- package/dist/core/config/config-validator.d.ts +21 -0
- package/dist/core/config/config-validator.js +791 -0
- package/dist/core/config/config-validator.js.map +1 -0
- package/dist/core/config/file-loader.d.ts +1 -6
- package/dist/core/config/file-loader.js +21 -249
- package/dist/core/config/file-loader.js.map +1 -1
- package/dist/core/config/index.d.ts +41 -12
- package/dist/core/config/index.js +65 -54
- package/dist/core/config/index.js.map +1 -1
- package/dist/core/config/schema.d.ts +2 -2
- package/dist/core/config/schema.js +55 -44
- package/dist/core/config/schema.js.map +1 -1
- package/dist/core/config/utils.d.ts +10 -3
- package/dist/core/config/utils.js +31 -58
- package/dist/core/config/utils.js.map +1 -1
- package/dist/core/database/adapters/drizzle.d.ts +1 -1
- package/dist/core/database/adapters/drizzle.js +18 -11
- package/dist/core/database/adapters/drizzle.js.map +1 -1
- package/dist/core/database/adapters/index.d.ts +7 -7
- package/dist/core/database/adapters/index.js +19 -29
- package/dist/core/database/adapters/index.js.map +1 -1
- package/dist/core/database/adapters/mongodb.d.ts +13 -1
- package/dist/core/database/adapters/mongodb.js +46 -10
- package/dist/core/database/adapters/mongodb.js.map +1 -1
- package/dist/core/database/adapters/mysql.d.ts +14 -1
- package/dist/core/database/adapters/mysql.js +19 -9
- package/dist/core/database/adapters/mysql.js.map +1 -1
- package/dist/core/database/adapters/postgresql.d.ts +12 -2
- package/dist/core/database/adapters/postgresql.js +19 -9
- package/dist/core/database/adapters/postgresql.js.map +1 -1
- package/dist/core/database/adapters/redis.d.ts +12 -1
- package/dist/core/database/adapters/redis.js +48 -13
- package/dist/core/database/adapters/redis.js.map +1 -1
- package/dist/core/database/adapters/sqlite.d.ts +3 -1
- package/dist/core/database/adapters/sqlite.js +19 -8
- package/dist/core/database/adapters/sqlite.js.map +1 -1
- package/dist/core/database/index.d.ts +2 -2
- package/dist/core/database/index.js +2 -18
- package/dist/core/database/index.js.map +1 -1
- package/dist/core/docs/index.d.ts +9 -9
- package/dist/core/docs/index.js +14 -35
- package/dist/core/docs/index.js.map +1 -1
- package/dist/core/docs/openapi-generator.d.ts +2 -2
- package/dist/core/docs/openapi-generator.js +11 -16
- package/dist/core/docs/openapi-generator.js.map +1 -1
- package/dist/core/docs/schema-to-openapi.d.ts +2 -2
- package/dist/core/docs/schema-to-openapi.js +5 -11
- package/dist/core/docs/schema-to-openapi.js.map +1 -1
- package/dist/core/docs/simple-docs.d.ts +1 -1
- package/dist/core/docs/simple-docs.js +4 -9
- package/dist/core/docs/simple-docs.js.map +1 -1
- package/dist/core/docs/swagger-ui.d.ts +2 -2
- package/dist/core/docs/swagger-ui.js +26 -29
- package/dist/core/docs/swagger-ui.js.map +1 -1
- package/dist/core/docs/zod-to-openapi.js +31 -28
- package/dist/core/docs/zod-to-openapi.js.map +1 -1
- package/dist/core/events/event-bus.d.ts +1 -1
- package/dist/core/events/event-bus.js +7 -11
- package/dist/core/events/event-bus.js.map +1 -1
- package/dist/core/events/index.d.ts +2 -2
- package/dist/core/events/index.js +1 -5
- package/dist/core/events/index.js.map +1 -1
- package/dist/core/framework.d.ts +20 -13
- package/dist/core/framework.js +285 -102
- package/dist/core/framework.js.map +1 -1
- package/dist/core/http/http-server.d.ts +59 -7
- package/dist/core/http/http-server.js +190 -176
- package/dist/core/http/http-server.js.map +1 -1
- package/dist/core/http/index.d.ts +4 -3
- package/dist/core/http/index.js +3 -8
- package/dist/core/http/index.js.map +1 -1
- package/dist/core/http/uws-http-server.d.ts +46 -0
- package/dist/core/http/uws-http-server.js +523 -0
- package/dist/core/http/uws-http-server.js.map +1 -0
- package/dist/core/logger/filters.d.ts +1 -1
- package/dist/core/logger/filters.js +20 -23
- package/dist/core/logger/filters.js.map +1 -1
- package/dist/core/logger/index.d.ts +3 -3
- package/dist/core/logger/index.js +2 -24
- package/dist/core/logger/index.js.map +1 -1
- package/dist/core/logger/logger.d.ts +30 -14
- package/dist/core/logger/logger.js +398 -223
- package/dist/core/logger/logger.js.map +1 -1
- package/dist/core/logger/outputs.d.ts +1 -1
- package/dist/core/logger/outputs.js +8 -17
- package/dist/core/logger/outputs.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cache/file.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cache/file.js +10 -47
- package/dist/core/middleware/built-in/adapters/cache/file.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cache/index.d.ts +4 -4
- package/dist/core/middleware/built-in/adapters/cache/index.js +10 -17
- package/dist/core/middleware/built-in/adapters/cache/index.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cache/memory.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cache/memory.js +3 -7
- package/dist/core/middleware/built-in/adapters/cache/memory.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cache/redis.d.ts +3 -1
- package/dist/core/middleware/built-in/adapters/cache/redis.js +11 -9
- package/dist/core/middleware/built-in/adapters/cache/redis.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/azure.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/azure.js +3 -7
- package/dist/core/middleware/built-in/adapters/cdn/azure.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js +3 -7
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.d.ts +3 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js +12 -10
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/index.d.ts +4 -4
- package/dist/core/middleware/built-in/adapters/cdn/index.js +10 -17
- package/dist/core/middleware/built-in/adapters/cdn/index.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/index.d.ts +4 -4
- package/dist/core/middleware/built-in/adapters/index.js +4 -23
- package/dist/core/middleware/built-in/adapters/index.js.map +1 -1
- package/dist/core/middleware/built-in/auth-helpers.js +11 -22
- package/dist/core/middleware/built-in/auth-helpers.js.map +1 -1
- package/dist/core/middleware/built-in/auth-providers.d.ts +1 -1
- package/dist/core/middleware/built-in/auth-providers.js +4 -9
- package/dist/core/middleware/built-in/auth-providers.js.map +1 -1
- package/dist/core/middleware/built-in/auth.d.ts +2 -2
- package/dist/core/middleware/built-in/auth.js +93 -26
- package/dist/core/middleware/built-in/auth.js.map +1 -1
- package/dist/core/middleware/built-in/cache.d.ts +2 -2
- package/dist/core/middleware/built-in/cache.js +11 -12
- package/dist/core/middleware/built-in/cache.js.map +1 -1
- package/dist/core/middleware/built-in/cdn.d.ts +2 -2
- package/dist/core/middleware/built-in/cdn.js +5 -9
- package/dist/core/middleware/built-in/cdn.js.map +1 -1
- package/dist/core/middleware/built-in/cookie.d.ts +1 -1
- package/dist/core/middleware/built-in/cookie.js +3 -7
- package/dist/core/middleware/built-in/cookie.js.map +1 -1
- package/dist/core/middleware/built-in/cors.d.ts +1 -1
- package/dist/core/middleware/built-in/cors.js +3 -7
- package/dist/core/middleware/built-in/cors.js.map +1 -1
- package/dist/core/middleware/built-in/csp.d.ts +1 -1
- package/dist/core/middleware/built-in/csp.js +5 -8
- package/dist/core/middleware/built-in/csp.js.map +1 -1
- package/dist/core/middleware/built-in/csrf.d.ts +1 -1
- package/dist/core/middleware/built-in/csrf.js +5 -8
- package/dist/core/middleware/built-in/csrf.js.map +1 -1
- package/dist/core/middleware/built-in/error-tracker.js +3 -7
- package/dist/core/middleware/built-in/error-tracker.js.map +1 -1
- package/dist/core/middleware/built-in/index.d.ts +28 -27
- package/dist/core/middleware/built-in/index.js +48 -78
- package/dist/core/middleware/built-in/index.js.map +1 -1
- package/dist/core/middleware/built-in/jwt-helpers.d.ts +118 -0
- package/dist/core/middleware/built-in/jwt-helpers.js +218 -0
- package/dist/core/middleware/built-in/jwt-helpers.js.map +1 -0
- package/dist/core/middleware/built-in/performance-monitor.js +3 -7
- package/dist/core/middleware/built-in/performance-monitor.js.map +1 -1
- package/dist/core/middleware/built-in/rate-limit.d.ts +1 -1
- package/dist/core/middleware/built-in/rate-limit.js +3 -7
- package/dist/core/middleware/built-in/rate-limit.js.map +1 -1
- package/dist/core/middleware/built-in/request-logger.js +5 -8
- package/dist/core/middleware/built-in/request-logger.js.map +1 -1
- package/dist/core/middleware/built-in/session.d.ts +2 -2
- package/dist/core/middleware/built-in/session.js +11 -15
- package/dist/core/middleware/built-in/session.js.map +1 -1
- package/dist/core/middleware/built-in/sse.d.ts +1 -1
- package/dist/core/middleware/built-in/sse.js +12 -14
- package/dist/core/middleware/built-in/sse.js.map +1 -1
- package/dist/core/middleware/built-in/validation.d.ts +1 -1
- package/dist/core/middleware/built-in/validation.js +3 -7
- package/dist/core/middleware/built-in/validation.js.map +1 -1
- package/dist/core/middleware/index.d.ts +4 -4
- package/dist/core/middleware/index.js +8 -28
- package/dist/core/middleware/index.js.map +1 -1
- package/dist/core/modules/auto-discovery.d.ts +19 -2
- package/dist/core/modules/auto-discovery.js +391 -74
- package/dist/core/modules/auto-discovery.js.map +1 -1
- package/dist/core/modules/index.d.ts +2 -2
- package/dist/core/modules/index.js +2 -9
- package/dist/core/modules/index.js.map +1 -1
- package/dist/core/modules/modules.d.ts +3 -3
- package/dist/core/modules/modules.js +23 -54
- package/dist/core/modules/modules.js.map +1 -1
- package/dist/core/networking/adapters/index.d.ts +4 -3
- package/dist/core/networking/adapters/index.js +3 -7
- package/dist/core/networking/adapters/index.js.map +1 -1
- package/dist/core/networking/adapters/socketio-adapter.d.ts +1 -1
- package/dist/core/networking/adapters/socketio-adapter.js +5 -40
- package/dist/core/networking/adapters/socketio-adapter.js.map +1 -1
- package/dist/core/networking/adapters/uws-adapter.d.ts +44 -0
- package/dist/core/networking/adapters/uws-adapter.js +513 -0
- package/dist/core/networking/adapters/uws-adapter.js.map +1 -0
- package/dist/core/networking/adapters/ws-adapter.d.ts +2 -2
- package/dist/core/networking/adapters/ws-adapter.js +8 -43
- package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
- package/dist/core/networking/index.d.ts +3 -2
- package/dist/core/networking/index.js +2 -7
- package/dist/core/networking/index.js.map +1 -1
- package/dist/core/networking/service-discovery.js +8 -12
- package/dist/core/networking/service-discovery.js.map +1 -1
- package/dist/core/networking/websocket-adapter.js +1 -2
- package/dist/core/networking/websocket-adapter.js.map +1 -1
- package/dist/core/networking/websocket-manager.d.ts +3 -3
- package/dist/core/networking/websocket-manager.js +9 -11
- package/dist/core/networking/websocket-manager.js.map +1 -1
- package/dist/core/pooling/object-pool-manager.d.ts +140 -0
- package/dist/core/pooling/object-pool-manager.js +502 -0
- package/dist/core/pooling/object-pool-manager.js.map +1 -0
- package/dist/core/routing/app-integration.d.ts +14 -12
- package/dist/core/routing/app-integration.js +49 -85
- package/dist/core/routing/app-integration.js.map +1 -1
- package/dist/core/routing/index.d.ts +17 -11
- package/dist/core/routing/index.js +48 -237
- package/dist/core/routing/index.js.map +1 -1
- package/dist/core/routing/path-matcher.d.ts +67 -0
- package/dist/core/routing/path-matcher.js +182 -0
- package/dist/core/routing/path-matcher.js.map +1 -0
- package/dist/core/routing/router.d.ts +38 -0
- package/dist/core/routing/router.js +68 -0
- package/dist/core/routing/router.js.map +1 -0
- package/dist/core/routing/unified-router.d.ts +148 -0
- package/dist/core/routing/unified-router.js +684 -0
- package/dist/core/routing/unified-router.js.map +1 -0
- package/dist/core/runtime/aws-lambda-adapter.d.ts +3 -3
- package/dist/core/runtime/aws-lambda-adapter.js +2 -6
- package/dist/core/runtime/aws-lambda-adapter.js.map +1 -1
- package/dist/core/runtime/base-adapter.d.ts +2 -2
- package/dist/core/runtime/base-adapter.js +3 -7
- package/dist/core/runtime/base-adapter.js.map +1 -1
- package/dist/core/runtime/cloudflare-workers-adapter.d.ts +3 -3
- package/dist/core/runtime/cloudflare-workers-adapter.js +2 -6
- package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -1
- package/dist/core/runtime/index.d.ts +12 -12
- package/dist/core/runtime/index.js +22 -35
- package/dist/core/runtime/index.js.map +1 -1
- package/dist/core/runtime/node-adapter.d.ts +4 -4
- package/dist/core/runtime/node-adapter.js +18 -49
- package/dist/core/runtime/node-adapter.js.map +1 -1
- package/dist/core/runtime/vercel-edge-adapter.d.ts +3 -3
- package/dist/core/runtime/vercel-edge-adapter.js +2 -6
- package/dist/core/runtime/vercel-edge-adapter.js.map +1 -1
- package/dist/core/utilities/circuit-breaker.js +1 -5
- package/dist/core/utilities/circuit-breaker.js.map +1 -1
- package/dist/core/utilities/container.js +12 -22
- package/dist/core/utilities/container.js.map +1 -1
- package/dist/core/utilities/hooks.d.ts +2 -2
- package/dist/core/utilities/hooks.js +7 -12
- package/dist/core/utilities/hooks.js.map +1 -1
- package/dist/core/utilities/index.d.ts +5 -4
- package/dist/core/utilities/index.js +5 -19
- package/dist/core/utilities/index.js.map +1 -1
- package/dist/core/utilities/package-utils.d.ts +38 -0
- package/dist/core/utilities/package-utils.js +57 -0
- package/dist/core/utilities/package-utils.js.map +1 -0
- package/dist/core/validation/adapters.d.ts +1 -1
- package/dist/core/validation/adapters.js +15 -26
- package/dist/core/validation/adapters.js.map +1 -1
- package/dist/core/validation/index.d.ts +6 -4
- package/dist/core/validation/index.js +57 -28
- package/dist/core/validation/index.js.map +1 -1
- package/dist/core/validation/schema-interface.js +3 -9
- package/dist/core/validation/schema-interface.js.map +1 -1
- package/dist/index.d.ts +51 -52
- package/dist/index.js +23 -132
- package/dist/index.js.map +1 -1
- package/dist/moro.d.ts +70 -16
- package/dist/moro.js +658 -271
- package/dist/moro.js.map +1 -1
- package/dist/types/auth.js +3 -9
- package/dist/types/auth.js.map +1 -1
- package/dist/types/cache.js +1 -2
- package/dist/types/cdn.js +1 -2
- package/dist/types/config.d.ts +73 -2
- package/dist/types/config.js +1 -2
- package/dist/types/config.js.map +1 -1
- package/dist/types/core.d.ts +36 -42
- package/dist/types/core.js +1 -2
- package/dist/types/database.js +1 -2
- package/dist/types/discovery.js +1 -2
- package/dist/types/events.js +1 -2
- package/dist/types/hooks.d.ts +1 -1
- package/dist/types/hooks.js +1 -2
- package/dist/types/http.d.ts +16 -1
- package/dist/types/http.js +1 -2
- package/dist/types/logger.d.ts +7 -0
- package/dist/types/logger.js +1 -2
- package/dist/types/module.d.ts +11 -0
- package/dist/types/module.js +1 -2
- package/dist/types/runtime.d.ts +1 -1
- package/dist/types/runtime.js +1 -2
- package/dist/types/session.js +1 -2
- package/jest.config.mjs +41 -0
- package/package.json +19 -52
- package/src/core/auth/morojs-adapter.ts +18 -13
- package/src/core/config/config-manager.ts +133 -0
- package/src/core/config/config-sources.ts +600 -0
- package/src/core/config/config-validator.ts +1116 -0
- package/src/core/config/file-loader.ts +16 -273
- package/src/core/config/index.ts +83 -34
- package/src/core/config/schema.ts +47 -33
- package/src/core/config/utils.ts +24 -31
- package/src/core/database/README.md +26 -16
- package/src/core/database/adapters/drizzle.ts +18 -6
- package/src/core/database/adapters/index.ts +13 -13
- package/src/core/database/adapters/mongodb.ts +53 -5
- package/src/core/database/adapters/mysql.ts +32 -4
- package/src/core/database/adapters/postgresql.ts +30 -5
- package/src/core/database/adapters/redis.ts +61 -8
- package/src/core/database/adapters/sqlite.ts +19 -3
- package/src/core/database/index.ts +2 -2
- package/src/core/docs/index.ts +8 -8
- package/src/core/docs/openapi-generator.ts +4 -4
- package/src/core/docs/schema-to-openapi.ts +3 -6
- package/src/core/docs/simple-docs.ts +2 -2
- package/src/core/docs/swagger-ui.ts +19 -16
- package/src/core/docs/zod-to-openapi.ts +34 -34
- package/src/core/events/event-bus.ts +3 -3
- package/src/core/events/index.ts +2 -2
- package/src/core/framework.ts +320 -71
- package/src/core/http/http-server.ts +203 -143
- package/src/core/http/index.ts +4 -3
- package/src/core/http/uws-http-server.ts +591 -0
- package/src/core/logger/filters.ts +13 -5
- package/src/core/logger/index.ts +4 -3
- package/src/core/logger/logger.ts +435 -216
- package/src/core/logger/outputs.ts +1 -3
- package/src/core/middleware/built-in/adapters/cache/file.ts +3 -3
- package/src/core/middleware/built-in/adapters/cache/index.ts +7 -7
- package/src/core/middleware/built-in/adapters/cache/memory.ts +2 -2
- package/src/core/middleware/built-in/adapters/cache/redis.ts +18 -4
- package/src/core/middleware/built-in/adapters/cdn/azure.ts +2 -2
- package/src/core/middleware/built-in/adapters/cdn/cloudflare.ts +2 -2
- package/src/core/middleware/built-in/adapters/cdn/cloudfront.ts +16 -5
- package/src/core/middleware/built-in/adapters/cdn/index.ts +7 -7
- package/src/core/middleware/built-in/adapters/index.ts +4 -4
- package/src/core/middleware/built-in/auth-helpers.ts +1 -1
- package/src/core/middleware/built-in/auth-providers.ts +1 -1
- package/src/core/middleware/built-in/auth.ts +102 -21
- package/src/core/middleware/built-in/cache.ts +8 -6
- package/src/core/middleware/built-in/cdn.ts +4 -4
- package/src/core/middleware/built-in/cookie.ts +2 -2
- package/src/core/middleware/built-in/cors.ts +2 -2
- package/src/core/middleware/built-in/csp.ts +3 -3
- package/src/core/middleware/built-in/csrf.ts +3 -3
- package/src/core/middleware/built-in/error-tracker.ts +1 -1
- package/src/core/middleware/built-in/index.ts +38 -30
- package/src/core/middleware/built-in/jwt-helpers.ts +243 -0
- package/src/core/middleware/built-in/performance-monitor.ts +1 -1
- package/src/core/middleware/built-in/rate-limit.ts +2 -2
- package/src/core/middleware/built-in/request-logger.ts +3 -1
- package/src/core/middleware/built-in/session.ts +7 -8
- package/src/core/middleware/built-in/sse.ts +11 -9
- package/src/core/middleware/built-in/validation.ts +2 -2
- package/src/core/middleware/index.ts +6 -6
- package/src/core/modules/auto-discovery.ts +478 -15
- package/src/core/modules/index.ts +2 -2
- package/src/core/modules/modules.ts +23 -12
- package/src/core/networking/adapters/index.ts +4 -3
- package/src/core/networking/adapters/socketio-adapter.ts +5 -3
- package/src/core/networking/adapters/uws-adapter.ts +619 -0
- package/src/core/networking/adapters/ws-adapter.ts +8 -9
- package/src/core/networking/index.ts +3 -2
- package/src/core/networking/service-discovery.ts +6 -7
- package/src/core/networking/websocket-manager.ts +7 -7
- package/src/core/pooling/object-pool-manager.ts +630 -0
- package/src/core/routing/app-integration.ts +60 -112
- package/src/core/routing/index.ts +66 -293
- package/src/core/routing/path-matcher.ts +222 -0
- package/src/core/routing/router.ts +97 -0
- package/src/core/routing/unified-router.ts +870 -0
- package/src/core/runtime/aws-lambda-adapter.ts +3 -3
- package/src/core/runtime/base-adapter.ts +2 -2
- package/src/core/runtime/cloudflare-workers-adapter.ts +3 -3
- package/src/core/runtime/index.ts +13 -13
- package/src/core/runtime/node-adapter.ts +16 -10
- package/src/core/runtime/vercel-edge-adapter.ts +3 -3
- package/src/core/utilities/hooks.ts +3 -3
- package/src/core/utilities/index.ts +5 -4
- package/src/core/utilities/package-utils.ts +59 -0
- package/src/core/validation/adapters.ts +1 -1
- package/src/core/validation/index.ts +68 -16
- package/src/index.ts +73 -66
- package/src/moro.ts +784 -253
- package/src/types/config.ts +74 -2
- package/src/types/core.ts +49 -47
- package/src/types/hooks.ts +1 -1
- package/src/types/http.ts +23 -1
- package/src/types/logger.ts +9 -0
- package/src/types/module.ts +12 -0
- package/src/types/runtime.ts +1 -1
- package/tsconfig.json +4 -2
- package/dist/core/config/loader.d.ts +0 -7
- package/dist/core/config/loader.js +0 -269
- package/dist/core/config/loader.js.map +0 -1
- package/dist/core/config/validation.d.ts +0 -17
- package/dist/core/config/validation.js +0 -131
- package/dist/core/config/validation.js.map +0 -1
- package/dist/core/http/router.d.ts +0 -14
- package/dist/core/http/router.js +0 -109
- package/dist/core/http/router.js.map +0 -1
- package/src/core/config/loader.ts +0 -633
- package/src/core/config/validation.ts +0 -140
- package/src/core/http/router.ts +0 -141
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
// src/core/http-server.ts
|
|
2
2
|
import { IncomingMessage, ServerResponse, createServer, Server } from 'http';
|
|
3
3
|
import * as zlib from 'zlib';
|
|
4
|
+
import { createReadStream } from 'fs';
|
|
5
|
+
import * as crypto from 'crypto';
|
|
4
6
|
import { promisify } from 'util';
|
|
5
|
-
import { createFrameworkLogger } from '../logger';
|
|
6
|
-
import {
|
|
7
|
+
import { createFrameworkLogger } from '../logger/index.js';
|
|
8
|
+
import {
|
|
9
|
+
HttpRequest,
|
|
10
|
+
HttpResponse,
|
|
11
|
+
HttpHandler,
|
|
12
|
+
Middleware,
|
|
13
|
+
RouteEntry,
|
|
14
|
+
} from '../../types/http.js';
|
|
15
|
+
import { PathMatcher } from '../routing/path-matcher.js';
|
|
16
|
+
import { ObjectPoolManager } from '../pooling/object-pool-manager.js';
|
|
7
17
|
|
|
8
18
|
const gzip = promisify(zlib.gzip);
|
|
9
19
|
const deflate = promisify(zlib.deflate);
|
|
@@ -14,41 +24,15 @@ export class MoroHttpServer {
|
|
|
14
24
|
private globalMiddleware: Middleware[] = [];
|
|
15
25
|
private compressionEnabled = true;
|
|
16
26
|
private compressionThreshold = 1024;
|
|
27
|
+
private requestTrackingEnabled = true; // Generate request IDs
|
|
17
28
|
private logger = createFrameworkLogger('HttpServer');
|
|
18
29
|
private hookManager: any;
|
|
19
30
|
private requestCounter = 0;
|
|
20
31
|
|
|
21
|
-
//
|
|
22
|
-
private
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// Request handler pooling to avoid function creation overhead
|
|
27
|
-
private middlewareExecutionCache = new Map<string, Function>();
|
|
28
|
-
|
|
29
|
-
// String interning for common values (massive memory savings)
|
|
30
|
-
private static readonly INTERNED_METHODS = new Map([
|
|
31
|
-
['GET', 'GET'],
|
|
32
|
-
['POST', 'POST'],
|
|
33
|
-
['PUT', 'PUT'],
|
|
34
|
-
['DELETE', 'DELETE'],
|
|
35
|
-
['PATCH', 'PATCH'],
|
|
36
|
-
['HEAD', 'HEAD'],
|
|
37
|
-
['OPTIONS', 'OPTIONS'],
|
|
38
|
-
]);
|
|
39
|
-
|
|
40
|
-
private static readonly INTERNED_HEADERS = new Map([
|
|
41
|
-
['content-type', 'content-type'],
|
|
42
|
-
['content-length', 'content-length'],
|
|
43
|
-
['authorization', 'authorization'],
|
|
44
|
-
['accept', 'accept'],
|
|
45
|
-
['user-agent', 'user-agent'],
|
|
46
|
-
['host', 'host'],
|
|
47
|
-
['connection', 'connection'],
|
|
48
|
-
['cache-control', 'cache-control'],
|
|
49
|
-
]);
|
|
50
|
-
|
|
51
|
-
// Pre-compiled response templates for ultra-common responses
|
|
32
|
+
// Use shared object pool manager
|
|
33
|
+
private poolManager = ObjectPoolManager.getInstance();
|
|
34
|
+
|
|
35
|
+
// Pre-compiled response templates for common responses
|
|
52
36
|
private static readonly RESPONSE_TEMPLATES = {
|
|
53
37
|
notFound: Buffer.from('{"success":false,"error":"Not found"}'),
|
|
54
38
|
unauthorized: Buffer.from('{"success":false,"error":"Unauthorized"}'),
|
|
@@ -58,7 +42,7 @@ export class MoroHttpServer {
|
|
|
58
42
|
rateLimited: Buffer.from('{"success":false,"error":"Rate limit exceeded"}'),
|
|
59
43
|
};
|
|
60
44
|
|
|
61
|
-
//
|
|
45
|
+
// Buffer pool for zero-copy operations
|
|
62
46
|
private static readonly BUFFER_SIZES = [64, 256, 1024, 4096, 16384];
|
|
63
47
|
private static readonly BUFFER_POOLS = new Map<number, Buffer[]>();
|
|
64
48
|
|
|
@@ -126,6 +110,11 @@ export class MoroHttpServer {
|
|
|
126
110
|
}
|
|
127
111
|
}
|
|
128
112
|
|
|
113
|
+
// Configure request tracking (ID generation)
|
|
114
|
+
setRequestTracking(enabled: boolean): void {
|
|
115
|
+
this.requestTrackingEnabled = enabled;
|
|
116
|
+
}
|
|
117
|
+
|
|
129
118
|
// Middleware management
|
|
130
119
|
use(middleware: Middleware): void {
|
|
131
120
|
this.globalMiddleware.push(middleware);
|
|
@@ -193,45 +182,37 @@ export class MoroHttpServer {
|
|
|
193
182
|
}
|
|
194
183
|
|
|
195
184
|
private pathToRegex(path: string): { pattern: RegExp; paramNames: string[] } {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
// Convert parameterized routes to regex
|
|
199
|
-
const regexPattern = path
|
|
200
|
-
.replace(/\/:([^/]+)/g, (match, paramName) => {
|
|
201
|
-
paramNames.push(paramName);
|
|
202
|
-
return '/([^/]+)';
|
|
203
|
-
})
|
|
204
|
-
.replace(/\//g, '\\/');
|
|
205
|
-
|
|
185
|
+
// Use shared PathMatcher for consistent path compilation
|
|
186
|
+
const compiled = PathMatcher.compile(path);
|
|
206
187
|
return {
|
|
207
|
-
pattern: new RegExp(`^${
|
|
208
|
-
paramNames,
|
|
188
|
+
pattern: compiled.pattern || new RegExp(`^${path.replace(/\//g, '\\/')}$`),
|
|
189
|
+
paramNames: compiled.paramNames,
|
|
209
190
|
};
|
|
210
191
|
}
|
|
211
192
|
|
|
212
193
|
private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {
|
|
213
194
|
const httpReq = this.enhanceRequest(req);
|
|
214
|
-
const httpRes = this.enhanceResponse(res);
|
|
195
|
+
const httpRes = this.enhanceResponse(res, httpReq);
|
|
215
196
|
|
|
216
197
|
// Store original params for efficient cleanup
|
|
217
198
|
const originalParams = httpReq.params;
|
|
218
199
|
|
|
219
200
|
try {
|
|
220
|
-
// Optimized URL and query parsing
|
|
201
|
+
// Optimized URL and query parsing with object pooling
|
|
221
202
|
const urlString = req.url!;
|
|
222
203
|
const queryIndex = urlString.indexOf('?');
|
|
223
204
|
|
|
224
205
|
if (queryIndex === -1) {
|
|
225
|
-
// No query string
|
|
206
|
+
// No query string
|
|
226
207
|
httpReq.path = urlString;
|
|
227
208
|
httpReq.query = {};
|
|
228
209
|
} else {
|
|
229
|
-
// Has query string - parse efficiently
|
|
210
|
+
// Has query string - parse efficiently with pooled object
|
|
230
211
|
httpReq.path = urlString.substring(0, queryIndex);
|
|
231
|
-
httpReq.query = this.
|
|
212
|
+
httpReq.query = this.parseQueryStringPooled(urlString.substring(queryIndex + 1));
|
|
232
213
|
}
|
|
233
214
|
|
|
234
|
-
//
|
|
215
|
+
// Method checking - avoid array includes
|
|
235
216
|
const method = req.method!;
|
|
236
217
|
if (method === 'POST' || method === 'PUT' || method === 'PATCH') {
|
|
237
218
|
httpReq.body = await this.parseBody(req);
|
|
@@ -256,7 +237,7 @@ export class MoroHttpServer {
|
|
|
256
237
|
// Find matching route
|
|
257
238
|
const route = this.findRoute(req.method!, httpReq.path);
|
|
258
239
|
if (!route) {
|
|
259
|
-
//
|
|
240
|
+
// 404 response with pre-compiled buffer
|
|
260
241
|
httpRes.statusCode = 404;
|
|
261
242
|
httpRes.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
262
243
|
httpRes.setHeader('Content-Length', MoroHttpServer.RESPONSE_TEMPLATES.notFound.length);
|
|
@@ -281,18 +262,13 @@ export class MoroHttpServer {
|
|
|
281
262
|
await route.handler(httpReq, httpRes);
|
|
282
263
|
} catch (error) {
|
|
283
264
|
// Debug: Log the actual error and where it came from
|
|
284
|
-
this.logger.debug('
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
`📍 Error stack: ${error instanceof Error ? error.stack : 'No stack trace'}`,
|
|
292
|
-
'RequestHandler'
|
|
293
|
-
);
|
|
294
|
-
this.logger.debug(`📍 Request path: ${req.url}`, 'RequestHandler');
|
|
295
|
-
this.logger.debug(`📍 Request method: ${req.method}`, 'RequestHandler');
|
|
265
|
+
this.logger.debug('Request error details', 'RequestHandler', {
|
|
266
|
+
errorType: typeof error,
|
|
267
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
268
|
+
errorStack: error instanceof Error ? error.stack : 'No stack trace',
|
|
269
|
+
requestPath: req.url,
|
|
270
|
+
requestMethod: req.method,
|
|
271
|
+
});
|
|
296
272
|
|
|
297
273
|
this.logger.error('Request error', 'RequestHandler', {
|
|
298
274
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -310,20 +286,16 @@ export class MoroHttpServer {
|
|
|
310
286
|
requestId: httpReq.requestId,
|
|
311
287
|
});
|
|
312
288
|
} else {
|
|
313
|
-
//
|
|
289
|
+
// Defensive fallback - check each method individually
|
|
314
290
|
if (typeof httpRes.setHeader === 'function') {
|
|
315
291
|
httpRes.statusCode = 500;
|
|
316
292
|
httpRes.setHeader('Content-Type', 'application/json');
|
|
317
293
|
} else {
|
|
318
294
|
// Even setHeader doesn't exist - object is completely wrong
|
|
319
|
-
this.logger.error(
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
responseType: typeof httpRes,
|
|
324
|
-
responseKeys: Object.keys(httpRes),
|
|
325
|
-
}
|
|
326
|
-
);
|
|
295
|
+
this.logger.error('Response object is not a proper ServerResponse', 'RequestHandler', {
|
|
296
|
+
responseType: typeof httpRes,
|
|
297
|
+
responseKeys: Object.keys(httpRes),
|
|
298
|
+
});
|
|
327
299
|
}
|
|
328
300
|
|
|
329
301
|
if (typeof httpRes.end === 'function') {
|
|
@@ -336,7 +308,7 @@ export class MoroHttpServer {
|
|
|
336
308
|
);
|
|
337
309
|
} else {
|
|
338
310
|
this.logger.error(
|
|
339
|
-
'
|
|
311
|
+
'Cannot send error response - end() method missing',
|
|
340
312
|
'RequestHandler'
|
|
341
313
|
);
|
|
342
314
|
}
|
|
@@ -372,55 +344,32 @@ export class MoroHttpServer {
|
|
|
372
344
|
});
|
|
373
345
|
}
|
|
374
346
|
|
|
375
|
-
//
|
|
347
|
+
// Use shared object pool for parameter objects
|
|
376
348
|
private acquireParamObject(): Record<string, string> {
|
|
377
|
-
|
|
378
|
-
if (obj) {
|
|
379
|
-
// ES2022: Use Object.hasOwn for safer property checks and faster clearing
|
|
380
|
-
// Clear existing properties more efficiently
|
|
381
|
-
for (const key in obj) {
|
|
382
|
-
if (Object.hasOwn(obj, key)) {
|
|
383
|
-
delete obj[key];
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
return obj;
|
|
387
|
-
}
|
|
388
|
-
return {};
|
|
349
|
+
return this.poolManager.acquireParams();
|
|
389
350
|
}
|
|
390
351
|
|
|
391
352
|
private releaseParamObject(params: Record<string, string>): void {
|
|
392
|
-
|
|
393
|
-
this.paramObjectPool.push(params);
|
|
394
|
-
}
|
|
353
|
+
this.poolManager.releaseParams(params);
|
|
395
354
|
}
|
|
396
355
|
|
|
397
356
|
// Force cleanup of all pooled objects
|
|
398
357
|
private forceCleanupPools(): void {
|
|
399
|
-
//
|
|
400
|
-
this.
|
|
401
|
-
this.bufferPool.splice(0);
|
|
358
|
+
// Use shared pool manager cleanup
|
|
359
|
+
this.poolManager.clearAll();
|
|
402
360
|
|
|
403
361
|
// Force garbage collection if available
|
|
404
|
-
// Use modern globalThis check with optional chaining
|
|
405
362
|
if (globalThis?.gc) {
|
|
406
363
|
globalThis.gc();
|
|
407
364
|
}
|
|
408
365
|
}
|
|
409
366
|
|
|
410
367
|
private acquireBuffer(size: number): Buffer {
|
|
411
|
-
|
|
412
|
-
const index = this.bufferPool.findIndex(b => b.length >= size);
|
|
413
|
-
if (index !== -1) {
|
|
414
|
-
const buffer = this.bufferPool.splice(index, 1)[0];
|
|
415
|
-
return buffer.subarray(0, size);
|
|
416
|
-
}
|
|
417
|
-
return Buffer.allocUnsafe(size);
|
|
368
|
+
return this.poolManager.acquireBuffer(size);
|
|
418
369
|
}
|
|
419
370
|
|
|
420
371
|
private releaseBuffer(buffer: Buffer): void {
|
|
421
|
-
|
|
422
|
-
this.bufferPool.push(buffer);
|
|
423
|
-
}
|
|
372
|
+
this.poolManager.releaseBuffer(buffer);
|
|
424
373
|
}
|
|
425
374
|
|
|
426
375
|
private streamLargeResponse(res: any, data: any): void {
|
|
@@ -444,7 +393,7 @@ export class MoroHttpServer {
|
|
|
444
393
|
return this.pathNormalizationCache.get(path)!;
|
|
445
394
|
}
|
|
446
395
|
|
|
447
|
-
//
|
|
396
|
+
// Normalization: remove trailing slash (except root), decode once
|
|
448
397
|
let normalized = path;
|
|
449
398
|
if (normalized.length > 1 && normalized.endsWith('/')) {
|
|
450
399
|
normalized = normalized.slice(0, -1);
|
|
@@ -465,8 +414,8 @@ export class MoroHttpServer {
|
|
|
465
414
|
httpReq.body = null;
|
|
466
415
|
httpReq.path = '';
|
|
467
416
|
httpReq.ip = req.socket.remoteAddress || '';
|
|
468
|
-
//
|
|
469
|
-
httpReq.requestId =
|
|
417
|
+
// Request ID generation using pool manager (if enabled)
|
|
418
|
+
httpReq.requestId = this.requestTrackingEnabled ? this.poolManager.generateRequestId() : '';
|
|
470
419
|
httpReq.headers = req.headers as Record<string, string>;
|
|
471
420
|
|
|
472
421
|
// Parse cookies
|
|
@@ -489,9 +438,12 @@ export class MoroHttpServer {
|
|
|
489
438
|
return cookies;
|
|
490
439
|
}
|
|
491
440
|
|
|
492
|
-
private enhanceResponse(res: ServerResponse): HttpResponse {
|
|
441
|
+
private enhanceResponse(res: ServerResponse, req: HttpRequest): HttpResponse {
|
|
493
442
|
const httpRes = res as HttpResponse;
|
|
494
443
|
|
|
444
|
+
// Store request reference for access to headers (needed for compression, logging, etc.)
|
|
445
|
+
(httpRes as any).req = req;
|
|
446
|
+
|
|
495
447
|
// BULLETPROOF status method - always works
|
|
496
448
|
httpRes.status = (code: number) => {
|
|
497
449
|
httpRes.statusCode = code;
|
|
@@ -501,7 +453,7 @@ export class MoroHttpServer {
|
|
|
501
453
|
httpRes.json = async (data: any) => {
|
|
502
454
|
if (httpRes.headersSent) return;
|
|
503
455
|
|
|
504
|
-
//
|
|
456
|
+
// JSON serialization with zero-copy buffers
|
|
505
457
|
let jsonString: string;
|
|
506
458
|
|
|
507
459
|
// Enhanced JSON optimization for common API patterns
|
|
@@ -587,6 +539,7 @@ export class MoroHttpServer {
|
|
|
587
539
|
});
|
|
588
540
|
|
|
589
541
|
httpRes.end(finalBuffer);
|
|
542
|
+
|
|
590
543
|
// Return buffer to pool after response (zero-copy achievement!)
|
|
591
544
|
process.nextTick(() => MoroHttpServer.returnBuffer(buffer));
|
|
592
545
|
};
|
|
@@ -615,6 +568,26 @@ export class MoroHttpServer {
|
|
|
615
568
|
};
|
|
616
569
|
|
|
617
570
|
httpRes.cookie = (name: string, value: string, options: any = {}) => {
|
|
571
|
+
if (httpRes.headersSent) {
|
|
572
|
+
const isCritical =
|
|
573
|
+
options.critical ||
|
|
574
|
+
name.includes('session') ||
|
|
575
|
+
name.includes('auth') ||
|
|
576
|
+
name.includes('csrf');
|
|
577
|
+
const message = `Cookie '${name}' could not be set - headers already sent`;
|
|
578
|
+
|
|
579
|
+
if (isCritical || options.throwOnLateSet) {
|
|
580
|
+
throw new Error(`${message}. This may cause authentication or security issues.`);
|
|
581
|
+
} else {
|
|
582
|
+
this.logger.warn(message, 'CookieWarning', {
|
|
583
|
+
cookieName: name,
|
|
584
|
+
critical: isCritical,
|
|
585
|
+
stackTrace: new Error().stack,
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
return httpRes;
|
|
589
|
+
}
|
|
590
|
+
|
|
618
591
|
const cookieValue = encodeURIComponent(value);
|
|
619
592
|
let cookieString = `${name}=${cookieValue}`;
|
|
620
593
|
|
|
@@ -678,6 +651,62 @@ export class MoroHttpServer {
|
|
|
678
651
|
}
|
|
679
652
|
};
|
|
680
653
|
|
|
654
|
+
// Header management utilities
|
|
655
|
+
httpRes.hasHeader = (name: string): boolean => {
|
|
656
|
+
return httpRes.getHeader(name) !== undefined;
|
|
657
|
+
};
|
|
658
|
+
|
|
659
|
+
// Note: removeHeader is inherited from ServerResponse, we don't override it
|
|
660
|
+
|
|
661
|
+
httpRes.setBulkHeaders = (headers: Record<string, string | number>) => {
|
|
662
|
+
if (httpRes.headersSent) {
|
|
663
|
+
this.logger.warn('Cannot set headers - headers already sent', 'HeaderWarning', {
|
|
664
|
+
attemptedHeaders: Object.keys(headers),
|
|
665
|
+
});
|
|
666
|
+
return httpRes;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
670
|
+
httpRes.setHeader(key, value);
|
|
671
|
+
});
|
|
672
|
+
return httpRes;
|
|
673
|
+
};
|
|
674
|
+
|
|
675
|
+
httpRes.appendHeader = (name: string, value: string | string[]) => {
|
|
676
|
+
if (httpRes.headersSent) {
|
|
677
|
+
this.logger.warn(
|
|
678
|
+
`Cannot append to header '${name}' - headers already sent`,
|
|
679
|
+
'HeaderWarning'
|
|
680
|
+
);
|
|
681
|
+
return httpRes;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
const existing = httpRes.getHeader(name);
|
|
685
|
+
if (existing) {
|
|
686
|
+
const values = Array.isArray(existing) ? existing : [existing.toString()];
|
|
687
|
+
const newValues = Array.isArray(value) ? value : [value];
|
|
688
|
+
httpRes.setHeader(name, [...values, ...newValues]);
|
|
689
|
+
} else {
|
|
690
|
+
httpRes.setHeader(name, value);
|
|
691
|
+
}
|
|
692
|
+
return httpRes;
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
// Response state utilities
|
|
696
|
+
httpRes.canSetHeaders = (): boolean => {
|
|
697
|
+
return !httpRes.headersSent;
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
httpRes.getResponseState = () => {
|
|
701
|
+
return {
|
|
702
|
+
headersSent: httpRes.headersSent,
|
|
703
|
+
statusCode: httpRes.statusCode,
|
|
704
|
+
headers: httpRes.getHeaders ? httpRes.getHeaders() : {},
|
|
705
|
+
finished: httpRes.finished || false,
|
|
706
|
+
writable: httpRes.writable,
|
|
707
|
+
};
|
|
708
|
+
};
|
|
709
|
+
|
|
681
710
|
return httpRes;
|
|
682
711
|
}
|
|
683
712
|
|
|
@@ -815,12 +844,20 @@ export class MoroHttpServer {
|
|
|
815
844
|
return result;
|
|
816
845
|
}
|
|
817
846
|
|
|
847
|
+
// Legacy method for backward compatibility
|
|
818
848
|
private parseQueryString(queryString: string): Record<string, string> {
|
|
819
|
-
|
|
820
|
-
|
|
849
|
+
return this.parseQueryStringPooled(queryString);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
// Optimized query string parser with object pooling
|
|
853
|
+
private parseQueryStringPooled(queryString: string): Record<string, string> {
|
|
854
|
+
if (!queryString) return {};
|
|
821
855
|
|
|
856
|
+
const result = this.poolManager.acquireQuery();
|
|
822
857
|
const pairs = queryString.split('&');
|
|
823
|
-
|
|
858
|
+
|
|
859
|
+
for (let i = 0; i < pairs.length; i++) {
|
|
860
|
+
const pair = pairs[i];
|
|
824
861
|
const equalIndex = pair.indexOf('=');
|
|
825
862
|
if (equalIndex === -1) {
|
|
826
863
|
result[decodeURIComponent(pair)] = '';
|
|
@@ -840,7 +877,7 @@ export class MoroHttpServer {
|
|
|
840
877
|
private routesBySegmentCount = new Map<number, RouteEntry[]>();
|
|
841
878
|
private pathNormalizationCache = new Map<string, string>();
|
|
842
879
|
|
|
843
|
-
//
|
|
880
|
+
// CPU cache-friendly optimizations
|
|
844
881
|
private routeHitCount = new Map<string, number>(); // Track route popularity for cache optimization
|
|
845
882
|
private static readonly HOT_ROUTE_THRESHOLD = 100; // Routes accessed 100+ times get hot path treatment
|
|
846
883
|
|
|
@@ -896,21 +933,25 @@ export class MoroHttpServer {
|
|
|
896
933
|
return route;
|
|
897
934
|
}
|
|
898
935
|
|
|
936
|
+
// Optimized middleware execution with reduced Promise allocation
|
|
899
937
|
private async executeMiddleware(
|
|
900
938
|
middleware: Middleware[],
|
|
901
939
|
req: HttpRequest,
|
|
902
940
|
res: HttpResponse
|
|
903
941
|
): Promise<void> {
|
|
904
|
-
for (
|
|
942
|
+
for (let i = 0; i < middleware.length; i++) {
|
|
905
943
|
// Short-circuit if response already sent
|
|
906
944
|
if (res.headersSent) return;
|
|
907
945
|
|
|
946
|
+
const mw = middleware[i];
|
|
947
|
+
|
|
908
948
|
await new Promise<void>((resolve, reject) => {
|
|
909
|
-
let
|
|
949
|
+
let resolved = false;
|
|
910
950
|
|
|
951
|
+
// Reuse next function to reduce allocations
|
|
911
952
|
const next = () => {
|
|
912
|
-
if (
|
|
913
|
-
|
|
953
|
+
if (resolved) return;
|
|
954
|
+
resolved = true;
|
|
914
955
|
resolve();
|
|
915
956
|
};
|
|
916
957
|
|
|
@@ -918,15 +959,21 @@ export class MoroHttpServer {
|
|
|
918
959
|
const result = mw(req, res, next);
|
|
919
960
|
|
|
920
961
|
// Handle async middleware
|
|
921
|
-
if (result
|
|
922
|
-
result
|
|
962
|
+
if (result && typeof (result as any).then === 'function') {
|
|
963
|
+
(result as Promise<void>)
|
|
923
964
|
.then(() => {
|
|
924
|
-
if (!
|
|
965
|
+
if (!resolved) next();
|
|
925
966
|
})
|
|
926
967
|
.catch(reject);
|
|
968
|
+
} else if (!resolved) {
|
|
969
|
+
// Sync middleware that didn't call next
|
|
970
|
+
next();
|
|
927
971
|
}
|
|
928
972
|
} catch (error) {
|
|
929
|
-
|
|
973
|
+
if (!resolved) {
|
|
974
|
+
resolved = true;
|
|
975
|
+
reject(error);
|
|
976
|
+
}
|
|
930
977
|
}
|
|
931
978
|
});
|
|
932
979
|
}
|
|
@@ -962,6 +1009,17 @@ export class MoroHttpServer {
|
|
|
962
1009
|
getServer(): Server {
|
|
963
1010
|
return this.server;
|
|
964
1011
|
}
|
|
1012
|
+
|
|
1013
|
+
// Performance statistics
|
|
1014
|
+
getPerformanceStats() {
|
|
1015
|
+
const poolStats = this.poolManager.getStats();
|
|
1016
|
+
return {
|
|
1017
|
+
paramObjectPoolSize: poolStats.paramPool.poolSize,
|
|
1018
|
+
queryObjectPoolSize: poolStats.queryPool.poolSize,
|
|
1019
|
+
headerObjectPoolSize: poolStats.headerPool.poolSize,
|
|
1020
|
+
poolManager: poolStats,
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
965
1023
|
}
|
|
966
1024
|
|
|
967
1025
|
// Built-in middleware
|
|
@@ -998,7 +1056,6 @@ export const middleware = {
|
|
|
998
1056
|
},
|
|
999
1057
|
|
|
1000
1058
|
compression: (options: { threshold?: number; level?: number } = {}): Middleware => {
|
|
1001
|
-
const zlib = require('zlib');
|
|
1002
1059
|
const threshold = options.threshold || 1024;
|
|
1003
1060
|
const level = options.level || 6;
|
|
1004
1061
|
|
|
@@ -1018,23 +1075,25 @@ export const middleware = {
|
|
|
1018
1075
|
}
|
|
1019
1076
|
|
|
1020
1077
|
if (acceptEncoding.includes('gzip')) {
|
|
1021
|
-
res.setHeader('Content-Encoding', 'gzip');
|
|
1022
1078
|
zlib.gzip(buffer, { level }, (err: any, compressed: Buffer) => {
|
|
1023
1079
|
if (err) {
|
|
1024
1080
|
return isJson ? originalJson.call(res, data) : originalSend.call(res, data);
|
|
1025
1081
|
}
|
|
1026
|
-
res.
|
|
1027
|
-
|
|
1082
|
+
if (!res.headersSent) {
|
|
1083
|
+
res.setHeader('Content-Encoding', 'gzip');
|
|
1084
|
+
res.setHeader('Content-Length', compressed.length);
|
|
1085
|
+
}
|
|
1028
1086
|
res.end(compressed);
|
|
1029
1087
|
});
|
|
1030
1088
|
} else if (acceptEncoding.includes('deflate')) {
|
|
1031
|
-
res.setHeader('Content-Encoding', 'deflate');
|
|
1032
1089
|
zlib.deflate(buffer, { level }, (err: any, compressed: Buffer) => {
|
|
1033
1090
|
if (err) {
|
|
1034
1091
|
return isJson ? originalJson.call(res, data) : originalSend.call(res, data);
|
|
1035
1092
|
}
|
|
1036
|
-
res.
|
|
1037
|
-
|
|
1093
|
+
if (!res.headersSent) {
|
|
1094
|
+
res.setHeader('Content-Encoding', 'deflate');
|
|
1095
|
+
res.setHeader('Content-Length', compressed.length);
|
|
1096
|
+
}
|
|
1038
1097
|
res.end(compressed);
|
|
1039
1098
|
});
|
|
1040
1099
|
} else {
|
|
@@ -1462,13 +1521,15 @@ export const middleware = {
|
|
|
1462
1521
|
// Only handle SSE requests
|
|
1463
1522
|
if (req.headers.accept?.includes('text/event-stream')) {
|
|
1464
1523
|
// Set SSE headers
|
|
1465
|
-
res.
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1524
|
+
if (!res.headersSent) {
|
|
1525
|
+
res.writeHead(200, {
|
|
1526
|
+
'Content-Type': 'text/event-stream',
|
|
1527
|
+
'Cache-Control': 'no-cache',
|
|
1528
|
+
Connection: 'keep-alive',
|
|
1529
|
+
'Access-Control-Allow-Origin': options.cors ? '*' : undefined,
|
|
1530
|
+
'Access-Control-Allow-Headers': options.cors ? 'Cache-Control' : undefined,
|
|
1531
|
+
});
|
|
1532
|
+
}
|
|
1472
1533
|
|
|
1473
1534
|
// Add SSE methods to response
|
|
1474
1535
|
(res as any).sendEvent = (data: any, event?: string, id?: string) => {
|
|
@@ -1569,7 +1630,8 @@ export const middleware = {
|
|
|
1569
1630
|
const chunkSize = end - start + 1;
|
|
1570
1631
|
|
|
1571
1632
|
if (start >= fileSize || end >= fileSize) {
|
|
1572
|
-
res.status(416)
|
|
1633
|
+
res.status(416);
|
|
1634
|
+
res.setHeader('Content-Range', `bytes */${fileSize}`);
|
|
1573
1635
|
res.json({ success: false, error: 'Range not satisfiable' });
|
|
1574
1636
|
return;
|
|
1575
1637
|
}
|
|
@@ -1579,7 +1641,7 @@ export const middleware = {
|
|
|
1579
1641
|
res.setHeader('Content-Length', chunkSize);
|
|
1580
1642
|
|
|
1581
1643
|
// Stream the range
|
|
1582
|
-
const stream =
|
|
1644
|
+
const stream = createReadStream(filePath, {
|
|
1583
1645
|
start,
|
|
1584
1646
|
end,
|
|
1585
1647
|
});
|
|
@@ -1597,12 +1659,12 @@ export const middleware = {
|
|
|
1597
1659
|
res.write(`\r\n--${boundary}\r\n`);
|
|
1598
1660
|
res.write(`Content-Range: bytes ${start}-${end}/${fileSize}\r\n\r\n`);
|
|
1599
1661
|
|
|
1600
|
-
const stream =
|
|
1662
|
+
const stream = createReadStream(filePath, {
|
|
1601
1663
|
start,
|
|
1602
1664
|
end,
|
|
1603
1665
|
});
|
|
1604
|
-
await new Promise(resolve => {
|
|
1605
|
-
stream.on('end', resolve);
|
|
1666
|
+
await new Promise<void>(resolve => {
|
|
1667
|
+
stream.on('end', () => resolve());
|
|
1606
1668
|
stream.pipe(res, { end: false });
|
|
1607
1669
|
});
|
|
1608
1670
|
}
|
|
@@ -1636,7 +1698,6 @@ export const middleware = {
|
|
|
1636
1698
|
const ignoreMethods = options.ignoreMethods || ['GET', 'HEAD', 'OPTIONS'];
|
|
1637
1699
|
|
|
1638
1700
|
const generateToken = () => {
|
|
1639
|
-
const crypto = require('crypto');
|
|
1640
1701
|
return crypto.randomBytes(tokenLength).toString('hex');
|
|
1641
1702
|
};
|
|
1642
1703
|
|
|
@@ -1725,7 +1786,6 @@ export const middleware = {
|
|
|
1725
1786
|
// Generate nonce if requested
|
|
1726
1787
|
let nonce: string | undefined;
|
|
1727
1788
|
if (options.nonce) {
|
|
1728
|
-
const crypto = require('crypto');
|
|
1729
1789
|
nonce = crypto.randomBytes(16).toString('base64');
|
|
1730
1790
|
(req as any).cspNonce = nonce;
|
|
1731
1791
|
}
|
package/src/core/http/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// HTTP System - Centralized Exports
|
|
2
|
-
export { MoroHttpServer, middleware } from './http-server';
|
|
3
|
-
export {
|
|
2
|
+
export { MoroHttpServer, middleware } from './http-server.js';
|
|
3
|
+
export { UWebSocketsHttpServer } from './uws-http-server.js';
|
|
4
|
+
export { Router } from '../routing/router.js';
|
|
4
5
|
|
|
5
6
|
// Type exports
|
|
6
|
-
export type { HttpRequest, HttpResponse, HttpHandler, Middleware } from '../../types/http';
|
|
7
|
+
export type { HttpRequest, HttpResponse, HttpHandler, Middleware } from '../../types/http.js';
|