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