@stacksjs/bun-router 0.0.4 → 0.0.6
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 +2 -2
- package/dist/auth.d.ts +134 -0
- package/dist/cache/lru-cache.d.ts +139 -0
- package/dist/cache/middleware-memoization.d.ts +151 -0
- package/dist/cache/route-cache-warmer.d.ts +161 -0
- package/dist/cache/sqlite-cache.d.ts +209 -0
- package/dist/cache/streaming-cache.d.ts +132 -0
- package/dist/chunk-jhsk5c5b.js +15758 -0
- package/dist/cli/colors.d.ts +15 -0
- package/dist/cli/index.d.ts +10 -0
- package/dist/cli/middleware.d.ts +31 -0
- package/dist/cli/openapi.d.ts +17 -0
- package/dist/cli/router.d.ts +15 -0
- package/dist/cli/routes.d.ts +29 -0
- package/dist/cli/utils.d.ts +74 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +2 -2
- package/dist/config.d.ts +7 -0
- package/dist/container/container.d.ts +273 -0
- package/dist/container/contextual-binding.d.ts +240 -0
- package/dist/container/decorators.d.ts +141 -0
- package/dist/container/service-provider.d.ts +285 -0
- package/dist/development/hot-reload.d.ts +187 -0
- package/dist/development/index.d.ts +167 -0
- package/dist/development/performance-profiler.d.ts +217 -0
- package/dist/development/route-debugger.d.ts +154 -0
- package/dist/development/route-inspector.d.ts +211 -0
- package/dist/development/typescript-utilities.d.ts +209 -0
- package/dist/docs.d.ts +11 -0
- package/dist/errors/circuit-breaker.d.ts +195 -0
- package/dist/errors/error-handler.d.ts +88 -0
- package/dist/errors/error-reporting.d.ts +144 -0
- package/dist/errors/exceptions.d.ts +184 -0
- package/dist/errors/graceful-degradation.d.ts +154 -0
- package/dist/errors/index.d.ts +9 -0
- package/dist/errors/router-errors.d.ts +110 -0
- package/dist/file-serving/static-files.d.ts +143 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +320 -206
- package/dist/middleware/auth.d.ts +63 -0
- package/dist/middleware/content_security_policy.d.ts +53 -0
- package/dist/middleware/cors.d.ts +5 -0
- package/dist/middleware/csrf.d.ts +7 -0
- package/dist/middleware/ddos_protection.d.ts +39 -0
- package/dist/middleware/file_security.d.ts +26 -0
- package/dist/middleware/file_upload.d.ts +38 -0
- package/dist/middleware/helmet.d.ts +54 -0
- package/dist/middleware/index.d.ts +44 -0
- package/dist/middleware/input_validation.d.ts +45 -0
- package/dist/middleware/json_body.d.ts +4 -0
- package/dist/middleware/performance_alerting.d.ts +87 -0
- package/dist/middleware/performance_dashboard.d.ts +87 -0
- package/dist/middleware/performance_monitor.d.ts +209 -0
- package/dist/middleware/pipeline.d.ts +131 -0
- package/dist/middleware/rate_limit.d.ts +36 -0
- package/dist/middleware/request_id.d.ts +4 -0
- package/dist/middleware/request_signing.d.ts +153 -0
- package/dist/middleware/request_tracer.d.ts +72 -0
- package/dist/middleware/response_cache.d.ts +97 -0
- package/dist/middleware/security.d.ts +69 -0
- package/dist/middleware/security_suite.d.ts +46 -0
- package/dist/middleware/session.d.ts +23 -0
- package/dist/model-binding/index.d.ts +2 -0
- package/dist/model-binding/model-middleware.d.ts +118 -0
- package/dist/model-binding/model-registry.d.ts +164 -0
- package/dist/model-binding.d.ts +185 -0
- package/dist/model-resolver-factory.d.ts +31 -0
- package/dist/observability/correlation.d.ts +187 -0
- package/dist/observability/health-checks.d.ts +186 -0
- package/dist/observability/index.d.ts +60 -0
- package/dist/observability/integration.d.ts +147 -0
- package/dist/observability/metrics.d.ts +184 -0
- package/dist/observability/tracing.d.ts +187 -0
- package/dist/optimization/bun-utilities.d.ts +224 -0
- package/dist/query-builder-integration.d.ts +36 -0
- package/dist/request/context.d.ts +34 -0
- package/dist/request/enhanced-request.d.ts +213 -0
- package/dist/request/macros.d.ts +300 -0
- package/dist/response/macros.d.ts +245 -0
- package/dist/response/response-factory.d.ts +133 -0
- package/dist/router/api-routes.d.ts +5 -0
- package/dist/router/file-based-routing.d.ts +118 -0
- package/dist/router/file-streaming.d.ts +5 -0
- package/dist/router/fluent-router.d.ts +315 -0
- package/dist/router/fluent-routing.d.ts +271 -0
- package/dist/router/group-organization.d.ts +5 -0
- package/dist/router/handler-resolver.d.ts +24 -0
- package/dist/router/http-methods.d.ts +10 -0
- package/dist/router/index.d.ts +113 -0
- package/dist/router/middleware-groups.d.ts +94 -0
- package/dist/router/middleware-integration.d.ts +112 -0
- package/dist/router/middleware.d.ts +5 -0
- package/dist/router/model-binding.d.ts +5 -0
- package/dist/router/optimized-route-matching.d.ts +6 -0
- package/dist/router/route-building.d.ts +5 -0
- package/dist/router/route-compiler.d.ts +153 -0
- package/dist/router/route-matching.d.ts +5 -0
- package/dist/router/route-trie.d.ts +114 -0
- package/dist/router/router.d.ts +276 -0
- package/dist/router/server.d.ts +5 -0
- package/dist/router/validation-integration.d.ts +170 -0
- package/dist/router/view-rendering.d.ts +5 -0
- package/dist/router/websocket.d.ts +5 -0
- package/dist/routing/route-caching.d.ts +129 -0
- package/dist/routing/route-throttling.d.ts +150 -0
- package/dist/routing/subdomain-routing.d.ts +206 -0
- package/dist/session/database-store.d.ts +51 -0
- package/dist/session/file-store.d.ts +22 -0
- package/dist/session/index.d.ts +106 -0
- package/dist/session/memory-store.d.ts +21 -0
- package/dist/session/redis-store.d.ts +31 -0
- package/dist/streaming/index.d.ts +3 -0
- package/dist/streaming/sse-handler.d.ts +138 -0
- package/dist/streaming/stream-handler.d.ts +114 -0
- package/dist/testing/auth-testing.d.ts +156 -0
- package/dist/testing/file-upload-testing.d.ts +190 -0
- package/dist/testing/index.d.ts +10 -0
- package/dist/testing/middleware-testing.d.ts +138 -0
- package/dist/testing/model-binding-testing.d.ts +186 -0
- package/dist/testing/performance-testing.d.ts +235 -0
- package/dist/testing/test-client.d.ts +117 -0
- package/dist/testing/test-request.d.ts +85 -0
- package/dist/testing/test-response.d.ts +90 -0
- package/dist/testing/types.d.ts +207 -0
- package/dist/testing/websocket-testing.d.ts +227 -0
- package/dist/types/controller-types.d.ts +208 -0
- package/dist/types/core.d.ts +543 -0
- package/dist/types/middleware-types.d.ts +227 -0
- package/dist/types/request-response-augmentation.d.ts +261 -0
- package/dist/types/route-inference.d.ts +168 -0
- package/dist/types.d.ts +1776 -0
- package/dist/url.d.ts +56 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/query-preservation.d.ts +48 -0
- package/dist/utils.d.ts +69 -0
- package/dist/validation/validator.d.ts +140 -0
- package/dist/websocket/clustering.d.ts +185 -0
- package/package.json +18 -4
- package/src/auth.ts +469 -0
- package/src/cache/lru-cache.ts +457 -0
- package/src/cache/middleware-memoization.ts +531 -0
- package/src/cache/route-cache-warmer.ts +486 -0
- package/src/cache/sqlite-cache.ts +783 -0
- package/src/cache/streaming-cache.ts +572 -0
- package/src/cli/colors.ts +29 -0
- package/src/cli/index.ts +287 -0
- package/src/cli/middleware.ts +291 -0
- package/src/cli/openapi.ts +407 -0
- package/src/cli/router.ts +188 -0
- package/src/cli/routes.ts +265 -0
- package/src/cli/utils.ts +531 -0
- package/src/cli.ts +5 -0
- package/src/config.ts +322 -0
- package/src/container/container.ts +740 -0
- package/src/container/contextual-binding.ts +603 -0
- package/src/container/decorators.ts +359 -0
- package/src/container/service-provider.ts +596 -0
- package/src/development/hot-reload.ts +673 -0
- package/src/development/index.ts +499 -0
- package/src/development/performance-profiler.ts +717 -0
- package/src/development/route-debugger.ts +527 -0
- package/src/development/route-inspector.ts +749 -0
- package/src/development/typescript-utilities.ts +678 -0
- package/src/docs.ts +397 -0
- package/src/errors/circuit-breaker.ts +732 -0
- package/src/errors/error-handler.ts +569 -0
- package/src/errors/error-reporting.ts +672 -0
- package/src/errors/exceptions.ts +536 -0
- package/src/errors/graceful-degradation.ts +621 -0
- package/src/errors/index.ts +21 -0
- package/src/errors/router-errors.ts +632 -0
- package/src/file-serving/static-files.ts +581 -0
- package/src/index.ts +14 -0
- package/src/middleware/auth.ts +219 -0
- package/src/middleware/content_security_policy.ts +215 -0
- package/src/middleware/cors.ts +74 -0
- package/src/middleware/csrf.ts +108 -0
- package/src/middleware/ddos_protection.ts +255 -0
- package/src/middleware/file_security.ts +191 -0
- package/src/middleware/file_upload.ts +264 -0
- package/src/middleware/helmet.ts +268 -0
- package/src/middleware/index.ts +117 -0
- package/src/middleware/input_validation.ts +449 -0
- package/src/middleware/json_body.ts +37 -0
- package/src/middleware/performance_alerting.ts +538 -0
- package/src/middleware/performance_dashboard.ts +661 -0
- package/src/middleware/performance_monitor.ts +943 -0
- package/src/middleware/pipeline.ts +489 -0
- package/src/middleware/rate_limit.ts +245 -0
- package/src/middleware/request_id.ts +36 -0
- package/src/middleware/request_signing.ts +636 -0
- package/src/middleware/request_tracer.ts +636 -0
- package/src/middleware/response_cache.ts +743 -0
- package/src/middleware/security.ts +482 -0
- package/src/middleware/security_suite.ts +257 -0
- package/src/middleware/session.ts +91 -0
- package/src/model-binding/index.ts +18 -0
- package/src/model-binding/model-middleware.ts +425 -0
- package/src/model-binding/model-registry.ts +550 -0
- package/src/model-binding.ts +370 -0
- package/src/model-resolver-factory.ts +106 -0
- package/src/observability/correlation.ts +691 -0
- package/src/observability/health-checks.ts +729 -0
- package/src/observability/index.ts +184 -0
- package/src/observability/integration.ts +548 -0
- package/src/observability/metrics.ts +753 -0
- package/src/observability/tracing.ts +638 -0
- package/src/optimization/bun-utilities.ts +778 -0
- package/src/query-builder-integration.ts +137 -0
- package/src/request/context.ts +62 -0
- package/src/request/enhanced-request.ts +857 -0
- package/src/request/macros.ts +688 -0
- package/src/response/macros.ts +612 -0
- package/src/response/response-factory.ts +588 -0
- package/src/router/api-routes.ts +243 -0
- package/src/router/file-based-routing.ts +670 -0
- package/src/router/file-streaming.ts +372 -0
- package/src/router/fluent-router.ts +927 -0
- package/src/router/fluent-routing.ts +797 -0
- package/src/router/group-organization.ts +213 -0
- package/src/router/handler-resolver.ts +291 -0
- package/src/router/http-methods.ts +377 -0
- package/src/router/index.ts +185 -0
- package/src/router/middleware-groups.ts +222 -0
- package/src/router/middleware-integration.ts +399 -0
- package/src/router/middleware.ts +231 -0
- package/src/router/model-binding.ts +215 -0
- package/src/router/optimized-route-matching.ts +253 -0
- package/src/router/route-building.ts +212 -0
- package/src/router/route-compiler.ts +702 -0
- package/src/router/route-matching.ts +349 -0
- package/src/router/route-trie.ts +464 -0
- package/src/router/router.ts +1508 -0
- package/src/router/server.ts +406 -0
- package/src/router/validation-integration.ts +443 -0
- package/src/router/view-rendering.ts +233 -0
- package/src/router/websocket.ts +100 -0
- package/src/routing/route-caching.ts +402 -0
- package/src/routing/route-throttling.ts +469 -0
- package/src/routing/subdomain-routing.ts +492 -0
- package/src/session/database-store.ts +109 -0
- package/src/session/file-store.ts +148 -0
- package/src/session/index.ts +244 -0
- package/src/session/memory-store.ts +88 -0
- package/src/session/redis-store.ts +93 -0
- package/src/streaming/index.ts +17 -0
- package/src/streaming/sse-handler.ts +482 -0
- package/src/streaming/stream-handler.ts +552 -0
- package/src/testing/auth-testing.ts +446 -0
- package/src/testing/file-upload-testing.ts +543 -0
- package/src/testing/index.ts +10 -0
- package/src/testing/middleware-testing.ts +322 -0
- package/src/testing/model-binding-testing.ts +645 -0
- package/src/testing/performance-testing.ts +738 -0
- package/src/testing/test-client.ts +310 -0
- package/src/testing/test-request.ts +315 -0
- package/src/testing/test-response.ts +332 -0
- package/src/testing/types.ts +224 -0
- package/src/testing/websocket-testing.ts +590 -0
- package/src/types/controller-types.ts +385 -0
- package/src/types/core.ts +683 -0
- package/src/types/middleware-types.ts +419 -0
- package/src/types/request-response-augmentation.ts +489 -0
- package/src/types/route-inference.ts +357 -0
- package/src/types.ts +2049 -0
- package/src/url.ts +126 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/query-preservation.ts +201 -0
- package/src/utils.ts +327 -0
- package/src/validation/validator.ts +685 -0
- package/src/websocket/clustering.ts +762 -0
- package/dist/chunk-cjdekj87.js +0 -25886
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
/* eslint-disable ts/no-unsafe-function-type */
|
|
2
|
+
/**
|
|
3
|
+
* Service Providers for Bootstrapping
|
|
4
|
+
*
|
|
5
|
+
* Service provider system for registering services, managing lifecycle,
|
|
6
|
+
* and bootstrapping application components with dependency injection
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { BindingBuilder, Container, ResolutionContext } from './container'
|
|
10
|
+
|
|
11
|
+
// Service provider interfaces
|
|
12
|
+
export interface ServiceProvider {
|
|
13
|
+
/**
|
|
14
|
+
* Register services in the container
|
|
15
|
+
*/
|
|
16
|
+
register: (container: Container) => void | Promise<void>
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Boot services after all providers are registered
|
|
20
|
+
*/
|
|
21
|
+
boot?: (container: Container) => void | Promise<void>
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Shutdown services gracefully
|
|
25
|
+
*/
|
|
26
|
+
shutdown?: (container: Container) => void | Promise<void>
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Provider metadata
|
|
30
|
+
*/
|
|
31
|
+
readonly name: string
|
|
32
|
+
readonly version?: string
|
|
33
|
+
readonly dependencies?: readonly string[]
|
|
34
|
+
readonly environment?: string[]
|
|
35
|
+
readonly priority?: number
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface DeferredServiceProvider extends ServiceProvider {
|
|
39
|
+
/**
|
|
40
|
+
* Services that should trigger loading of this provider
|
|
41
|
+
*/
|
|
42
|
+
provides: () => (string | symbol | Function)[]
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Check if provider should be loaded
|
|
46
|
+
*/
|
|
47
|
+
isDeferred: () => boolean
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ConditionalServiceProvider extends ServiceProvider {
|
|
51
|
+
/**
|
|
52
|
+
* Check if provider should be loaded based on environment
|
|
53
|
+
*/
|
|
54
|
+
shouldLoad: (container: Container) => boolean | Promise<boolean>
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Service provider manager
|
|
58
|
+
export interface ServiceProviderManager {
|
|
59
|
+
register: (provider: ServiceProvider) => this
|
|
60
|
+
boot: () => Promise<void>
|
|
61
|
+
shutdown: () => Promise<void>
|
|
62
|
+
getProvider: (name: string) => ServiceProvider | undefined
|
|
63
|
+
getProviders: () => ServiceProvider[]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Base service provider implementation
|
|
68
|
+
*/
|
|
69
|
+
export abstract class BaseServiceProvider implements ServiceProvider {
|
|
70
|
+
abstract readonly name: string
|
|
71
|
+
readonly version?: string
|
|
72
|
+
readonly dependencies?: readonly string[]
|
|
73
|
+
readonly environment?: string[]
|
|
74
|
+
readonly priority: number = 0
|
|
75
|
+
|
|
76
|
+
abstract register(container: Container): void | Promise<void>
|
|
77
|
+
|
|
78
|
+
boot?(_container: Container): void | Promise<void> {
|
|
79
|
+
// Default implementation - override if needed
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
shutdown?(_container: Container): void | Promise<void> {
|
|
83
|
+
// Default implementation - override if needed
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Helper method to bind singleton
|
|
88
|
+
*/
|
|
89
|
+
protected singleton<T>(
|
|
90
|
+
container: Container,
|
|
91
|
+
token: string | symbol | Function,
|
|
92
|
+
implementation: new (...args: any[]) => T,
|
|
93
|
+
): void {
|
|
94
|
+
container.singleton(token, implementation)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Helper method to bind transient
|
|
99
|
+
*/
|
|
100
|
+
protected transient<T>(
|
|
101
|
+
container: Container,
|
|
102
|
+
token: string | symbol | Function,
|
|
103
|
+
implementation: new (...args: any[]) => T,
|
|
104
|
+
): void {
|
|
105
|
+
container.transient(token, implementation)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Helper method to bind value
|
|
110
|
+
*/
|
|
111
|
+
protected value<T>(
|
|
112
|
+
container: Container,
|
|
113
|
+
token: string | symbol | Function,
|
|
114
|
+
value: T,
|
|
115
|
+
): void {
|
|
116
|
+
container.value(token, value)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Helper method to bind factory
|
|
121
|
+
*/
|
|
122
|
+
protected factory<T>(
|
|
123
|
+
container: Container,
|
|
124
|
+
token: string | symbol | Function,
|
|
125
|
+
factory: (...args: any[]) => T,
|
|
126
|
+
): void {
|
|
127
|
+
container.factory(token, factory)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Helper method for conditional binding
|
|
132
|
+
*/
|
|
133
|
+
protected when(
|
|
134
|
+
container: Container,
|
|
135
|
+
condition: (context: ResolutionContext) => boolean,
|
|
136
|
+
): { bind: <T>(token: string | symbol | Function) => BindingBuilder<T> } {
|
|
137
|
+
return {
|
|
138
|
+
bind: <T>(token: string | symbol | Function): BindingBuilder<T> => {
|
|
139
|
+
return container.bind<T>(token).when(condition)
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Helper method for environment-specific binding
|
|
146
|
+
*/
|
|
147
|
+
protected forEnvironment(container: Container, ...environments: string[]): { bind: <T>(token: string | symbol | Function) => BindingBuilder<T> } {
|
|
148
|
+
return this.when(container, context =>
|
|
149
|
+
environments.includes(context.environment || 'development'))
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Deferred service provider base class
|
|
155
|
+
*/
|
|
156
|
+
export abstract class BaseDeferredServiceProvider extends BaseServiceProvider implements DeferredServiceProvider {
|
|
157
|
+
abstract provides(): (string | symbol | Function)[]
|
|
158
|
+
|
|
159
|
+
isDeferred(): boolean {
|
|
160
|
+
return true
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Service provider manager implementation
|
|
166
|
+
*/
|
|
167
|
+
export class DefaultServiceProviderManager implements ServiceProviderManager {
|
|
168
|
+
private providers = new Map<string, ServiceProvider>()
|
|
169
|
+
private deferredProviders = new Map<string, DeferredServiceProvider>()
|
|
170
|
+
private loadedProviders = new Set<string>()
|
|
171
|
+
private bootedProviders = new Set<string>()
|
|
172
|
+
private container: Container
|
|
173
|
+
|
|
174
|
+
constructor(container: Container) {
|
|
175
|
+
this.container = container
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Register a service provider
|
|
180
|
+
*/
|
|
181
|
+
register(provider: ServiceProvider): this {
|
|
182
|
+
// Check if provider should be loaded
|
|
183
|
+
if (this.isConditionalProvider(provider)) {
|
|
184
|
+
const shouldLoad = provider.shouldLoad(this.container)
|
|
185
|
+
if (shouldLoad instanceof Promise) {
|
|
186
|
+
shouldLoad.then((load) => {
|
|
187
|
+
if (load) {
|
|
188
|
+
this.doRegister(provider)
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
else if (!shouldLoad) {
|
|
193
|
+
return this
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
this.doRegister(provider)
|
|
198
|
+
return this
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Boot all registered providers
|
|
203
|
+
*/
|
|
204
|
+
async boot(): Promise<void> {
|
|
205
|
+
// Sort providers by priority (higher priority first)
|
|
206
|
+
const providers = Array.from(this.providers.values())
|
|
207
|
+
.sort((a, b) => (b.priority || 0) - (a.priority || 0))
|
|
208
|
+
|
|
209
|
+
// Check dependencies
|
|
210
|
+
this.validateDependencies(providers)
|
|
211
|
+
|
|
212
|
+
// Register all providers first
|
|
213
|
+
for (const provider of providers) {
|
|
214
|
+
if (!this.loadedProviders.has(provider.name)) {
|
|
215
|
+
await this.loadProvider(provider)
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Boot all providers
|
|
220
|
+
for (const provider of providers) {
|
|
221
|
+
if (!this.bootedProviders.has(provider.name)) {
|
|
222
|
+
await this.bootProvider(provider)
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Shutdown all providers
|
|
229
|
+
*/
|
|
230
|
+
async shutdown(): Promise<void> {
|
|
231
|
+
const providers = Array.from(this.providers.values())
|
|
232
|
+
.reverse() // Shutdown in reverse order
|
|
233
|
+
|
|
234
|
+
for (const provider of providers) {
|
|
235
|
+
if (provider.shutdown) {
|
|
236
|
+
try {
|
|
237
|
+
await provider.shutdown(this.container)
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
console.error(`Error shutting down provider ${provider.name}:`, error)
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
this.providers.clear()
|
|
246
|
+
this.deferredProviders.clear()
|
|
247
|
+
this.loadedProviders.clear()
|
|
248
|
+
this.bootedProviders.clear()
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Get provider by name
|
|
253
|
+
*/
|
|
254
|
+
getProvider(name: string): ServiceProvider | undefined {
|
|
255
|
+
return this.providers.get(name)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Get all providers
|
|
260
|
+
*/
|
|
261
|
+
getProviders(): ServiceProvider[] {
|
|
262
|
+
return Array.from(this.providers.values())
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Load deferred provider when needed
|
|
267
|
+
*/
|
|
268
|
+
async loadDeferredProvider(token: string | symbol | Function): Promise<void> {
|
|
269
|
+
for (const [name, provider] of this.deferredProviders) {
|
|
270
|
+
if (provider.provides().includes(token) && !this.loadedProviders.has(name)) {
|
|
271
|
+
await this.loadProvider(provider)
|
|
272
|
+
await this.bootProvider(provider)
|
|
273
|
+
this.deferredProviders.delete(name)
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Internal registration logic
|
|
280
|
+
*/
|
|
281
|
+
private doRegister(provider: ServiceProvider): void {
|
|
282
|
+
if (this.providers.has(provider.name)) {
|
|
283
|
+
throw new Error(`Provider ${provider.name} is already registered`)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
this.providers.set(provider.name, provider)
|
|
287
|
+
|
|
288
|
+
// Handle deferred providers
|
|
289
|
+
if (this.isDeferredProvider(provider)) {
|
|
290
|
+
this.deferredProviders.set(provider.name, provider)
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Load a provider
|
|
296
|
+
*/
|
|
297
|
+
private async loadProvider(provider: ServiceProvider): Promise<void> {
|
|
298
|
+
try {
|
|
299
|
+
await provider.register(this.container)
|
|
300
|
+
this.loadedProviders.add(provider.name)
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
throw new Error(`Failed to load provider ${provider.name}: ${error}`)
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Boot a provider
|
|
309
|
+
*/
|
|
310
|
+
private async bootProvider(provider: ServiceProvider): Promise<void> {
|
|
311
|
+
if (provider.boot) {
|
|
312
|
+
try {
|
|
313
|
+
await provider.boot(this.container)
|
|
314
|
+
this.bootedProviders.add(provider.name)
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
throw new Error(`Failed to boot provider ${provider.name}: ${error}`)
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
this.bootedProviders.add(provider.name)
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Validate provider dependencies
|
|
327
|
+
*/
|
|
328
|
+
private validateDependencies(providers: ServiceProvider[]): void {
|
|
329
|
+
const providerNames = new Set(providers.map(p => p.name))
|
|
330
|
+
|
|
331
|
+
for (const provider of providers) {
|
|
332
|
+
if (provider.dependencies) {
|
|
333
|
+
for (const dependency of provider.dependencies) {
|
|
334
|
+
if (!providerNames.has(dependency)) {
|
|
335
|
+
throw new Error(
|
|
336
|
+
`Provider ${provider.name} depends on ${dependency}, but it's not registered`,
|
|
337
|
+
)
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Check if provider is deferred
|
|
346
|
+
*/
|
|
347
|
+
private isDeferredProvider(provider: ServiceProvider): provider is DeferredServiceProvider {
|
|
348
|
+
return 'provides' in provider && 'isDeferred' in provider
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Check if provider is conditional
|
|
353
|
+
*/
|
|
354
|
+
private isConditionalProvider(provider: ServiceProvider): provider is ConditionalServiceProvider {
|
|
355
|
+
return 'shouldLoad' in provider
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Common service providers
|
|
361
|
+
*/
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Configuration service provider
|
|
365
|
+
*/
|
|
366
|
+
export class ConfigServiceProvider extends BaseServiceProvider {
|
|
367
|
+
readonly name = 'config'
|
|
368
|
+
readonly priority = 100
|
|
369
|
+
|
|
370
|
+
register(container: Container): void {
|
|
371
|
+
// Register configuration service
|
|
372
|
+
container.singleton('config', ConfigService)
|
|
373
|
+
|
|
374
|
+
// Register environment-specific configs
|
|
375
|
+
this.forEnvironment(container, 'development').bind('config.debug').toValue(true)
|
|
376
|
+
this.forEnvironment(container, 'production').bind('config.debug').toValue(false)
|
|
377
|
+
this.forEnvironment(container, 'test').bind('config.debug').toValue(false)
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Logging service provider
|
|
383
|
+
*/
|
|
384
|
+
export class LoggingServiceProvider extends BaseServiceProvider {
|
|
385
|
+
readonly name = 'logging'
|
|
386
|
+
readonly priority = 90
|
|
387
|
+
|
|
388
|
+
register(container: Container): void {
|
|
389
|
+
// Register logger factory
|
|
390
|
+
container.factory('logger', (config: ConfigService) => {
|
|
391
|
+
return new Logger(config.get('logging', {}))
|
|
392
|
+
})
|
|
393
|
+
|
|
394
|
+
// Register console logger for development
|
|
395
|
+
this.forEnvironment(container, 'development')
|
|
396
|
+
.bind('logger')
|
|
397
|
+
.toFactory(() => new ConsoleLogger())
|
|
398
|
+
|
|
399
|
+
// Register file logger for production
|
|
400
|
+
this.forEnvironment(container, 'production')
|
|
401
|
+
.bind('logger')
|
|
402
|
+
.toFactory((config: ConfigService) =>
|
|
403
|
+
new FileLogger(config.get('logging.file', './app.log')),
|
|
404
|
+
)
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Database service provider
|
|
410
|
+
*/
|
|
411
|
+
export class DatabaseServiceProvider extends BaseServiceProvider {
|
|
412
|
+
readonly name = 'database'
|
|
413
|
+
readonly dependencies = ['config', 'logging'] as const
|
|
414
|
+
|
|
415
|
+
register(container: Container): void {
|
|
416
|
+
// Register database connection
|
|
417
|
+
container.singleton('database', DatabaseConnection)
|
|
418
|
+
|
|
419
|
+
// Register repositories
|
|
420
|
+
container.transient('userRepository', UserRepository)
|
|
421
|
+
container.transient('postRepository', PostRepository)
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
async boot(container: Container): Promise<void> {
|
|
425
|
+
// Initialize database connection
|
|
426
|
+
const db = container.resolve<DatabaseConnection>('database')
|
|
427
|
+
await db.connect()
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
async shutdown(container: Container): Promise<void> {
|
|
431
|
+
// Close database connection
|
|
432
|
+
const db = container.resolve<DatabaseConnection>('database')
|
|
433
|
+
await db.disconnect()
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Cache service provider
|
|
439
|
+
*/
|
|
440
|
+
export class CacheServiceProvider extends BaseServiceProvider {
|
|
441
|
+
readonly name = 'cache'
|
|
442
|
+
readonly dependencies = ['config'] as const
|
|
443
|
+
|
|
444
|
+
register(container: Container): void {
|
|
445
|
+
// Register cache manager
|
|
446
|
+
container.singleton('cache', CacheManager)
|
|
447
|
+
|
|
448
|
+
// Environment-specific cache implementations
|
|
449
|
+
this.forEnvironment(container, 'development')
|
|
450
|
+
.bind('cache.store')
|
|
451
|
+
.toFactory(() => new MemoryCache())
|
|
452
|
+
|
|
453
|
+
this.forEnvironment(container, 'production')
|
|
454
|
+
.bind('cache.store')
|
|
455
|
+
.toFactory((config: ConfigService) =>
|
|
456
|
+
new RedisCache(config.get('cache.redis')),
|
|
457
|
+
)
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Authentication service provider
|
|
463
|
+
*/
|
|
464
|
+
export class AuthServiceProvider extends BaseServiceProvider {
|
|
465
|
+
readonly name = 'auth'
|
|
466
|
+
readonly dependencies = ['config', 'database'] as const
|
|
467
|
+
|
|
468
|
+
register(container: Container): void {
|
|
469
|
+
// Register auth services
|
|
470
|
+
container.singleton('authService', AuthService)
|
|
471
|
+
container.singleton('jwtService', JwtService)
|
|
472
|
+
container.transient('authGuard', AuthGuard)
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Validation service provider
|
|
478
|
+
*/
|
|
479
|
+
export class ValidationServiceProvider extends BaseServiceProvider {
|
|
480
|
+
readonly name = 'validation'
|
|
481
|
+
|
|
482
|
+
register(container: Container): void {
|
|
483
|
+
// Register validation services
|
|
484
|
+
container.singleton('validator', Validator)
|
|
485
|
+
container.factory('validationPipe', (validator: Validator) => new ValidationPipe(validator))
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Event service provider (deferred)
|
|
491
|
+
*/
|
|
492
|
+
export class EventServiceProvider extends BaseDeferredServiceProvider {
|
|
493
|
+
readonly name = 'events'
|
|
494
|
+
|
|
495
|
+
provides(): (string | symbol | Function)[] {
|
|
496
|
+
return ['eventBus', 'eventDispatcher', EventBus, EventDispatcher]
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
register(container: Container): void {
|
|
500
|
+
container.singleton('eventBus', EventBus)
|
|
501
|
+
container.singleton('eventDispatcher', EventDispatcher)
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Mock service classes for demonstration
|
|
506
|
+
class ConfigService {
|
|
507
|
+
get(key: string, defaultValue?: any): any {
|
|
508
|
+
return defaultValue
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
class Logger {
|
|
513
|
+
constructor(private config: any) {}
|
|
514
|
+
log(message: string): void { console.log(message) }
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
class ConsoleLogger extends Logger {
|
|
518
|
+
constructor() { super({}) }
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
class FileLogger extends Logger {
|
|
522
|
+
constructor(private filePath: string) { super({}) }
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
class DatabaseConnection {
|
|
526
|
+
async connect(): Promise<void> { /* implementation */ }
|
|
527
|
+
async disconnect(): Promise<void> { /* implementation */ }
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
class UserRepository {
|
|
531
|
+
constructor(private db: DatabaseConnection) {}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
class PostRepository {
|
|
535
|
+
constructor(private db: DatabaseConnection) {}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
class CacheManager {
|
|
539
|
+
constructor(private store: any) {}
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
class MemoryCache {
|
|
543
|
+
private cache = new Map()
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
class RedisCache {
|
|
547
|
+
constructor(private config: any) {}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
class AuthService {
|
|
551
|
+
constructor(private jwt: JwtService, private userRepo: UserRepository) {}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
class JwtService {
|
|
555
|
+
constructor(private config: ConfigService) {}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
class AuthGuard {
|
|
559
|
+
constructor(private auth: AuthService) {}
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
class Validator {
|
|
563
|
+
validate(_data: any, _rules: any): boolean { return true }
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
class ValidationPipe {
|
|
567
|
+
constructor(private validator: Validator) {}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
class EventBus {
|
|
571
|
+
emit(_event: string, _data: any): void {}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
class EventDispatcher {
|
|
575
|
+
constructor(private bus: EventBus) {}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
export {
|
|
579
|
+
AuthGuard,
|
|
580
|
+
AuthService,
|
|
581
|
+
CacheManager,
|
|
582
|
+
ConfigService,
|
|
583
|
+
ConsoleLogger,
|
|
584
|
+
DatabaseConnection,
|
|
585
|
+
EventBus,
|
|
586
|
+
EventDispatcher,
|
|
587
|
+
FileLogger,
|
|
588
|
+
JwtService,
|
|
589
|
+
Logger,
|
|
590
|
+
MemoryCache,
|
|
591
|
+
PostRepository,
|
|
592
|
+
RedisCache,
|
|
593
|
+
UserRepository,
|
|
594
|
+
ValidationPipe,
|
|
595
|
+
Validator,
|
|
596
|
+
}
|