@expressots/core 3.0.0 → 4.0.0-preview.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -21
- package/README.md +66 -118
- package/lib/CHANGELOG.md +774 -739
- package/lib/README.md +66 -118
- package/lib/cjs/application/application-container.js +467 -33
- package/lib/cjs/application/application-factory.js +111 -5
- package/lib/cjs/application/application.types.js +32 -2
- package/lib/cjs/application/bootstrap.js +716 -0
- package/lib/cjs/application/index.js +10 -7
- package/lib/cjs/authorization/authorization-config.interface.js +2 -0
- package/lib/cjs/authorization/decorators/convenience.js +80 -0
- package/lib/cjs/authorization/guard-constants.js +12 -0
- package/lib/cjs/authorization/guard-decorators.js +159 -0
- package/lib/cjs/authorization/guard-executor.js +101 -0
- package/lib/cjs/authorization/guard-registry.js +133 -0
- package/lib/cjs/authorization/guard.interface.js +75 -0
- package/lib/cjs/authorization/guards/attribute-based.guard.js +109 -0
- package/lib/cjs/authorization/guards/authenticated.guard.js +49 -0
- package/lib/cjs/authorization/guards/composition.guard.js +67 -0
- package/lib/cjs/authorization/guards/conditional.guard.js +41 -0
- package/lib/cjs/authorization/guards/index.js +24 -0
- package/lib/cjs/authorization/guards/permission.guard.js +82 -0
- package/lib/cjs/authorization/guards/resource-owner.guard.js +61 -0
- package/lib/cjs/authorization/guards/role.guard.js +64 -0
- package/lib/cjs/authorization/index.js +40 -0
- package/lib/cjs/authorization/services/guard-cache.interface.js +2 -0
- package/lib/cjs/authorization/services/guard-cache.js +56 -0
- package/lib/cjs/authorization/services/permission-hierarchy.interface.js +2 -0
- package/lib/cjs/authorization/services/permission-hierarchy.js +54 -0
- package/lib/cjs/authorization/services/permission-service.interface.js +2 -0
- package/lib/cjs/authorization/services/permission-service.js +58 -0
- package/lib/cjs/authorization/services/security-context.interface.js +2 -0
- package/lib/cjs/authorization/services/security-context.js +75 -0
- package/lib/cjs/authorization/setup.js +141 -0
- package/lib/cjs/config/config-resolver.js +719 -0
- package/lib/cjs/config/config.interfaces.js +14 -0
- package/lib/cjs/config/define-config.js +495 -0
- package/lib/cjs/config/env-field-builders.js +449 -0
- package/lib/cjs/config/index.js +89 -0
- package/lib/cjs/config/secret-value.js +201 -0
- package/lib/cjs/console/color-codes.js +4 -0
- package/lib/cjs/console/console.js +72 -9
- package/lib/cjs/console/index.js +2 -2
- package/lib/cjs/container-module/container-module.js +257 -26
- package/lib/cjs/container-module/index.js +6 -4
- package/lib/cjs/decorator/index.js +1 -1
- package/lib/cjs/decorator/scope-binding.js +307 -16
- package/lib/cjs/di/annotation/decorator_utils.js +4 -4
- package/lib/cjs/di/annotation/inject.js +3 -3
- package/lib/cjs/di/annotation/inject_base.js +5 -5
- package/lib/cjs/di/annotation/injectable.js +2 -2
- package/lib/cjs/di/annotation/multi_inject.js +3 -3
- package/lib/cjs/di/annotation/named.js +4 -4
- package/lib/cjs/di/annotation/optional.js +4 -4
- package/lib/cjs/di/annotation/post_construct.js +4 -4
- package/lib/cjs/di/annotation/pre_destroy.js +4 -4
- package/lib/cjs/di/annotation/property_event_decorator.js +2 -2
- package/lib/cjs/di/annotation/tagged.js +3 -3
- package/lib/cjs/di/annotation/target_name.js +5 -5
- package/lib/cjs/di/annotation/unmanaged.js +5 -5
- package/lib/cjs/di/binding-decorator/constants.js +3 -0
- package/lib/cjs/di/binding-decorator/decorator/fluent_provide.js +7 -7
- package/lib/cjs/di/binding-decorator/decorator/provide.js +7 -7
- package/lib/cjs/di/binding-decorator/factory/module_factory.js +23 -4
- package/lib/cjs/di/binding-decorator/index.js +11 -9
- package/lib/cjs/di/binding-decorator/syntax/provide_done_syntax.js +7 -7
- package/lib/cjs/di/binding-decorator/syntax/provide_in_syntax.js +19 -12
- package/lib/cjs/di/binding-decorator/syntax/provide_in_when_on_syntax.js +3 -0
- package/lib/cjs/di/binding-decorator/syntax/provide_on_syntax.js +4 -4
- package/lib/cjs/di/binding-decorator/syntax/provide_when_syntax.js +30 -30
- package/lib/cjs/di/binding-decorator/utils/auto_wire.js +4 -4
- package/lib/cjs/di/bindings/binding.js +5 -6
- package/lib/cjs/di/constants/error_msgs.js +6 -2
- package/lib/cjs/di/constants/literal_types.js +3 -3
- package/lib/cjs/di/container/container.js +44 -44
- package/lib/cjs/di/container/container_module.js +3 -3
- package/lib/cjs/di/container/lookup.js +3 -3
- package/lib/cjs/di/container/module_activation_store.js +3 -3
- package/lib/cjs/di/container-introspection.js +42 -0
- package/lib/cjs/di/inversify.js +85 -52
- package/lib/cjs/di/planning/context.js +2 -2
- package/lib/cjs/di/planning/metadata.js +1 -1
- package/lib/cjs/di/planning/metadata_reader.js +1 -1
- package/lib/cjs/di/planning/planner.js +37 -37
- package/lib/cjs/di/planning/reflection_utils.js +12 -12
- package/lib/cjs/di/planning/request.js +2 -2
- package/lib/cjs/di/planning/target.js +10 -10
- package/lib/cjs/di/resolution/instantiation.js +13 -13
- package/lib/cjs/di/resolution/resolver.js +22 -22
- package/lib/cjs/di/scope/scope-registry.js +115 -0
- package/lib/cjs/di/scope/scope.js +38 -8
- package/lib/cjs/di/syntax/binding_in_syntax.js +18 -8
- package/lib/cjs/di/syntax/binding_in_when_on_syntax.js +9 -6
- package/lib/cjs/di/syntax/binding_on_syntax.js +3 -3
- package/lib/cjs/di/syntax/binding_to_syntax.js +27 -27
- package/lib/cjs/di/syntax/binding_when_on_syntax.js +4 -4
- package/lib/cjs/di/syntax/binding_when_syntax.js +30 -30
- package/lib/cjs/di/syntax/constraint_helpers.js +3 -3
- package/lib/cjs/di/utils/binding_utils.js +18 -18
- package/lib/cjs/di/utils/exceptions.js +1 -1
- package/lib/cjs/di/utils/serialization.js +1 -1
- package/lib/cjs/error/app-error.js +152 -8
- package/lib/cjs/error/base-exception-filter.js +135 -0
- package/lib/cjs/error/error-handler-middleware.js +7 -7
- package/lib/cjs/error/exception-filter-constants.js +12 -0
- package/lib/cjs/error/exception-filter-decorators.js +161 -0
- package/lib/cjs/error/exception-filter-registry.js +163 -0
- package/lib/cjs/error/exception-filter.interface.js +2 -0
- package/lib/cjs/error/exception-handler-middleware.js +378 -0
- package/lib/cjs/error/filters/app-error.filter.js +31 -0
- package/lib/cjs/error/filters/global-exception.filter.js +39 -0
- package/lib/cjs/error/filters/not-found.filter.js +35 -0
- package/lib/cjs/error/filters/validation-error.filter.js +35 -0
- package/lib/cjs/error/index.js +28 -7
- package/lib/cjs/error/not-found.error.js +17 -0
- package/lib/cjs/error/report.js +104 -9
- package/lib/cjs/error/status-code.js +20 -0
- package/lib/cjs/error/utils.js +247 -33
- package/lib/cjs/error/validation.error.js +18 -0
- package/lib/cjs/event/event-decorators.js +280 -0
- package/lib/cjs/event/event-emitter.js +373 -0
- package/lib/cjs/event/event-flow-tracker.js +236 -0
- package/lib/cjs/event/event-recorder.js +289 -0
- package/lib/cjs/event/event-registry.js +207 -0
- package/lib/cjs/event/event.interfaces.js +54 -0
- package/lib/cjs/event/index.js +80 -0
- package/lib/cjs/framework-version.js +10 -0
- package/lib/cjs/index.js +29 -8
- package/lib/cjs/interceptor/conditional-interceptor.js +108 -0
- package/lib/cjs/interceptor/execution-context.js +66 -0
- package/lib/cjs/interceptor/index.js +64 -0
- package/lib/cjs/interceptor/interceptor-composition.js +130 -0
- package/lib/cjs/interceptor/interceptor-constants.js +20 -0
- package/lib/cjs/interceptor/interceptor-decorators.js +155 -0
- package/lib/cjs/interceptor/interceptor-executor.js +140 -0
- package/lib/cjs/interceptor/interceptor-registry.js +159 -0
- package/lib/cjs/interceptor/interceptor.interface.js +20 -0
- package/lib/cjs/interceptor/interceptors/index.js +22 -0
- package/lib/cjs/interceptor/interceptors/logging.interceptor.js +70 -0
- package/lib/cjs/interceptor/interceptors/performance.interceptor.js +251 -0
- package/lib/cjs/interceptor/interceptors/timeout.interceptor.js +66 -0
- package/lib/cjs/lazy-loading/index.js +77 -0
- package/lib/cjs/lazy-loading/lazy-load-metrics.js +355 -0
- package/lib/cjs/lazy-loading/lazy-module-helpers.js +49 -0
- package/lib/cjs/lazy-loading/lazy-module-loader.js +311 -0
- package/lib/cjs/lazy-loading/lazy-module-manager.js +244 -0
- package/lib/cjs/lazy-loading/lazy-module-warmup.js +294 -0
- package/lib/cjs/lazy-loading/lazy-module.js +380 -0
- package/lib/cjs/lazy-loading/lazy.interfaces.js +18 -0
- package/lib/cjs/lifecycle/index.js +15 -0
- package/lib/cjs/lifecycle/lifecycle-registry.js +301 -0
- package/lib/cjs/lifecycle/lifecycle.interface.js +37 -0
- package/lib/cjs/middleware/content-negotiation/accept-header-parser.js +110 -0
- package/lib/cjs/middleware/content-negotiation/content-negotiation-service.js +288 -0
- package/lib/cjs/middleware/content-negotiation/formatter-registry.js +168 -0
- package/lib/cjs/middleware/content-negotiation/formatters/csv-formatter.js +114 -0
- package/lib/cjs/middleware/content-negotiation/formatters/index.js +16 -0
- package/lib/cjs/middleware/content-negotiation/formatters/json-formatter.js +34 -0
- package/lib/cjs/middleware/content-negotiation/formatters/plain-text-formatter.js +44 -0
- package/lib/cjs/middleware/content-negotiation/formatters/xml-formatter.js +124 -0
- package/lib/cjs/middleware/content-negotiation/formatters/yaml-formatter.js +134 -0
- package/lib/cjs/middleware/content-negotiation/index.js +27 -0
- package/lib/cjs/middleware/index.js +58 -30
- package/lib/cjs/middleware/interfaces/content-negotiation.interface.js +7 -0
- package/lib/cjs/middleware/middleware-config.js +10 -0
- package/lib/cjs/middleware/middleware-profiler.js +310 -0
- package/lib/cjs/middleware/middleware-registry.js +160 -0
- package/lib/cjs/middleware/middleware-resolver.js +318 -57
- package/lib/cjs/middleware/middleware-service.js +1692 -308
- package/lib/cjs/middleware/middleware-utils.js +280 -0
- package/lib/cjs/middleware/presets-standalone.js +93 -0
- package/lib/cjs/middleware/upload-registry.js +91 -0
- package/lib/cjs/path-resolver/index.js +252 -0
- package/lib/cjs/provider/db-in-memory/adapter/adapter.interface.js +10 -0
- package/lib/cjs/provider/db-in-memory/adapter/in-memory.adapter.js +688 -0
- package/lib/cjs/provider/db-in-memory/adapter/index.js +10 -0
- package/lib/cjs/provider/db-in-memory/base-repo.repository.js +4 -4
- package/lib/cjs/provider/db-in-memory/db-in-memory.provider.js +14 -18
- package/lib/cjs/provider/db-in-memory/db.provider.js +402 -0
- package/lib/cjs/provider/db-in-memory/index.js +125 -9
- package/lib/cjs/provider/db-in-memory/query/index.js +24 -0
- package/lib/cjs/provider/db-in-memory/query/query-engine.js +601 -0
- package/lib/cjs/provider/db-in-memory/query/query.types.js +10 -0
- package/lib/cjs/provider/db-in-memory/schema/decorators.js +420 -0
- package/lib/cjs/provider/db-in-memory/schema/entity.interface.js +9 -0
- package/lib/cjs/provider/db-in-memory/schema/index.js +21 -0
- package/lib/cjs/provider/db-in-memory/storage/index.js +16 -0
- package/lib/cjs/provider/db-in-memory/storage/memory-store.js +777 -0
- package/lib/cjs/provider/dto-validator/dto-validator.provider.js +8 -8
- package/lib/cjs/provider/dto-validator/package-resolver.js +2 -2
- package/lib/cjs/provider/index.js +14 -10
- package/lib/cjs/provider/logger/decorators/index.js +17 -0
- package/lib/cjs/provider/logger/decorators/log-performance.decorator.js +178 -0
- package/lib/cjs/provider/logger/index.js +35 -0
- package/lib/cjs/provider/logger/logger.banner.js +482 -0
- package/lib/cjs/provider/logger/logger.config.js +32 -0
- package/lib/cjs/provider/logger/logger.context.js +341 -0
- package/lib/cjs/provider/logger/logger.flow.js +255 -0
- package/lib/cjs/provider/logger/logger.formatter.js +697 -0
- package/lib/cjs/provider/logger/logger.grouping.js +319 -0
- package/lib/cjs/provider/logger/logger.health.js +295 -0
- package/lib/cjs/provider/logger/logger.metrics-collector.js +184 -0
- package/lib/cjs/provider/logger/logger.metrics.js +91 -0
- package/lib/cjs/provider/logger/logger.performance.js +300 -0
- package/lib/cjs/provider/logger/logger.provider.js +746 -73
- package/lib/cjs/provider/logger/logger.query.js +532 -0
- package/lib/cjs/provider/logger/logger.redaction.js +456 -0
- package/lib/cjs/provider/logger/logger.suggestions.js +480 -0
- package/lib/cjs/provider/logger/transports/console.transport.js +141 -0
- package/lib/cjs/provider/logger/transports/file.transport.js +296 -0
- package/lib/cjs/provider/logger/transports/http-server.js +141 -0
- package/lib/cjs/provider/logger/transports/http.transport.js +151 -0
- package/lib/cjs/provider/logger/transports/index.js +21 -0
- package/lib/cjs/provider/logger/transports/transport.interface.js +2 -0
- package/lib/cjs/provider/logger/utils/index.js +18 -0
- package/lib/cjs/provider/logger/utils/log-entry.js +26 -0
- package/lib/cjs/provider/logger/utils/log-levels.js +107 -0
- package/lib/cjs/provider/provider-manager.js +209 -16
- package/lib/cjs/provider/provider-registry.js +414 -0
- package/lib/cjs/provider/provider.interface.js +49 -0
- package/lib/cjs/provider/validation/adapters/class-validator.adapter.js +264 -0
- package/lib/cjs/provider/validation/adapters/index.js +21 -0
- package/lib/cjs/provider/validation/adapters/yup.adapter.js +118 -0
- package/lib/cjs/provider/validation/adapters/zod.adapter.js +137 -0
- package/lib/cjs/provider/validation/helpful-error-formatter.js +228 -0
- package/lib/cjs/provider/validation/index.js +39 -0
- package/lib/cjs/provider/validation/smart-field-detector.js +543 -0
- package/lib/cjs/provider/validation/type-inference.js +192 -0
- package/lib/cjs/provider/validation/validation-registry.js +220 -0
- package/lib/cjs/provider/validation/validation.interface.js +9 -0
- package/lib/cjs/render/adapters/base-adapter.js +134 -0
- package/lib/cjs/render/adapters/ejs-adapter.js +172 -0
- package/lib/cjs/render/adapters/handlebars-adapter.js +191 -0
- package/lib/cjs/render/adapters/index.js +20 -0
- package/lib/cjs/render/adapters/pug-adapter.js +164 -0
- package/lib/cjs/render/adapters/react-adapter.js +336 -0
- package/lib/cjs/render/features/auto-detection.js +228 -0
- package/lib/cjs/render/features/hot-reload.js +155 -0
- package/lib/cjs/render/features/index.js +20 -0
- package/lib/cjs/render/features/streaming.js +106 -0
- package/lib/cjs/render/features/type-generator.js +221 -0
- package/lib/cjs/render/features/view-debugger.js +194 -0
- package/lib/cjs/render/index.js +80 -0
- package/lib/cjs/render/presets/index.js +216 -0
- package/lib/cjs/render/render-config.js +10 -0
- package/lib/cjs/render/render-interface.js +2 -0
- package/lib/cjs/render/render-registry.js +130 -0
- package/lib/cjs/render/render-service.js +418 -0
- package/lib/cjs/render/utils/cache-manager.js +199 -0
- package/lib/cjs/render/utils/index.js +20 -0
- package/lib/cjs/render/utils/package-resolver.js +121 -0
- package/lib/cjs/render/utils/view-scanner.js +208 -0
- package/lib/cjs/testing/create-test-app.js +366 -0
- package/lib/cjs/testing/create-test-database.js +416 -0
- package/lib/cjs/testing/fluent-request.js +461 -0
- package/lib/cjs/testing/index.js +142 -0
- package/lib/cjs/testing/load-test.js +484 -0
- package/lib/cjs/testing/matchers.js +444 -0
- package/lib/cjs/testing/mock-context.js +406 -0
- package/lib/cjs/testing/mock-provider.js +339 -0
- package/lib/cjs/testing/snapshot-request.js +380 -0
- package/lib/cjs/testing/testing.interfaces.js +10 -0
- package/lib/cjs/types/application/application-container.d.ts +320 -20
- package/lib/cjs/types/application/application-factory.d.ts +105 -3
- package/lib/cjs/types/application/application.types.d.ts +177 -2
- package/lib/cjs/types/application/bootstrap.d.ts +656 -0
- package/lib/cjs/types/application/index.d.ts +4 -3
- package/lib/cjs/types/authorization/authorization-config.interface.d.ts +45 -0
- package/lib/cjs/types/authorization/decorators/convenience.d.ts +64 -0
- package/lib/cjs/types/authorization/guard-constants.d.ts +9 -0
- package/lib/cjs/types/authorization/guard-decorators.d.ts +128 -0
- package/lib/cjs/types/authorization/guard-executor.d.ts +26 -0
- package/lib/cjs/types/authorization/guard-registry.d.ts +35 -0
- package/lib/cjs/types/authorization/guard.interface.d.ts +335 -0
- package/lib/cjs/types/authorization/guards/attribute-based.guard.d.ts +60 -0
- package/lib/cjs/types/authorization/guards/authenticated.guard.d.ts +26 -0
- package/lib/cjs/types/authorization/guards/composition.guard.d.ts +42 -0
- package/lib/cjs/types/authorization/guards/conditional.guard.d.ts +21 -0
- package/lib/cjs/types/authorization/guards/index.d.ts +7 -0
- package/lib/cjs/types/authorization/guards/permission.guard.d.ts +29 -0
- package/lib/cjs/types/authorization/guards/resource-owner.guard.d.ts +29 -0
- package/lib/cjs/types/authorization/guards/role.guard.d.ts +28 -0
- package/lib/cjs/types/authorization/index.d.ts +18 -0
- package/lib/cjs/types/authorization/services/guard-cache.d.ts +26 -0
- package/lib/cjs/types/authorization/services/guard-cache.interface.d.ts +29 -0
- package/lib/cjs/types/authorization/services/permission-hierarchy.d.ts +21 -0
- package/lib/cjs/types/authorization/services/permission-hierarchy.interface.d.ts +22 -0
- package/lib/cjs/types/authorization/services/permission-service.d.ts +21 -0
- package/lib/cjs/types/authorization/services/permission-service.interface.d.ts +19 -0
- package/lib/cjs/types/authorization/services/security-context.d.ts +32 -0
- package/lib/cjs/types/authorization/services/security-context.interface.d.ts +25 -0
- package/lib/cjs/types/authorization/setup.d.ts +84 -0
- package/lib/cjs/types/config/config-resolver.d.ts +40 -0
- package/lib/cjs/types/config/config.interfaces.d.ts +576 -0
- package/lib/cjs/types/config/define-config.d.ts +109 -0
- package/lib/cjs/types/config/env-field-builders.d.ts +327 -0
- package/lib/cjs/types/config/index.d.ts +61 -0
- package/lib/cjs/types/config/secret-value.d.ts +99 -0
- package/lib/cjs/types/console/color-codes.d.ts +1 -1
- package/lib/cjs/types/console/console.d.ts +65 -2
- package/lib/cjs/types/console/index.d.ts +1 -1
- package/lib/cjs/types/container-module/container-module.d.ts +215 -8
- package/lib/cjs/types/container-module/index.d.ts +1 -1
- package/lib/cjs/types/decorator/index.d.ts +1 -1
- package/lib/cjs/types/decorator/scope-binding.d.ts +339 -11
- package/lib/cjs/types/di/annotation/decorator_utils.d.ts +1 -1
- package/lib/cjs/types/di/annotation/inject.d.ts +1 -1
- package/lib/cjs/types/di/annotation/inject_base.d.ts +2 -2
- package/lib/cjs/types/di/annotation/lazy_service_identifier.d.ts +1 -1
- package/lib/cjs/types/di/annotation/multi_inject.d.ts +1 -1
- package/lib/cjs/types/di/annotation/named.d.ts +1 -1
- package/lib/cjs/types/di/annotation/target_name.d.ts +1 -1
- package/lib/cjs/types/di/annotation/unmanaged.d.ts +1 -1
- package/lib/cjs/types/di/binding-decorator/constants.d.ts +3 -0
- package/lib/cjs/types/di/binding-decorator/decorator/fluent_provide.d.ts +2 -2
- package/lib/cjs/types/di/binding-decorator/decorator/provide.d.ts +1 -1
- package/lib/cjs/types/di/binding-decorator/factory/module_factory.d.ts +20 -1
- package/lib/cjs/types/di/binding-decorator/index.d.ts +6 -4
- package/lib/cjs/types/di/binding-decorator/interfaces/interfaces.d.ts +2 -1
- package/lib/cjs/types/di/binding-decorator/syntax/provide_done_syntax.d.ts +1 -1
- package/lib/cjs/types/di/binding-decorator/syntax/provide_in_syntax.d.ts +3 -2
- package/lib/cjs/types/di/binding-decorator/syntax/provide_in_when_on_syntax.d.ts +3 -2
- package/lib/cjs/types/di/binding-decorator/syntax/provide_on_syntax.d.ts +2 -2
- package/lib/cjs/types/di/binding-decorator/syntax/provide_when_on_syntax.d.ts +2 -2
- package/lib/cjs/types/di/binding-decorator/syntax/provide_when_syntax.d.ts +2 -2
- package/lib/cjs/types/di/binding-decorator/utils/auto_wire.d.ts +1 -1
- package/lib/cjs/types/di/bindings/binding.d.ts +1 -1
- package/lib/cjs/types/di/constants/literal_types.d.ts +3 -3
- package/lib/cjs/types/di/container/container.d.ts +1 -1
- package/lib/cjs/types/di/container/container_module.d.ts +1 -1
- package/lib/cjs/types/di/container/container_snapshot.d.ts +1 -1
- package/lib/cjs/types/di/container/lookup.d.ts +1 -1
- package/lib/cjs/types/di/container/module_activation_store.d.ts +1 -1
- package/lib/cjs/types/di/container-introspection.d.ts +25 -0
- package/lib/cjs/types/di/interfaces/interfaces.d.ts +4 -3
- package/lib/cjs/types/di/inversify.d.ts +53 -24
- package/lib/cjs/types/di/planning/context.d.ts +1 -1
- package/lib/cjs/types/di/planning/metadata.d.ts +1 -1
- package/lib/cjs/types/di/planning/metadata_reader.d.ts +1 -1
- package/lib/cjs/types/di/planning/plan.d.ts +1 -1
- package/lib/cjs/types/di/planning/planner.d.ts +1 -1
- package/lib/cjs/types/di/planning/queryable_string.d.ts +1 -1
- package/lib/cjs/types/di/planning/reflection_utils.d.ts +2 -2
- package/lib/cjs/types/di/planning/request.d.ts +1 -1
- package/lib/cjs/types/di/planning/target.d.ts +2 -2
- package/lib/cjs/types/di/resolution/instantiation.d.ts +1 -1
- package/lib/cjs/types/di/resolution/resolver.d.ts +1 -1
- package/lib/cjs/types/di/scope/scope-registry.d.ts +91 -0
- package/lib/cjs/types/di/scope/scope.d.ts +1 -1
- package/lib/cjs/types/di/syntax/binding_in_syntax.d.ts +2 -1
- package/lib/cjs/types/di/syntax/binding_in_when_on_syntax.d.ts +2 -1
- package/lib/cjs/types/di/syntax/binding_on_syntax.d.ts +1 -1
- package/lib/cjs/types/di/syntax/binding_to_syntax.d.ts +2 -2
- package/lib/cjs/types/di/syntax/binding_when_on_syntax.d.ts +1 -1
- package/lib/cjs/types/di/syntax/binding_when_syntax.d.ts +1 -1
- package/lib/cjs/types/di/syntax/constraint_helpers.d.ts +1 -1
- package/lib/cjs/types/di/utils/binding_utils.d.ts +1 -1
- package/lib/cjs/types/di/utils/clonable.d.ts +1 -1
- package/lib/cjs/types/di/utils/serialization.d.ts +1 -1
- package/lib/cjs/types/error/app-error.d.ts +155 -7
- package/lib/cjs/types/error/base-exception-filter.d.ts +73 -0
- package/lib/cjs/types/error/exception-filter-constants.d.ts +9 -0
- package/lib/cjs/types/error/exception-filter-decorators.d.ts +126 -0
- package/lib/cjs/types/error/exception-filter-registry.d.ts +38 -0
- package/lib/cjs/types/error/exception-filter.interface.d.ts +82 -0
- package/lib/cjs/types/error/exception-handler-middleware.d.ts +35 -0
- package/lib/cjs/types/error/filters/app-error.filter.d.ts +10 -0
- package/lib/cjs/types/error/filters/global-exception.filter.d.ts +9 -0
- package/lib/cjs/types/error/filters/not-found.filter.d.ts +10 -0
- package/lib/cjs/types/error/filters/validation-error.filter.d.ts +10 -0
- package/lib/cjs/types/error/index.d.ts +14 -3
- package/lib/cjs/types/error/not-found.error.d.ts +7 -0
- package/lib/cjs/types/error/report.d.ts +84 -6
- package/lib/cjs/types/error/status-code.d.ts +20 -0
- package/lib/cjs/types/error/utils.d.ts +16 -0
- package/lib/cjs/types/error/validation.error.d.ts +8 -0
- package/lib/cjs/types/event/event-decorators.d.ts +199 -0
- package/lib/cjs/types/event/event-emitter.d.ts +109 -0
- package/lib/cjs/types/event/event-flow-tracker.d.ts +88 -0
- package/lib/cjs/types/event/event-recorder.d.ts +121 -0
- package/lib/cjs/types/event/event-registry.d.ts +84 -0
- package/lib/cjs/types/event/event.interfaces.d.ts +528 -0
- package/lib/cjs/types/event/index.d.ts +55 -0
- package/lib/cjs/types/framework-version.d.ts +7 -0
- package/lib/cjs/types/index.d.ts +27 -8
- package/lib/cjs/types/interceptor/conditional-interceptor.d.ts +91 -0
- package/lib/cjs/types/interceptor/execution-context.d.ts +41 -0
- package/lib/cjs/types/interceptor/index.d.ts +41 -0
- package/lib/cjs/types/interceptor/interceptor-composition.d.ts +115 -0
- package/lib/cjs/types/interceptor/interceptor-constants.d.ts +17 -0
- package/lib/cjs/types/interceptor/interceptor-decorators.d.ts +124 -0
- package/lib/cjs/types/interceptor/interceptor-executor.d.ts +46 -0
- package/lib/cjs/types/interceptor/interceptor-registry.d.ts +65 -0
- package/lib/cjs/types/interceptor/interceptor.interface.d.ts +281 -0
- package/lib/cjs/types/interceptor/interceptors/index.d.ts +6 -0
- package/lib/cjs/types/interceptor/interceptors/logging.interceptor.d.ts +28 -0
- package/lib/cjs/types/interceptor/interceptors/performance.interceptor.d.ts +197 -0
- package/lib/cjs/types/interceptor/interceptors/timeout.interceptor.d.ts +42 -0
- package/lib/cjs/types/lazy-loading/index.d.ts +43 -0
- package/lib/cjs/types/lazy-loading/lazy-load-metrics.d.ts +139 -0
- package/lib/cjs/types/lazy-loading/lazy-module-helpers.d.ts +42 -0
- package/lib/cjs/types/lazy-loading/lazy-module-loader.d.ts +169 -0
- package/lib/cjs/types/lazy-loading/lazy-module-manager.d.ts +148 -0
- package/lib/cjs/types/lazy-loading/lazy-module-warmup.d.ts +130 -0
- package/lib/cjs/types/lazy-loading/lazy-module.d.ts +168 -0
- package/lib/cjs/types/lazy-loading/lazy.interfaces.d.ts +480 -0
- package/lib/cjs/types/lifecycle/index.d.ts +9 -0
- package/lib/cjs/types/lifecycle/lifecycle-registry.d.ts +213 -0
- package/lib/cjs/types/lifecycle/lifecycle.interface.d.ts +191 -0
- package/lib/cjs/types/middleware/content-negotiation/accept-header-parser.d.ts +26 -0
- package/lib/cjs/types/middleware/content-negotiation/content-negotiation-service.d.ts +64 -0
- package/lib/cjs/types/middleware/content-negotiation/formatter-registry.d.ts +60 -0
- package/lib/cjs/types/middleware/content-negotiation/formatters/csv-formatter.d.ts +34 -0
- package/lib/cjs/types/middleware/content-negotiation/formatters/index.d.ts +8 -0
- package/lib/cjs/types/middleware/content-negotiation/formatters/json-formatter.d.ts +14 -0
- package/lib/cjs/types/middleware/content-negotiation/formatters/plain-text-formatter.d.ts +12 -0
- package/lib/cjs/types/middleware/content-negotiation/formatters/xml-formatter.d.ts +26 -0
- package/lib/cjs/types/middleware/content-negotiation/formatters/yaml-formatter.d.ts +26 -0
- package/lib/cjs/types/middleware/content-negotiation/index.d.ts +7 -0
- package/lib/cjs/types/middleware/index.d.ts +25 -15
- package/lib/cjs/types/middleware/interfaces/content-negotiation.interface.d.ts +142 -0
- package/lib/cjs/types/middleware/interfaces/cookie-session/cookie-session.interface.d.ts +1 -1
- package/lib/cjs/types/middleware/middleware-config.d.ts +574 -0
- package/lib/cjs/types/middleware/middleware-interface.d.ts +594 -88
- package/lib/cjs/types/middleware/middleware-profiler.d.ts +199 -0
- package/lib/cjs/types/middleware/middleware-registry.d.ts +103 -0
- package/lib/cjs/types/middleware/middleware-resolver.d.ts +156 -8
- package/lib/cjs/types/middleware/middleware-service.d.ts +654 -111
- package/lib/cjs/types/middleware/middleware-utils.d.ts +145 -0
- package/lib/cjs/types/middleware/presets-standalone.d.ts +75 -0
- package/lib/cjs/types/middleware/upload-registry.d.ts +50 -0
- package/lib/cjs/types/path-resolver/index.d.ts +80 -0
- package/lib/cjs/types/provider/db-in-memory/adapter/adapter.interface.d.ts +222 -0
- package/lib/cjs/types/provider/db-in-memory/adapter/in-memory.adapter.d.ts +241 -0
- package/lib/cjs/types/provider/db-in-memory/adapter/index.d.ts +6 -0
- package/lib/cjs/types/provider/db-in-memory/base-repo.repository.d.ts +1 -1
- package/lib/cjs/types/provider/db-in-memory/db-in-memory.interface.d.ts +1 -1
- package/lib/cjs/types/provider/db-in-memory/db-in-memory.provider.d.ts +8 -2
- package/lib/cjs/types/provider/db-in-memory/db.provider.d.ts +281 -0
- package/lib/cjs/types/provider/db-in-memory/index.d.ts +71 -4
- package/lib/cjs/types/provider/db-in-memory/query/index.d.ts +6 -0
- package/lib/cjs/types/provider/db-in-memory/query/query-engine.d.ts +114 -0
- package/lib/cjs/types/provider/db-in-memory/query/query.types.d.ts +318 -0
- package/lib/cjs/types/provider/db-in-memory/schema/decorators.d.ts +328 -0
- package/lib/cjs/types/provider/db-in-memory/schema/entity.interface.d.ts +60 -0
- package/lib/cjs/types/provider/db-in-memory/schema/index.d.ts +6 -0
- package/lib/cjs/types/provider/db-in-memory/storage/index.d.ts +5 -0
- package/lib/cjs/types/provider/db-in-memory/storage/memory-store.d.ts +360 -0
- package/lib/cjs/types/provider/index.d.ts +7 -5
- package/lib/cjs/types/provider/logger/decorators/index.d.ts +1 -0
- package/lib/cjs/types/provider/logger/decorators/log-performance.decorator.d.ts +49 -0
- package/lib/cjs/types/provider/logger/index.d.ts +17 -0
- package/lib/cjs/types/provider/logger/logger.banner.d.ts +94 -0
- package/lib/cjs/types/provider/logger/logger.config.d.ts +62 -0
- package/lib/cjs/types/provider/logger/logger.context.d.ts +189 -0
- package/lib/cjs/types/provider/logger/logger.flow.d.ts +165 -0
- package/lib/cjs/types/provider/logger/logger.formatter.d.ts +54 -0
- package/lib/cjs/types/provider/logger/logger.grouping.d.ts +124 -0
- package/lib/cjs/types/provider/logger/logger.health.d.ts +123 -0
- package/lib/cjs/types/provider/logger/logger.metrics-collector.d.ts +44 -0
- package/lib/cjs/types/provider/logger/logger.metrics.d.ts +162 -0
- package/lib/cjs/types/provider/logger/logger.performance.d.ts +179 -0
- package/lib/cjs/types/provider/logger/logger.provider.d.ts +332 -28
- package/lib/cjs/types/provider/logger/logger.query.d.ts +232 -0
- package/lib/cjs/types/provider/logger/logger.redaction.d.ts +169 -0
- package/lib/cjs/types/provider/logger/logger.suggestions.d.ts +124 -0
- package/lib/cjs/types/provider/logger/transports/console.transport.d.ts +56 -0
- package/lib/cjs/types/provider/logger/transports/file.transport.d.ts +87 -0
- package/lib/cjs/types/provider/logger/transports/http-server.d.ts +88 -0
- package/lib/cjs/types/provider/logger/transports/http.transport.d.ts +74 -0
- package/lib/cjs/types/provider/logger/transports/index.d.ts +5 -0
- package/lib/cjs/types/provider/logger/transports/transport.interface.d.ts +31 -0
- package/lib/cjs/types/provider/logger/utils/index.d.ts +2 -0
- package/lib/cjs/types/provider/logger/utils/log-entry.d.ts +82 -0
- package/lib/cjs/types/provider/logger/utils/log-levels.d.ts +53 -0
- package/lib/cjs/types/provider/provider-manager.d.ts +165 -13
- package/lib/cjs/types/provider/provider-registry.d.ts +192 -0
- package/lib/cjs/types/provider/provider.interface.d.ts +337 -0
- package/lib/cjs/types/provider/validation/adapters/class-validator.adapter.d.ts +68 -0
- package/lib/cjs/types/provider/validation/adapters/index.d.ts +13 -0
- package/lib/cjs/types/provider/validation/adapters/yup.adapter.d.ts +65 -0
- package/lib/cjs/types/provider/validation/adapters/zod.adapter.d.ts +84 -0
- package/lib/cjs/types/provider/validation/helpful-error-formatter.d.ts +110 -0
- package/lib/cjs/types/provider/validation/index.d.ts +19 -0
- package/lib/cjs/types/provider/validation/smart-field-detector.d.ts +91 -0
- package/lib/cjs/types/provider/validation/type-inference.d.ts +81 -0
- package/lib/cjs/types/provider/validation/validation-registry.d.ts +105 -0
- package/lib/cjs/types/provider/validation/validation.interface.d.ts +178 -0
- package/lib/cjs/types/render/adapters/base-adapter.d.ts +95 -0
- package/lib/cjs/types/render/adapters/ejs-adapter.d.ts +57 -0
- package/lib/cjs/types/render/adapters/handlebars-adapter.d.ts +74 -0
- package/lib/cjs/types/render/adapters/index.d.ts +12 -0
- package/lib/cjs/types/render/adapters/pug-adapter.d.ts +57 -0
- package/lib/cjs/types/render/adapters/react-adapter.d.ts +99 -0
- package/lib/cjs/types/render/features/auto-detection.d.ts +58 -0
- package/lib/cjs/types/render/features/hot-reload.d.ts +65 -0
- package/lib/cjs/types/render/features/index.d.ts +12 -0
- package/lib/cjs/types/render/features/streaming.d.ts +39 -0
- package/lib/cjs/types/render/features/type-generator.d.ts +64 -0
- package/lib/cjs/types/render/features/view-debugger.d.ts +52 -0
- package/lib/cjs/types/render/index.d.ts +50 -0
- package/lib/cjs/types/render/presets/index.d.ts +119 -0
- package/lib/cjs/types/render/render-config.d.ts +213 -0
- package/lib/cjs/types/render/render-interface.d.ts +126 -0
- package/lib/cjs/types/render/render-registry.d.ts +86 -0
- package/lib/cjs/types/render/render-service.d.ts +157 -0
- package/lib/cjs/types/render/utils/cache-manager.d.ts +106 -0
- package/lib/cjs/types/render/utils/index.d.ts +11 -0
- package/lib/cjs/types/render/utils/package-resolver.d.ts +57 -0
- package/lib/cjs/types/render/utils/view-scanner.d.ts +74 -0
- package/lib/cjs/types/testing/create-test-app.d.ts +71 -0
- package/lib/cjs/types/testing/create-test-database.d.ts +100 -0
- package/lib/cjs/types/testing/fluent-request.d.ts +37 -0
- package/lib/cjs/types/testing/index.d.ts +93 -0
- package/lib/cjs/types/testing/load-test.d.ts +139 -0
- package/lib/cjs/types/testing/matchers.d.ts +184 -0
- package/lib/cjs/types/testing/mock-context.d.ts +117 -0
- package/lib/cjs/types/testing/mock-provider.d.ts +93 -0
- package/lib/cjs/types/testing/snapshot-request.d.ts +46 -0
- package/lib/cjs/types/testing/testing.interfaces.d.ts +973 -0
- package/lib/cjs/types/utils/node-require.d.ts +11 -0
- package/lib/cjs/utils/node-require.js +59 -0
- package/lib/esm/application/application-container.js +526 -0
- package/lib/esm/application/application-factory.js +140 -0
- package/lib/esm/application/application.types.js +41 -0
- package/lib/esm/application/bootstrap.js +709 -0
- package/lib/esm/application/index.js +4 -0
- package/lib/esm/authorization/authorization-config.interface.js +1 -0
- package/lib/esm/authorization/decorators/convenience.js +74 -0
- package/lib/esm/authorization/guard-constants.js +9 -0
- package/lib/esm/authorization/guard-decorators.js +155 -0
- package/lib/esm/authorization/guard-executor.js +101 -0
- package/lib/esm/authorization/guard-registry.js +132 -0
- package/lib/esm/authorization/guard.interface.js +73 -0
- package/lib/esm/authorization/guards/attribute-based.guard.js +106 -0
- package/lib/esm/authorization/guards/authenticated.guard.js +45 -0
- package/lib/esm/authorization/guards/composition.guard.js +63 -0
- package/lib/esm/authorization/guards/conditional.guard.js +38 -0
- package/lib/esm/authorization/guards/index.js +8 -0
- package/lib/esm/authorization/guards/permission.guard.js +80 -0
- package/lib/esm/authorization/guards/resource-owner.guard.js +58 -0
- package/lib/esm/authorization/guards/role.guard.js +61 -0
- package/lib/esm/authorization/index.js +24 -0
- package/lib/esm/authorization/services/guard-cache.interface.js +1 -0
- package/lib/esm/authorization/services/guard-cache.js +51 -0
- package/lib/esm/authorization/services/permission-hierarchy.interface.js +1 -0
- package/lib/esm/authorization/services/permission-hierarchy.js +49 -0
- package/lib/esm/authorization/services/permission-service.interface.js +1 -0
- package/lib/esm/authorization/services/permission-service.js +56 -0
- package/lib/esm/authorization/services/security-context.interface.js +1 -0
- package/lib/esm/authorization/services/security-context.js +74 -0
- package/lib/esm/authorization/setup.js +137 -0
- package/lib/esm/config/config-resolver.js +714 -0
- package/lib/esm/config/config.interfaces.js +13 -0
- package/lib/esm/config/define-config.js +492 -0
- package/lib/esm/config/env-field-builders.js +440 -0
- package/lib/esm/config/index.js +72 -0
- package/lib/esm/config/secret-value.js +175 -0
- package/lib/esm/console/color-codes.js +46 -0
- package/lib/esm/console/console.js +107 -0
- package/lib/esm/console/index.js +1 -0
- package/lib/esm/container-module/container-module.js +322 -0
- package/lib/esm/container-module/index.js +1 -0
- package/lib/esm/decorator/index.js +1 -0
- package/lib/esm/decorator/scope-binding.js +344 -0
- package/lib/esm/di/annotation/decorator_utils.js +93 -0
- package/lib/esm/di/annotation/inject.js +18 -0
- package/lib/esm/di/annotation/inject_base.js +14 -0
- package/lib/esm/di/annotation/injectable.js +19 -0
- package/lib/esm/di/annotation/lazy_service_identifier.js +9 -0
- package/lib/esm/di/annotation/multi_inject.js +4 -0
- package/lib/esm/di/annotation/named.js +9 -0
- package/lib/esm/di/annotation/optional.js +7 -0
- package/lib/esm/di/annotation/post_construct.js +5 -0
- package/lib/esm/di/annotation/pre_destroy.js +5 -0
- package/lib/esm/di/annotation/property_event_decorator.js +13 -0
- package/lib/esm/di/annotation/tagged.js +7 -0
- package/lib/esm/di/annotation/target_name.js +10 -0
- package/lib/esm/di/annotation/unmanaged.js +10 -0
- package/lib/esm/di/binding-decorator/constants.js +7 -0
- package/lib/esm/di/binding-decorator/decorator/fluent_provide.js +15 -0
- package/lib/esm/di/binding-decorator/decorator/provide.js +35 -0
- package/lib/esm/di/binding-decorator/factory/module_factory.js +34 -0
- package/lib/esm/di/binding-decorator/index.js +10 -0
- package/lib/esm/di/binding-decorator/interfaces/interfaces.js +1 -0
- package/lib/esm/di/binding-decorator/syntax/provide_done_syntax.js +41 -0
- package/lib/esm/di/binding-decorator/syntax/provide_in_syntax.js +37 -0
- package/lib/esm/di/binding-decorator/syntax/provide_in_when_on_syntax.js +68 -0
- package/lib/esm/di/binding-decorator/syntax/provide_on_syntax.js +19 -0
- package/lib/esm/di/binding-decorator/syntax/provide_when_on_syntax.js +57 -0
- package/lib/esm/di/binding-decorator/syntax/provide_when_syntax.js +86 -0
- package/lib/esm/di/binding-decorator/utils/auto_wire.js +13 -0
- package/lib/esm/di/bindings/binding.js +64 -0
- package/lib/esm/di/bindings/binding_count.js +5 -0
- package/lib/esm/di/constants/error_msgs.js +54 -0
- package/lib/esm/di/constants/literal_types.js +21 -0
- package/lib/esm/di/constants/metadata_keys.js +35 -0
- package/lib/esm/di/container/container.js +505 -0
- package/lib/esm/di/container/container_module.js +17 -0
- package/lib/esm/di/container/container_snapshot.js +17 -0
- package/lib/esm/di/container/lookup.js +108 -0
- package/lib/esm/di/container/module_activation_store.js +43 -0
- package/lib/esm/di/container-introspection.js +38 -0
- package/lib/esm/di/interfaces/interfaces.js +1 -0
- package/lib/esm/di/inversify.js +53 -0
- package/lib/esm/di/planning/context.js +18 -0
- package/lib/esm/di/planning/metadata.js +18 -0
- package/lib/esm/di/planning/metadata_reader.js +19 -0
- package/lib/esm/di/planning/plan.js +9 -0
- package/lib/esm/di/planning/planner.js +159 -0
- package/lib/esm/di/planning/queryable_string.js +25 -0
- package/lib/esm/di/planning/reflection_utils.js +150 -0
- package/lib/esm/di/planning/request.js +28 -0
- package/lib/esm/di/planning/target.js +89 -0
- package/lib/esm/di/resolution/instantiation.js +125 -0
- package/lib/esm/di/resolution/resolver.js +163 -0
- package/lib/esm/di/scope/scope-registry.js +109 -0
- package/lib/esm/di/scope/scope.js +75 -0
- package/lib/esm/di/syntax/binding_in_syntax.js +31 -0
- package/lib/esm/di/syntax/binding_in_when_on_syntax.js +79 -0
- package/lib/esm/di/syntax/binding_on_syntax.js +16 -0
- package/lib/esm/di/syntax/binding_to_syntax.js +89 -0
- package/lib/esm/di/syntax/binding_when_on_syntax.js +64 -0
- package/lib/esm/di/syntax/binding_when_syntax.js +82 -0
- package/lib/esm/di/syntax/constraint_helpers.js +39 -0
- package/lib/esm/di/utils/async.js +12 -0
- package/lib/esm/di/utils/binding_utils.js +48 -0
- package/lib/esm/di/utils/clonable.js +7 -0
- package/lib/esm/di/utils/exceptions.js +18 -0
- package/lib/esm/di/utils/factory_type.js +6 -0
- package/lib/esm/di/utils/id.js +5 -0
- package/lib/esm/di/utils/js.js +12 -0
- package/lib/esm/di/utils/serialization.js +102 -0
- package/lib/esm/error/app-error.js +209 -0
- package/lib/esm/error/base-exception-filter.js +134 -0
- package/lib/esm/error/error-handler-middleware.js +34 -0
- package/lib/esm/error/exception-filter-constants.js +9 -0
- package/lib/esm/error/exception-filter-decorators.js +157 -0
- package/lib/esm/error/exception-filter-registry.js +162 -0
- package/lib/esm/error/exception-filter.interface.js +1 -0
- package/lib/esm/error/exception-handler-middleware.js +378 -0
- package/lib/esm/error/filters/app-error.filter.js +28 -0
- package/lib/esm/error/filters/global-exception.filter.js +36 -0
- package/lib/esm/error/filters/not-found.filter.js +32 -0
- package/lib/esm/error/filters/validation-error.filter.js +32 -0
- package/lib/esm/error/index.js +13 -0
- package/lib/esm/error/not-found.error.js +13 -0
- package/lib/esm/error/report.js +153 -0
- package/lib/esm/error/status-code.js +106 -0
- package/lib/esm/error/utils.js +252 -0
- package/lib/esm/error/validation.error.js +15 -0
- package/lib/esm/event/event-decorators.js +268 -0
- package/lib/esm/event/event-emitter.js +376 -0
- package/lib/esm/event/event-flow-tracker.js +230 -0
- package/lib/esm/event/event-recorder.js +286 -0
- package/lib/esm/event/event-registry.js +201 -0
- package/lib/esm/event/event.interfaces.js +51 -0
- package/lib/esm/event/index.js +58 -0
- package/lib/esm/framework-version.js +7 -0
- package/lib/esm/index.mjs +27 -0
- package/lib/esm/interceptor/conditional-interceptor.js +104 -0
- package/lib/esm/interceptor/execution-context.js +66 -0
- package/lib/esm/interceptor/index.js +48 -0
- package/lib/esm/interceptor/interceptor-composition.js +126 -0
- package/lib/esm/interceptor/interceptor-constants.js +17 -0
- package/lib/esm/interceptor/interceptor-decorators.js +151 -0
- package/lib/esm/interceptor/interceptor-executor.js +139 -0
- package/lib/esm/interceptor/interceptor-registry.js +158 -0
- package/lib/esm/interceptor/interceptor.interface.js +16 -0
- package/lib/esm/interceptor/interceptors/index.js +6 -0
- package/lib/esm/interceptor/interceptors/logging.interceptor.js +68 -0
- package/lib/esm/interceptor/interceptors/performance.interceptor.js +253 -0
- package/lib/esm/interceptor/interceptors/timeout.interceptor.js +65 -0
- package/lib/esm/lazy-loading/index.js +58 -0
- package/lib/esm/lazy-loading/lazy-load-metrics.js +352 -0
- package/lib/esm/lazy-loading/lazy-module-helpers.js +45 -0
- package/lib/esm/lazy-loading/lazy-module-loader.js +305 -0
- package/lib/esm/lazy-loading/lazy-module-manager.js +241 -0
- package/lib/esm/lazy-loading/lazy-module-warmup.js +291 -0
- package/lib/esm/lazy-loading/lazy-module.js +352 -0
- package/lib/esm/lazy-loading/lazy.interfaces.js +17 -0
- package/lib/esm/lifecycle/index.js +9 -0
- package/lib/esm/lifecycle/lifecycle-registry.js +298 -0
- package/lib/esm/lifecycle/lifecycle.interface.js +33 -0
- package/lib/esm/middleware/content-negotiation/accept-header-parser.js +106 -0
- package/lib/esm/middleware/content-negotiation/content-negotiation-service.js +286 -0
- package/lib/esm/middleware/content-negotiation/formatter-registry.js +165 -0
- package/lib/esm/middleware/content-negotiation/formatters/csv-formatter.js +111 -0
- package/lib/esm/middleware/content-negotiation/formatters/index.js +8 -0
- package/lib/esm/middleware/content-negotiation/formatters/json-formatter.js +30 -0
- package/lib/esm/middleware/content-negotiation/formatters/plain-text-formatter.js +40 -0
- package/lib/esm/middleware/content-negotiation/formatters/xml-formatter.js +121 -0
- package/lib/esm/middleware/content-negotiation/formatters/yaml-formatter.js +131 -0
- package/lib/esm/middleware/content-negotiation/index.js +7 -0
- package/lib/esm/middleware/index.js +20 -0
- package/lib/esm/middleware/interfaces/body-parser.interface.js +1 -0
- package/lib/esm/middleware/interfaces/compression.interface.js +1 -0
- package/lib/esm/middleware/interfaces/content-negotiation.interface.js +6 -0
- package/lib/esm/middleware/interfaces/cookie-parser.interface.js +1 -0
- package/lib/esm/middleware/interfaces/cookie-session/cookie-session.interface.js +1 -0
- package/lib/esm/middleware/interfaces/cookie-session/keygrip.interface.js +1 -0
- package/lib/esm/middleware/interfaces/cors.interface.js +1 -0
- package/lib/esm/middleware/interfaces/express-rate-limit.interface.js +1 -0
- package/lib/esm/middleware/interfaces/express-session.interface.js +1 -0
- package/lib/esm/middleware/interfaces/helmet.interface.js +1 -0
- package/lib/esm/middleware/interfaces/morgan.interface.js +1 -0
- package/lib/esm/middleware/interfaces/multer.interface.js +1 -0
- package/lib/esm/middleware/interfaces/serve-favicon.interface.js +1 -0
- package/lib/esm/middleware/interfaces/serve-static.interface.js +1 -0
- package/lib/esm/middleware/interfaces/url-encoded.interface.js +1 -0
- package/lib/esm/middleware/middleware-config.js +9 -0
- package/lib/esm/middleware/middleware-interface.js +1 -0
- package/lib/esm/middleware/middleware-profiler.js +307 -0
- package/lib/esm/middleware/middleware-registry.js +152 -0
- package/lib/esm/middleware/middleware-resolver.js +320 -0
- package/lib/esm/middleware/middleware-service.js +1853 -0
- package/lib/esm/middleware/middleware-utils.js +273 -0
- package/lib/esm/middleware/presets-standalone.js +87 -0
- package/lib/esm/middleware/upload-registry.js +84 -0
- package/lib/esm/package.json +3 -0
- package/lib/esm/path-resolver/index.js +224 -0
- package/lib/esm/provider/db-in-memory/adapter/adapter.interface.js +9 -0
- package/lib/esm/provider/db-in-memory/adapter/in-memory.adapter.js +690 -0
- package/lib/esm/provider/db-in-memory/adapter/index.js +5 -0
- package/lib/esm/provider/db-in-memory/base-repo.repository.js +54 -0
- package/lib/esm/provider/db-in-memory/db-in-memory.interface.js +1 -0
- package/lib/esm/provider/db-in-memory/db-in-memory.provider.js +104 -0
- package/lib/esm/provider/db-in-memory/db-in-memory.types.js +20 -0
- package/lib/esm/provider/db-in-memory/db.provider.js +405 -0
- package/lib/esm/provider/db-in-memory/index.js +98 -0
- package/lib/esm/provider/db-in-memory/query/index.js +6 -0
- package/lib/esm/provider/db-in-memory/query/query-engine.js +598 -0
- package/lib/esm/provider/db-in-memory/query/query.types.js +9 -0
- package/lib/esm/provider/db-in-memory/schema/decorators.js +405 -0
- package/lib/esm/provider/db-in-memory/schema/entity.interface.js +8 -0
- package/lib/esm/provider/db-in-memory/schema/index.js +5 -0
- package/lib/esm/provider/db-in-memory/storage/index.js +5 -0
- package/lib/esm/provider/db-in-memory/storage/memory-store.js +784 -0
- package/lib/esm/provider/dto-validator/dto-validator.provider.js +49 -0
- package/lib/esm/provider/dto-validator/package-resolver.js +30 -0
- package/lib/esm/provider/index.js +7 -0
- package/lib/esm/provider/logger/decorators/index.js +1 -0
- package/lib/esm/provider/logger/decorators/log-performance.decorator.js +175 -0
- package/lib/esm/provider/logger/index.js +17 -0
- package/lib/esm/provider/logger/logger.banner.js +480 -0
- package/lib/esm/provider/logger/logger.config.js +29 -0
- package/lib/esm/provider/logger/logger.context.js +334 -0
- package/lib/esm/provider/logger/logger.flow.js +248 -0
- package/lib/esm/provider/logger/logger.formatter.js +691 -0
- package/lib/esm/provider/logger/logger.grouping.js +314 -0
- package/lib/esm/provider/logger/logger.health.js +291 -0
- package/lib/esm/provider/logger/logger.metrics-collector.js +180 -0
- package/lib/esm/provider/logger/logger.metrics.js +85 -0
- package/lib/esm/provider/logger/logger.performance.js +299 -0
- package/lib/esm/provider/logger/logger.provider.js +797 -0
- package/lib/esm/provider/logger/logger.query.js +529 -0
- package/lib/esm/provider/logger/logger.redaction.js +450 -0
- package/lib/esm/provider/logger/logger.suggestions.js +471 -0
- package/lib/esm/provider/logger/transports/console.transport.js +144 -0
- package/lib/esm/provider/logger/transports/file.transport.js +300 -0
- package/lib/esm/provider/logger/transports/http-server.js +141 -0
- package/lib/esm/provider/logger/transports/http.transport.js +157 -0
- package/lib/esm/provider/logger/transports/index.js +5 -0
- package/lib/esm/provider/logger/transports/transport.interface.js +1 -0
- package/lib/esm/provider/logger/utils/index.js +2 -0
- package/lib/esm/provider/logger/utils/log-entry.js +23 -0
- package/lib/esm/provider/logger/utils/log-levels.js +101 -0
- package/lib/esm/provider/provider-manager.js +283 -0
- package/lib/esm/provider/provider-registry.js +411 -0
- package/lib/esm/provider/provider.interface.js +44 -0
- package/lib/esm/provider/validation/adapters/class-validator.adapter.js +258 -0
- package/lib/esm/provider/validation/adapters/index.js +13 -0
- package/lib/esm/provider/validation/adapters/yup.adapter.js +111 -0
- package/lib/esm/provider/validation/adapters/zod.adapter.js +130 -0
- package/lib/esm/provider/validation/helpful-error-formatter.js +225 -0
- package/lib/esm/provider/validation/index.js +21 -0
- package/lib/esm/provider/validation/smart-field-detector.js +539 -0
- package/lib/esm/provider/validation/type-inference.js +183 -0
- package/lib/esm/provider/validation/validation-registry.js +214 -0
- package/lib/esm/provider/validation/validation.interface.js +8 -0
- package/lib/esm/render/adapters/base-adapter.js +131 -0
- package/lib/esm/render/adapters/ejs-adapter.js +142 -0
- package/lib/esm/render/adapters/handlebars-adapter.js +161 -0
- package/lib/esm/render/adapters/index.js +12 -0
- package/lib/esm/render/adapters/pug-adapter.js +134 -0
- package/lib/esm/render/adapters/react-adapter.js +303 -0
- package/lib/esm/render/features/auto-detection.js +202 -0
- package/lib/esm/render/features/hot-reload.js +153 -0
- package/lib/esm/render/features/index.js +12 -0
- package/lib/esm/render/features/streaming.js +103 -0
- package/lib/esm/render/features/type-generator.js +195 -0
- package/lib/esm/render/features/view-debugger.js +192 -0
- package/lib/esm/render/index.js +54 -0
- package/lib/esm/render/presets/index.js +207 -0
- package/lib/esm/render/render-config.js +9 -0
- package/lib/esm/render/render-interface.js +1 -0
- package/lib/esm/render/render-registry.js +124 -0
- package/lib/esm/render/render-service.js +394 -0
- package/lib/esm/render/utils/cache-manager.js +196 -0
- package/lib/esm/render/utils/index.js +10 -0
- package/lib/esm/render/utils/package-resolver.js +118 -0
- package/lib/esm/render/utils/view-scanner.js +178 -0
- package/lib/esm/testing/create-test-app.js +365 -0
- package/lib/esm/testing/create-test-database.js +411 -0
- package/lib/esm/testing/fluent-request.js +459 -0
- package/lib/esm/testing/index.js +102 -0
- package/lib/esm/testing/load-test.js +479 -0
- package/lib/esm/testing/matchers.js +440 -0
- package/lib/esm/testing/mock-context.js +400 -0
- package/lib/esm/testing/mock-provider.js +333 -0
- package/lib/esm/testing/snapshot-request.js +358 -0
- package/lib/esm/testing/testing.interfaces.js +9 -0
- package/lib/esm/types/application/application-container.d.ts +352 -0
- package/lib/esm/types/application/application-factory.d.ts +124 -0
- package/lib/esm/types/application/application.types.d.ts +185 -0
- package/lib/esm/types/application/bootstrap.d.ts +656 -0
- package/lib/esm/types/application/index.d.ts +4 -0
- package/lib/esm/types/authorization/authorization-config.interface.d.ts +45 -0
- package/lib/esm/types/authorization/decorators/convenience.d.ts +64 -0
- package/lib/esm/types/authorization/guard-constants.d.ts +9 -0
- package/lib/esm/types/authorization/guard-decorators.d.ts +128 -0
- package/lib/esm/types/authorization/guard-executor.d.ts +26 -0
- package/lib/esm/types/authorization/guard-registry.d.ts +35 -0
- package/lib/esm/types/authorization/guard.interface.d.ts +335 -0
- package/lib/esm/types/authorization/guards/attribute-based.guard.d.ts +60 -0
- package/lib/esm/types/authorization/guards/authenticated.guard.d.ts +26 -0
- package/lib/esm/types/authorization/guards/composition.guard.d.ts +42 -0
- package/lib/esm/types/authorization/guards/conditional.guard.d.ts +21 -0
- package/lib/esm/types/authorization/guards/index.d.ts +7 -0
- package/lib/esm/types/authorization/guards/permission.guard.d.ts +29 -0
- package/lib/esm/types/authorization/guards/resource-owner.guard.d.ts +29 -0
- package/lib/esm/types/authorization/guards/role.guard.d.ts +28 -0
- package/lib/esm/types/authorization/index.d.ts +18 -0
- package/lib/esm/types/authorization/services/guard-cache.d.ts +26 -0
- package/lib/esm/types/authorization/services/guard-cache.interface.d.ts +29 -0
- package/lib/esm/types/authorization/services/permission-hierarchy.d.ts +21 -0
- package/lib/esm/types/authorization/services/permission-hierarchy.interface.d.ts +22 -0
- package/lib/esm/types/authorization/services/permission-service.d.ts +21 -0
- package/lib/esm/types/authorization/services/permission-service.interface.d.ts +19 -0
- package/lib/esm/types/authorization/services/security-context.d.ts +32 -0
- package/lib/esm/types/authorization/services/security-context.interface.d.ts +25 -0
- package/lib/esm/types/authorization/setup.d.ts +84 -0
- package/lib/esm/types/config/config-resolver.d.ts +40 -0
- package/lib/esm/types/config/config.interfaces.d.ts +576 -0
- package/lib/esm/types/config/define-config.d.ts +109 -0
- package/lib/esm/types/config/env-field-builders.d.ts +327 -0
- package/lib/esm/types/config/index.d.ts +61 -0
- package/lib/esm/types/config/secret-value.d.ts +99 -0
- package/lib/esm/types/console/color-codes.d.ts +29 -0
- package/lib/esm/types/console/console.d.ts +83 -0
- package/lib/esm/types/console/index.d.ts +2 -0
- package/lib/esm/types/container-module/container-module.d.ts +242 -0
- package/lib/esm/types/container-module/index.d.ts +1 -0
- package/lib/esm/types/decorator/index.d.ts +1 -0
- package/lib/esm/types/decorator/scope-binding.d.ts +374 -0
- package/lib/esm/types/di/annotation/decorator_utils.d.ts +16 -0
- package/lib/esm/types/di/annotation/inject.d.ts +16 -0
- package/lib/esm/types/di/annotation/inject_base.d.ts +3 -0
- package/lib/esm/types/di/annotation/injectable.d.ts +7 -0
- package/lib/esm/types/di/annotation/lazy_service_identifier.d.ts +7 -0
- package/lib/esm/types/di/annotation/multi_inject.d.ts +2 -0
- package/lib/esm/types/di/annotation/named.d.ts +2 -0
- package/lib/esm/types/di/annotation/optional.d.ts +2 -0
- package/lib/esm/types/di/annotation/post_construct.d.ts +4 -0
- package/lib/esm/types/di/annotation/pre_destroy.d.ts +4 -0
- package/lib/esm/types/di/annotation/property_event_decorator.d.ts +4 -0
- package/lib/esm/types/di/annotation/tagged.d.ts +2 -0
- package/lib/esm/types/di/annotation/target_name.d.ts +3 -0
- package/lib/esm/types/di/annotation/unmanaged.d.ts +3 -0
- package/lib/esm/types/di/binding-decorator/constants.d.ts +7 -0
- package/lib/esm/types/di/binding-decorator/decorator/fluent_provide.d.ts +4 -0
- package/lib/esm/types/di/binding-decorator/decorator/provide.d.ts +4 -0
- package/lib/esm/types/di/binding-decorator/factory/module_factory.d.ts +23 -0
- package/lib/esm/types/di/binding-decorator/index.d.ts +10 -0
- package/lib/esm/types/di/binding-decorator/interfaces/interfaces.d.ts +40 -0
- package/lib/esm/types/di/binding-decorator/syntax/provide_done_syntax.d.ts +7 -0
- package/lib/esm/types/di/binding-decorator/syntax/provide_in_syntax.d.ts +12 -0
- package/lib/esm/types/di/binding-decorator/syntax/provide_in_when_on_syntax.d.ts +28 -0
- package/lib/esm/types/di/binding-decorator/syntax/provide_on_syntax.d.ts +10 -0
- package/lib/esm/types/di/binding-decorator/syntax/provide_when_on_syntax.d.ts +24 -0
- package/lib/esm/types/di/binding-decorator/syntax/provide_when_syntax.d.ts +23 -0
- package/lib/esm/types/di/binding-decorator/utils/auto_wire.d.ts +3 -0
- package/lib/esm/types/di/bindings/binding.d.ts +20 -0
- package/lib/esm/types/di/bindings/binding_count.d.ts +5 -0
- package/lib/esm/types/di/constants/error_msgs.d.ts +32 -0
- package/lib/esm/types/di/constants/literal_types.d.ts +5 -0
- package/lib/esm/types/di/constants/metadata_keys.d.ts +13 -0
- package/lib/esm/types/di/container/container.d.ts +73 -0
- package/lib/esm/types/di/container/container_module.d.ts +11 -0
- package/lib/esm/types/di/container/container_snapshot.d.ts +10 -0
- package/lib/esm/types/di/container/lookup.d.ts +16 -0
- package/lib/esm/types/di/container/module_activation_store.d.ts +10 -0
- package/lib/esm/types/di/container-introspection.d.ts +25 -0
- package/lib/esm/types/di/interfaces/interfaces.d.ts +300 -0
- package/lib/esm/types/di/inversify.d.ts +54 -0
- package/lib/esm/types/di/planning/context.d.ts +11 -0
- package/lib/esm/types/di/planning/metadata.d.ts +8 -0
- package/lib/esm/types/di/planning/metadata_reader.d.ts +6 -0
- package/lib/esm/types/di/planning/plan.d.ts +7 -0
- package/lib/esm/types/di/planning/planner.d.ts +5 -0
- package/lib/esm/types/di/planning/queryable_string.d.ts +11 -0
- package/lib/esm/types/di/planning/reflection_utils.d.ts +5 -0
- package/lib/esm/types/di/planning/request.d.ts +14 -0
- package/lib/esm/types/di/planning/target.d.ts +23 -0
- package/lib/esm/types/di/resolution/instantiation.d.ts +3 -0
- package/lib/esm/types/di/resolution/resolver.d.ts +3 -0
- package/lib/esm/types/di/scope/scope-registry.d.ts +91 -0
- package/lib/esm/types/di/scope/scope.d.ts +3 -0
- package/lib/esm/types/di/syntax/binding_in_syntax.d.ts +10 -0
- package/lib/esm/types/di/syntax/binding_in_when_on_syntax.d.ts +30 -0
- package/lib/esm/types/di/syntax/binding_on_syntax.d.ts +8 -0
- package/lib/esm/types/di/syntax/binding_to_syntax.d.ts +18 -0
- package/lib/esm/types/di/syntax/binding_when_on_syntax.d.ts +25 -0
- package/lib/esm/types/di/syntax/binding_when_syntax.d.ts +21 -0
- package/lib/esm/types/di/syntax/constraint_helpers.d.ts +6 -0
- package/lib/esm/types/di/utils/async.d.ts +3 -0
- package/lib/esm/types/di/utils/binding_utils.d.ts +4 -0
- package/lib/esm/types/di/utils/clonable.d.ts +3 -0
- package/lib/esm/types/di/utils/exceptions.d.ts +2 -0
- package/lib/esm/types/di/utils/factory_type.d.ts +5 -0
- package/lib/esm/types/di/utils/id.d.ts +2 -0
- package/lib/esm/types/di/utils/js.d.ts +1 -0
- package/lib/esm/types/di/utils/serialization.d.ts +10 -0
- package/lib/esm/types/error/app-error.d.ts +177 -0
- package/lib/esm/types/error/base-exception-filter.d.ts +73 -0
- package/lib/esm/types/error/error-handler-middleware.d.ts +11 -0
- package/lib/esm/types/error/exception-filter-constants.d.ts +9 -0
- package/lib/esm/types/error/exception-filter-decorators.d.ts +126 -0
- package/lib/esm/types/error/exception-filter-registry.d.ts +38 -0
- package/lib/esm/types/error/exception-filter.interface.d.ts +82 -0
- package/lib/esm/types/error/exception-handler-middleware.d.ts +35 -0
- package/lib/esm/types/error/filters/app-error.filter.d.ts +10 -0
- package/lib/esm/types/error/filters/global-exception.filter.d.ts +9 -0
- package/lib/esm/types/error/filters/not-found.filter.d.ts +10 -0
- package/lib/esm/types/error/filters/validation-error.filter.d.ts +10 -0
- package/lib/esm/types/error/index.d.ts +14 -0
- package/lib/esm/types/error/not-found.error.d.ts +7 -0
- package/lib/esm/types/error/report.d.ts +105 -0
- package/lib/esm/types/error/status-code.d.ts +156 -0
- package/lib/esm/types/error/utils.d.ts +17 -0
- package/lib/esm/types/error/validation.error.d.ts +8 -0
- package/lib/esm/types/event/event-decorators.d.ts +199 -0
- package/lib/esm/types/event/event-emitter.d.ts +109 -0
- package/lib/esm/types/event/event-flow-tracker.d.ts +88 -0
- package/lib/esm/types/event/event-recorder.d.ts +121 -0
- package/lib/esm/types/event/event-registry.d.ts +84 -0
- package/lib/esm/types/event/event.interfaces.d.ts +528 -0
- package/lib/esm/types/event/index.d.ts +55 -0
- package/lib/esm/types/framework-version.d.ts +7 -0
- package/lib/esm/types/index.d.ts +27 -0
- package/lib/esm/types/interceptor/conditional-interceptor.d.ts +91 -0
- package/lib/esm/types/interceptor/execution-context.d.ts +41 -0
- package/lib/esm/types/interceptor/index.d.ts +41 -0
- package/lib/esm/types/interceptor/interceptor-composition.d.ts +115 -0
- package/lib/esm/types/interceptor/interceptor-constants.d.ts +17 -0
- package/lib/esm/types/interceptor/interceptor-decorators.d.ts +124 -0
- package/lib/esm/types/interceptor/interceptor-executor.d.ts +46 -0
- package/lib/esm/types/interceptor/interceptor-registry.d.ts +65 -0
- package/lib/esm/types/interceptor/interceptor.interface.d.ts +281 -0
- package/lib/esm/types/interceptor/interceptors/index.d.ts +6 -0
- package/lib/esm/types/interceptor/interceptors/logging.interceptor.d.ts +28 -0
- package/lib/esm/types/interceptor/interceptors/performance.interceptor.d.ts +197 -0
- package/lib/esm/types/interceptor/interceptors/timeout.interceptor.d.ts +42 -0
- package/lib/esm/types/lazy-loading/index.d.ts +43 -0
- package/lib/esm/types/lazy-loading/lazy-load-metrics.d.ts +139 -0
- package/lib/esm/types/lazy-loading/lazy-module-helpers.d.ts +42 -0
- package/lib/esm/types/lazy-loading/lazy-module-loader.d.ts +169 -0
- package/lib/esm/types/lazy-loading/lazy-module-manager.d.ts +148 -0
- package/lib/esm/types/lazy-loading/lazy-module-warmup.d.ts +130 -0
- package/lib/esm/types/lazy-loading/lazy-module.d.ts +168 -0
- package/lib/esm/types/lazy-loading/lazy.interfaces.d.ts +480 -0
- package/lib/esm/types/lifecycle/index.d.ts +9 -0
- package/lib/esm/types/lifecycle/lifecycle-registry.d.ts +213 -0
- package/lib/esm/types/lifecycle/lifecycle.interface.d.ts +191 -0
- package/lib/esm/types/middleware/content-negotiation/accept-header-parser.d.ts +26 -0
- package/lib/esm/types/middleware/content-negotiation/content-negotiation-service.d.ts +64 -0
- package/lib/esm/types/middleware/content-negotiation/formatter-registry.d.ts +60 -0
- package/lib/esm/types/middleware/content-negotiation/formatters/csv-formatter.d.ts +34 -0
- package/lib/esm/types/middleware/content-negotiation/formatters/index.d.ts +8 -0
- package/lib/esm/types/middleware/content-negotiation/formatters/json-formatter.d.ts +14 -0
- package/lib/esm/types/middleware/content-negotiation/formatters/plain-text-formatter.d.ts +12 -0
- package/lib/esm/types/middleware/content-negotiation/formatters/xml-formatter.d.ts +26 -0
- package/lib/esm/types/middleware/content-negotiation/formatters/yaml-formatter.d.ts +26 -0
- package/lib/esm/types/middleware/content-negotiation/index.d.ts +7 -0
- package/lib/esm/types/middleware/index.d.ts +25 -0
- package/lib/esm/types/middleware/interfaces/body-parser.interface.d.ts +31 -0
- package/lib/esm/types/middleware/interfaces/compression.interface.d.ts +98 -0
- package/lib/esm/types/middleware/interfaces/content-negotiation.interface.d.ts +142 -0
- package/lib/esm/types/middleware/interfaces/cookie-parser.interface.d.ts +9 -0
- package/lib/esm/types/middleware/interfaces/cookie-session/cookie-session.interface.d.ts +57 -0
- package/lib/esm/types/middleware/interfaces/cookie-session/keygrip.interface.d.ts +27 -0
- package/lib/esm/types/middleware/interfaces/cors.interface.d.ts +57 -0
- package/lib/esm/types/middleware/interfaces/express-rate-limit.interface.d.ts +292 -0
- package/lib/esm/types/middleware/interfaces/express-session.interface.d.ts +207 -0
- package/lib/esm/types/middleware/interfaces/helmet.interface.d.ts +210 -0
- package/lib/esm/types/middleware/interfaces/morgan.interface.d.ts +39 -0
- package/lib/esm/types/middleware/interfaces/multer.interface.d.ts +253 -0
- package/lib/esm/types/middleware/interfaces/serve-favicon.interface.d.ts +11 -0
- package/lib/esm/types/middleware/interfaces/serve-static.interface.d.ts +69 -0
- package/lib/esm/types/middleware/interfaces/url-encoded.interface.d.ts +37 -0
- package/lib/esm/types/middleware/middleware-config.d.ts +574 -0
- package/lib/esm/types/middleware/middleware-interface.d.ts +691 -0
- package/lib/esm/types/middleware/middleware-profiler.d.ts +199 -0
- package/lib/esm/types/middleware/middleware-registry.d.ts +103 -0
- package/lib/esm/types/middleware/middleware-resolver.d.ts +159 -0
- package/lib/esm/types/middleware/middleware-service.d.ts +788 -0
- package/lib/esm/types/middleware/middleware-utils.d.ts +145 -0
- package/lib/esm/types/middleware/presets-standalone.d.ts +75 -0
- package/lib/esm/types/middleware/upload-registry.d.ts +50 -0
- package/lib/esm/types/path-resolver/index.d.ts +80 -0
- package/lib/esm/types/provider/db-in-memory/adapter/adapter.interface.d.ts +222 -0
- package/lib/esm/types/provider/db-in-memory/adapter/in-memory.adapter.d.ts +241 -0
- package/lib/esm/types/provider/db-in-memory/adapter/index.d.ts +6 -0
- package/lib/esm/types/provider/db-in-memory/base-repo.repository.d.ts +18 -0
- package/lib/esm/types/provider/db-in-memory/db-in-memory.interface.d.ts +43 -0
- package/lib/esm/types/provider/db-in-memory/db-in-memory.provider.d.ts +39 -0
- package/lib/esm/types/provider/db-in-memory/db-in-memory.types.d.ts +14 -0
- package/lib/esm/types/provider/db-in-memory/db.provider.d.ts +281 -0
- package/lib/esm/types/provider/db-in-memory/index.d.ts +71 -0
- package/lib/esm/types/provider/db-in-memory/query/index.d.ts +6 -0
- package/lib/esm/types/provider/db-in-memory/query/query-engine.d.ts +114 -0
- package/lib/esm/types/provider/db-in-memory/query/query.types.d.ts +318 -0
- package/lib/esm/types/provider/db-in-memory/schema/decorators.d.ts +328 -0
- package/lib/esm/types/provider/db-in-memory/schema/entity.interface.d.ts +60 -0
- package/lib/esm/types/provider/db-in-memory/schema/index.d.ts +6 -0
- package/lib/esm/types/provider/db-in-memory/storage/index.d.ts +5 -0
- package/lib/esm/types/provider/db-in-memory/storage/memory-store.d.ts +360 -0
- package/lib/esm/types/provider/dto-validator/dto-validator.provider.d.ts +10 -0
- package/lib/esm/types/provider/dto-validator/package-resolver.d.ts +7 -0
- package/lib/esm/types/provider/index.d.ts +7 -0
- package/lib/esm/types/provider/logger/decorators/index.d.ts +1 -0
- package/lib/esm/types/provider/logger/decorators/log-performance.decorator.d.ts +49 -0
- package/lib/esm/types/provider/logger/index.d.ts +17 -0
- package/lib/esm/types/provider/logger/logger.banner.d.ts +94 -0
- package/lib/esm/types/provider/logger/logger.config.d.ts +62 -0
- package/lib/esm/types/provider/logger/logger.context.d.ts +189 -0
- package/lib/esm/types/provider/logger/logger.flow.d.ts +165 -0
- package/lib/esm/types/provider/logger/logger.formatter.d.ts +54 -0
- package/lib/esm/types/provider/logger/logger.grouping.d.ts +124 -0
- package/lib/esm/types/provider/logger/logger.health.d.ts +123 -0
- package/lib/esm/types/provider/logger/logger.metrics-collector.d.ts +44 -0
- package/lib/esm/types/provider/logger/logger.metrics.d.ts +162 -0
- package/lib/esm/types/provider/logger/logger.performance.d.ts +179 -0
- package/lib/esm/types/provider/logger/logger.provider.d.ts +363 -0
- package/lib/esm/types/provider/logger/logger.query.d.ts +232 -0
- package/lib/esm/types/provider/logger/logger.redaction.d.ts +169 -0
- package/lib/esm/types/provider/logger/logger.suggestions.d.ts +124 -0
- package/lib/esm/types/provider/logger/transports/console.transport.d.ts +56 -0
- package/lib/esm/types/provider/logger/transports/file.transport.d.ts +87 -0
- package/lib/esm/types/provider/logger/transports/http-server.d.ts +88 -0
- package/lib/esm/types/provider/logger/transports/http.transport.d.ts +74 -0
- package/lib/esm/types/provider/logger/transports/index.d.ts +5 -0
- package/lib/esm/types/provider/logger/transports/transport.interface.d.ts +31 -0
- package/lib/esm/types/provider/logger/utils/index.d.ts +2 -0
- package/lib/esm/types/provider/logger/utils/log-entry.d.ts +82 -0
- package/lib/esm/types/provider/logger/utils/log-levels.d.ts +53 -0
- package/lib/esm/types/provider/provider-manager.d.ts +208 -0
- package/lib/esm/types/provider/provider-registry.d.ts +192 -0
- package/lib/esm/types/provider/provider.interface.d.ts +337 -0
- package/lib/esm/types/provider/validation/adapters/class-validator.adapter.d.ts +68 -0
- package/lib/esm/types/provider/validation/adapters/index.d.ts +13 -0
- package/lib/esm/types/provider/validation/adapters/yup.adapter.d.ts +65 -0
- package/lib/esm/types/provider/validation/adapters/zod.adapter.d.ts +84 -0
- package/lib/esm/types/provider/validation/helpful-error-formatter.d.ts +110 -0
- package/lib/esm/types/provider/validation/index.d.ts +19 -0
- package/lib/esm/types/provider/validation/smart-field-detector.d.ts +91 -0
- package/lib/esm/types/provider/validation/type-inference.d.ts +81 -0
- package/lib/esm/types/provider/validation/validation-registry.d.ts +105 -0
- package/lib/esm/types/provider/validation/validation.interface.d.ts +178 -0
- package/lib/esm/types/render/adapters/base-adapter.d.ts +95 -0
- package/lib/esm/types/render/adapters/ejs-adapter.d.ts +57 -0
- package/lib/esm/types/render/adapters/handlebars-adapter.d.ts +74 -0
- package/lib/esm/types/render/adapters/index.d.ts +12 -0
- package/lib/esm/types/render/adapters/pug-adapter.d.ts +57 -0
- package/lib/esm/types/render/adapters/react-adapter.d.ts +99 -0
- package/lib/esm/types/render/features/auto-detection.d.ts +58 -0
- package/lib/esm/types/render/features/hot-reload.d.ts +65 -0
- package/lib/esm/types/render/features/index.d.ts +12 -0
- package/lib/esm/types/render/features/streaming.d.ts +39 -0
- package/lib/esm/types/render/features/type-generator.d.ts +64 -0
- package/lib/esm/types/render/features/view-debugger.d.ts +52 -0
- package/lib/esm/types/render/index.d.ts +50 -0
- package/lib/esm/types/render/presets/index.d.ts +119 -0
- package/lib/esm/types/render/render-config.d.ts +213 -0
- package/lib/esm/types/render/render-interface.d.ts +126 -0
- package/lib/esm/types/render/render-registry.d.ts +86 -0
- package/lib/esm/types/render/render-service.d.ts +157 -0
- package/lib/esm/types/render/utils/cache-manager.d.ts +106 -0
- package/lib/esm/types/render/utils/index.d.ts +11 -0
- package/lib/esm/types/render/utils/package-resolver.d.ts +57 -0
- package/lib/esm/types/render/utils/view-scanner.d.ts +74 -0
- package/lib/esm/types/testing/create-test-app.d.ts +71 -0
- package/lib/esm/types/testing/create-test-database.d.ts +100 -0
- package/lib/esm/types/testing/fluent-request.d.ts +37 -0
- package/lib/esm/types/testing/index.d.ts +93 -0
- package/lib/esm/types/testing/load-test.d.ts +139 -0
- package/lib/esm/types/testing/matchers.d.ts +184 -0
- package/lib/esm/types/testing/mock-context.d.ts +117 -0
- package/lib/esm/types/testing/mock-provider.d.ts +93 -0
- package/lib/esm/types/testing/snapshot-request.d.ts +46 -0
- package/lib/esm/types/testing/testing.interfaces.d.ts +973 -0
- package/lib/esm/types/utils/node-require.d.ts +11 -0
- package/lib/esm/utils/node-require.js +56 -0
- package/lib/package.json +167 -151
- package/package.json +167 -151
- package/lib/cjs/provider/environment/env-validator.provider.js +0 -100
- package/lib/cjs/types/provider/environment/env-validator.provider.d.ts +0 -39
|
@@ -0,0 +1,1853 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { static as expressStatic, json, urlencoded, } from "express";
|
|
8
|
+
import { injectable } from "../di/inversify.js";
|
|
9
|
+
import defaultErrorHandler from "../error/error-handler-middleware.js";
|
|
10
|
+
import { ExceptionHandlerMiddleware } from "../error/exception-handler-middleware.js";
|
|
11
|
+
import { Logger } from "../provider/logger/logger.provider.js";
|
|
12
|
+
import { middlewareResolver, isMiddlewareAvailable, isPackageAvailable, resolvePackage, getResolverStartupWarnings, clearResolverStartupWarnings, } from "./middleware-resolver.js";
|
|
13
|
+
import { getMiddlewareRegistry, } from "./middleware-registry.js";
|
|
14
|
+
import { setGlobalUploadConfig } from "./upload-registry.js";
|
|
15
|
+
import { ContentNegotiationService } from "./content-negotiation/content-negotiation-service.js";
|
|
16
|
+
import { MiddlewareProfiler, } from "./middleware-profiler.js";
|
|
17
|
+
/**
|
|
18
|
+
* Abstract class for creating custom Expresso middleware.
|
|
19
|
+
*
|
|
20
|
+
* @layer public
|
|
21
|
+
* @audience application-developers
|
|
22
|
+
* @concept custom-middleware
|
|
23
|
+
* @difficulty intermediate
|
|
24
|
+
*
|
|
25
|
+
* @summary Quick Start
|
|
26
|
+
* Create custom middleware classes by extending this abstract class.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* class AuthMiddleware extends ExpressoMiddleware {
|
|
31
|
+
* use(req: Request, res: Response, next: NextFunction): void {
|
|
32
|
+
* const token = req.headers.authorization;
|
|
33
|
+
* if (!token) {
|
|
34
|
+
* return res.status(401).json({ error: "Unauthorized" });
|
|
35
|
+
* }
|
|
36
|
+
* next();
|
|
37
|
+
* }
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* // Use in application
|
|
41
|
+
* services.Middleware.addMiddleware(new AuthMiddleware());
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @layer internal
|
|
45
|
+
* @audience framework-developers
|
|
46
|
+
*
|
|
47
|
+
* **Internal Behavior**
|
|
48
|
+
* - Provides `name` getter (returns constructor name)
|
|
49
|
+
* - Abstract `use()` method must be implemented
|
|
50
|
+
* - Compatible with Express middleware signature
|
|
51
|
+
*
|
|
52
|
+
* @see {@link IMiddleware.addMiddleware} for adding middleware
|
|
53
|
+
*
|
|
54
|
+
* @public API
|
|
55
|
+
*/
|
|
56
|
+
let ExpressoMiddleware = class ExpressoMiddleware {
|
|
57
|
+
get name() {
|
|
58
|
+
return this.constructor.name;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
ExpressoMiddleware = __decorate([
|
|
62
|
+
injectable()
|
|
63
|
+
], ExpressoMiddleware);
|
|
64
|
+
export { ExpressoMiddleware };
|
|
65
|
+
/**
|
|
66
|
+
* MiddlewareType Enum
|
|
67
|
+
*
|
|
68
|
+
* The MiddlewareType enum represents the various types of middleware that can be added to the middleware collection.
|
|
69
|
+
* - Config: Middleware configuration object.
|
|
70
|
+
* - ExpressHandler: Express request handler function.
|
|
71
|
+
* - IExpressoMiddleware: Custom Expresso middleware.
|
|
72
|
+
*/
|
|
73
|
+
var MiddlewareType;
|
|
74
|
+
(function (MiddlewareType) {
|
|
75
|
+
MiddlewareType[MiddlewareType["Config"] = 0] = "Config";
|
|
76
|
+
MiddlewareType[MiddlewareType["ExpressHandler"] = 1] = "ExpressHandler";
|
|
77
|
+
MiddlewareType[MiddlewareType["IExpressoMiddleware"] = 2] = "IExpressoMiddleware";
|
|
78
|
+
})(MiddlewareType || (MiddlewareType = {}));
|
|
79
|
+
/**
|
|
80
|
+
* Mapping of known middleware names to categories.
|
|
81
|
+
*/
|
|
82
|
+
const MIDDLEWARE_CATEGORIES = {
|
|
83
|
+
// Parsers
|
|
84
|
+
jsonParser: "parser",
|
|
85
|
+
urlencodedParser: "parser",
|
|
86
|
+
bodyParser: "parser",
|
|
87
|
+
cookieParser: "parser",
|
|
88
|
+
// Security
|
|
89
|
+
cors: "security",
|
|
90
|
+
helmet: "security",
|
|
91
|
+
rateLimit: "security",
|
|
92
|
+
// Session
|
|
93
|
+
session: "session",
|
|
94
|
+
cookieSession: "session",
|
|
95
|
+
// Logging
|
|
96
|
+
morgan: "logging",
|
|
97
|
+
RequestLoggingMiddleware: "logging",
|
|
98
|
+
// Static
|
|
99
|
+
serveStatic: "static",
|
|
100
|
+
serveFavicon: "static",
|
|
101
|
+
// Compression/Other
|
|
102
|
+
compression: "other",
|
|
103
|
+
multer: "other",
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Category icons for visual pipeline display.
|
|
107
|
+
*/
|
|
108
|
+
const CATEGORY_ICONS = {
|
|
109
|
+
parser: "📦",
|
|
110
|
+
security: "🔒",
|
|
111
|
+
logging: "📝",
|
|
112
|
+
validation: "✅",
|
|
113
|
+
error: "⚠️",
|
|
114
|
+
session: "🔑",
|
|
115
|
+
static: "📁",
|
|
116
|
+
other: "⚙️",
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Middleware service for managing Express middleware pipeline.
|
|
120
|
+
*
|
|
121
|
+
* @layer public
|
|
122
|
+
* @audience application-developers
|
|
123
|
+
* @concept middleware-management
|
|
124
|
+
* @difficulty beginner
|
|
125
|
+
*
|
|
126
|
+
* @summary Quick Start
|
|
127
|
+
* Configure and manage middleware for your ExpressoTS application.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* @provide(App)
|
|
132
|
+
* export class App extends AppFactory {
|
|
133
|
+
* configureServices(services: IService): void {
|
|
134
|
+
* // Add built-in middleware
|
|
135
|
+
* services.Middleware.addCors();
|
|
136
|
+
* services.Middleware.addBodyParser();
|
|
137
|
+
* services.Middleware.addHelmet();
|
|
138
|
+
*
|
|
139
|
+
* // Add custom middleware
|
|
140
|
+
* services.Middleware.addMiddleware((req, res, next) => {
|
|
141
|
+
* // Custom logic
|
|
142
|
+
* next();
|
|
143
|
+
* });
|
|
144
|
+
* }
|
|
145
|
+
* }
|
|
146
|
+
* ```
|
|
147
|
+
*
|
|
148
|
+
* **Features:**
|
|
149
|
+
* - Built-in middleware helpers (CORS, Helmet, Body Parser, etc.)
|
|
150
|
+
* - Custom middleware support
|
|
151
|
+
* - Middleware presets for common configurations
|
|
152
|
+
* - Conditional middleware execution
|
|
153
|
+
* - Content negotiation
|
|
154
|
+
* - Request validation
|
|
155
|
+
* - Performance profiling
|
|
156
|
+
*
|
|
157
|
+
* @layer internal
|
|
158
|
+
* @audience framework-developers
|
|
159
|
+
*
|
|
160
|
+
* **Internal Architecture**
|
|
161
|
+
*
|
|
162
|
+
* Middleware service:
|
|
163
|
+
* - Maintains ordered pipeline array
|
|
164
|
+
* - Uses Map for O(1) middleware lookup
|
|
165
|
+
* - Caches sorted pipeline for performance
|
|
166
|
+
* - Supports conditional middleware execution
|
|
167
|
+
* - Integrates with middleware resolver for auto-discovery
|
|
168
|
+
*
|
|
169
|
+
* **Design Decisions**
|
|
170
|
+
* - Singleton pattern (one instance per app)
|
|
171
|
+
* - Ordered pipeline (insertion order preserved)
|
|
172
|
+
* - Cached sorting (invalidated on changes)
|
|
173
|
+
* - Built-in middleware auto-discovery
|
|
174
|
+
*
|
|
175
|
+
* @see {@link IMiddleware} for interface definition
|
|
176
|
+
* @see {@link middlewareResolver} for middleware resolution
|
|
177
|
+
*
|
|
178
|
+
* @layer advanced
|
|
179
|
+
* @audience power-users
|
|
180
|
+
*
|
|
181
|
+
* **Advanced Usage**
|
|
182
|
+
*
|
|
183
|
+
* Conditional middleware:
|
|
184
|
+
* ```typescript
|
|
185
|
+
* services.Middleware.addConditional({
|
|
186
|
+
* middleware: rateLimiter,
|
|
187
|
+
* condition: (req) => !req.headers["x-internal-service"],
|
|
188
|
+
* name: "conditional-rate-limit"
|
|
189
|
+
* });
|
|
190
|
+
* ```
|
|
191
|
+
*
|
|
192
|
+
* Middleware presets:
|
|
193
|
+
* ```typescript
|
|
194
|
+
* services.Middleware.usePreset("api", {
|
|
195
|
+
* overrides: {
|
|
196
|
+
* Cors: { origin: "https://myapp.com" }
|
|
197
|
+
* }
|
|
198
|
+
* });
|
|
199
|
+
* ```
|
|
200
|
+
*
|
|
201
|
+
* @public API
|
|
202
|
+
*/
|
|
203
|
+
export class Middleware {
|
|
204
|
+
// O(1) lookup map for middleware by name
|
|
205
|
+
middlewareMap = new Map();
|
|
206
|
+
// Ordered pipeline array
|
|
207
|
+
middlewarePipeline = [];
|
|
208
|
+
// Insertion order counter for stable sorting
|
|
209
|
+
insertionOrder = 0;
|
|
210
|
+
// Cached sorted pipeline
|
|
211
|
+
sortedPipelineCache = null;
|
|
212
|
+
// Error handler
|
|
213
|
+
errorHandler;
|
|
214
|
+
// Singleton logger (renamed to avoid conflict with logger() method)
|
|
215
|
+
_logger;
|
|
216
|
+
// Content negotiation service
|
|
217
|
+
contentNegotiationService;
|
|
218
|
+
// Profiler instance
|
|
219
|
+
profiler = null;
|
|
220
|
+
// Profiling enabled flag
|
|
221
|
+
profilingEnabled = false;
|
|
222
|
+
// v4: Custom presets storage
|
|
223
|
+
customPresets = new Map();
|
|
224
|
+
// v4: Last applied preset info (for Studio integration)
|
|
225
|
+
_lastPreset = null;
|
|
226
|
+
// v4: Middleware registry reference
|
|
227
|
+
registry = getMiddlewareRegistry();
|
|
228
|
+
// v4: Buffered startup logs (displayed after banner)
|
|
229
|
+
startupLogs = [];
|
|
230
|
+
// v4: Track registered middleware names for summary
|
|
231
|
+
registeredMiddlewareNames = [];
|
|
232
|
+
constructor() {
|
|
233
|
+
this._logger = new Logger();
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Buffer a startup log message to be displayed after the banner.
|
|
237
|
+
* Only buffers in development mode.
|
|
238
|
+
* @param message - The message to buffer
|
|
239
|
+
* @param type - Log type: "info" or "warn"
|
|
240
|
+
*/
|
|
241
|
+
bufferStartupLog(message, type = "info") {
|
|
242
|
+
this.startupLogs.push({ message, type });
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Get all buffered startup logs for display after the banner.
|
|
246
|
+
* Includes warnings from the middleware resolver (e.g., missing packages).
|
|
247
|
+
* @returns Array of startup log entries
|
|
248
|
+
*/
|
|
249
|
+
getStartupLogs() {
|
|
250
|
+
// Combine service logs with resolver warnings
|
|
251
|
+
const logs = [...this.startupLogs, ...getResolverStartupWarnings()];
|
|
252
|
+
// Add registered middleware summary at the end if any were registered
|
|
253
|
+
if (this.registeredMiddlewareNames.length > 0) {
|
|
254
|
+
logs.push({
|
|
255
|
+
message: `Registered: ${this.registeredMiddlewareNames.join(", ")}`,
|
|
256
|
+
type: "info",
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
return logs;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Clear all buffered startup logs.
|
|
263
|
+
*/
|
|
264
|
+
clearStartupLogs() {
|
|
265
|
+
this.startupLogs = [];
|
|
266
|
+
this.registeredMiddlewareNames = [];
|
|
267
|
+
clearResolverStartupWarnings();
|
|
268
|
+
}
|
|
269
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
270
|
+
// PRIVATE HELPER METHODS
|
|
271
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
272
|
+
/**
|
|
273
|
+
* Retrieves the type of the middleware.
|
|
274
|
+
*
|
|
275
|
+
* @param middleware - The middleware to be checked.
|
|
276
|
+
* @returns The type of the middleware.
|
|
277
|
+
*/
|
|
278
|
+
getMiddlewareType(middleware) {
|
|
279
|
+
if (middleware &&
|
|
280
|
+
typeof middleware === "object" &&
|
|
281
|
+
("path" in middleware || "middlewares" in middleware)) {
|
|
282
|
+
return MiddlewareType.Config;
|
|
283
|
+
}
|
|
284
|
+
if (typeof middleware === "function") {
|
|
285
|
+
return MiddlewareType.ExpressHandler;
|
|
286
|
+
}
|
|
287
|
+
return MiddlewareType.IExpressoMiddleware;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Checks if a middleware with the given name exists in the middleware collection.
|
|
291
|
+
* Uses O(1) Map lookup instead of O(n) array scan.
|
|
292
|
+
*
|
|
293
|
+
* @param middlewareName - The name of the middleware to be checked.
|
|
294
|
+
* @returns A boolean value indicating whether the middleware exists or not.
|
|
295
|
+
*/
|
|
296
|
+
middlewareExists(middlewareName) {
|
|
297
|
+
return this.middlewareMap.has(middlewareName);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Invalidate the sorted pipeline cache.
|
|
301
|
+
*/
|
|
302
|
+
invalidateCache() {
|
|
303
|
+
this.sortedPipelineCache = null;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Generic method to add built-in middleware with consistent pattern.
|
|
307
|
+
*
|
|
308
|
+
* @param name - Middleware name for lookup
|
|
309
|
+
* @param category - Middleware category
|
|
310
|
+
* @param middlewareFactory - Factory function that creates the middleware
|
|
311
|
+
* @returns True if middleware was added, false if skipped
|
|
312
|
+
*/
|
|
313
|
+
addBuiltInMiddleware(name, category, middlewareFactory) {
|
|
314
|
+
if (this.middlewareExists(name)) {
|
|
315
|
+
this._logger.warn(`[${name}] already exists. Skipping...`, "middleware-service");
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
const middleware = middlewareFactory();
|
|
319
|
+
if (!middleware) {
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
const entry = {
|
|
323
|
+
order: this.insertionOrder++,
|
|
324
|
+
middleware,
|
|
325
|
+
name,
|
|
326
|
+
category,
|
|
327
|
+
isBuiltIn: true,
|
|
328
|
+
};
|
|
329
|
+
this.middlewarePipeline.push(entry);
|
|
330
|
+
this.middlewareMap.set(name, entry);
|
|
331
|
+
this.invalidateCache();
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Get middleware name from a pipeline entry.
|
|
336
|
+
*/
|
|
337
|
+
getMiddlewareName(m) {
|
|
338
|
+
if (m.name) {
|
|
339
|
+
return m.name;
|
|
340
|
+
}
|
|
341
|
+
const middlewareType = this.getMiddlewareType(m.middleware);
|
|
342
|
+
if (middlewareType === MiddlewareType.Config) {
|
|
343
|
+
const config = m.middleware;
|
|
344
|
+
if (config.path)
|
|
345
|
+
return config.path;
|
|
346
|
+
const names = config.middlewares
|
|
347
|
+
.map((fn) => typeof fn === "function" ? fn.name : fn?.constructor?.name)
|
|
348
|
+
.filter((n) => n && n !== "anonymous" && n !== "");
|
|
349
|
+
return names.length > 0 ? names.join(", ") : "ConfigMiddleware";
|
|
350
|
+
}
|
|
351
|
+
else if (middlewareType === MiddlewareType.IExpressoMiddleware) {
|
|
352
|
+
return m.middleware.constructor.name;
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
return m.middleware?.name || "Anonymous";
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Get the category of a middleware.
|
|
360
|
+
*/
|
|
361
|
+
getMiddlewareCategory(name,
|
|
362
|
+
// Parameter reserved for future use (built-in middleware differentiation)
|
|
363
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
364
|
+
_isBuiltIn) {
|
|
365
|
+
// Check known categories
|
|
366
|
+
if (MIDDLEWARE_CATEGORIES[name]) {
|
|
367
|
+
return MIDDLEWARE_CATEGORIES[name];
|
|
368
|
+
}
|
|
369
|
+
// Try to infer from name
|
|
370
|
+
const lowerName = name.toLowerCase();
|
|
371
|
+
if (lowerName.includes("parser") ||
|
|
372
|
+
lowerName.includes("body") ||
|
|
373
|
+
lowerName.includes("json")) {
|
|
374
|
+
return "parser";
|
|
375
|
+
}
|
|
376
|
+
if (lowerName.includes("cors") ||
|
|
377
|
+
lowerName.includes("helmet") ||
|
|
378
|
+
lowerName.includes("auth") ||
|
|
379
|
+
lowerName.includes("security")) {
|
|
380
|
+
return "security";
|
|
381
|
+
}
|
|
382
|
+
if (lowerName.includes("log") ||
|
|
383
|
+
lowerName.includes("morgan") ||
|
|
384
|
+
lowerName.includes("request")) {
|
|
385
|
+
return "logging";
|
|
386
|
+
}
|
|
387
|
+
if (lowerName.includes("valid")) {
|
|
388
|
+
return "validation";
|
|
389
|
+
}
|
|
390
|
+
if (lowerName.includes("error") || lowerName.includes("handler")) {
|
|
391
|
+
return "error";
|
|
392
|
+
}
|
|
393
|
+
if (lowerName.includes("session") || lowerName.includes("cookie")) {
|
|
394
|
+
return "session";
|
|
395
|
+
}
|
|
396
|
+
if (lowerName.includes("static") || lowerName.includes("favicon")) {
|
|
397
|
+
return "static";
|
|
398
|
+
}
|
|
399
|
+
return "other";
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Get the path for a middleware.
|
|
403
|
+
*/
|
|
404
|
+
getMiddlewarePath(m) {
|
|
405
|
+
const middlewareType = this.getMiddlewareType(m.middleware);
|
|
406
|
+
if (middlewareType === MiddlewareType.Config) {
|
|
407
|
+
return m.middleware.path || "Global";
|
|
408
|
+
}
|
|
409
|
+
return "Global";
|
|
410
|
+
}
|
|
411
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
412
|
+
// INTERNAL MIDDLEWARE HELPERS (used by v4 unified methods)
|
|
413
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
414
|
+
/**
|
|
415
|
+
* Internal: Sets up Multer middleware for handling multipart/form-data.
|
|
416
|
+
* Used by upload() method.
|
|
417
|
+
* @internal
|
|
418
|
+
*/
|
|
419
|
+
setupMulter(options) {
|
|
420
|
+
const multerMiddleware = middlewareResolver("multer", options);
|
|
421
|
+
if (multerMiddleware) {
|
|
422
|
+
return multerMiddleware;
|
|
423
|
+
}
|
|
424
|
+
return null;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Internal: Adds a middleware to serve static files.
|
|
428
|
+
* Used by static() method.
|
|
429
|
+
* @internal
|
|
430
|
+
*/
|
|
431
|
+
serveStatic(root, options) {
|
|
432
|
+
this.addBuiltInMiddleware("serveStatic", "static", () => expressStatic(root, options));
|
|
433
|
+
}
|
|
434
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
435
|
+
// CUSTOM MIDDLEWARE METHODS
|
|
436
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
437
|
+
/**
|
|
438
|
+
* Helper method to add middleware configuration objects.
|
|
439
|
+
*/
|
|
440
|
+
addConfigMiddleware(middleware) {
|
|
441
|
+
const config = middleware;
|
|
442
|
+
if (config.middlewares.length === 0) {
|
|
443
|
+
this._logger.warn(`No middlewares in the route [${config.path}]. Skipping...`, "middleware-service");
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
const inferredName = config.middlewares
|
|
447
|
+
.map((fn) => (typeof fn === "function" ? fn.name : fn?.constructor?.name))
|
|
448
|
+
.filter((n) => n && n !== "anonymous" && n !== "")
|
|
449
|
+
.join(", ");
|
|
450
|
+
const configKey = config.path || inferredName || `custom_${this.insertionOrder}`;
|
|
451
|
+
if (this.middlewareExists(configKey)) {
|
|
452
|
+
this._logger.warn(`[${config.path}] route already exists. Skipping...`, "middleware-service");
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
const entry = {
|
|
456
|
+
order: this.insertionOrder++,
|
|
457
|
+
middleware: config,
|
|
458
|
+
name: configKey,
|
|
459
|
+
category: "other",
|
|
460
|
+
isBuiltIn: false,
|
|
461
|
+
};
|
|
462
|
+
this.middlewarePipeline.push(entry);
|
|
463
|
+
this.middlewareMap.set(configKey, entry);
|
|
464
|
+
this.invalidateCache();
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Helper method to add express request handler functions.
|
|
468
|
+
*/
|
|
469
|
+
addExpressHandlerMiddleware(middleware) {
|
|
470
|
+
const middlewareName = middleware?.name || `anonymous_${this.insertionOrder}`;
|
|
471
|
+
if (this.middlewareExists(middlewareName) && middleware?.name) {
|
|
472
|
+
this._logger.warn(`[${middlewareName}] already exists. Skipping...`, "middleware-service");
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const entry = {
|
|
476
|
+
order: this.insertionOrder++,
|
|
477
|
+
middleware,
|
|
478
|
+
name: middlewareName,
|
|
479
|
+
category: this.getMiddlewareCategory(middlewareName),
|
|
480
|
+
isBuiltIn: false,
|
|
481
|
+
};
|
|
482
|
+
this.middlewarePipeline.push(entry);
|
|
483
|
+
this.middlewareMap.set(middlewareName, entry);
|
|
484
|
+
this.invalidateCache();
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Helper method to add custom Expresso middleware.
|
|
488
|
+
*/
|
|
489
|
+
addIExpressoMiddleware(middleware) {
|
|
490
|
+
const middlewareName = middleware.constructor.name;
|
|
491
|
+
if (this.middlewareExists(middlewareName)) {
|
|
492
|
+
this._logger.warn(`[${middlewareName}] already exists. Skipping...`, "middleware-service");
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
const entry = {
|
|
496
|
+
order: this.insertionOrder++,
|
|
497
|
+
middleware,
|
|
498
|
+
name: middlewareName,
|
|
499
|
+
category: this.getMiddlewareCategory(middlewareName),
|
|
500
|
+
isBuiltIn: false,
|
|
501
|
+
};
|
|
502
|
+
this.middlewarePipeline.push(entry);
|
|
503
|
+
this.middlewareMap.set(middlewareName, entry);
|
|
504
|
+
this.invalidateCache();
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Adds a middleware to the middleware collection.
|
|
508
|
+
*
|
|
509
|
+
* @param options - The Express request handler function, middleware configuration object,
|
|
510
|
+
* or a custom Expresso middleware.
|
|
511
|
+
*
|
|
512
|
+
* @example Express Handler
|
|
513
|
+
* ```typescript
|
|
514
|
+
* const middleware = (req, res, next) => {
|
|
515
|
+
* // Your middleware logic here
|
|
516
|
+
* next();
|
|
517
|
+
* }
|
|
518
|
+
* ```
|
|
519
|
+
*
|
|
520
|
+
* @example Middleware Configuration Object
|
|
521
|
+
* ```typescript
|
|
522
|
+
* const middleware = {
|
|
523
|
+
* path: "/",
|
|
524
|
+
* middlewares: [] // Array of Express Handlers
|
|
525
|
+
* }
|
|
526
|
+
* ```
|
|
527
|
+
*
|
|
528
|
+
* @example Expresso Middleware
|
|
529
|
+
* ```typescript
|
|
530
|
+
* class CustomMiddleware implements IExpressoMiddleware {
|
|
531
|
+
* use(req: Request, res: Response, next: NextFunction): Promise<void> | void {
|
|
532
|
+
* // Your middleware logic here
|
|
533
|
+
* next();
|
|
534
|
+
* }
|
|
535
|
+
* }
|
|
536
|
+
* ```
|
|
537
|
+
*/
|
|
538
|
+
addMiddleware(options) {
|
|
539
|
+
switch (this.getMiddlewareType(options)) {
|
|
540
|
+
case MiddlewareType.Config:
|
|
541
|
+
this.addConfigMiddleware(options);
|
|
542
|
+
break;
|
|
543
|
+
case MiddlewareType.ExpressHandler:
|
|
544
|
+
this.addExpressHandlerMiddleware(options);
|
|
545
|
+
break;
|
|
546
|
+
case MiddlewareType.IExpressoMiddleware:
|
|
547
|
+
this.addIExpressoMiddleware(options);
|
|
548
|
+
break;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
552
|
+
// CONDITIONAL MIDDLEWARE
|
|
553
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
554
|
+
/**
|
|
555
|
+
* Add middleware that only executes when a condition is met.
|
|
556
|
+
*
|
|
557
|
+
* @param config - Conditional middleware configuration
|
|
558
|
+
*
|
|
559
|
+
* @example
|
|
560
|
+
* ```typescript
|
|
561
|
+
* // Only apply rate limiting for non-internal requests
|
|
562
|
+
* middleware.addConditional({
|
|
563
|
+
* middleware: rateLimiter,
|
|
564
|
+
* condition: (req) => !req.headers["x-internal-service"],
|
|
565
|
+
* name: "conditional-rate-limit"
|
|
566
|
+
* });
|
|
567
|
+
*
|
|
568
|
+
* // Only apply auth for non-public routes
|
|
569
|
+
* middleware.addConditional({
|
|
570
|
+
* middleware: authMiddleware,
|
|
571
|
+
* condition: (req) => !req.path.startsWith("/public"),
|
|
572
|
+
* name: "conditional-auth"
|
|
573
|
+
* });
|
|
574
|
+
* ```
|
|
575
|
+
*
|
|
576
|
+
* @public API
|
|
577
|
+
*/
|
|
578
|
+
addConditional(config) {
|
|
579
|
+
const name = config.name || `conditional_${this.insertionOrder}`;
|
|
580
|
+
if (this.middlewareExists(name)) {
|
|
581
|
+
this._logger.warn(`[${name}] already exists. Skipping...`, "middleware-service");
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
// Wrap the middleware with the condition check
|
|
585
|
+
const wrappedMiddleware = (req, res, next) => {
|
|
586
|
+
if (config.condition(req)) {
|
|
587
|
+
return config.middleware(req, res, next);
|
|
588
|
+
}
|
|
589
|
+
next();
|
|
590
|
+
};
|
|
591
|
+
const entry = {
|
|
592
|
+
order: this.insertionOrder++,
|
|
593
|
+
middleware: wrappedMiddleware,
|
|
594
|
+
name,
|
|
595
|
+
category: config.category || "other",
|
|
596
|
+
isBuiltIn: false,
|
|
597
|
+
condition: config.condition,
|
|
598
|
+
};
|
|
599
|
+
this.middlewarePipeline.push(entry);
|
|
600
|
+
this.middlewareMap.set(name, entry);
|
|
601
|
+
this.invalidateCache();
|
|
602
|
+
}
|
|
603
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
604
|
+
// ERROR HANDLER
|
|
605
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
606
|
+
/**
|
|
607
|
+
* Configures the error handling middleware for the application.
|
|
608
|
+
*
|
|
609
|
+
* @param options - The object containing the configuration options for the error handler middleware.
|
|
610
|
+
*/
|
|
611
|
+
setErrorHandler(options = {}) {
|
|
612
|
+
const { errorHandler: errorHandling, showStackTrace, enableExceptionFilters = false, container, } = options;
|
|
613
|
+
// Custom error handler takes precedence (backward compatibility)
|
|
614
|
+
if (errorHandling) {
|
|
615
|
+
this.errorHandler = errorHandling;
|
|
616
|
+
if (enableExceptionFilters) {
|
|
617
|
+
this._logger.warn("Custom errorHandler provided - exception filters are disabled. Remove errorHandler to use exception filters.", "middleware-service");
|
|
618
|
+
}
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
// If exception filters are enabled, wrap the error handler with ExceptionHandlerMiddleware
|
|
622
|
+
if (enableExceptionFilters && container) {
|
|
623
|
+
try {
|
|
624
|
+
const exceptionHandler = new ExceptionHandlerMiddleware(container, undefined, showStackTrace ?? false);
|
|
625
|
+
this.errorHandler = exceptionHandler.handle;
|
|
626
|
+
}
|
|
627
|
+
catch (error) {
|
|
628
|
+
this._logger.warn(`Failed to enable exception filters: ${error}. Falling back to default error handler.`, "middleware-service");
|
|
629
|
+
// Fall back to default handler
|
|
630
|
+
this.errorHandler = (error, req, res, next) => {
|
|
631
|
+
defaultErrorHandler(error, res, next, showStackTrace);
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
// Default error handler
|
|
637
|
+
this.errorHandler = (error, req, res, next) => {
|
|
638
|
+
defaultErrorHandler(error, res, next, showStackTrace);
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
// Warn if enableExceptionFilters is true but container is not provided
|
|
642
|
+
if (enableExceptionFilters && !container) {
|
|
643
|
+
this._logger.warn("enableExceptionFilters is true but container is not provided. Exception filters will not be enabled.", "middleware-service");
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Gets the configured error handler middleware.
|
|
648
|
+
*
|
|
649
|
+
* @returns The error handler middleware.
|
|
650
|
+
*/
|
|
651
|
+
getErrorHandler() {
|
|
652
|
+
return this.errorHandler;
|
|
653
|
+
}
|
|
654
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
655
|
+
// CONTENT NEGOTIATION
|
|
656
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
657
|
+
/**
|
|
658
|
+
* Configures content negotiation middleware for automatic response format selection.
|
|
659
|
+
*
|
|
660
|
+
* @param options - Configuration options for content negotiation
|
|
661
|
+
* @public API
|
|
662
|
+
*/
|
|
663
|
+
addContentNegotiation(options) {
|
|
664
|
+
if (!this.contentNegotiationService) {
|
|
665
|
+
this.contentNegotiationService = new ContentNegotiationService();
|
|
666
|
+
}
|
|
667
|
+
this.contentNegotiationService.configure(options || {});
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Gets the content negotiation service instance.
|
|
671
|
+
* @returns Content negotiation service or undefined if not configured
|
|
672
|
+
* @internal
|
|
673
|
+
*/
|
|
674
|
+
getContentNegotiationService() {
|
|
675
|
+
return this.contentNegotiationService;
|
|
676
|
+
}
|
|
677
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
678
|
+
// VALIDATION
|
|
679
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
680
|
+
// Validation Service - will be set by adapter-express
|
|
681
|
+
validationServiceFactory;
|
|
682
|
+
/**
|
|
683
|
+
* Configures validation for automatic request parameter validation.
|
|
684
|
+
*
|
|
685
|
+
* @param options - Configuration options for validation
|
|
686
|
+
* @public API
|
|
687
|
+
*/
|
|
688
|
+
addValidation(options) {
|
|
689
|
+
this._validationConfig = options || {};
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Gets the validation configuration.
|
|
693
|
+
* @internal
|
|
694
|
+
*/
|
|
695
|
+
getValidationConfig() {
|
|
696
|
+
return this
|
|
697
|
+
._validationConfig;
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Sets the validation service factory (called by adapter-express).
|
|
701
|
+
* @internal
|
|
702
|
+
*/
|
|
703
|
+
setValidationServiceFactory(factory) {
|
|
704
|
+
this.validationServiceFactory = factory;
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Gets the validation service instance.
|
|
708
|
+
* @internal
|
|
709
|
+
*/
|
|
710
|
+
getValidationService() {
|
|
711
|
+
return this.validationServiceFactory?.();
|
|
712
|
+
}
|
|
713
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
714
|
+
// PROFILING
|
|
715
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
716
|
+
/**
|
|
717
|
+
* Enable middleware profiling to track execution times.
|
|
718
|
+
*
|
|
719
|
+
* @param options - Profiler options
|
|
720
|
+
* @returns The profiler instance
|
|
721
|
+
*
|
|
722
|
+
* @example
|
|
723
|
+
* ```typescript
|
|
724
|
+
* const profiler = middleware.enableProfiling();
|
|
725
|
+
*
|
|
726
|
+
* // Later, get metrics
|
|
727
|
+
* const stats = profiler.getStats();
|
|
728
|
+
* console.log(stats.metrics);
|
|
729
|
+
* ```
|
|
730
|
+
*
|
|
731
|
+
* @public API
|
|
732
|
+
*/
|
|
733
|
+
enableProfiling(options) {
|
|
734
|
+
if (!this.profiler) {
|
|
735
|
+
this.profiler = new MiddlewareProfiler(options);
|
|
736
|
+
}
|
|
737
|
+
this.profilingEnabled = true;
|
|
738
|
+
return this.profiler;
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Disable middleware profiling.
|
|
742
|
+
* @public API
|
|
743
|
+
*/
|
|
744
|
+
disableProfiling() {
|
|
745
|
+
this.profilingEnabled = false;
|
|
746
|
+
if (this.profiler) {
|
|
747
|
+
this.profiler.setEnabled(false);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Get the profiler instance.
|
|
752
|
+
* @returns The profiler or null if not enabled
|
|
753
|
+
* @public API
|
|
754
|
+
*/
|
|
755
|
+
getProfiler() {
|
|
756
|
+
return this.profiler;
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Get profiling metrics for all middleware.
|
|
760
|
+
*
|
|
761
|
+
* @returns Array of middleware metrics or empty array if profiling is disabled
|
|
762
|
+
* @public API
|
|
763
|
+
*/
|
|
764
|
+
getProfilingMetrics() {
|
|
765
|
+
return this.profiler?.getAllMetrics() ?? [];
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Get profiling statistics.
|
|
769
|
+
*
|
|
770
|
+
* @returns Profiler statistics or null if profiling is disabled
|
|
771
|
+
* @public API
|
|
772
|
+
*/
|
|
773
|
+
getProfilingStats() {
|
|
774
|
+
return this.profiler?.getStats() ?? null;
|
|
775
|
+
}
|
|
776
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
777
|
+
// HEALTH CHECK
|
|
778
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
779
|
+
/**
|
|
780
|
+
* Add a health check endpoint that reports middleware status.
|
|
781
|
+
*
|
|
782
|
+
* @param options - Health check options
|
|
783
|
+
*
|
|
784
|
+
* @example
|
|
785
|
+
* ```typescript
|
|
786
|
+
* middleware.addHealthCheck({
|
|
787
|
+
* path: "/health/middleware",
|
|
788
|
+
* includeMetrics: true
|
|
789
|
+
* });
|
|
790
|
+
* ```
|
|
791
|
+
*
|
|
792
|
+
* @public API
|
|
793
|
+
*/
|
|
794
|
+
addHealthCheck(options) {
|
|
795
|
+
const path = options?.path ?? "/health/middleware";
|
|
796
|
+
const healthHandler = (req, res) => {
|
|
797
|
+
const info = this.getPipelineInfo();
|
|
798
|
+
const response = {
|
|
799
|
+
status: "healthy",
|
|
800
|
+
timestamp: new Date().toISOString(),
|
|
801
|
+
middleware: {
|
|
802
|
+
total: info.total,
|
|
803
|
+
byCategory: info.byCategory,
|
|
804
|
+
},
|
|
805
|
+
};
|
|
806
|
+
if (options?.detailed) {
|
|
807
|
+
response.middleware = {
|
|
808
|
+
...response.middleware,
|
|
809
|
+
entries: info.entries.map((e) => ({
|
|
810
|
+
name: e.name,
|
|
811
|
+
type: e.type,
|
|
812
|
+
category: e.category,
|
|
813
|
+
path: e.path,
|
|
814
|
+
})),
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
if (options?.includeMetrics && this.profiler) {
|
|
818
|
+
response.metrics = this.profiler.getStats();
|
|
819
|
+
}
|
|
820
|
+
res.json(response);
|
|
821
|
+
};
|
|
822
|
+
this.addMiddleware({ path, middlewares: [healthHandler] });
|
|
823
|
+
}
|
|
824
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
825
|
+
// PIPELINE RETRIEVAL
|
|
826
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
827
|
+
/**
|
|
828
|
+
* Retrieves middleware pipeline in the order they were added.
|
|
829
|
+
* Uses cached sorting for performance.
|
|
830
|
+
*
|
|
831
|
+
* @returns An array of middleware pipeline entries.
|
|
832
|
+
*/
|
|
833
|
+
getMiddlewarePipeline() {
|
|
834
|
+
if (this.sortedPipelineCache) {
|
|
835
|
+
return this.sortedPipelineCache;
|
|
836
|
+
}
|
|
837
|
+
this.sortedPipelineCache = [...this.middlewarePipeline].sort((a, b) => a.order - b.order);
|
|
838
|
+
return this.sortedPipelineCache;
|
|
839
|
+
}
|
|
840
|
+
/**
|
|
841
|
+
* View middleware pipeline formatted as a table.
|
|
842
|
+
*/
|
|
843
|
+
viewMiddlewarePipeline() {
|
|
844
|
+
const sortedMiddlewarePipeline = this.getMiddlewarePipeline();
|
|
845
|
+
const formattedPipeline = sortedMiddlewarePipeline.map((m) => {
|
|
846
|
+
const middlewareType = this.getMiddlewareType(m.middleware);
|
|
847
|
+
if (middlewareType === MiddlewareType.Config) {
|
|
848
|
+
const middlewareNames = m.middleware.middlewares.map((mw) => mw?.name || "Anonymous");
|
|
849
|
+
return {
|
|
850
|
+
order: m.order,
|
|
851
|
+
path: m.middleware.path,
|
|
852
|
+
middleware: `[${middlewareNames.join(", ")}]`,
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
else if (middlewareType === MiddlewareType.IExpressoMiddleware) {
|
|
856
|
+
return {
|
|
857
|
+
order: m.order,
|
|
858
|
+
path: m.middleware.path ?? "Global",
|
|
859
|
+
middleware: m.middleware.constructor.name,
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
else {
|
|
863
|
+
return {
|
|
864
|
+
order: m.order,
|
|
865
|
+
path: "Global",
|
|
866
|
+
middleware: m.middleware?.name,
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
});
|
|
870
|
+
console.table(formattedPipeline);
|
|
871
|
+
}
|
|
872
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
873
|
+
// VISUAL PIPELINE
|
|
874
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
875
|
+
/**
|
|
876
|
+
* Get a visual ASCII representation of the middleware pipeline.
|
|
877
|
+
*
|
|
878
|
+
* @returns ASCII art diagram of the pipeline
|
|
879
|
+
*
|
|
880
|
+
* @example
|
|
881
|
+
* ```typescript
|
|
882
|
+
* console.log(middleware.visualizePipeline());
|
|
883
|
+
* // ╔══════════════════════════════════════════════════════════════╗
|
|
884
|
+
* // ║ MIDDLEWARE PIPELINE ║
|
|
885
|
+
* // ╠══════════════════════════════════════════════════════════════╣
|
|
886
|
+
* // ║ 📦 jsonParser [parser] ║
|
|
887
|
+
* // ║ ↓ ║
|
|
888
|
+
* // ║ 🔒 cors [security] ║
|
|
889
|
+
* // ║ ↓ ║
|
|
890
|
+
* // ║ 🔒 helmet [security] ║
|
|
891
|
+
* // ╚══════════════════════════════════════════════════════════════╝
|
|
892
|
+
* ```
|
|
893
|
+
*
|
|
894
|
+
* @public API
|
|
895
|
+
*/
|
|
896
|
+
visualizePipeline() {
|
|
897
|
+
const pipeline = this.getMiddlewarePipeline();
|
|
898
|
+
const width = 64;
|
|
899
|
+
const lines = [
|
|
900
|
+
"╔" + "═".repeat(width) + "╗",
|
|
901
|
+
"║" +
|
|
902
|
+
"MIDDLEWARE PIPELINE".padStart((width + 19) / 2).padEnd(width) +
|
|
903
|
+
"║",
|
|
904
|
+
"╠" + "═".repeat(width) + "╣",
|
|
905
|
+
];
|
|
906
|
+
if (pipeline.length === 0) {
|
|
907
|
+
lines.push("║" + "(empty)".padStart((width + 7) / 2).padEnd(width) + "║");
|
|
908
|
+
}
|
|
909
|
+
else {
|
|
910
|
+
for (let i = 0; i < pipeline.length; i++) {
|
|
911
|
+
const m = pipeline[i];
|
|
912
|
+
const name = this.getMiddlewareName(m);
|
|
913
|
+
const category = m.category ?? this.getMiddlewareCategory(name);
|
|
914
|
+
const icon = CATEGORY_ICONS[category];
|
|
915
|
+
const categoryLabel = `[${category}]`;
|
|
916
|
+
const content = `${icon} ${name}`;
|
|
917
|
+
const contentWithCategory = content.padEnd(width - categoryLabel.length - 2) + categoryLabel;
|
|
918
|
+
lines.push("║ " + contentWithCategory.padEnd(width - 1) + "║");
|
|
919
|
+
if (i < pipeline.length - 1) {
|
|
920
|
+
lines.push("║" + " ↓".padEnd(width) + "║");
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
lines.push("╚" + "═".repeat(width) + "╝");
|
|
925
|
+
return lines.join("\n");
|
|
926
|
+
}
|
|
927
|
+
/**
|
|
928
|
+
* Get a compact summary of the middleware pipeline.
|
|
929
|
+
*
|
|
930
|
+
* @returns Single-line summary
|
|
931
|
+
* @public API
|
|
932
|
+
*/
|
|
933
|
+
getPipelineSummary() {
|
|
934
|
+
const info = this.getPipelineInfo();
|
|
935
|
+
const categories = Object.entries(info.byCategory)
|
|
936
|
+
.filter(([, count]) => count > 0)
|
|
937
|
+
.map(([cat, count]) => `${CATEGORY_ICONS[cat]}${count}`)
|
|
938
|
+
.join(" ");
|
|
939
|
+
return `Middleware: ${info.total} total | ${categories}`;
|
|
940
|
+
}
|
|
941
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
942
|
+
// INTROSPECTION METHODS
|
|
943
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
944
|
+
/**
|
|
945
|
+
* Get structured pipeline info for banner display and introspection.
|
|
946
|
+
* @returns Middleware pipeline information
|
|
947
|
+
* @public API
|
|
948
|
+
*/
|
|
949
|
+
getPipelineInfo() {
|
|
950
|
+
const sorted = this.getMiddlewarePipeline();
|
|
951
|
+
const entries = [];
|
|
952
|
+
const byCategory = {
|
|
953
|
+
parser: 0,
|
|
954
|
+
security: 0,
|
|
955
|
+
logging: 0,
|
|
956
|
+
validation: 0,
|
|
957
|
+
error: 0,
|
|
958
|
+
session: 0,
|
|
959
|
+
static: 0,
|
|
960
|
+
other: 0,
|
|
961
|
+
};
|
|
962
|
+
sorted.forEach((m, index) => {
|
|
963
|
+
const name = this.getMiddlewareName(m);
|
|
964
|
+
const category = m.category || this.getMiddlewareCategory(name, m.isBuiltIn);
|
|
965
|
+
const path = this.getMiddlewarePath(m);
|
|
966
|
+
const isBuiltIn = m.isBuiltIn ?? !name.includes("Middleware");
|
|
967
|
+
entries.push({
|
|
968
|
+
name,
|
|
969
|
+
type: isBuiltIn ? "built-in" : "custom",
|
|
970
|
+
category,
|
|
971
|
+
order: index,
|
|
972
|
+
path,
|
|
973
|
+
middleware: m.middleware,
|
|
974
|
+
});
|
|
975
|
+
byCategory[category]++;
|
|
976
|
+
});
|
|
977
|
+
return {
|
|
978
|
+
total: entries.length,
|
|
979
|
+
entries,
|
|
980
|
+
byCategory,
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Get a formatted view for banner display.
|
|
985
|
+
* @param maxDisplay - Maximum number of middleware to show
|
|
986
|
+
* @returns Formatted middleware view
|
|
987
|
+
* @public API
|
|
988
|
+
*/
|
|
989
|
+
getFormattedView(maxDisplay = 6) {
|
|
990
|
+
const info = this.getPipelineInfo();
|
|
991
|
+
const entries = info.entries.slice(0, maxDisplay).map((e) => ({
|
|
992
|
+
name: e.name,
|
|
993
|
+
category: e.category,
|
|
994
|
+
type: e.type,
|
|
995
|
+
}));
|
|
996
|
+
return {
|
|
997
|
+
entries,
|
|
998
|
+
total: info.total,
|
|
999
|
+
remaining: Math.max(0, info.total - maxDisplay),
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
/**
|
|
1003
|
+
* Get middleware count by category.
|
|
1004
|
+
* @returns Record of category to count
|
|
1005
|
+
* @public API
|
|
1006
|
+
*/
|
|
1007
|
+
getCountByCategory() {
|
|
1008
|
+
return this.getPipelineInfo().byCategory;
|
|
1009
|
+
}
|
|
1010
|
+
/**
|
|
1011
|
+
* Get middleware by name.
|
|
1012
|
+
* @param name - The middleware name
|
|
1013
|
+
* @returns The middleware entry or undefined
|
|
1014
|
+
* @public API
|
|
1015
|
+
*/
|
|
1016
|
+
getByName(name) {
|
|
1017
|
+
return this.getPipelineInfo().entries.find((e) => e.name === name);
|
|
1018
|
+
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Remove a middleware from the pipeline by name.
|
|
1021
|
+
*
|
|
1022
|
+
* @param name - The middleware name to remove
|
|
1023
|
+
* @returns True if removed, false if not found
|
|
1024
|
+
* @public API
|
|
1025
|
+
*/
|
|
1026
|
+
remove(name) {
|
|
1027
|
+
if (!this.middlewareMap.has(name)) {
|
|
1028
|
+
return false;
|
|
1029
|
+
}
|
|
1030
|
+
this.middlewareMap.delete(name);
|
|
1031
|
+
const index = this.middlewarePipeline.findIndex((m) => m.name === name);
|
|
1032
|
+
if (index >= 0) {
|
|
1033
|
+
this.middlewarePipeline.splice(index, 1);
|
|
1034
|
+
}
|
|
1035
|
+
this.invalidateCache();
|
|
1036
|
+
return true;
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* Clear all middleware from the pipeline.
|
|
1040
|
+
* @public API
|
|
1041
|
+
*/
|
|
1042
|
+
clear() {
|
|
1043
|
+
this.middlewarePipeline = [];
|
|
1044
|
+
this.middlewareMap.clear();
|
|
1045
|
+
this.insertionOrder = 0;
|
|
1046
|
+
this.invalidateCache();
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Get the total number of middleware in the pipeline.
|
|
1050
|
+
* @returns Number of middleware
|
|
1051
|
+
* @public API
|
|
1052
|
+
*/
|
|
1053
|
+
count() {
|
|
1054
|
+
return this.middlewarePipeline.length;
|
|
1055
|
+
}
|
|
1056
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1057
|
+
// V4 UNIFIED METHODS
|
|
1058
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1059
|
+
/**
|
|
1060
|
+
* Configure request parsing (unified method).
|
|
1061
|
+
* Replaces: addBodyParser, addUrlEncodedParser, addCookieParser
|
|
1062
|
+
*/
|
|
1063
|
+
parse(options) {
|
|
1064
|
+
const opts = options || {};
|
|
1065
|
+
// JSON parsing (default: enabled)
|
|
1066
|
+
if (opts.json !== false) {
|
|
1067
|
+
const jsonOpts = typeof opts.json === "object" ? opts.json : { limit: "100kb" };
|
|
1068
|
+
this.addBuiltInMiddleware("jsonParser", "parser", () => json(jsonOpts));
|
|
1069
|
+
}
|
|
1070
|
+
// URL-encoded parsing (default: enabled)
|
|
1071
|
+
if (opts.urlencoded !== false) {
|
|
1072
|
+
const urlencodedOpts = typeof opts.urlencoded === "object"
|
|
1073
|
+
? opts.urlencoded
|
|
1074
|
+
: { extended: true };
|
|
1075
|
+
this.addBuiltInMiddleware("urlencodedParser", "parser", () => urlencoded(urlencodedOpts));
|
|
1076
|
+
}
|
|
1077
|
+
// Cookie parsing (default: disabled, requires package)
|
|
1078
|
+
if (opts.cookies) {
|
|
1079
|
+
const cookieOpts = typeof opts.cookies === "object" ? opts.cookies : {};
|
|
1080
|
+
this.addBuiltInMiddleware("cookieParser", "parser", () => middlewareResolver("cookieParser", cookieOpts.secret, cookieOpts.options));
|
|
1081
|
+
}
|
|
1082
|
+
this.bufferStartupLog("Request parsing configured");
|
|
1083
|
+
}
|
|
1084
|
+
/**
|
|
1085
|
+
* Configure logging with any implementation.
|
|
1086
|
+
* Replaces: addMorgan
|
|
1087
|
+
*/
|
|
1088
|
+
logger(config) {
|
|
1089
|
+
// Skip in test if configured
|
|
1090
|
+
if (config?.disableInTest !== false && process.env.NODE_ENV === "test") {
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
1093
|
+
// Custom logger takes precedence
|
|
1094
|
+
if (config?.custom) {
|
|
1095
|
+
const customHandler = config.custom;
|
|
1096
|
+
this.addBuiltInMiddleware("customLogger", "logging", () => customHandler);
|
|
1097
|
+
this.bufferStartupLog("Using custom logger");
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
const implementation = config?.implementation || "auto";
|
|
1101
|
+
const handler = this.resolveLoggerImplementation(implementation, config?.options, config?.skip);
|
|
1102
|
+
if (handler) {
|
|
1103
|
+
const implName = implementation === "auto" ? this.detectBestLogger() : implementation;
|
|
1104
|
+
this.addBuiltInMiddleware(`logger-${implName}`, "logging", () => handler);
|
|
1105
|
+
this.bufferStartupLog(`Using ${implName} logger${implementation === "auto" ? " (auto-detected)" : ""}`);
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
// Internal logger getter
|
|
1109
|
+
get loggerInstance() {
|
|
1110
|
+
return this._logger;
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Detect the best available logger.
|
|
1114
|
+
*/
|
|
1115
|
+
detectBestLogger() {
|
|
1116
|
+
if (isPackageAvailable("pino-http"))
|
|
1117
|
+
return "pino";
|
|
1118
|
+
if (isPackageAvailable("express-winston"))
|
|
1119
|
+
return "winston";
|
|
1120
|
+
if (isMiddlewareAvailable("morgan"))
|
|
1121
|
+
return "morgan";
|
|
1122
|
+
return "console";
|
|
1123
|
+
}
|
|
1124
|
+
/**
|
|
1125
|
+
* Resolve logger implementation.
|
|
1126
|
+
*/
|
|
1127
|
+
resolveLoggerImplementation(implementation, options, skip) {
|
|
1128
|
+
const impl = implementation === "auto" ? this.detectBestLogger() : implementation;
|
|
1129
|
+
switch (impl) {
|
|
1130
|
+
case "morgan": {
|
|
1131
|
+
const morganOpts = options;
|
|
1132
|
+
const format = morganOpts?.format || "combined";
|
|
1133
|
+
// Only pass options object if skip is defined to avoid passing undefined
|
|
1134
|
+
if (skip) {
|
|
1135
|
+
return middlewareResolver("morgan", format, { skip });
|
|
1136
|
+
}
|
|
1137
|
+
return middlewareResolver("morgan", format);
|
|
1138
|
+
}
|
|
1139
|
+
case "pino": {
|
|
1140
|
+
const pino = resolvePackage("pino-http");
|
|
1141
|
+
if (pino) {
|
|
1142
|
+
return pino(options);
|
|
1143
|
+
}
|
|
1144
|
+
this.bufferStartupLog("pino-http not installed, falling back to morgan", "warn");
|
|
1145
|
+
return this.resolveLoggerImplementation("morgan", options, skip);
|
|
1146
|
+
}
|
|
1147
|
+
case "winston": {
|
|
1148
|
+
const winston = resolvePackage("express-winston");
|
|
1149
|
+
if (winston?.logger) {
|
|
1150
|
+
return winston.logger(options);
|
|
1151
|
+
}
|
|
1152
|
+
this.bufferStartupLog("express-winston not installed, falling back to morgan", "warn");
|
|
1153
|
+
return this.resolveLoggerImplementation("morgan", options, skip);
|
|
1154
|
+
}
|
|
1155
|
+
case "console": {
|
|
1156
|
+
// Simple console logger
|
|
1157
|
+
const handler = (req, _res, next) => {
|
|
1158
|
+
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
|
|
1159
|
+
next();
|
|
1160
|
+
};
|
|
1161
|
+
return handler;
|
|
1162
|
+
}
|
|
1163
|
+
default:
|
|
1164
|
+
return null;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
/**
|
|
1168
|
+
* Unified security configuration.
|
|
1169
|
+
* Replaces: addHelmet, addCors, addRateLimiter
|
|
1170
|
+
*/
|
|
1171
|
+
security(config) {
|
|
1172
|
+
// Handle preset strings
|
|
1173
|
+
const secConfig = typeof config === "string"
|
|
1174
|
+
? this.getSecurityPreset(config)
|
|
1175
|
+
: config || this.getSecurityPreset("standard");
|
|
1176
|
+
// Helmet/security headers
|
|
1177
|
+
if (secConfig.headers !== false) {
|
|
1178
|
+
const helmetOpts = typeof secConfig.headers === "object" ? secConfig.headers : {};
|
|
1179
|
+
this.addBuiltInMiddleware("helmet", "security", () => middlewareResolver("helmet", helmetOpts));
|
|
1180
|
+
}
|
|
1181
|
+
// CORS
|
|
1182
|
+
if (secConfig.cors !== false) {
|
|
1183
|
+
const corsOpts = typeof secConfig.cors === "object" ? secConfig.cors : { origin: true };
|
|
1184
|
+
this.addBuiltInMiddleware("cors", "security", () => middlewareResolver("cors", corsOpts));
|
|
1185
|
+
}
|
|
1186
|
+
// Rate limiting
|
|
1187
|
+
if (secConfig.rateLimit) {
|
|
1188
|
+
const rateLimitOpts = typeof secConfig.rateLimit === "object"
|
|
1189
|
+
? secConfig.rateLimit
|
|
1190
|
+
: { windowMs: 60000, max: 100 };
|
|
1191
|
+
this.addBuiltInMiddleware("rateLimit", "security", () => middlewareResolver("rateLimit", rateLimitOpts));
|
|
1192
|
+
}
|
|
1193
|
+
// Custom security middleware
|
|
1194
|
+
if (secConfig.custom) {
|
|
1195
|
+
for (const middleware of secConfig.custom) {
|
|
1196
|
+
this.addMiddleware(middleware);
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
this.bufferStartupLog("Security configured");
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Get security preset configuration.
|
|
1203
|
+
*/
|
|
1204
|
+
getSecurityPreset(preset) {
|
|
1205
|
+
const presets = {
|
|
1206
|
+
standard: {
|
|
1207
|
+
headers: "helmet",
|
|
1208
|
+
cors: true,
|
|
1209
|
+
rateLimit: false,
|
|
1210
|
+
},
|
|
1211
|
+
strict: {
|
|
1212
|
+
headers: "helmet",
|
|
1213
|
+
cors: { origin: false, credentials: true },
|
|
1214
|
+
rateLimit: { windowMs: 60000, max: 60 },
|
|
1215
|
+
},
|
|
1216
|
+
api: {
|
|
1217
|
+
headers: "helmet",
|
|
1218
|
+
cors: {
|
|
1219
|
+
origin: true,
|
|
1220
|
+
credentials: true,
|
|
1221
|
+
methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
|
|
1222
|
+
allowedHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
|
|
1223
|
+
},
|
|
1224
|
+
rateLimit: { windowMs: 60000, max: 100 },
|
|
1225
|
+
},
|
|
1226
|
+
minimal: {
|
|
1227
|
+
headers: false,
|
|
1228
|
+
cors: true,
|
|
1229
|
+
rateLimit: false,
|
|
1230
|
+
},
|
|
1231
|
+
relaxed: {
|
|
1232
|
+
headers: false,
|
|
1233
|
+
cors: { origin: true },
|
|
1234
|
+
rateLimit: false,
|
|
1235
|
+
},
|
|
1236
|
+
};
|
|
1237
|
+
return presets[preset] || presets.standard;
|
|
1238
|
+
}
|
|
1239
|
+
/**
|
|
1240
|
+
* Configure compression.
|
|
1241
|
+
* Replaces: addCompression
|
|
1242
|
+
*/
|
|
1243
|
+
compress(config) {
|
|
1244
|
+
const impl = config?.implementation || "auto";
|
|
1245
|
+
let handler = null;
|
|
1246
|
+
if (impl === "auto") {
|
|
1247
|
+
// Try shrink-ray first, then compression
|
|
1248
|
+
if (isPackageAvailable("shrink-ray-current")) {
|
|
1249
|
+
const shrinkRay = resolvePackage("shrink-ray-current");
|
|
1250
|
+
if (shrinkRay) {
|
|
1251
|
+
handler = shrinkRay(config);
|
|
1252
|
+
this.bufferStartupLog("Using shrink-ray compression (auto-detected)");
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
if (!handler) {
|
|
1256
|
+
handler = middlewareResolver("compression", config);
|
|
1257
|
+
if (handler) {
|
|
1258
|
+
this.bufferStartupLog("Using compression (auto-detected)");
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
else if (impl === "shrink-ray") {
|
|
1263
|
+
const shrinkRay = resolvePackage("shrink-ray-current");
|
|
1264
|
+
if (shrinkRay) {
|
|
1265
|
+
handler = shrinkRay(config);
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
else {
|
|
1269
|
+
handler = middlewareResolver("compression", config);
|
|
1270
|
+
}
|
|
1271
|
+
if (handler) {
|
|
1272
|
+
this.addBuiltInMiddleware("compression", "other", () => handler);
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
/**
|
|
1276
|
+
* Unified session management.
|
|
1277
|
+
* Replaces: addSession, addCookieSession
|
|
1278
|
+
*/
|
|
1279
|
+
session(config) {
|
|
1280
|
+
switch (config.type) {
|
|
1281
|
+
case "cookie": {
|
|
1282
|
+
// Use cookie-session
|
|
1283
|
+
const cookieSessionOpts = {
|
|
1284
|
+
name: config.name || "session",
|
|
1285
|
+
secret: config.secret,
|
|
1286
|
+
keys: config.keys || [
|
|
1287
|
+
typeof config.secret === "string"
|
|
1288
|
+
? config.secret
|
|
1289
|
+
: config.secret[0],
|
|
1290
|
+
],
|
|
1291
|
+
...config.cookie,
|
|
1292
|
+
};
|
|
1293
|
+
this.addBuiltInMiddleware("cookieSession", "session", () => middlewareResolver("cookieSession", cookieSessionOpts));
|
|
1294
|
+
break;
|
|
1295
|
+
}
|
|
1296
|
+
case "store": {
|
|
1297
|
+
// Use express-session
|
|
1298
|
+
const sessionOpts = {
|
|
1299
|
+
secret: config.secret,
|
|
1300
|
+
name: config.name,
|
|
1301
|
+
store: config.store,
|
|
1302
|
+
resave: config.resave ?? false,
|
|
1303
|
+
saveUninitialized: config.saveUninitialized ?? false,
|
|
1304
|
+
rolling: config.rolling,
|
|
1305
|
+
cookie: config.cookie,
|
|
1306
|
+
};
|
|
1307
|
+
this.addBuiltInMiddleware("session", "session", () => middlewareResolver("session", sessionOpts));
|
|
1308
|
+
break;
|
|
1309
|
+
}
|
|
1310
|
+
case "jwt": {
|
|
1311
|
+
// JWT session - minimal implementation
|
|
1312
|
+
this.bufferStartupLog("JWT sessions require custom implementation. Use Middleware.add() with your JWT middleware.", "warn");
|
|
1313
|
+
break;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
/**
|
|
1318
|
+
* Enhanced file upload handling.
|
|
1319
|
+
* Configures global upload settings and returns upload handlers.
|
|
1320
|
+
*
|
|
1321
|
+
* When called, this stores the configuration globally so that
|
|
1322
|
+
* @FileUpload decorators can use these settings as defaults.
|
|
1323
|
+
*
|
|
1324
|
+
* @param config - Upload configuration
|
|
1325
|
+
* @returns Upload handler with single, array, fields, any, none methods
|
|
1326
|
+
*
|
|
1327
|
+
* @example
|
|
1328
|
+
* ```typescript
|
|
1329
|
+
* // In app.ts - configure globally
|
|
1330
|
+
* this.Middleware.upload({
|
|
1331
|
+
* destination: './uploads',
|
|
1332
|
+
* limits: { fileSize: 10 * 1024 * 1024 }
|
|
1333
|
+
* });
|
|
1334
|
+
*
|
|
1335
|
+
* // In controller - @FileUpload uses global config
|
|
1336
|
+
* @FileUpload({ fieldName: 'avatar' })
|
|
1337
|
+
* uploadAvatar(req: Request) { }
|
|
1338
|
+
* ```
|
|
1339
|
+
*
|
|
1340
|
+
* @public API
|
|
1341
|
+
*/
|
|
1342
|
+
upload(config) {
|
|
1343
|
+
// Store configuration globally for @FileUpload decorator
|
|
1344
|
+
if (config) {
|
|
1345
|
+
setGlobalUploadConfig(config);
|
|
1346
|
+
this.bufferStartupLog("Upload configured");
|
|
1347
|
+
}
|
|
1348
|
+
const multerOpts = {
|
|
1349
|
+
dest: config?.destination,
|
|
1350
|
+
limits: config?.limits,
|
|
1351
|
+
};
|
|
1352
|
+
if (config?.fileFilter) {
|
|
1353
|
+
const userFilter = config.fileFilter;
|
|
1354
|
+
multerOpts.fileFilter = (_req, file, cb) => {
|
|
1355
|
+
try {
|
|
1356
|
+
const result = userFilter(file);
|
|
1357
|
+
if (result instanceof Promise) {
|
|
1358
|
+
result
|
|
1359
|
+
.then((accepted) => cb(null, accepted))
|
|
1360
|
+
.catch((err) => cb(err));
|
|
1361
|
+
}
|
|
1362
|
+
else {
|
|
1363
|
+
cb(null, result);
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
catch (err) {
|
|
1367
|
+
cb(err);
|
|
1368
|
+
}
|
|
1369
|
+
};
|
|
1370
|
+
}
|
|
1371
|
+
const multerInstance = this.setupMulter(multerOpts);
|
|
1372
|
+
return {
|
|
1373
|
+
single: (fieldName) => multerInstance.single(fieldName),
|
|
1374
|
+
array: (fieldName, maxCount) => multerInstance.array(fieldName, maxCount),
|
|
1375
|
+
fields: (fields) => multerInstance.fields(fields),
|
|
1376
|
+
any: () => multerInstance.any(),
|
|
1377
|
+
none: () => multerInstance.none(),
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* Enhanced static file serving.
|
|
1382
|
+
* Replaces: serveStatic, addServeFavicon
|
|
1383
|
+
*/
|
|
1384
|
+
static(config) {
|
|
1385
|
+
const configs = Array.isArray(config) ? config : [config];
|
|
1386
|
+
for (const cfg of configs) {
|
|
1387
|
+
if (typeof cfg === "string") {
|
|
1388
|
+
// Simple path string
|
|
1389
|
+
this.serveStatic(cfg);
|
|
1390
|
+
}
|
|
1391
|
+
else {
|
|
1392
|
+
// Full config object
|
|
1393
|
+
const staticOpts = {
|
|
1394
|
+
maxAge: cfg.maxAge,
|
|
1395
|
+
etag: cfg.etag,
|
|
1396
|
+
index: cfg.spa ? false : cfg.index,
|
|
1397
|
+
...cfg.options,
|
|
1398
|
+
};
|
|
1399
|
+
if (cfg.prefix) {
|
|
1400
|
+
// Route-specific static serving
|
|
1401
|
+
this.addMiddleware({
|
|
1402
|
+
path: cfg.prefix,
|
|
1403
|
+
middlewares: [expressStatic(cfg.path, staticOpts)],
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
else {
|
|
1407
|
+
this.serveStatic(cfg.path, staticOpts);
|
|
1408
|
+
}
|
|
1409
|
+
// SPA support - serve index.html for all non-file routes
|
|
1410
|
+
if (cfg.spa) {
|
|
1411
|
+
const indexPath = cfg.index || "index.html";
|
|
1412
|
+
const spaHandler = (_req, res, next) => {
|
|
1413
|
+
const filePath = `${cfg.path}/${indexPath}`;
|
|
1414
|
+
res.sendFile(filePath, { root: process.cwd() }, (err) => {
|
|
1415
|
+
if (err)
|
|
1416
|
+
next(err);
|
|
1417
|
+
});
|
|
1418
|
+
};
|
|
1419
|
+
this.addBuiltInMiddleware("spa-fallback", "static", () => spaHandler);
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1425
|
+
// V4 MIDDLEWARE REGISTRY
|
|
1426
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1427
|
+
/**
|
|
1428
|
+
* Register a named middleware for use in routes.
|
|
1429
|
+
*/
|
|
1430
|
+
register(name, handler) {
|
|
1431
|
+
this.registry.register(name, handler);
|
|
1432
|
+
// Track registered names for summary (no individual logging)
|
|
1433
|
+
this.registeredMiddlewareNames.push(name);
|
|
1434
|
+
}
|
|
1435
|
+
/**
|
|
1436
|
+
* Get a registered middleware by name.
|
|
1437
|
+
*/
|
|
1438
|
+
get(name) {
|
|
1439
|
+
return this.registry.get(name);
|
|
1440
|
+
}
|
|
1441
|
+
/**
|
|
1442
|
+
* Check if a middleware is registered.
|
|
1443
|
+
*/
|
|
1444
|
+
has(name) {
|
|
1445
|
+
return this.registry.has(name);
|
|
1446
|
+
}
|
|
1447
|
+
/**
|
|
1448
|
+
* Get all registered middleware names.
|
|
1449
|
+
*/
|
|
1450
|
+
getRegisteredNames() {
|
|
1451
|
+
return this.registry.getRegisteredNames();
|
|
1452
|
+
}
|
|
1453
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1454
|
+
// V4 PRESET SYSTEM
|
|
1455
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1456
|
+
/**
|
|
1457
|
+
* Define a custom reusable preset.
|
|
1458
|
+
*/
|
|
1459
|
+
definePreset(name, config) {
|
|
1460
|
+
this.customPresets.set(name, config);
|
|
1461
|
+
this.bufferStartupLog(`Defined custom preset: ${name}`);
|
|
1462
|
+
}
|
|
1463
|
+
/**
|
|
1464
|
+
* Apply a preset configuration.
|
|
1465
|
+
*/
|
|
1466
|
+
applyPreset(preset, overrides) {
|
|
1467
|
+
const config = this.getPresetConfig(preset);
|
|
1468
|
+
if (!config) {
|
|
1469
|
+
this.loggerInstance.error(`Preset '${preset}' not found. Available: ${this.getAvailablePresetNames().join(", ")}`, "middleware");
|
|
1470
|
+
return;
|
|
1471
|
+
}
|
|
1472
|
+
// Merge with overrides
|
|
1473
|
+
const finalConfig = overrides
|
|
1474
|
+
? this.mergeConfigs(config, overrides)
|
|
1475
|
+
: config;
|
|
1476
|
+
this._lastPreset = {
|
|
1477
|
+
name: preset,
|
|
1478
|
+
hasOverrides: !!overrides,
|
|
1479
|
+
config: finalConfig,
|
|
1480
|
+
};
|
|
1481
|
+
// Apply each category
|
|
1482
|
+
if (finalConfig.parse) {
|
|
1483
|
+
if (typeof finalConfig.parse === "boolean") {
|
|
1484
|
+
this.parse();
|
|
1485
|
+
}
|
|
1486
|
+
else {
|
|
1487
|
+
this.parse(finalConfig.parse);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
if (finalConfig.logger) {
|
|
1491
|
+
if (typeof finalConfig.logger === "boolean") {
|
|
1492
|
+
this.logger();
|
|
1493
|
+
}
|
|
1494
|
+
else {
|
|
1495
|
+
this.logger(finalConfig.logger);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
if (finalConfig.security) {
|
|
1499
|
+
if (typeof finalConfig.security === "boolean") {
|
|
1500
|
+
this.security();
|
|
1501
|
+
}
|
|
1502
|
+
else {
|
|
1503
|
+
this.security(finalConfig.security);
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
if (finalConfig.compress) {
|
|
1507
|
+
if (typeof finalConfig.compress === "boolean") {
|
|
1508
|
+
this.compress();
|
|
1509
|
+
}
|
|
1510
|
+
else {
|
|
1511
|
+
this.compress(finalConfig.compress);
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
if (finalConfig.session) {
|
|
1515
|
+
this.session(finalConfig.session);
|
|
1516
|
+
}
|
|
1517
|
+
if (finalConfig.static) {
|
|
1518
|
+
this.static(finalConfig.static);
|
|
1519
|
+
}
|
|
1520
|
+
this.bufferStartupLog(`Applied preset: ${preset}`);
|
|
1521
|
+
}
|
|
1522
|
+
/**
|
|
1523
|
+
* Get all available presets.
|
|
1524
|
+
*/
|
|
1525
|
+
getAllPresets() {
|
|
1526
|
+
const builtIn = this.getBuiltInPresets();
|
|
1527
|
+
const custom = Object.fromEntries(this.customPresets);
|
|
1528
|
+
return { ...builtIn, ...custom };
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* Returns info about the last applied preset (name, whether overrides
|
|
1532
|
+
* were used, and the effective merged config). Used by the adapter to
|
|
1533
|
+
* forward preset metadata to Studio.
|
|
1534
|
+
*/
|
|
1535
|
+
getLastAppliedPreset() {
|
|
1536
|
+
return this._lastPreset;
|
|
1537
|
+
}
|
|
1538
|
+
/**
|
|
1539
|
+
* Get built-in presets.
|
|
1540
|
+
*
|
|
1541
|
+
* Each preset is tuned for a specific workload:
|
|
1542
|
+
* - api: REST APIs (large payloads, rate-limited, strict CORS)
|
|
1543
|
+
* - web: traditional server-rendered apps (cookies, sessions, relaxed CORS)
|
|
1544
|
+
* - spa: single-page apps served with static fallback
|
|
1545
|
+
* - microservice: internal service-to-service (minimal surface, no security)
|
|
1546
|
+
* - graphql: single endpoint with large JSON payloads
|
|
1547
|
+
* - minimal: parsing only, no security or compression
|
|
1548
|
+
* - development: relaxed for local iteration, verbose logging
|
|
1549
|
+
* - production: hardened defaults for shipped deployments
|
|
1550
|
+
*/
|
|
1551
|
+
getBuiltInPresets() {
|
|
1552
|
+
return {
|
|
1553
|
+
api: {
|
|
1554
|
+
parse: {
|
|
1555
|
+
json: { limit: "10mb" },
|
|
1556
|
+
urlencoded: { extended: true, limit: "10mb" },
|
|
1557
|
+
},
|
|
1558
|
+
logger: { implementation: "auto" },
|
|
1559
|
+
security: "api",
|
|
1560
|
+
compress: { level: 6 },
|
|
1561
|
+
},
|
|
1562
|
+
web: {
|
|
1563
|
+
parse: {
|
|
1564
|
+
json: { limit: "5mb" },
|
|
1565
|
+
urlencoded: { extended: true, limit: "5mb" },
|
|
1566
|
+
cookies: true,
|
|
1567
|
+
},
|
|
1568
|
+
logger: { implementation: "auto" },
|
|
1569
|
+
security: "standard",
|
|
1570
|
+
compress: true,
|
|
1571
|
+
},
|
|
1572
|
+
spa: {
|
|
1573
|
+
parse: {
|
|
1574
|
+
json: { limit: "5mb" },
|
|
1575
|
+
urlencoded: { extended: true, limit: "5mb" },
|
|
1576
|
+
},
|
|
1577
|
+
security: "standard",
|
|
1578
|
+
compress: true,
|
|
1579
|
+
},
|
|
1580
|
+
microservice: {
|
|
1581
|
+
parse: {
|
|
1582
|
+
json: { limit: "1mb" },
|
|
1583
|
+
urlencoded: { extended: false, limit: "1mb" },
|
|
1584
|
+
},
|
|
1585
|
+
compress: { level: 6 },
|
|
1586
|
+
},
|
|
1587
|
+
graphql: {
|
|
1588
|
+
parse: { json: { limit: "50mb" } },
|
|
1589
|
+
security: {
|
|
1590
|
+
headers: "helmet",
|
|
1591
|
+
cors: { origin: true, methods: ["GET", "POST", "OPTIONS"] },
|
|
1592
|
+
},
|
|
1593
|
+
compress: true,
|
|
1594
|
+
},
|
|
1595
|
+
minimal: {
|
|
1596
|
+
parse: true,
|
|
1597
|
+
},
|
|
1598
|
+
development: {
|
|
1599
|
+
parse: {
|
|
1600
|
+
json: { limit: "50mb" },
|
|
1601
|
+
urlencoded: { extended: true, limit: "50mb" },
|
|
1602
|
+
},
|
|
1603
|
+
logger: { implementation: "morgan", options: { format: "dev" } },
|
|
1604
|
+
security: "relaxed",
|
|
1605
|
+
},
|
|
1606
|
+
production: {
|
|
1607
|
+
parse: {
|
|
1608
|
+
json: { limit: "10mb" },
|
|
1609
|
+
urlencoded: { extended: true, limit: "10mb" },
|
|
1610
|
+
},
|
|
1611
|
+
logger: { implementation: "auto", disableInTest: true },
|
|
1612
|
+
security: "strict",
|
|
1613
|
+
compress: { level: 6 },
|
|
1614
|
+
},
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
/**
|
|
1618
|
+
* Get preset config by name.
|
|
1619
|
+
*/
|
|
1620
|
+
getPresetConfig(name) {
|
|
1621
|
+
return this.customPresets.get(name) || this.getBuiltInPresets()[name];
|
|
1622
|
+
}
|
|
1623
|
+
/**
|
|
1624
|
+
* Get available preset names.
|
|
1625
|
+
*/
|
|
1626
|
+
getAvailablePresetNames() {
|
|
1627
|
+
return [
|
|
1628
|
+
...Object.keys(this.getBuiltInPresets()),
|
|
1629
|
+
...this.customPresets.keys(),
|
|
1630
|
+
];
|
|
1631
|
+
}
|
|
1632
|
+
/**
|
|
1633
|
+
* Merge two configs.
|
|
1634
|
+
*/
|
|
1635
|
+
mergeConfigs(base, override) {
|
|
1636
|
+
return {
|
|
1637
|
+
...base,
|
|
1638
|
+
...override,
|
|
1639
|
+
// Deep merge for nested objects
|
|
1640
|
+
parse: override.parse !== undefined
|
|
1641
|
+
? typeof override.parse === "object" && typeof base.parse === "object"
|
|
1642
|
+
? { ...base.parse, ...override.parse }
|
|
1643
|
+
: override.parse
|
|
1644
|
+
: base.parse,
|
|
1645
|
+
logger: override.logger !== undefined
|
|
1646
|
+
? typeof override.logger === "object" &&
|
|
1647
|
+
typeof base.logger === "object"
|
|
1648
|
+
? { ...base.logger, ...override.logger }
|
|
1649
|
+
: override.logger
|
|
1650
|
+
: base.logger,
|
|
1651
|
+
security: override.security !== undefined ? override.security : base.security,
|
|
1652
|
+
compress: override.compress !== undefined ? override.compress : base.compress,
|
|
1653
|
+
session: override.session !== undefined ? override.session : base.session,
|
|
1654
|
+
static: override.static !== undefined ? override.static : base.static,
|
|
1655
|
+
};
|
|
1656
|
+
}
|
|
1657
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1658
|
+
// V4 ADVANCED FEATURES
|
|
1659
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1660
|
+
/**
|
|
1661
|
+
* Conditional middleware application.
|
|
1662
|
+
*/
|
|
1663
|
+
when(condition, handler) {
|
|
1664
|
+
const shouldApply = typeof condition === "function" ? condition() : condition;
|
|
1665
|
+
if (shouldApply) {
|
|
1666
|
+
if (typeof handler === "function" && handler.length === 0) {
|
|
1667
|
+
// It's a callback function, execute it
|
|
1668
|
+
handler();
|
|
1669
|
+
}
|
|
1670
|
+
else {
|
|
1671
|
+
// It's a middleware handler
|
|
1672
|
+
this.addMiddleware(handler);
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
/**
|
|
1677
|
+
* Auto-optimize middleware pipeline.
|
|
1678
|
+
*/
|
|
1679
|
+
optimize(config) {
|
|
1680
|
+
if (config?.autoReorder) {
|
|
1681
|
+
this.reorderForPerformance();
|
|
1682
|
+
}
|
|
1683
|
+
if (config?.metrics) {
|
|
1684
|
+
this.enableProfiling();
|
|
1685
|
+
}
|
|
1686
|
+
this.bufferStartupLog("Middleware pipeline optimized");
|
|
1687
|
+
}
|
|
1688
|
+
/**
|
|
1689
|
+
* Reorder middleware for optimal performance.
|
|
1690
|
+
*/
|
|
1691
|
+
reorderForPerformance() {
|
|
1692
|
+
// Priority order: security first, then parsers, then logging, then others
|
|
1693
|
+
const priorityOrder = {
|
|
1694
|
+
security: 1,
|
|
1695
|
+
parser: 2,
|
|
1696
|
+
logging: 3,
|
|
1697
|
+
session: 4,
|
|
1698
|
+
validation: 5,
|
|
1699
|
+
static: 6,
|
|
1700
|
+
other: 7,
|
|
1701
|
+
error: 100, // Error handlers go last
|
|
1702
|
+
};
|
|
1703
|
+
this.middlewarePipeline.sort((a, b) => {
|
|
1704
|
+
const priorityA = priorityOrder[a.category] || 50;
|
|
1705
|
+
const priorityB = priorityOrder[b.category] || 50;
|
|
1706
|
+
if (priorityA !== priorityB) {
|
|
1707
|
+
return priorityA - priorityB;
|
|
1708
|
+
}
|
|
1709
|
+
return a.order - b.order;
|
|
1710
|
+
});
|
|
1711
|
+
this.invalidateCache();
|
|
1712
|
+
}
|
|
1713
|
+
/**
|
|
1714
|
+
* Analyze middleware pipeline.
|
|
1715
|
+
*/
|
|
1716
|
+
analyze() {
|
|
1717
|
+
const info = this.getPipelineInfo();
|
|
1718
|
+
const issues = [];
|
|
1719
|
+
const bottlenecks = [];
|
|
1720
|
+
// Check for common issues
|
|
1721
|
+
if (!this.middlewareExists("jsonParser")) {
|
|
1722
|
+
issues.push("No JSON body parser configured");
|
|
1723
|
+
}
|
|
1724
|
+
if (!this.middlewareExists("compression") &&
|
|
1725
|
+
process.env.NODE_ENV === "production") {
|
|
1726
|
+
issues.push("Compression not enabled in production");
|
|
1727
|
+
}
|
|
1728
|
+
if (!this.middlewareExists("rateLimit") &&
|
|
1729
|
+
process.env.NODE_ENV === "production") {
|
|
1730
|
+
issues.push("Rate limiting not enabled in production");
|
|
1731
|
+
}
|
|
1732
|
+
// Identify potential bottlenecks
|
|
1733
|
+
if (this.profilingEnabled && this.profiler) {
|
|
1734
|
+
const metrics = this.profiler.getAllMetrics();
|
|
1735
|
+
for (const metric of metrics) {
|
|
1736
|
+
if (metric.avgExecutionMs > 50) {
|
|
1737
|
+
bottlenecks.push(`${metric.name}: avg ${metric.avgExecutionMs.toFixed(2)}ms`);
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
return {
|
|
1742
|
+
count: info.total,
|
|
1743
|
+
estimatedOverhead: info.total * 0.1, // Rough estimate: 0.1ms per middleware
|
|
1744
|
+
order: info.entries.map((e) => ({
|
|
1745
|
+
name: e.name,
|
|
1746
|
+
category: e.category,
|
|
1747
|
+
isBuiltIn: e.type === "built-in",
|
|
1748
|
+
})),
|
|
1749
|
+
issues,
|
|
1750
|
+
bottlenecks,
|
|
1751
|
+
};
|
|
1752
|
+
}
|
|
1753
|
+
/**
|
|
1754
|
+
* Get recommendations for improvement.
|
|
1755
|
+
*/
|
|
1756
|
+
getRecommendations() {
|
|
1757
|
+
const recommendations = [];
|
|
1758
|
+
const analysis = this.analyze();
|
|
1759
|
+
// Check compression
|
|
1760
|
+
if (!this.middlewareExists("compression")) {
|
|
1761
|
+
recommendations.push({
|
|
1762
|
+
type: "performance",
|
|
1763
|
+
severity: "medium",
|
|
1764
|
+
message: "Compression is not enabled. Responses can be 60-80% smaller.",
|
|
1765
|
+
action: "this.Middleware.compress()",
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
// Check rate limiting in production
|
|
1769
|
+
if (!this.middlewareExists("rateLimit") &&
|
|
1770
|
+
process.env.NODE_ENV === "production") {
|
|
1771
|
+
recommendations.push({
|
|
1772
|
+
type: "security",
|
|
1773
|
+
severity: "high",
|
|
1774
|
+
message: "Rate limiting not enabled in production. API is vulnerable to abuse.",
|
|
1775
|
+
action: "this.Middleware.security({ rateLimit: true })",
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
// Check helmet in production
|
|
1779
|
+
if (!this.middlewareExists("helmet") &&
|
|
1780
|
+
process.env.NODE_ENV === "production") {
|
|
1781
|
+
recommendations.push({
|
|
1782
|
+
type: "security",
|
|
1783
|
+
severity: "high",
|
|
1784
|
+
message: "Security headers (Helmet) not enabled in production.",
|
|
1785
|
+
action: "this.Middleware.security('standard')",
|
|
1786
|
+
});
|
|
1787
|
+
}
|
|
1788
|
+
// Check for issues
|
|
1789
|
+
for (const issue of analysis.issues) {
|
|
1790
|
+
recommendations.push({
|
|
1791
|
+
type: "best-practice",
|
|
1792
|
+
severity: "low",
|
|
1793
|
+
message: issue,
|
|
1794
|
+
});
|
|
1795
|
+
}
|
|
1796
|
+
return recommendations;
|
|
1797
|
+
}
|
|
1798
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1799
|
+
// V4 ALIAS: add() for addMiddleware()
|
|
1800
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1801
|
+
/**
|
|
1802
|
+
* Add custom middleware to global pipeline.
|
|
1803
|
+
* Alias for addMiddleware() with shorter name.
|
|
1804
|
+
*/
|
|
1805
|
+
add(middleware) {
|
|
1806
|
+
this.addMiddleware(middleware);
|
|
1807
|
+
}
|
|
1808
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1809
|
+
// V4 RENDER ENGINE
|
|
1810
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1811
|
+
/** Render service instance (lazy initialized) */
|
|
1812
|
+
renderService = null;
|
|
1813
|
+
/** Express app reference for render service */
|
|
1814
|
+
expressApp = null;
|
|
1815
|
+
/**
|
|
1816
|
+
* Set the Express app reference for render service initialization.
|
|
1817
|
+
* Called internally by AppExpress.
|
|
1818
|
+
* @internal
|
|
1819
|
+
*/
|
|
1820
|
+
setExpressApp(app) {
|
|
1821
|
+
this.expressApp = app;
|
|
1822
|
+
}
|
|
1823
|
+
/**
|
|
1824
|
+
* Configure view rendering with unified API.
|
|
1825
|
+
* Supports traditional engines (EJS, Pug, Handlebars) and modern frameworks (React, Vue, Svelte).
|
|
1826
|
+
*
|
|
1827
|
+
* @param config - Render configuration or preset name
|
|
1828
|
+
*/
|
|
1829
|
+
async render(config) {
|
|
1830
|
+
if (!this.expressApp) {
|
|
1831
|
+
throw new Error("Express app not available. render() must be called within configureServices().");
|
|
1832
|
+
}
|
|
1833
|
+
// Lazy import to avoid circular dependencies.
|
|
1834
|
+
// The `.js` extension is required by NodeNext for ESM consumers; the
|
|
1835
|
+
// CJS build also accepts it (TypeScript rewrites unchanged).
|
|
1836
|
+
const { RenderService } = await import("../render/render-service.js");
|
|
1837
|
+
if (!this.renderService) {
|
|
1838
|
+
this.renderService = new RenderService(this.expressApp);
|
|
1839
|
+
}
|
|
1840
|
+
await this.renderService.configure(config || {});
|
|
1841
|
+
// Buffer startup log
|
|
1842
|
+
const engine = this.renderService.getActiveEngine().name;
|
|
1843
|
+
this.bufferStartupLog(`Render engine configured: ${engine}`, "info");
|
|
1844
|
+
}
|
|
1845
|
+
/**
|
|
1846
|
+
* Get the render service instance.
|
|
1847
|
+
*
|
|
1848
|
+
* @returns Render service or null if not configured
|
|
1849
|
+
*/
|
|
1850
|
+
getRenderService() {
|
|
1851
|
+
return this.renderService;
|
|
1852
|
+
}
|
|
1853
|
+
}
|