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