@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,82 +1,27 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.middleware = exports.MoroHttpServer = void 0;
|
|
37
1
|
// src/core/http-server.ts
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
2
|
+
import { createServer } from 'http';
|
|
3
|
+
import * as zlib from 'zlib';
|
|
4
|
+
import { createReadStream } from 'fs';
|
|
5
|
+
import * as crypto from 'crypto';
|
|
6
|
+
import { promisify } from 'util';
|
|
7
|
+
import { createFrameworkLogger } from '../logger/index.js';
|
|
8
|
+
import { PathMatcher } from '../routing/path-matcher.js';
|
|
9
|
+
import { ObjectPoolManager } from '../pooling/object-pool-manager.js';
|
|
10
|
+
const gzip = promisify(zlib.gzip);
|
|
11
|
+
const deflate = promisify(zlib.deflate);
|
|
12
|
+
export class MoroHttpServer {
|
|
45
13
|
server;
|
|
46
14
|
routes = [];
|
|
47
15
|
globalMiddleware = [];
|
|
48
16
|
compressionEnabled = true;
|
|
49
17
|
compressionThreshold = 1024;
|
|
50
|
-
|
|
18
|
+
requestTrackingEnabled = true; // Generate request IDs
|
|
19
|
+
logger = createFrameworkLogger('HttpServer');
|
|
51
20
|
hookManager;
|
|
52
21
|
requestCounter = 0;
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
maxPoolSize = 50;
|
|
57
|
-
// Request handler pooling to avoid function creation overhead
|
|
58
|
-
middlewareExecutionCache = new Map();
|
|
59
|
-
// String interning for common values (massive memory savings)
|
|
60
|
-
static INTERNED_METHODS = new Map([
|
|
61
|
-
['GET', 'GET'],
|
|
62
|
-
['POST', 'POST'],
|
|
63
|
-
['PUT', 'PUT'],
|
|
64
|
-
['DELETE', 'DELETE'],
|
|
65
|
-
['PATCH', 'PATCH'],
|
|
66
|
-
['HEAD', 'HEAD'],
|
|
67
|
-
['OPTIONS', 'OPTIONS'],
|
|
68
|
-
]);
|
|
69
|
-
static INTERNED_HEADERS = new Map([
|
|
70
|
-
['content-type', 'content-type'],
|
|
71
|
-
['content-length', 'content-length'],
|
|
72
|
-
['authorization', 'authorization'],
|
|
73
|
-
['accept', 'accept'],
|
|
74
|
-
['user-agent', 'user-agent'],
|
|
75
|
-
['host', 'host'],
|
|
76
|
-
['connection', 'connection'],
|
|
77
|
-
['cache-control', 'cache-control'],
|
|
78
|
-
]);
|
|
79
|
-
// Pre-compiled response templates for ultra-common responses
|
|
22
|
+
// Use shared object pool manager
|
|
23
|
+
poolManager = ObjectPoolManager.getInstance();
|
|
24
|
+
// Pre-compiled response templates for common responses
|
|
80
25
|
static RESPONSE_TEMPLATES = {
|
|
81
26
|
notFound: Buffer.from('{"success":false,"error":"Not found"}'),
|
|
82
27
|
unauthorized: Buffer.from('{"success":false,"error":"Unauthorized"}'),
|
|
@@ -85,7 +30,7 @@ class MoroHttpServer {
|
|
|
85
30
|
methodNotAllowed: Buffer.from('{"success":false,"error":"Method not allowed"}'),
|
|
86
31
|
rateLimited: Buffer.from('{"success":false,"error":"Rate limit exceeded"}'),
|
|
87
32
|
};
|
|
88
|
-
//
|
|
33
|
+
// Buffer pool for zero-copy operations
|
|
89
34
|
static BUFFER_SIZES = [64, 256, 1024, 4096, 16384];
|
|
90
35
|
static BUFFER_POOLS = new Map();
|
|
91
36
|
static {
|
|
@@ -120,7 +65,7 @@ class MoroHttpServer {
|
|
|
120
65
|
}
|
|
121
66
|
}
|
|
122
67
|
constructor() {
|
|
123
|
-
this.server =
|
|
68
|
+
this.server = createServer(this.handleRequest.bind(this));
|
|
124
69
|
// Optimize server for high performance (conservative settings for compatibility)
|
|
125
70
|
this.server.keepAliveTimeout = 5000; // 5 seconds
|
|
126
71
|
this.server.headersTimeout = 6000; // 6 seconds
|
|
@@ -140,6 +85,10 @@ class MoroHttpServer {
|
|
|
140
85
|
this.compressionThreshold = Infinity; // Never compress
|
|
141
86
|
}
|
|
142
87
|
}
|
|
88
|
+
// Configure request tracking (ID generation)
|
|
89
|
+
setRequestTracking(enabled) {
|
|
90
|
+
this.requestTrackingEnabled = enabled;
|
|
91
|
+
}
|
|
143
92
|
// Middleware management
|
|
144
93
|
use(middleware) {
|
|
145
94
|
this.globalMiddleware.push(middleware);
|
|
@@ -195,39 +144,33 @@ class MoroHttpServer {
|
|
|
195
144
|
}
|
|
196
145
|
}
|
|
197
146
|
pathToRegex(path) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
const regexPattern = path
|
|
201
|
-
.replace(/\/:([^/]+)/g, (match, paramName) => {
|
|
202
|
-
paramNames.push(paramName);
|
|
203
|
-
return '/([^/]+)';
|
|
204
|
-
})
|
|
205
|
-
.replace(/\//g, '\\/');
|
|
147
|
+
// Use shared PathMatcher for consistent path compilation
|
|
148
|
+
const compiled = PathMatcher.compile(path);
|
|
206
149
|
return {
|
|
207
|
-
pattern: new RegExp(`^${
|
|
208
|
-
paramNames,
|
|
150
|
+
pattern: compiled.pattern || new RegExp(`^${path.replace(/\//g, '\\/')}$`),
|
|
151
|
+
paramNames: compiled.paramNames,
|
|
209
152
|
};
|
|
210
153
|
}
|
|
211
154
|
async handleRequest(req, res) {
|
|
212
155
|
const httpReq = this.enhanceRequest(req);
|
|
213
|
-
const httpRes = this.enhanceResponse(res);
|
|
156
|
+
const httpRes = this.enhanceResponse(res, httpReq);
|
|
214
157
|
// Store original params for efficient cleanup
|
|
215
158
|
const originalParams = httpReq.params;
|
|
216
159
|
try {
|
|
217
|
-
// Optimized URL and query parsing
|
|
160
|
+
// Optimized URL and query parsing with object pooling
|
|
218
161
|
const urlString = req.url;
|
|
219
162
|
const queryIndex = urlString.indexOf('?');
|
|
220
163
|
if (queryIndex === -1) {
|
|
221
|
-
// No query string
|
|
164
|
+
// No query string
|
|
222
165
|
httpReq.path = urlString;
|
|
223
166
|
httpReq.query = {};
|
|
224
167
|
}
|
|
225
168
|
else {
|
|
226
|
-
// Has query string - parse efficiently
|
|
169
|
+
// Has query string - parse efficiently with pooled object
|
|
227
170
|
httpReq.path = urlString.substring(0, queryIndex);
|
|
228
|
-
httpReq.query = this.
|
|
171
|
+
httpReq.query = this.parseQueryStringPooled(urlString.substring(queryIndex + 1));
|
|
229
172
|
}
|
|
230
|
-
//
|
|
173
|
+
// Method checking - avoid array includes
|
|
231
174
|
const method = req.method;
|
|
232
175
|
if (method === 'POST' || method === 'PUT' || method === 'PATCH') {
|
|
233
176
|
httpReq.body = await this.parseBody(req);
|
|
@@ -248,7 +191,7 @@ class MoroHttpServer {
|
|
|
248
191
|
// Find matching route
|
|
249
192
|
const route = this.findRoute(req.method, httpReq.path);
|
|
250
193
|
if (!route) {
|
|
251
|
-
//
|
|
194
|
+
// 404 response with pre-compiled buffer
|
|
252
195
|
httpRes.statusCode = 404;
|
|
253
196
|
httpRes.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
254
197
|
httpRes.setHeader('Content-Length', MoroHttpServer.RESPONSE_TEMPLATES.notFound.length);
|
|
@@ -271,12 +214,13 @@ class MoroHttpServer {
|
|
|
271
214
|
}
|
|
272
215
|
catch (error) {
|
|
273
216
|
// Debug: Log the actual error and where it came from
|
|
274
|
-
this.logger.debug('
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
217
|
+
this.logger.debug('Request error details', 'RequestHandler', {
|
|
218
|
+
errorType: typeof error,
|
|
219
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
220
|
+
errorStack: error instanceof Error ? error.stack : 'No stack trace',
|
|
221
|
+
requestPath: req.url,
|
|
222
|
+
requestMethod: req.method,
|
|
223
|
+
});
|
|
280
224
|
this.logger.error('Request error', 'RequestHandler', {
|
|
281
225
|
error: error instanceof Error ? error.message : String(error),
|
|
282
226
|
requestId: httpReq.requestId,
|
|
@@ -293,14 +237,14 @@ class MoroHttpServer {
|
|
|
293
237
|
});
|
|
294
238
|
}
|
|
295
239
|
else {
|
|
296
|
-
//
|
|
240
|
+
// Defensive fallback - check each method individually
|
|
297
241
|
if (typeof httpRes.setHeader === 'function') {
|
|
298
242
|
httpRes.statusCode = 500;
|
|
299
243
|
httpRes.setHeader('Content-Type', 'application/json');
|
|
300
244
|
}
|
|
301
245
|
else {
|
|
302
246
|
// Even setHeader doesn't exist - object is completely wrong
|
|
303
|
-
this.logger.error('
|
|
247
|
+
this.logger.error('Response object is not a proper ServerResponse', 'RequestHandler', {
|
|
304
248
|
responseType: typeof httpRes,
|
|
305
249
|
responseKeys: Object.keys(httpRes),
|
|
306
250
|
});
|
|
@@ -313,7 +257,7 @@ class MoroHttpServer {
|
|
|
313
257
|
}));
|
|
314
258
|
}
|
|
315
259
|
else {
|
|
316
|
-
this.logger.error('
|
|
260
|
+
this.logger.error('Cannot send error response - end() method missing', 'RequestHandler');
|
|
317
261
|
}
|
|
318
262
|
}
|
|
319
263
|
}
|
|
@@ -342,50 +286,27 @@ class MoroHttpServer {
|
|
|
342
286
|
}
|
|
343
287
|
});
|
|
344
288
|
}
|
|
345
|
-
//
|
|
289
|
+
// Use shared object pool for parameter objects
|
|
346
290
|
acquireParamObject() {
|
|
347
|
-
|
|
348
|
-
if (obj) {
|
|
349
|
-
// ES2022: Use Object.hasOwn for safer property checks and faster clearing
|
|
350
|
-
// Clear existing properties more efficiently
|
|
351
|
-
for (const key in obj) {
|
|
352
|
-
if (Object.hasOwn(obj, key)) {
|
|
353
|
-
delete obj[key];
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
return obj;
|
|
357
|
-
}
|
|
358
|
-
return {};
|
|
291
|
+
return this.poolManager.acquireParams();
|
|
359
292
|
}
|
|
360
293
|
releaseParamObject(params) {
|
|
361
|
-
|
|
362
|
-
this.paramObjectPool.push(params);
|
|
363
|
-
}
|
|
294
|
+
this.poolManager.releaseParams(params);
|
|
364
295
|
}
|
|
365
296
|
// Force cleanup of all pooled objects
|
|
366
297
|
forceCleanupPools() {
|
|
367
|
-
//
|
|
368
|
-
this.
|
|
369
|
-
this.bufferPool.splice(0);
|
|
298
|
+
// Use shared pool manager cleanup
|
|
299
|
+
this.poolManager.clearAll();
|
|
370
300
|
// Force garbage collection if available
|
|
371
|
-
// Use modern globalThis check with optional chaining
|
|
372
301
|
if (globalThis?.gc) {
|
|
373
302
|
globalThis.gc();
|
|
374
303
|
}
|
|
375
304
|
}
|
|
376
305
|
acquireBuffer(size) {
|
|
377
|
-
|
|
378
|
-
const index = this.bufferPool.findIndex(b => b.length >= size);
|
|
379
|
-
if (index !== -1) {
|
|
380
|
-
const buffer = this.bufferPool.splice(index, 1)[0];
|
|
381
|
-
return buffer.subarray(0, size);
|
|
382
|
-
}
|
|
383
|
-
return Buffer.allocUnsafe(size);
|
|
306
|
+
return this.poolManager.acquireBuffer(size);
|
|
384
307
|
}
|
|
385
308
|
releaseBuffer(buffer) {
|
|
386
|
-
|
|
387
|
-
this.bufferPool.push(buffer);
|
|
388
|
-
}
|
|
309
|
+
this.poolManager.releaseBuffer(buffer);
|
|
389
310
|
}
|
|
390
311
|
streamLargeResponse(res, data) {
|
|
391
312
|
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
@@ -404,7 +325,7 @@ class MoroHttpServer {
|
|
|
404
325
|
if (this.pathNormalizationCache.has(path)) {
|
|
405
326
|
return this.pathNormalizationCache.get(path);
|
|
406
327
|
}
|
|
407
|
-
//
|
|
328
|
+
// Normalization: remove trailing slash (except root), decode once
|
|
408
329
|
let normalized = path;
|
|
409
330
|
if (normalized.length > 1 && normalized.endsWith('/')) {
|
|
410
331
|
normalized = normalized.slice(0, -1);
|
|
@@ -422,8 +343,8 @@ class MoroHttpServer {
|
|
|
422
343
|
httpReq.body = null;
|
|
423
344
|
httpReq.path = '';
|
|
424
345
|
httpReq.ip = req.socket.remoteAddress || '';
|
|
425
|
-
//
|
|
426
|
-
httpReq.requestId =
|
|
346
|
+
// Request ID generation using pool manager (if enabled)
|
|
347
|
+
httpReq.requestId = this.requestTrackingEnabled ? this.poolManager.generateRequestId() : '';
|
|
427
348
|
httpReq.headers = req.headers;
|
|
428
349
|
// Parse cookies
|
|
429
350
|
httpReq.cookies = this.parseCookies(req.headers.cookie || '');
|
|
@@ -441,8 +362,10 @@ class MoroHttpServer {
|
|
|
441
362
|
});
|
|
442
363
|
return cookies;
|
|
443
364
|
}
|
|
444
|
-
enhanceResponse(res) {
|
|
365
|
+
enhanceResponse(res, req) {
|
|
445
366
|
const httpRes = res;
|
|
367
|
+
// Store request reference for access to headers (needed for compression, logging, etc.)
|
|
368
|
+
httpRes.req = req;
|
|
446
369
|
// BULLETPROOF status method - always works
|
|
447
370
|
httpRes.status = (code) => {
|
|
448
371
|
httpRes.statusCode = code;
|
|
@@ -451,7 +374,7 @@ class MoroHttpServer {
|
|
|
451
374
|
httpRes.json = async (data) => {
|
|
452
375
|
if (httpRes.headersSent)
|
|
453
376
|
return;
|
|
454
|
-
//
|
|
377
|
+
// JSON serialization with zero-copy buffers
|
|
455
378
|
let jsonString;
|
|
456
379
|
// Enhanced JSON optimization for common API patterns
|
|
457
380
|
if (data && typeof data === 'object' && 'success' in data) {
|
|
@@ -555,6 +478,24 @@ class MoroHttpServer {
|
|
|
555
478
|
httpRes.end(data);
|
|
556
479
|
};
|
|
557
480
|
httpRes.cookie = (name, value, options = {}) => {
|
|
481
|
+
if (httpRes.headersSent) {
|
|
482
|
+
const isCritical = options.critical ||
|
|
483
|
+
name.includes('session') ||
|
|
484
|
+
name.includes('auth') ||
|
|
485
|
+
name.includes('csrf');
|
|
486
|
+
const message = `Cookie '${name}' could not be set - headers already sent`;
|
|
487
|
+
if (isCritical || options.throwOnLateSet) {
|
|
488
|
+
throw new Error(`${message}. This may cause authentication or security issues.`);
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
this.logger.warn(message, 'CookieWarning', {
|
|
492
|
+
cookieName: name,
|
|
493
|
+
critical: isCritical,
|
|
494
|
+
stackTrace: new Error().stack,
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
return httpRes;
|
|
498
|
+
}
|
|
558
499
|
const cookieValue = encodeURIComponent(value);
|
|
559
500
|
let cookieString = `${name}=${cookieValue}`;
|
|
560
501
|
if (options.maxAge)
|
|
@@ -594,8 +535,8 @@ class MoroHttpServer {
|
|
|
594
535
|
if (httpRes.headersSent)
|
|
595
536
|
return;
|
|
596
537
|
try {
|
|
597
|
-
const fs = await
|
|
598
|
-
const path = await
|
|
538
|
+
const fs = await import('fs/promises');
|
|
539
|
+
const path = await import('path');
|
|
599
540
|
const extension = path.extname(filePath);
|
|
600
541
|
const mime = await this.getMimeType(extension);
|
|
601
542
|
const stats = await fs.stat(filePath);
|
|
@@ -615,6 +556,52 @@ class MoroHttpServer {
|
|
|
615
556
|
httpRes.status(404).json({ success: false, error: 'File not found' });
|
|
616
557
|
}
|
|
617
558
|
};
|
|
559
|
+
// Header management utilities
|
|
560
|
+
httpRes.hasHeader = (name) => {
|
|
561
|
+
return httpRes.getHeader(name) !== undefined;
|
|
562
|
+
};
|
|
563
|
+
// Note: removeHeader is inherited from ServerResponse, we don't override it
|
|
564
|
+
httpRes.setBulkHeaders = (headers) => {
|
|
565
|
+
if (httpRes.headersSent) {
|
|
566
|
+
this.logger.warn('Cannot set headers - headers already sent', 'HeaderWarning', {
|
|
567
|
+
attemptedHeaders: Object.keys(headers),
|
|
568
|
+
});
|
|
569
|
+
return httpRes;
|
|
570
|
+
}
|
|
571
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
572
|
+
httpRes.setHeader(key, value);
|
|
573
|
+
});
|
|
574
|
+
return httpRes;
|
|
575
|
+
};
|
|
576
|
+
httpRes.appendHeader = (name, value) => {
|
|
577
|
+
if (httpRes.headersSent) {
|
|
578
|
+
this.logger.warn(`Cannot append to header '${name}' - headers already sent`, 'HeaderWarning');
|
|
579
|
+
return httpRes;
|
|
580
|
+
}
|
|
581
|
+
const existing = httpRes.getHeader(name);
|
|
582
|
+
if (existing) {
|
|
583
|
+
const values = Array.isArray(existing) ? existing : [existing.toString()];
|
|
584
|
+
const newValues = Array.isArray(value) ? value : [value];
|
|
585
|
+
httpRes.setHeader(name, [...values, ...newValues]);
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
httpRes.setHeader(name, value);
|
|
589
|
+
}
|
|
590
|
+
return httpRes;
|
|
591
|
+
};
|
|
592
|
+
// Response state utilities
|
|
593
|
+
httpRes.canSetHeaders = () => {
|
|
594
|
+
return !httpRes.headersSent;
|
|
595
|
+
};
|
|
596
|
+
httpRes.getResponseState = () => {
|
|
597
|
+
return {
|
|
598
|
+
headersSent: httpRes.headersSent,
|
|
599
|
+
statusCode: httpRes.statusCode,
|
|
600
|
+
headers: httpRes.getHeaders ? httpRes.getHeaders() : {},
|
|
601
|
+
finished: httpRes.finished || false,
|
|
602
|
+
writable: httpRes.writable,
|
|
603
|
+
};
|
|
604
|
+
};
|
|
618
605
|
return httpRes;
|
|
619
606
|
}
|
|
620
607
|
async getMimeType(ext) {
|
|
@@ -733,12 +720,18 @@ class MoroHttpServer {
|
|
|
733
720
|
}
|
|
734
721
|
return result;
|
|
735
722
|
}
|
|
723
|
+
// Legacy method for backward compatibility
|
|
736
724
|
parseQueryString(queryString) {
|
|
737
|
-
|
|
725
|
+
return this.parseQueryStringPooled(queryString);
|
|
726
|
+
}
|
|
727
|
+
// Optimized query string parser with object pooling
|
|
728
|
+
parseQueryStringPooled(queryString) {
|
|
738
729
|
if (!queryString)
|
|
739
|
-
return
|
|
730
|
+
return {};
|
|
731
|
+
const result = this.poolManager.acquireQuery();
|
|
740
732
|
const pairs = queryString.split('&');
|
|
741
|
-
for (
|
|
733
|
+
for (let i = 0; i < pairs.length; i++) {
|
|
734
|
+
const pair = pairs[i];
|
|
742
735
|
const equalIndex = pair.indexOf('=');
|
|
743
736
|
if (equalIndex === -1) {
|
|
744
737
|
result[decodeURIComponent(pair)] = '';
|
|
@@ -757,7 +750,7 @@ class MoroHttpServer {
|
|
|
757
750
|
dynamicRoutes = [];
|
|
758
751
|
routesBySegmentCount = new Map();
|
|
759
752
|
pathNormalizationCache = new Map();
|
|
760
|
-
//
|
|
753
|
+
// CPU cache-friendly optimizations
|
|
761
754
|
routeHitCount = new Map(); // Track route popularity for cache optimization
|
|
762
755
|
static HOT_ROUTE_THRESHOLD = 100; // Routes accessed 100+ times get hot path treatment
|
|
763
756
|
findRoute(method, path) {
|
|
@@ -802,33 +795,43 @@ class MoroHttpServer {
|
|
|
802
795
|
}
|
|
803
796
|
return route;
|
|
804
797
|
}
|
|
798
|
+
// Optimized middleware execution with reduced Promise allocation
|
|
805
799
|
async executeMiddleware(middleware, req, res) {
|
|
806
|
-
for (
|
|
800
|
+
for (let i = 0; i < middleware.length; i++) {
|
|
807
801
|
// Short-circuit if response already sent
|
|
808
802
|
if (res.headersSent)
|
|
809
803
|
return;
|
|
804
|
+
const mw = middleware[i];
|
|
810
805
|
await new Promise((resolve, reject) => {
|
|
811
|
-
let
|
|
806
|
+
let resolved = false;
|
|
807
|
+
// Reuse next function to reduce allocations
|
|
812
808
|
const next = () => {
|
|
813
|
-
if (
|
|
809
|
+
if (resolved)
|
|
814
810
|
return;
|
|
815
|
-
|
|
811
|
+
resolved = true;
|
|
816
812
|
resolve();
|
|
817
813
|
};
|
|
818
814
|
try {
|
|
819
815
|
const result = mw(req, res, next);
|
|
820
816
|
// Handle async middleware
|
|
821
|
-
if (result
|
|
817
|
+
if (result && typeof result.then === 'function') {
|
|
822
818
|
result
|
|
823
819
|
.then(() => {
|
|
824
|
-
if (!
|
|
820
|
+
if (!resolved)
|
|
825
821
|
next();
|
|
826
822
|
})
|
|
827
823
|
.catch(reject);
|
|
828
824
|
}
|
|
825
|
+
else if (!resolved) {
|
|
826
|
+
// Sync middleware that didn't call next
|
|
827
|
+
next();
|
|
828
|
+
}
|
|
829
829
|
}
|
|
830
830
|
catch (error) {
|
|
831
|
-
|
|
831
|
+
if (!resolved) {
|
|
832
|
+
resolved = true;
|
|
833
|
+
reject(error);
|
|
834
|
+
}
|
|
832
835
|
}
|
|
833
836
|
});
|
|
834
837
|
}
|
|
@@ -858,10 +861,19 @@ class MoroHttpServer {
|
|
|
858
861
|
getServer() {
|
|
859
862
|
return this.server;
|
|
860
863
|
}
|
|
864
|
+
// Performance statistics
|
|
865
|
+
getPerformanceStats() {
|
|
866
|
+
const poolStats = this.poolManager.getStats();
|
|
867
|
+
return {
|
|
868
|
+
paramObjectPoolSize: poolStats.paramPool.poolSize,
|
|
869
|
+
queryObjectPoolSize: poolStats.queryPool.poolSize,
|
|
870
|
+
headerObjectPoolSize: poolStats.headerPool.poolSize,
|
|
871
|
+
poolManager: poolStats,
|
|
872
|
+
};
|
|
873
|
+
}
|
|
861
874
|
}
|
|
862
|
-
exports.MoroHttpServer = MoroHttpServer;
|
|
863
875
|
// Built-in middleware
|
|
864
|
-
|
|
876
|
+
export const middleware = {
|
|
865
877
|
cors: (options = {}) => {
|
|
866
878
|
return (req, res, next) => {
|
|
867
879
|
res.setHeader('Access-Control-Allow-Origin', options.origin || '*');
|
|
@@ -889,7 +901,6 @@ exports.middleware = {
|
|
|
889
901
|
};
|
|
890
902
|
},
|
|
891
903
|
compression: (options = {}) => {
|
|
892
|
-
const zlib = require('zlib');
|
|
893
904
|
const threshold = options.threshold || 1024;
|
|
894
905
|
const level = options.level || 6;
|
|
895
906
|
return (req, res, next) => {
|
|
@@ -904,24 +915,26 @@ exports.middleware = {
|
|
|
904
915
|
return isJson ? originalJson.call(res, data) : originalSend.call(res, data);
|
|
905
916
|
}
|
|
906
917
|
if (acceptEncoding.includes('gzip')) {
|
|
907
|
-
res.setHeader('Content-Encoding', 'gzip');
|
|
908
918
|
zlib.gzip(buffer, { level }, (err, compressed) => {
|
|
909
919
|
if (err) {
|
|
910
920
|
return isJson ? originalJson.call(res, data) : originalSend.call(res, data);
|
|
911
921
|
}
|
|
912
|
-
res.
|
|
913
|
-
|
|
922
|
+
if (!res.headersSent) {
|
|
923
|
+
res.setHeader('Content-Encoding', 'gzip');
|
|
924
|
+
res.setHeader('Content-Length', compressed.length);
|
|
925
|
+
}
|
|
914
926
|
res.end(compressed);
|
|
915
927
|
});
|
|
916
928
|
}
|
|
917
929
|
else if (acceptEncoding.includes('deflate')) {
|
|
918
|
-
res.setHeader('Content-Encoding', 'deflate');
|
|
919
930
|
zlib.deflate(buffer, { level }, (err, compressed) => {
|
|
920
931
|
if (err) {
|
|
921
932
|
return isJson ? originalJson.call(res, data) : originalSend.call(res, data);
|
|
922
933
|
}
|
|
923
|
-
res.
|
|
924
|
-
|
|
934
|
+
if (!res.headersSent) {
|
|
935
|
+
res.setHeader('Content-Encoding', 'deflate');
|
|
936
|
+
res.setHeader('Content-Length', compressed.length);
|
|
937
|
+
}
|
|
925
938
|
res.end(compressed);
|
|
926
939
|
});
|
|
927
940
|
}
|
|
@@ -976,9 +989,9 @@ exports.middleware = {
|
|
|
976
989
|
return;
|
|
977
990
|
}
|
|
978
991
|
try {
|
|
979
|
-
const fs = await
|
|
980
|
-
const path = await
|
|
981
|
-
const crypto = await
|
|
992
|
+
const fs = await import('fs/promises');
|
|
993
|
+
const path = await import('path');
|
|
994
|
+
const crypto = await import('crypto');
|
|
982
995
|
let filePath = path.join(options.root, req.path);
|
|
983
996
|
// Security: prevent directory traversal
|
|
984
997
|
if (!filePath.startsWith(path.resolve(options.root))) {
|
|
@@ -1146,8 +1159,8 @@ exports.middleware = {
|
|
|
1146
1159
|
// Add render method to response
|
|
1147
1160
|
res.render = async (template, data = {}) => {
|
|
1148
1161
|
try {
|
|
1149
|
-
const fs = await
|
|
1150
|
-
const path = await
|
|
1162
|
+
const fs = await import('fs/promises');
|
|
1163
|
+
const path = await import('path');
|
|
1151
1164
|
const templatePath = path.join(options.views, `${template}.html`);
|
|
1152
1165
|
let templateContent;
|
|
1153
1166
|
// Check cache first
|
|
@@ -1265,13 +1278,15 @@ exports.middleware = {
|
|
|
1265
1278
|
// Only handle SSE requests
|
|
1266
1279
|
if (req.headers.accept?.includes('text/event-stream')) {
|
|
1267
1280
|
// Set SSE headers
|
|
1268
|
-
res.
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1281
|
+
if (!res.headersSent) {
|
|
1282
|
+
res.writeHead(200, {
|
|
1283
|
+
'Content-Type': 'text/event-stream',
|
|
1284
|
+
'Cache-Control': 'no-cache',
|
|
1285
|
+
Connection: 'keep-alive',
|
|
1286
|
+
'Access-Control-Allow-Origin': options.cors ? '*' : undefined,
|
|
1287
|
+
'Access-Control-Allow-Headers': options.cors ? 'Cache-Control' : undefined,
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1275
1290
|
// Add SSE methods to response
|
|
1276
1291
|
res.sendEvent = (data, event, id) => {
|
|
1277
1292
|
if (id)
|
|
@@ -1315,8 +1330,8 @@ exports.middleware = {
|
|
|
1315
1330
|
// Add range support to response
|
|
1316
1331
|
res.sendRange = async (filePath, stats) => {
|
|
1317
1332
|
try {
|
|
1318
|
-
const fs = await
|
|
1319
|
-
const path = await
|
|
1333
|
+
const fs = await import('fs/promises');
|
|
1334
|
+
const path = await import('path');
|
|
1320
1335
|
if (!stats) {
|
|
1321
1336
|
stats = await fs.stat(filePath);
|
|
1322
1337
|
}
|
|
@@ -1352,7 +1367,8 @@ exports.middleware = {
|
|
|
1352
1367
|
const { start, end } = ranges[0];
|
|
1353
1368
|
const chunkSize = end - start + 1;
|
|
1354
1369
|
if (start >= fileSize || end >= fileSize) {
|
|
1355
|
-
res.status(416)
|
|
1370
|
+
res.status(416);
|
|
1371
|
+
res.setHeader('Content-Range', `bytes */${fileSize}`);
|
|
1356
1372
|
res.json({ success: false, error: 'Range not satisfiable' });
|
|
1357
1373
|
return;
|
|
1358
1374
|
}
|
|
@@ -1360,7 +1376,7 @@ exports.middleware = {
|
|
|
1360
1376
|
res.setHeader('Content-Range', `bytes ${start}-${end}/${fileSize}`);
|
|
1361
1377
|
res.setHeader('Content-Length', chunkSize);
|
|
1362
1378
|
// Stream the range
|
|
1363
|
-
const stream =
|
|
1379
|
+
const stream = createReadStream(filePath, {
|
|
1364
1380
|
start,
|
|
1365
1381
|
end,
|
|
1366
1382
|
});
|
|
@@ -1377,12 +1393,12 @@ exports.middleware = {
|
|
|
1377
1393
|
const chunkSize = end - start + 1;
|
|
1378
1394
|
res.write(`\r\n--${boundary}\r\n`);
|
|
1379
1395
|
res.write(`Content-Range: bytes ${start}-${end}/${fileSize}\r\n\r\n`);
|
|
1380
|
-
const stream =
|
|
1396
|
+
const stream = createReadStream(filePath, {
|
|
1381
1397
|
start,
|
|
1382
1398
|
end,
|
|
1383
1399
|
});
|
|
1384
1400
|
await new Promise(resolve => {
|
|
1385
|
-
stream.on('end', resolve);
|
|
1401
|
+
stream.on('end', () => resolve());
|
|
1386
1402
|
stream.pipe(res, { end: false });
|
|
1387
1403
|
});
|
|
1388
1404
|
}
|
|
@@ -1405,7 +1421,6 @@ exports.middleware = {
|
|
|
1405
1421
|
const headerName = options.headerName || 'x-csrf-token';
|
|
1406
1422
|
const ignoreMethods = options.ignoreMethods || ['GET', 'HEAD', 'OPTIONS'];
|
|
1407
1423
|
const generateToken = () => {
|
|
1408
|
-
const crypto = require('crypto');
|
|
1409
1424
|
return crypto.randomBytes(tokenLength).toString('hex');
|
|
1410
1425
|
};
|
|
1411
1426
|
const verifyToken = (token, sessionToken) => {
|
|
@@ -1462,7 +1477,6 @@ exports.middleware = {
|
|
|
1462
1477
|
// Generate nonce if requested
|
|
1463
1478
|
let nonce;
|
|
1464
1479
|
if (options.nonce) {
|
|
1465
|
-
const crypto = require('crypto');
|
|
1466
1480
|
nonce = crypto.randomBytes(16).toString('base64');
|
|
1467
1481
|
req.cspNonce = nonce;
|
|
1468
1482
|
}
|