@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,11 +1,6 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createFrameworkLogger = exports.logger = exports.MoroLogger = void 0;
|
|
4
|
-
exports.configureGlobalLogger = configureGlobalLogger;
|
|
5
|
-
exports.applyLoggingConfiguration = applyLoggingConfiguration;
|
|
6
1
|
// Moro Logger - Beautiful, Fast, Feature-Rich
|
|
7
|
-
|
|
8
|
-
class MoroLogger {
|
|
2
|
+
import { performance } from 'perf_hooks';
|
|
3
|
+
export class MoroLogger {
|
|
9
4
|
level = 'info';
|
|
10
5
|
options;
|
|
11
6
|
outputs = new Map();
|
|
@@ -32,12 +27,23 @@ class MoroLogger {
|
|
|
32
27
|
cachedTimestamp = '';
|
|
33
28
|
lastTimestamp = 0;
|
|
34
29
|
timestampCacheInterval = 100; // 100ms for better precision
|
|
35
|
-
//
|
|
30
|
+
// Object pooling for LogEntry objects (Pino's technique)
|
|
31
|
+
static ENTRY_POOL = [];
|
|
32
|
+
static MAX_POOL_SIZE = 100;
|
|
33
|
+
static poolIndex = 0;
|
|
34
|
+
// String builder for efficient concatenation
|
|
35
|
+
static stringBuilder = [];
|
|
36
|
+
static stringBuilderIndex = 0;
|
|
37
|
+
// Buffered output for performance
|
|
36
38
|
outputBuffer = [];
|
|
37
39
|
bufferSize = 0;
|
|
38
|
-
maxBufferSize =
|
|
40
|
+
maxBufferSize = 1000;
|
|
39
41
|
flushTimeout = null;
|
|
40
42
|
flushInterval = 1; // 1ms micro-batching
|
|
43
|
+
// Buffer overflow protection
|
|
44
|
+
bufferOverflowThreshold;
|
|
45
|
+
emergencyFlushInProgress = false;
|
|
46
|
+
isDestroyed = false;
|
|
41
47
|
// High-performance output methods
|
|
42
48
|
static LEVELS = {
|
|
43
49
|
debug: 0,
|
|
@@ -46,76 +52,6 @@ class MoroLogger {
|
|
|
46
52
|
error: 3,
|
|
47
53
|
fatal: 4,
|
|
48
54
|
};
|
|
49
|
-
// Static pre-allocated strings for maximum performance
|
|
50
|
-
static LEVEL_STRINGS = {
|
|
51
|
-
debug: 'DEBUG',
|
|
52
|
-
info: 'INFO',
|
|
53
|
-
warn: 'WARN',
|
|
54
|
-
error: 'ERROR',
|
|
55
|
-
fatal: 'FATAL',
|
|
56
|
-
};
|
|
57
|
-
// Pre-allocated ANSI color codes
|
|
58
|
-
static ANSI_COLORS = {
|
|
59
|
-
reset: '\x1b[0m',
|
|
60
|
-
bold: '\x1b[1m',
|
|
61
|
-
dim: '\x1b[2m',
|
|
62
|
-
red: '\x1b[31m',
|
|
63
|
-
green: '\x1b[32m',
|
|
64
|
-
yellow: '\x1b[33m',
|
|
65
|
-
blue: '\x1b[34m',
|
|
66
|
-
magenta: '\x1b[35m',
|
|
67
|
-
cyan: '\x1b[36m',
|
|
68
|
-
white: '\x1b[37m',
|
|
69
|
-
gray: '\x1b[90m',
|
|
70
|
-
};
|
|
71
|
-
// Object pool for LogEntry reuse
|
|
72
|
-
static ENTRY_POOL = [];
|
|
73
|
-
static MAX_POOL_SIZE = 100;
|
|
74
|
-
static poolIndex = 0;
|
|
75
|
-
// Object pool management
|
|
76
|
-
static getPooledEntry() {
|
|
77
|
-
if (MoroLogger.poolIndex > 0) {
|
|
78
|
-
return MoroLogger.ENTRY_POOL[--MoroLogger.poolIndex];
|
|
79
|
-
}
|
|
80
|
-
return {
|
|
81
|
-
timestamp: new Date(),
|
|
82
|
-
level: 'info',
|
|
83
|
-
message: '',
|
|
84
|
-
context: undefined,
|
|
85
|
-
metadata: undefined,
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
static returnPooledEntry(entry) {
|
|
89
|
-
if (MoroLogger.poolIndex < MoroLogger.MAX_POOL_SIZE) {
|
|
90
|
-
// Reset the entry
|
|
91
|
-
entry.timestamp = new Date();
|
|
92
|
-
entry.level = 'info';
|
|
93
|
-
entry.message = '';
|
|
94
|
-
entry.context = undefined;
|
|
95
|
-
entry.metadata = undefined;
|
|
96
|
-
MoroLogger.ENTRY_POOL[MoroLogger.poolIndex++] = entry;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
// String builder for efficient concatenation
|
|
100
|
-
static stringBuilder = [];
|
|
101
|
-
static stringBuilderIndex = 0;
|
|
102
|
-
static resetStringBuilder() {
|
|
103
|
-
MoroLogger.stringBuilderIndex = 0;
|
|
104
|
-
}
|
|
105
|
-
static appendToBuilder(str) {
|
|
106
|
-
if (MoroLogger.stringBuilderIndex < MoroLogger.stringBuilder.length) {
|
|
107
|
-
MoroLogger.stringBuilder[MoroLogger.stringBuilderIndex++] = str;
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
MoroLogger.stringBuilder.push(str);
|
|
111
|
-
MoroLogger.stringBuilderIndex++;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
static buildString() {
|
|
115
|
-
const result = MoroLogger.stringBuilder.slice(0, MoroLogger.stringBuilderIndex).join('');
|
|
116
|
-
MoroLogger.resetStringBuilder();
|
|
117
|
-
return result;
|
|
118
|
-
}
|
|
119
55
|
static COLORS = {
|
|
120
56
|
debug: '\x1b[36m', // Cyan
|
|
121
57
|
info: '\x1b[32m', // Green
|
|
@@ -126,11 +62,20 @@ class MoroLogger {
|
|
|
126
62
|
context: '\x1b[34m', // Blue
|
|
127
63
|
metadata: '\x1b[37m', // White
|
|
128
64
|
performance: '\x1b[36m', // Cyan
|
|
65
|
+
reset: '\x1b[0m', // Reset
|
|
129
66
|
};
|
|
130
67
|
static RESET = '\x1b[0m';
|
|
131
68
|
static BOLD = '\x1b[1m';
|
|
69
|
+
// Static pre-allocated strings for performance
|
|
70
|
+
static LEVEL_STRINGS = {
|
|
71
|
+
debug: 'DEBUG',
|
|
72
|
+
info: 'INFO ',
|
|
73
|
+
warn: 'WARN ',
|
|
74
|
+
error: 'ERROR',
|
|
75
|
+
fatal: 'FATAL',
|
|
76
|
+
};
|
|
132
77
|
constructor(options = {}) {
|
|
133
|
-
this.options = {
|
|
78
|
+
this.options = this.validateOptions({
|
|
134
79
|
level: 'info',
|
|
135
80
|
enableColors: true,
|
|
136
81
|
enableTimestamp: true,
|
|
@@ -141,9 +86,14 @@ class MoroLogger {
|
|
|
141
86
|
outputs: [],
|
|
142
87
|
filters: [],
|
|
143
88
|
maxEntries: 1000,
|
|
89
|
+
maxBufferSize: 1000,
|
|
144
90
|
...options,
|
|
145
|
-
};
|
|
91
|
+
});
|
|
146
92
|
this.level = this.options.level || 'info';
|
|
93
|
+
// Initialize buffer size from options
|
|
94
|
+
this.maxBufferSize = this.options.maxBufferSize || 1000;
|
|
95
|
+
// Initialize buffer overflow protection
|
|
96
|
+
this.bufferOverflowThreshold = this.maxBufferSize * 2;
|
|
147
97
|
// Add default console output
|
|
148
98
|
this.addOutput({
|
|
149
99
|
name: 'console',
|
|
@@ -154,6 +104,52 @@ class MoroLogger {
|
|
|
154
104
|
this.options.outputs?.forEach(output => this.addOutput(output));
|
|
155
105
|
this.options.filters?.forEach(filter => this.addFilter(filter));
|
|
156
106
|
}
|
|
107
|
+
// Object pooling methods
|
|
108
|
+
static getPooledEntry() {
|
|
109
|
+
if (MoroLogger.ENTRY_POOL.length > 0) {
|
|
110
|
+
const entry = MoroLogger.ENTRY_POOL.pop();
|
|
111
|
+
// Properly reset ALL properties to prevent memory leaks
|
|
112
|
+
entry.timestamp = new Date();
|
|
113
|
+
entry.level = 'info';
|
|
114
|
+
entry.message = '';
|
|
115
|
+
entry.context = undefined;
|
|
116
|
+
entry.metadata = undefined;
|
|
117
|
+
entry.performance = undefined;
|
|
118
|
+
entry.moduleId = undefined;
|
|
119
|
+
return entry;
|
|
120
|
+
}
|
|
121
|
+
return MoroLogger.createFreshEntry();
|
|
122
|
+
}
|
|
123
|
+
// ADD this new method:
|
|
124
|
+
static createFreshEntry() {
|
|
125
|
+
return {
|
|
126
|
+
timestamp: new Date(),
|
|
127
|
+
level: 'info',
|
|
128
|
+
message: '',
|
|
129
|
+
context: undefined,
|
|
130
|
+
metadata: undefined,
|
|
131
|
+
performance: undefined,
|
|
132
|
+
moduleId: undefined,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
static returnPooledEntry(entry) {
|
|
136
|
+
if (MoroLogger.ENTRY_POOL.length < MoroLogger.MAX_POOL_SIZE) {
|
|
137
|
+
MoroLogger.ENTRY_POOL.push(entry);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// String builder methods
|
|
141
|
+
static resetStringBuilder() {
|
|
142
|
+
MoroLogger.stringBuilder.length = 0;
|
|
143
|
+
MoroLogger.stringBuilderIndex = 0;
|
|
144
|
+
}
|
|
145
|
+
static appendToBuilder(str) {
|
|
146
|
+
MoroLogger.stringBuilder[MoroLogger.stringBuilderIndex++] = str;
|
|
147
|
+
}
|
|
148
|
+
static buildString() {
|
|
149
|
+
const result = MoroLogger.stringBuilder.join('');
|
|
150
|
+
MoroLogger.resetStringBuilder();
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
157
153
|
debug(message, context, metadata) {
|
|
158
154
|
this.log('debug', message, context, metadata);
|
|
159
155
|
}
|
|
@@ -174,12 +170,12 @@ class MoroLogger {
|
|
|
174
170
|
this.log('fatal', msg, context, { ...metadata, stack });
|
|
175
171
|
}
|
|
176
172
|
time(label) {
|
|
177
|
-
this.timers.set(label,
|
|
173
|
+
this.timers.set(label, performance.now());
|
|
178
174
|
}
|
|
179
175
|
timeEnd(label, context, metadata) {
|
|
180
176
|
const startTime = this.timers.get(label);
|
|
181
177
|
if (startTime !== undefined) {
|
|
182
|
-
const duration =
|
|
178
|
+
const duration = performance.now() - startTime;
|
|
183
179
|
this.timers.delete(label);
|
|
184
180
|
this.log('info', `Timer: ${label}`, context, {
|
|
185
181
|
...metadata,
|
|
@@ -188,7 +184,9 @@ class MoroLogger {
|
|
|
188
184
|
}
|
|
189
185
|
}
|
|
190
186
|
child(context, metadata) {
|
|
191
|
-
|
|
187
|
+
// Create child logger with current parent level (not original options level)
|
|
188
|
+
const childOptions = { ...this.options, level: this.level };
|
|
189
|
+
const childLogger = new MoroLogger(childOptions);
|
|
192
190
|
childLogger.contextPrefix = this.contextPrefix ? `${this.contextPrefix}:${context}` : context;
|
|
193
191
|
childLogger.contextMetadata = { ...this.contextMetadata, ...metadata };
|
|
194
192
|
childLogger.outputs = this.outputs;
|
|
@@ -200,6 +198,9 @@ class MoroLogger {
|
|
|
200
198
|
setLevel(level) {
|
|
201
199
|
this.level = level;
|
|
202
200
|
}
|
|
201
|
+
getLevel() {
|
|
202
|
+
return this.level;
|
|
203
|
+
}
|
|
203
204
|
addOutput(output) {
|
|
204
205
|
this.outputs.set(output.name, output);
|
|
205
206
|
}
|
|
@@ -242,6 +243,16 @@ class MoroLogger {
|
|
|
242
243
|
}
|
|
243
244
|
return this.cachedTimestamp;
|
|
244
245
|
}
|
|
246
|
+
// Cached timestamp generation (updates once per second)
|
|
247
|
+
getFastCachedTimestamp() {
|
|
248
|
+
const now = Date.now();
|
|
249
|
+
if (now - this.lastTimestamp > 1000) {
|
|
250
|
+
// Update every second
|
|
251
|
+
this.lastTimestamp = now;
|
|
252
|
+
this.cachedTimestamp = new Date(now).toISOString().slice(0, 19).replace('T', ' ');
|
|
253
|
+
}
|
|
254
|
+
return this.cachedTimestamp;
|
|
255
|
+
}
|
|
245
256
|
getMetrics() {
|
|
246
257
|
const now = Date.now();
|
|
247
258
|
const uptime = (now - this.startTime) / 1000; // seconds
|
|
@@ -266,47 +277,38 @@ class MoroLogger {
|
|
|
266
277
|
memoryUsage: 0,
|
|
267
278
|
};
|
|
268
279
|
}
|
|
269
|
-
// Optimized logging method
|
|
280
|
+
// Optimized logging method
|
|
270
281
|
log(level, message, context, metadata) {
|
|
271
|
-
//
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
282
|
+
// Prevent logging after destroy() is called (important for test cleanup)
|
|
283
|
+
if (this.isDestroyed) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
// Quick level check - use parent level if available (for child loggers)
|
|
287
|
+
const effectiveLevel = this.parent ? this.parent.level : this.level;
|
|
288
|
+
if (MoroLogger.LEVELS[level] < MoroLogger.LEVELS[effectiveLevel]) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
// Absolute minimal path for simple logs - pure speed
|
|
280
292
|
if (!metadata && !context && !this.contextPrefix && !this.contextMetadata) {
|
|
281
|
-
|
|
282
|
-
this.output(`${levelStr} ${message}\n`, level);
|
|
293
|
+
this.writeSimpleLog(level, message);
|
|
283
294
|
return;
|
|
284
295
|
}
|
|
285
|
-
//
|
|
296
|
+
// Minimal path for logs with context but no metadata
|
|
286
297
|
if (!metadata && !this.contextMetadata) {
|
|
287
|
-
|
|
288
|
-
if (context) {
|
|
289
|
-
this.output(`${levelStr} [${context}] ${message}\n`, level);
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
this.output(`${levelStr} ${message}\n`, level);
|
|
293
|
-
}
|
|
298
|
+
this.writeSimpleLog(level, message, context);
|
|
294
299
|
return;
|
|
295
300
|
}
|
|
296
|
-
//
|
|
297
|
-
if (metadata && Object.keys(metadata).length
|
|
298
|
-
|
|
299
|
-
const contextStr = context ? `[${context}] ` : '';
|
|
300
|
-
const metaStr = this.stringify(metadata);
|
|
301
|
-
this.output(`${levelStr} ${contextStr}${message} ${metaStr}\n`, level);
|
|
301
|
+
// Path for complex logs
|
|
302
|
+
if (metadata && Object.keys(metadata).length > 0) {
|
|
303
|
+
this.complexLog(level, message, context, metadata);
|
|
302
304
|
return;
|
|
303
305
|
}
|
|
304
|
-
//
|
|
306
|
+
// Full logging path for complex logs
|
|
305
307
|
this.fullLog(level, message, context, metadata);
|
|
306
308
|
}
|
|
307
|
-
// Full logging with all features
|
|
309
|
+
// Full logging with all features
|
|
308
310
|
fullLog(level, message, context, metadata) {
|
|
309
|
-
//
|
|
311
|
+
// Use object pooling for LogEntry (Pino's technique)
|
|
310
312
|
const entry = MoroLogger.getPooledEntry();
|
|
311
313
|
const now = Date.now();
|
|
312
314
|
entry.timestamp = new Date(now);
|
|
@@ -323,6 +325,7 @@ class MoroLogger {
|
|
|
323
325
|
if (this.filters.size > 0) {
|
|
324
326
|
for (const filter of this.filters.values()) {
|
|
325
327
|
if (!filter.filter(entry)) {
|
|
328
|
+
MoroLogger.returnPooledEntry(entry);
|
|
326
329
|
return;
|
|
327
330
|
}
|
|
328
331
|
}
|
|
@@ -333,8 +336,76 @@ class MoroLogger {
|
|
|
333
336
|
this.addToHistory(entry);
|
|
334
337
|
// Write to outputs with batched processing
|
|
335
338
|
this.writeToOutputs(entry, level);
|
|
336
|
-
// Return entry to pool
|
|
337
|
-
|
|
339
|
+
// Return entry to pool
|
|
340
|
+
MoroLogger.returnPooledEntry(entry);
|
|
341
|
+
}
|
|
342
|
+
// Absolute minimal logging - pure speed, no overhead
|
|
343
|
+
complexLog(level, message, context, metadata) {
|
|
344
|
+
// Use object pooling for LogEntry (Pino's technique)
|
|
345
|
+
const entry = MoroLogger.getPooledEntry();
|
|
346
|
+
const now = Date.now();
|
|
347
|
+
entry.timestamp = new Date(now);
|
|
348
|
+
entry.level = level;
|
|
349
|
+
entry.message = message;
|
|
350
|
+
entry.context = this.contextPrefix
|
|
351
|
+
? context
|
|
352
|
+
? `${this.contextPrefix}:${context}`
|
|
353
|
+
: this.contextPrefix
|
|
354
|
+
: context;
|
|
355
|
+
entry.metadata = this.createMetadata(metadata);
|
|
356
|
+
entry.performance = this.options.enablePerformance ? this.getPerformanceData(now) : undefined;
|
|
357
|
+
// Write to outputs with batched processing
|
|
358
|
+
this.writeToOutputs(entry, level);
|
|
359
|
+
// Return entry to pool
|
|
360
|
+
MoroLogger.returnPooledEntry(entry);
|
|
361
|
+
}
|
|
362
|
+
// Simple log writer with colors for minimal overhead cases
|
|
363
|
+
writeSimpleLog(level, message, context) {
|
|
364
|
+
const colors = this.options.enableColors !== false;
|
|
365
|
+
const levelReset = colors ? MoroLogger.RESET : '';
|
|
366
|
+
MoroLogger.resetStringBuilder();
|
|
367
|
+
// Timestamp with caching optimization
|
|
368
|
+
if (this.options.enableTimestamp !== false) {
|
|
369
|
+
const timestamp = this.getFastCachedTimestamp();
|
|
370
|
+
if (colors) {
|
|
371
|
+
MoroLogger.appendToBuilder(MoroLogger.COLORS.timestamp);
|
|
372
|
+
MoroLogger.appendToBuilder(timestamp);
|
|
373
|
+
MoroLogger.appendToBuilder(levelReset);
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
MoroLogger.appendToBuilder(timestamp);
|
|
377
|
+
}
|
|
378
|
+
MoroLogger.appendToBuilder(' ');
|
|
379
|
+
}
|
|
380
|
+
// Level with pre-allocated strings
|
|
381
|
+
const levelStr = MoroLogger.LEVEL_STRINGS[level];
|
|
382
|
+
if (colors) {
|
|
383
|
+
MoroLogger.appendToBuilder(MoroLogger.COLORS[level]);
|
|
384
|
+
MoroLogger.appendToBuilder(MoroLogger.BOLD);
|
|
385
|
+
MoroLogger.appendToBuilder(levelStr);
|
|
386
|
+
MoroLogger.appendToBuilder(levelReset);
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
MoroLogger.appendToBuilder(levelStr);
|
|
390
|
+
}
|
|
391
|
+
// Context
|
|
392
|
+
if (context && this.options.enableContext !== false) {
|
|
393
|
+
MoroLogger.appendToBuilder(' ');
|
|
394
|
+
if (colors) {
|
|
395
|
+
MoroLogger.appendToBuilder(MoroLogger.COLORS.context);
|
|
396
|
+
MoroLogger.appendToBuilder(`[${context}]`);
|
|
397
|
+
MoroLogger.appendToBuilder(levelReset);
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
MoroLogger.appendToBuilder(`[${context}]`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// Message
|
|
404
|
+
MoroLogger.appendToBuilder(' ');
|
|
405
|
+
MoroLogger.appendToBuilder(message);
|
|
406
|
+
// Output main log line with high-performance method
|
|
407
|
+
const finalMessage = MoroLogger.buildString();
|
|
408
|
+
this.output(`${finalMessage}\n`, level);
|
|
338
409
|
}
|
|
339
410
|
updateMetrics(entry) {
|
|
340
411
|
this.metrics.totalLogs++;
|
|
@@ -382,23 +453,35 @@ class MoroLogger {
|
|
|
382
453
|
writeToOutputs(entry, level) {
|
|
383
454
|
if (this.outputs.size === 0)
|
|
384
455
|
return;
|
|
456
|
+
let successCount = 0;
|
|
457
|
+
const errors = [];
|
|
385
458
|
for (const output of this.outputs.values()) {
|
|
386
459
|
if (!output.level || MoroLogger.LEVELS[level] >= MoroLogger.LEVELS[output.level]) {
|
|
387
460
|
try {
|
|
388
461
|
output.write(entry);
|
|
462
|
+
successCount++;
|
|
389
463
|
}
|
|
390
464
|
catch (error) {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
console.error('Logger output error:', error);
|
|
465
|
+
errors.push({ outputName: output.name, error });
|
|
466
|
+
this.handleOutputError(output.name, error);
|
|
394
467
|
}
|
|
395
468
|
}
|
|
396
469
|
}
|
|
470
|
+
// If all outputs fail, use emergency console
|
|
471
|
+
if (successCount === 0 && this.outputs.size > 0) {
|
|
472
|
+
this.emergencyConsoleWrite(entry);
|
|
473
|
+
}
|
|
474
|
+
// Log output errors (but avoid infinite loops)
|
|
475
|
+
if (errors.length > 0 && level !== 'error') {
|
|
476
|
+
this.error(`Logger output errors: ${errors.length} failed`, 'MoroLogger', {
|
|
477
|
+
errors: errors.map(e => e.outputName),
|
|
478
|
+
});
|
|
479
|
+
}
|
|
397
480
|
}
|
|
398
481
|
writeToConsole(entry) {
|
|
399
482
|
const format = this.options.format || 'pretty';
|
|
400
483
|
if (format === 'json') {
|
|
401
|
-
this.output(
|
|
484
|
+
this.output(`${this.safeStringify(entry)}\n`, entry.level);
|
|
402
485
|
return;
|
|
403
486
|
}
|
|
404
487
|
if (format === 'compact') {
|
|
@@ -412,6 +495,7 @@ class MoroLogger {
|
|
|
412
495
|
}
|
|
413
496
|
writePrettyLog(entry) {
|
|
414
497
|
const colors = this.options.enableColors !== false;
|
|
498
|
+
const levelReset = colors ? MoroLogger.RESET : '';
|
|
415
499
|
MoroLogger.resetStringBuilder();
|
|
416
500
|
// Timestamp with caching optimization
|
|
417
501
|
if (this.options.enableTimestamp !== false) {
|
|
@@ -419,35 +503,29 @@ class MoroLogger {
|
|
|
419
503
|
if (colors) {
|
|
420
504
|
MoroLogger.appendToBuilder(MoroLogger.COLORS.timestamp);
|
|
421
505
|
MoroLogger.appendToBuilder(timestamp);
|
|
422
|
-
MoroLogger.appendToBuilder(
|
|
506
|
+
MoroLogger.appendToBuilder(levelReset);
|
|
423
507
|
}
|
|
424
508
|
else {
|
|
425
509
|
MoroLogger.appendToBuilder(timestamp);
|
|
426
510
|
}
|
|
427
|
-
}
|
|
428
|
-
// Level with color using pre-allocated strings
|
|
429
|
-
const levelColor = colors ? MoroLogger.COLORS[entry.level] : '';
|
|
430
|
-
const levelReset = colors ? MoroLogger.RESET : '';
|
|
431
|
-
const levelText = MoroLogger.LEVEL_STRINGS[entry.level];
|
|
432
|
-
// Add space after timestamp if present
|
|
433
|
-
if (this.options.enableTimestamp !== false) {
|
|
434
511
|
MoroLogger.appendToBuilder(' ');
|
|
435
512
|
}
|
|
513
|
+
// Level with pre-allocated strings
|
|
514
|
+
const levelStr = MoroLogger.LEVEL_STRINGS[entry.level];
|
|
436
515
|
if (colors) {
|
|
437
|
-
MoroLogger.appendToBuilder(
|
|
516
|
+
MoroLogger.appendToBuilder(MoroLogger.COLORS[entry.level]);
|
|
438
517
|
MoroLogger.appendToBuilder(MoroLogger.BOLD);
|
|
439
|
-
MoroLogger.appendToBuilder(
|
|
518
|
+
MoroLogger.appendToBuilder(levelStr);
|
|
440
519
|
MoroLogger.appendToBuilder(levelReset);
|
|
441
520
|
}
|
|
442
521
|
else {
|
|
443
|
-
MoroLogger.appendToBuilder(
|
|
522
|
+
MoroLogger.appendToBuilder(levelStr);
|
|
444
523
|
}
|
|
445
524
|
// Context
|
|
446
525
|
if (entry.context && this.options.enableContext !== false) {
|
|
447
|
-
|
|
448
|
-
MoroLogger.appendToBuilder(' '); // Space before context
|
|
526
|
+
MoroLogger.appendToBuilder(' ');
|
|
449
527
|
if (colors) {
|
|
450
|
-
MoroLogger.appendToBuilder(
|
|
528
|
+
MoroLogger.appendToBuilder(MoroLogger.COLORS.context);
|
|
451
529
|
MoroLogger.appendToBuilder(`[${entry.context}]`);
|
|
452
530
|
MoroLogger.appendToBuilder(levelReset);
|
|
453
531
|
}
|
|
@@ -456,7 +534,7 @@ class MoroLogger {
|
|
|
456
534
|
}
|
|
457
535
|
}
|
|
458
536
|
// Message
|
|
459
|
-
MoroLogger.appendToBuilder(' ');
|
|
537
|
+
MoroLogger.appendToBuilder(' ');
|
|
460
538
|
MoroLogger.appendToBuilder(entry.message);
|
|
461
539
|
// Performance info
|
|
462
540
|
if (entry.performance && this.options.enablePerformance !== false) {
|
|
@@ -469,7 +547,7 @@ class MoroLogger {
|
|
|
469
547
|
perfParts.push(`${Math.round(entry.performance.memory)}MB`);
|
|
470
548
|
}
|
|
471
549
|
if (perfParts.length > 0) {
|
|
472
|
-
MoroLogger.appendToBuilder(' ');
|
|
550
|
+
MoroLogger.appendToBuilder(' ');
|
|
473
551
|
if (colors) {
|
|
474
552
|
MoroLogger.appendToBuilder(perfColor);
|
|
475
553
|
MoroLogger.appendToBuilder(`(${perfParts.join(', ')})`);
|
|
@@ -487,19 +565,20 @@ class MoroLogger {
|
|
|
487
565
|
const metaColor = colors ? MoroLogger.COLORS.metadata : '';
|
|
488
566
|
const cleanMetadata = this.cleanMetadata(entry.metadata);
|
|
489
567
|
if (Object.keys(cleanMetadata).length > 0) {
|
|
568
|
+
MoroLogger.appendToBuilder(' ');
|
|
490
569
|
if (colors) {
|
|
491
570
|
MoroLogger.appendToBuilder(metaColor);
|
|
492
|
-
MoroLogger.appendToBuilder(this.
|
|
571
|
+
MoroLogger.appendToBuilder(this.safeStringify(cleanMetadata));
|
|
493
572
|
MoroLogger.appendToBuilder(levelReset);
|
|
494
573
|
}
|
|
495
574
|
else {
|
|
496
|
-
MoroLogger.appendToBuilder(this.
|
|
575
|
+
MoroLogger.appendToBuilder(this.safeStringify(cleanMetadata));
|
|
497
576
|
}
|
|
498
577
|
}
|
|
499
578
|
}
|
|
500
579
|
// Output main log line with high-performance method
|
|
501
580
|
const finalMessage = MoroLogger.buildString();
|
|
502
|
-
this.output(finalMessage
|
|
581
|
+
this.output(`${finalMessage}\n`, entry.level);
|
|
503
582
|
// Stack trace for errors
|
|
504
583
|
if (entry.metadata?.stack && (entry.level === 'error' || entry.level === 'fatal')) {
|
|
505
584
|
const stackColor = colors ? MoroLogger.COLORS.error : '';
|
|
@@ -516,77 +595,181 @@ class MoroLogger {
|
|
|
516
595
|
}
|
|
517
596
|
return clean;
|
|
518
597
|
}
|
|
519
|
-
//
|
|
520
|
-
stringify(obj) {
|
|
521
|
-
try {
|
|
522
|
-
return JSON.stringify(obj);
|
|
523
|
-
}
|
|
524
|
-
catch {
|
|
525
|
-
return '[Circular Reference]';
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
// High-performance output with micro-batching
|
|
598
|
+
// High-performance output with buffering
|
|
529
599
|
output(message, level = 'info') {
|
|
530
|
-
//
|
|
600
|
+
// Prevent memory exhaustion
|
|
601
|
+
if (this.outputBuffer.length >= this.bufferOverflowThreshold &&
|
|
602
|
+
!this.emergencyFlushInProgress) {
|
|
603
|
+
this.emergencyFlushInProgress = true;
|
|
604
|
+
this.forceFlushBuffer();
|
|
605
|
+
this.emergencyFlushInProgress = false;
|
|
606
|
+
}
|
|
531
607
|
this.outputBuffer.push(message);
|
|
532
|
-
this.bufferSize
|
|
533
|
-
//
|
|
534
|
-
if (
|
|
608
|
+
this.bufferSize++;
|
|
609
|
+
// Immediate flush for critical levels or full buffer
|
|
610
|
+
if (level === 'fatal' || level === 'error' || this.bufferSize >= this.maxBufferSize) {
|
|
535
611
|
this.flushBuffer();
|
|
536
612
|
}
|
|
537
613
|
else {
|
|
538
|
-
// Schedule flush with micro-batching
|
|
539
614
|
this.scheduleFlush();
|
|
540
615
|
}
|
|
541
616
|
}
|
|
542
617
|
scheduleFlush() {
|
|
543
|
-
if (this.flushTimeout)
|
|
544
|
-
return; // Already scheduled
|
|
618
|
+
if (this.flushTimeout || this.isDestroyed) {
|
|
619
|
+
return; // Already scheduled or destroyed
|
|
620
|
+
}
|
|
545
621
|
this.flushTimeout = setTimeout(() => {
|
|
546
622
|
this.flushBuffer();
|
|
547
|
-
this.flushTimeout = null;
|
|
548
623
|
}, this.flushInterval);
|
|
624
|
+
// Unref the timeout so it doesn't prevent process exit (important for tests)
|
|
625
|
+
this.flushTimeout.unref();
|
|
549
626
|
}
|
|
550
627
|
flushBuffer() {
|
|
551
|
-
if (this.outputBuffer.length === 0)
|
|
628
|
+
if (this.outputBuffer.length === 0) {
|
|
552
629
|
return;
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
}
|
|
630
|
+
}
|
|
631
|
+
// Group messages by stream type
|
|
632
|
+
const stdoutMessages = [];
|
|
633
|
+
const stderrMessages = [];
|
|
634
|
+
for (const message of this.outputBuffer) {
|
|
635
|
+
// Determine stream based on message content or level
|
|
636
|
+
if (message.includes('ERROR') || message.includes('FATAL')) {
|
|
637
|
+
stderrMessages.push(message);
|
|
638
|
+
}
|
|
639
|
+
else {
|
|
640
|
+
stdoutMessages.push(message);
|
|
565
641
|
}
|
|
566
|
-
|
|
567
|
-
|
|
642
|
+
}
|
|
643
|
+
// Write to appropriate streams with error handling
|
|
644
|
+
try {
|
|
645
|
+
if (stdoutMessages.length > 0 && process.stdout.writable) {
|
|
568
646
|
process.stdout.write(stdoutMessages.join(''));
|
|
569
647
|
}
|
|
570
|
-
if (stderrMessages.length > 0) {
|
|
648
|
+
if (stderrMessages.length > 0 && process.stderr.writable) {
|
|
571
649
|
process.stderr.write(stderrMessages.join(''));
|
|
572
650
|
}
|
|
573
651
|
}
|
|
574
652
|
catch {
|
|
575
|
-
// Fallback to console
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
// eslint-disable-next-line no-console
|
|
583
|
-
console.log(message.trim());
|
|
584
|
-
}
|
|
653
|
+
// Fallback to console if streams fail
|
|
654
|
+
try {
|
|
655
|
+
// eslint-disable-next-line no-console
|
|
656
|
+
console.log(this.outputBuffer.join(''));
|
|
657
|
+
}
|
|
658
|
+
catch {
|
|
659
|
+
// If even console.log fails, just ignore
|
|
585
660
|
}
|
|
586
661
|
}
|
|
587
|
-
//
|
|
662
|
+
// Clear buffer
|
|
588
663
|
this.outputBuffer.length = 0;
|
|
589
664
|
this.bufferSize = 0;
|
|
665
|
+
// Clear timeout
|
|
666
|
+
if (this.flushTimeout) {
|
|
667
|
+
clearTimeout(this.flushTimeout);
|
|
668
|
+
this.flushTimeout = null;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
// Emergency flush for buffer overflow protection
|
|
672
|
+
forceFlushBuffer() {
|
|
673
|
+
if (this.outputBuffer.length === 0)
|
|
674
|
+
return;
|
|
675
|
+
try {
|
|
676
|
+
const message = this.outputBuffer.join('');
|
|
677
|
+
process.stdout.write(message);
|
|
678
|
+
}
|
|
679
|
+
catch (error) {
|
|
680
|
+
// Emergency fallback - write individual messages
|
|
681
|
+
for (const msg of this.outputBuffer) {
|
|
682
|
+
try {
|
|
683
|
+
process.stdout.write(msg);
|
|
684
|
+
}
|
|
685
|
+
catch {
|
|
686
|
+
// If even this fails, give up on this batch
|
|
687
|
+
break;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
finally {
|
|
692
|
+
this.outputBuffer.length = 0;
|
|
693
|
+
this.bufferSize = 0;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
// Safe stringify with circular reference detection
|
|
697
|
+
safeStringify(obj, maxDepth = 3) {
|
|
698
|
+
const seen = new WeakSet();
|
|
699
|
+
const stringify = (value, depth) => {
|
|
700
|
+
if (depth > maxDepth)
|
|
701
|
+
return '[Max Depth Reached]';
|
|
702
|
+
if (value === null || typeof value !== 'object')
|
|
703
|
+
return value;
|
|
704
|
+
if (seen.has(value))
|
|
705
|
+
return '[Circular Reference]';
|
|
706
|
+
seen.add(value);
|
|
707
|
+
if (Array.isArray(value)) {
|
|
708
|
+
return value.map(item => stringify(item, depth + 1));
|
|
709
|
+
}
|
|
710
|
+
const result = {};
|
|
711
|
+
for (const [key, val] of Object.entries(value)) {
|
|
712
|
+
if (typeof val !== 'function') {
|
|
713
|
+
// Skip functions
|
|
714
|
+
result[key] = stringify(val, depth + 1);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
return result;
|
|
718
|
+
};
|
|
719
|
+
try {
|
|
720
|
+
return JSON.stringify(stringify(obj, 0));
|
|
721
|
+
}
|
|
722
|
+
catch (error) {
|
|
723
|
+
return '[Stringify Error]';
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
// Configuration validation
|
|
727
|
+
validateOptions(options) {
|
|
728
|
+
const validated = { ...options };
|
|
729
|
+
// Validate log level
|
|
730
|
+
const validLevels = ['debug', 'info', 'warn', 'error', 'fatal'];
|
|
731
|
+
if (validated.level && !validLevels.includes(validated.level)) {
|
|
732
|
+
console.warn(`[MoroLogger] Invalid log level: ${validated.level}, defaulting to 'info'`);
|
|
733
|
+
validated.level = 'info';
|
|
734
|
+
}
|
|
735
|
+
// Validate max entries
|
|
736
|
+
if (validated.maxEntries !== undefined) {
|
|
737
|
+
if (validated.maxEntries < 1 || validated.maxEntries > 100000) {
|
|
738
|
+
console.warn(`[MoroLogger] Invalid maxEntries: ${validated.maxEntries}, defaulting to 1000`);
|
|
739
|
+
validated.maxEntries = 1000;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
// Validate buffer size
|
|
743
|
+
if (validated.maxBufferSize !== undefined) {
|
|
744
|
+
if (validated.maxBufferSize < 10 || validated.maxBufferSize > 10000) {
|
|
745
|
+
console.warn(`[MoroLogger] Invalid maxBufferSize: ${validated.maxBufferSize}, defaulting to 1000`);
|
|
746
|
+
validated.maxBufferSize = 1000;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
return validated;
|
|
750
|
+
}
|
|
751
|
+
// Error handling methods
|
|
752
|
+
handleOutputError(outputName, error) {
|
|
753
|
+
// Could implement output retry logic, circuit breaker, etc.
|
|
754
|
+
// For now, just track the error
|
|
755
|
+
if (!this.metrics.outputErrors) {
|
|
756
|
+
this.metrics.outputErrors = {};
|
|
757
|
+
}
|
|
758
|
+
this.metrics.outputErrors[outputName] = (this.metrics.outputErrors[outputName] || 0) + 1;
|
|
759
|
+
}
|
|
760
|
+
emergencyConsoleWrite(entry) {
|
|
761
|
+
const message = `${entry.timestamp.toISOString()} ${entry.level.toUpperCase()} ${entry.message}`;
|
|
762
|
+
try {
|
|
763
|
+
if (entry.level === 'error' || entry.level === 'fatal') {
|
|
764
|
+
process.stderr.write(`[EMERGENCY] ${message}\n`);
|
|
765
|
+
}
|
|
766
|
+
else {
|
|
767
|
+
process.stdout.write(`[EMERGENCY] ${message}\n`);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
catch {
|
|
771
|
+
// If even emergency write fails, there's nothing more we can do
|
|
772
|
+
}
|
|
590
773
|
}
|
|
591
774
|
// Force flush streams (useful for shutdown)
|
|
592
775
|
flush() {
|
|
@@ -598,76 +781,69 @@ class MoroLogger {
|
|
|
598
781
|
// Flush any remaining buffer
|
|
599
782
|
this.flushBuffer();
|
|
600
783
|
try {
|
|
601
|
-
// Force flush streams
|
|
784
|
+
// Force flush streams without ending them
|
|
602
785
|
if (process.stdout.writable) {
|
|
603
|
-
process.stdout.
|
|
786
|
+
process.stdout.write(''); // Force flush without ending
|
|
604
787
|
}
|
|
605
788
|
if (process.stderr.writable) {
|
|
606
|
-
process.stderr.
|
|
789
|
+
process.stderr.write(''); // Force flush without ending
|
|
607
790
|
}
|
|
608
791
|
}
|
|
609
792
|
catch {
|
|
610
793
|
// Ignore flush errors
|
|
611
794
|
}
|
|
612
795
|
}
|
|
613
|
-
//
|
|
614
|
-
|
|
615
|
-
//
|
|
796
|
+
// Destroy logger and clean up all resources (for testing)
|
|
797
|
+
destroy() {
|
|
798
|
+
// Mark as destroyed to prevent new timeouts
|
|
799
|
+
this.isDestroyed = true;
|
|
800
|
+
// Clear any remaining timeouts
|
|
616
801
|
if (this.flushTimeout) {
|
|
617
802
|
clearTimeout(this.flushTimeout);
|
|
618
803
|
this.flushTimeout = null;
|
|
619
804
|
}
|
|
620
|
-
// Flush any remaining
|
|
805
|
+
// Flush any remaining buffer
|
|
621
806
|
this.flushBuffer();
|
|
807
|
+
// Clear outputs and filters
|
|
808
|
+
this.outputs.clear();
|
|
809
|
+
this.filters.clear();
|
|
810
|
+
// Clear history
|
|
811
|
+
this.history.length = 0;
|
|
812
|
+
this.historyIndex = 0;
|
|
813
|
+
this.historySize = 0;
|
|
622
814
|
}
|
|
623
815
|
}
|
|
624
|
-
exports.MoroLogger = MoroLogger;
|
|
625
816
|
// Global logger instance
|
|
626
817
|
const initialLogLevel = process.env.LOG_LEVEL ||
|
|
627
818
|
process.env.MORO_LOG_LEVEL ||
|
|
628
819
|
(process.env.NODE_ENV === 'production' ? 'warn' : 'debug');
|
|
629
|
-
|
|
820
|
+
export const logger = new MoroLogger({
|
|
630
821
|
level: initialLogLevel,
|
|
631
822
|
enableColors: !process.env.NO_COLOR,
|
|
632
823
|
format: process.env.LOG_FORMAT || 'pretty',
|
|
633
824
|
});
|
|
634
|
-
// Add cleanup handlers for Jest and other test runners
|
|
635
|
-
if (typeof process !== 'undefined') {
|
|
636
|
-
// Cleanup on process exit
|
|
637
|
-
process.on('beforeExit', () => {
|
|
638
|
-
exports.logger.cleanup();
|
|
639
|
-
});
|
|
640
|
-
process.on('SIGINT', () => {
|
|
641
|
-
exports.logger.cleanup();
|
|
642
|
-
process.exit(0);
|
|
643
|
-
});
|
|
644
|
-
process.on('SIGTERM', () => {
|
|
645
|
-
exports.logger.cleanup();
|
|
646
|
-
process.exit(0);
|
|
647
|
-
});
|
|
648
|
-
// For Jest and other test runners - cleanup on uncaught exceptions
|
|
649
|
-
process.on('uncaughtException', () => {
|
|
650
|
-
exports.logger.cleanup();
|
|
651
|
-
});
|
|
652
|
-
process.on('unhandledRejection', () => {
|
|
653
|
-
exports.logger.cleanup();
|
|
654
|
-
});
|
|
655
|
-
}
|
|
656
825
|
/**
|
|
657
826
|
* Configure the global logger with new settings
|
|
658
827
|
* This allows runtime configuration of the logger
|
|
659
828
|
*/
|
|
660
|
-
function configureGlobalLogger(options) {
|
|
829
|
+
export function configureGlobalLogger(options) {
|
|
661
830
|
if (options.level) {
|
|
662
|
-
|
|
831
|
+
logger.setLevel(options.level);
|
|
663
832
|
}
|
|
664
833
|
// Additional configuration options can be added here as needed
|
|
665
834
|
// For now, focusing on level which is the most critical
|
|
666
835
|
}
|
|
836
|
+
/**
|
|
837
|
+
* Destroy the global logger and clean up resources (for testing)
|
|
838
|
+
* @internal
|
|
839
|
+
*/
|
|
840
|
+
export function destroyGlobalLogger() {
|
|
841
|
+
logger.destroy();
|
|
842
|
+
}
|
|
667
843
|
/**
|
|
668
844
|
* Apply logging configuration from the config system and/or createApp options
|
|
669
845
|
*/
|
|
670
|
-
function applyLoggingConfiguration(configLogging, appOptions) {
|
|
846
|
+
export function applyLoggingConfiguration(configLogging, appOptions) {
|
|
671
847
|
// First apply config system settings (from environment variables)
|
|
672
848
|
if (configLogging?.level) {
|
|
673
849
|
configureGlobalLogger({ level: configLogging.level });
|
|
@@ -684,20 +860,19 @@ function applyLoggingConfiguration(configLogging, appOptions) {
|
|
|
684
860
|
}
|
|
685
861
|
}
|
|
686
862
|
// Framework-specific logger
|
|
687
|
-
const createFrameworkLogger = (context) => {
|
|
688
|
-
return
|
|
863
|
+
export const createFrameworkLogger = (context) => {
|
|
864
|
+
return logger.child('Moro', { framework: 'moro', context });
|
|
689
865
|
};
|
|
690
|
-
exports.createFrameworkLogger = createFrameworkLogger;
|
|
691
866
|
// Graceful shutdown handler to flush any pending logs
|
|
692
867
|
process.on('SIGINT', () => {
|
|
693
|
-
|
|
868
|
+
logger.flush();
|
|
694
869
|
process.exit(0);
|
|
695
870
|
});
|
|
696
871
|
process.on('SIGTERM', () => {
|
|
697
|
-
|
|
872
|
+
logger.flush();
|
|
698
873
|
process.exit(0);
|
|
699
874
|
});
|
|
700
875
|
process.on('beforeExit', () => {
|
|
701
|
-
|
|
876
|
+
logger.flush();
|
|
702
877
|
});
|
|
703
878
|
//# sourceMappingURL=logger.js.map
|