decorator-dependency-injection 1.0.7 → 1.1.0
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 +87 -19
- package/docs/FRAMEWORK_INTEGRATION.md +808 -0
- package/eslint.config.js +4 -1
- package/index.d.ts +6 -355
- package/index.js +46 -378
- package/package.json +6 -1
- package/src/Container.js +48 -201
- package/src/integrations/middleware.d.ts +40 -0
- package/src/integrations/middleware.js +171 -0
package/eslint.config.js
CHANGED
package/index.d.ts
CHANGED
|
@@ -1,416 +1,67 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type definitions for decorator-dependency-injection
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A class constructor type.
|
|
7
|
-
* @template T The instance type
|
|
8
|
-
*/
|
|
9
1
|
export type Constructor<T = any> = new (...args: any[]) => T
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Valid injection target: either a class constructor or a string name.
|
|
13
|
-
*/
|
|
14
2
|
export type InjectionToken<T = any> = string | Constructor<T>
|
|
15
3
|
|
|
16
|
-
/**
|
|
17
|
-
* Context for registered instances in the container
|
|
18
|
-
*/
|
|
19
4
|
export interface InstanceContext {
|
|
20
|
-
/** The type of registration */
|
|
21
5
|
type: 'singleton' | 'factory'
|
|
22
|
-
/** The current class constructor (may be a mock) */
|
|
23
6
|
clazz: new (...args: any[]) => any
|
|
24
|
-
/** The original class constructor if mocked */
|
|
25
7
|
originalClazz?: new (...args: any[]) => any
|
|
26
|
-
/** The cached singleton instance */
|
|
27
8
|
instance?: any
|
|
28
|
-
/** Whether to use proxy mocking */
|
|
29
9
|
proxy?: boolean
|
|
30
10
|
}
|
|
31
11
|
|
|
32
|
-
/**
|
|
33
|
-
* Registration info returned by list()
|
|
34
|
-
*/
|
|
35
12
|
export interface RegistrationInfo {
|
|
36
|
-
/** The registration key (class or string name) */
|
|
37
13
|
key: string | Constructor
|
|
38
|
-
/** Human-readable name */
|
|
39
14
|
name: string
|
|
40
|
-
/** Registration type */
|
|
41
15
|
type: 'singleton' | 'factory'
|
|
42
|
-
/** Whether this registration is mocked */
|
|
43
16
|
isMocked: boolean
|
|
44
|
-
/** Whether a cached instance exists */
|
|
45
17
|
hasInstance: boolean
|
|
46
18
|
}
|
|
47
19
|
|
|
48
|
-
/**
|
|
49
|
-
* A dependency injection container that manages singleton and factory instances.
|
|
50
|
-
*/
|
|
51
20
|
export declare class Container {
|
|
52
|
-
/**
|
|
53
|
-
* Custom string tag for better debugging.
|
|
54
|
-
* Shows as [object Container] in console.
|
|
55
|
-
*/
|
|
56
21
|
readonly [Symbol.toStringTag]: 'Container'
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Make the container iterable.
|
|
60
|
-
* Yields registration info for each registered class.
|
|
61
|
-
*/
|
|
62
22
|
[Symbol.iterator](): IterableIterator<RegistrationInfo>
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Get the number of registrations in the container.
|
|
66
|
-
*/
|
|
67
23
|
readonly size: number
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Enable or disable debug logging.
|
|
71
|
-
* When enabled, logs when instances are created.
|
|
72
|
-
*/
|
|
73
24
|
setDebug(enabled: boolean): void
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Register a class as a singleton.
|
|
77
|
-
*/
|
|
78
25
|
registerSingleton<T>(clazz: Constructor<T>, name?: string): void
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Register a class as a factory.
|
|
82
|
-
*/
|
|
83
26
|
registerFactory<T>(clazz: Constructor<T>, name?: string): void
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Get the context for a given class or name.
|
|
87
|
-
* @throws Error if the class/name is not registered
|
|
88
|
-
*/
|
|
89
27
|
getContext<T>(clazzOrName: InjectionToken<T>): InstanceContext
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Check if a class or name is registered.
|
|
93
|
-
*/
|
|
94
28
|
has<T>(clazzOrName: InjectionToken<T>): boolean
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Check if a class or name has a mock registered.
|
|
98
|
-
*/
|
|
99
29
|
isMocked<T>(clazzOrName: InjectionToken<T>): boolean
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Unregister a class or name from the container.
|
|
103
|
-
* @returns true if the registration was removed, false if it wasn't registered
|
|
104
|
-
*/
|
|
105
30
|
unregister<T>(clazzOrName: InjectionToken<T>): boolean
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* List all registrations in the container.
|
|
109
|
-
*/
|
|
110
31
|
list(): RegistrationInfo[]
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Resolve and return an instance by class or name.
|
|
114
|
-
* This allows non-decorator code to retrieve instances from the container.
|
|
115
|
-
*/
|
|
116
32
|
resolve<T>(clazzOrName: InjectionToken<T>, ...params: any[]): T
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Get or create an instance based on the context.
|
|
120
|
-
*/
|
|
121
33
|
getInstance<T>(instanceContext: InstanceContext, params: any[]): T
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Register a mock for an existing class.
|
|
125
|
-
*/
|
|
126
34
|
registerMock<T>(targetClazzOrName: InjectionToken<T>, mockClazz: Constructor<Partial<T>>, useProxy?: boolean): void
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Get the mock instance for a mocked class.
|
|
130
|
-
* @throws Error if the class is not mocked
|
|
131
|
-
*/
|
|
132
35
|
getMockInstance<T>(clazzOrName: InjectionToken<T>, ...params: any[]): T
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Remove a specific mock and restore the original class.
|
|
136
|
-
* This completely removes the mock - it does NOT clear mock call history.
|
|
137
|
-
*/
|
|
138
36
|
removeMock<T>(clazzOrName: InjectionToken<T>): void
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Remove all mocks and restore original classes.
|
|
142
|
-
* This completely removes all mocks - it does NOT clear mock call history.
|
|
143
|
-
*/
|
|
144
37
|
removeAllMocks(): void
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* @deprecated Use removeMock() instead. This will be removed in a future version.
|
|
148
|
-
* WARNING: This removes the mock, it does NOT clear mock call history.
|
|
149
|
-
*/
|
|
150
|
-
resetMock<T>(clazzOrName: InjectionToken<T>): void
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* @deprecated Use removeAllMocks() instead. This will be removed in a future version.
|
|
154
|
-
* WARNING: This removes all mocks, it does NOT clear mock call history.
|
|
155
|
-
*/
|
|
156
|
-
resetAllMocks(): void
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Reset singleton instances without removing registrations.
|
|
160
|
-
* Mock registrations are preserved by default.
|
|
161
|
-
*/
|
|
162
38
|
resetSingletons(options?: { preserveMocks?: boolean }): void
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Clear all registered instances and mocks.
|
|
166
|
-
* @param options.preserveRegistrations If true, keeps all registrations but clears cached instances.
|
|
167
|
-
*/
|
|
168
39
|
clear(options?: { preserveRegistrations?: boolean }): void
|
|
169
40
|
}
|
|
170
41
|
|
|
171
|
-
/**
|
|
172
|
-
* Register a class as a singleton.
|
|
173
|
-
* @param name Optional name to register the singleton under
|
|
174
|
-
*/
|
|
175
|
-
export declare function Singleton(name?: string): ClassDecorator
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Register a class as a factory.
|
|
179
|
-
* @param name Optional name to register the factory under
|
|
180
|
-
*/
|
|
181
|
-
export declare function Factory(name?: string): ClassDecorator
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Decorator return type that works for both fields and accessors.
|
|
185
|
-
* For fields, returns a function that provides the initial value.
|
|
186
|
-
* For accessors, returns an object with get/set/init.
|
|
187
|
-
*/
|
|
188
42
|
export type FieldOrAccessorDecorator = (
|
|
189
43
|
target: undefined,
|
|
190
44
|
context: ClassFieldDecoratorContext | ClassAccessorDecoratorContext
|
|
191
45
|
) => void | ((initialValue: any) => any) | ClassAccessorDecoratorResult<any, any>
|
|
192
46
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
* - Private fields: `@Inject(MyClass) #myField`
|
|
199
|
-
* - Public accessors: `@Inject(MyClass) accessor myField`
|
|
200
|
-
* - Private accessors: `@Inject(MyClass) accessor #myField`
|
|
201
|
-
*
|
|
202
|
-
* @param clazzOrName The class or name to inject
|
|
203
|
-
* @param params Optional parameters to pass to the constructor
|
|
204
|
-
*
|
|
205
|
-
* @example
|
|
206
|
-
* class MyService {
|
|
207
|
-
* @Inject(Database) db
|
|
208
|
-
* @Inject(Logger) #logger // private field
|
|
209
|
-
* @Inject(Cache) accessor cache // accessor (recommended for lazy-like behavior)
|
|
210
|
-
* }
|
|
211
|
-
*/
|
|
212
|
-
export declare function Inject<T>(
|
|
213
|
-
clazzOrName: InjectionToken<T>,
|
|
214
|
-
...params: any[]
|
|
215
|
-
): FieldOrAccessorDecorator
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Inject a singleton or factory instance lazily into a class field or accessor.
|
|
219
|
-
* The instance is created on first access.
|
|
220
|
-
*
|
|
221
|
-
* Supports:
|
|
222
|
-
* - Public fields: `@InjectLazy(MyClass) myField` (true lazy)
|
|
223
|
-
* - Private fields: `@InjectLazy(MyClass) #myField` (not truly lazy - use accessor instead)
|
|
224
|
-
* - Public accessors: `@InjectLazy(MyClass) accessor myField` (true lazy)
|
|
225
|
-
* - Private accessors: `@InjectLazy(MyClass) accessor #myField` (true lazy, recommended)
|
|
226
|
-
*
|
|
227
|
-
* Note: For true lazy injection with private members, use the accessor syntax:
|
|
228
|
-
* `@InjectLazy(MyClass) accessor #myField`
|
|
229
|
-
*
|
|
230
|
-
* @param clazzOrName The class or name to inject
|
|
231
|
-
* @param params Optional parameters to pass to the constructor
|
|
232
|
-
*
|
|
233
|
-
* @example
|
|
234
|
-
* class MyService {
|
|
235
|
-
* @InjectLazy(ExpensiveService) accessor #expensiveService
|
|
236
|
-
* }
|
|
237
|
-
*/
|
|
238
|
-
export declare function InjectLazy<T>(
|
|
239
|
-
clazzOrName: InjectionToken<T>,
|
|
240
|
-
...params: any[]
|
|
241
|
-
): FieldOrAccessorDecorator
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Mark a class as a mock for another class.
|
|
245
|
-
* The mock class can implement only the methods you need (Partial<T>).
|
|
246
|
-
*
|
|
247
|
-
* @param mockedClazzOrName The class or name to mock
|
|
248
|
-
* @param proxy If true, unmocked methods delegate to the original implementation
|
|
249
|
-
*
|
|
250
|
-
* @example Basic mocking
|
|
251
|
-
* ```ts
|
|
252
|
-
* @Mock(UserService)
|
|
253
|
-
* class MockUserService {
|
|
254
|
-
* // Only implement methods you need to mock
|
|
255
|
-
* getUser() { return { id: 1, name: 'Test' } }
|
|
256
|
-
* }
|
|
257
|
-
* ```
|
|
258
|
-
*
|
|
259
|
-
* @example With hoisted mock functions (Vitest/Jest)
|
|
260
|
-
* ```ts
|
|
261
|
-
* const mockGetUser = vi.hoisted(() => vi.fn())
|
|
262
|
-
*
|
|
263
|
-
* @Mock(UserService)
|
|
264
|
-
* class MockUserService {
|
|
265
|
-
* getUser = mockGetUser
|
|
266
|
-
* }
|
|
267
|
-
*
|
|
268
|
-
* beforeEach(() => {
|
|
269
|
-
* mockGetUser.mockClear() // Clear call history, not removeMock()
|
|
270
|
-
* })
|
|
271
|
-
* ```
|
|
272
|
-
*/
|
|
273
|
-
export declare function Mock<T>(
|
|
274
|
-
mockedClazzOrName: InjectionToken<T>,
|
|
275
|
-
proxy?: boolean
|
|
276
|
-
): ClassDecorator
|
|
47
|
+
export declare function Singleton(name?: string): ClassDecorator
|
|
48
|
+
export declare function Factory(name?: string): ClassDecorator
|
|
49
|
+
export declare function Inject<T>(clazzOrName: InjectionToken<T>, ...params: any[]): FieldOrAccessorDecorator
|
|
50
|
+
export declare function InjectLazy<T>(clazzOrName: InjectionToken<T>, ...params: any[]): FieldOrAccessorDecorator
|
|
51
|
+
export declare function Mock<T>(mockedClazzOrName: InjectionToken<T>, proxy?: boolean): ClassDecorator
|
|
277
52
|
|
|
278
|
-
/**
|
|
279
|
-
* Remove all mocks and restore original classes.
|
|
280
|
-
* This completely removes all mocks - it does NOT clear mock call history.
|
|
281
|
-
*/
|
|
282
53
|
export declare function removeAllMocks(): void
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* Remove a specific mock and restore the original class.
|
|
286
|
-
* This completely removes the mock - it does NOT clear mock call history.
|
|
287
|
-
* @param clazzOrName The class or name to restore
|
|
288
|
-
*/
|
|
289
54
|
export declare function removeMock<T>(clazzOrName: InjectionToken<T>): void
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* @deprecated Use removeAllMocks() instead. This will be removed in a future version.
|
|
293
|
-
* WARNING: This removes all mocks, it does NOT clear mock call history.
|
|
294
|
-
*/
|
|
295
|
-
export declare function resetMocks(): void
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* @deprecated Use removeMock() instead. This will be removed in a future version.
|
|
299
|
-
* WARNING: This removes the mock, it does NOT clear mock call history.
|
|
300
|
-
* @param clazzOrName The class or name to restore
|
|
301
|
-
*/
|
|
302
|
-
export declare function resetMock<T>(clazzOrName: InjectionToken<T>): void
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Reset singleton instances without removing registrations.
|
|
306
|
-
* Mock registrations are preserved by default.
|
|
307
|
-
*
|
|
308
|
-
* Ideal for test isolation where you want fresh instances but keep mocks.
|
|
309
|
-
*
|
|
310
|
-
* @param options.preserveMocks If true (default), keeps mock registrations
|
|
311
|
-
*/
|
|
312
55
|
export declare function resetSingletons(options?: { preserveMocks?: boolean }): void
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Clear all registered instances and mocks from the container.
|
|
316
|
-
* @param options.preserveRegistrations If true, keeps all registrations but clears cached instances.
|
|
317
|
-
*/
|
|
318
56
|
export declare function clearContainer(options?: { preserveRegistrations?: boolean }): void
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* Get the default container instance.
|
|
322
|
-
*/
|
|
323
57
|
export declare function getContainer(): Container
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Enable or disable debug logging for dependency injection.
|
|
327
|
-
* When enabled, logs when instances are registered, created, and mocked.
|
|
328
|
-
* @param enabled Whether to enable debug mode
|
|
329
|
-
*/
|
|
330
58
|
export declare function setDebug(enabled: boolean): void
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* Check if a class or name is registered in the default container.
|
|
334
|
-
* Useful for validation before injection.
|
|
335
|
-
* @param clazzOrName The class or name to check
|
|
336
|
-
* @returns true if registered, false otherwise
|
|
337
|
-
*/
|
|
338
59
|
export declare function isRegistered<T>(clazzOrName: InjectionToken<T>): boolean
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* Check if a class or name has a mock registered.
|
|
342
|
-
* @param clazzOrName The class or name to check
|
|
343
|
-
* @returns true if mocked, false otherwise
|
|
344
|
-
*/
|
|
345
60
|
export declare function isMocked<T>(clazzOrName: InjectionToken<T>): boolean
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* Get the mock instance for a mocked class.
|
|
349
|
-
* Useful for configuring mock behavior dynamically in tests.
|
|
350
|
-
*
|
|
351
|
-
* @param clazzOrName The original class or name that was mocked
|
|
352
|
-
* @param params Parameters to pass to the constructor
|
|
353
|
-
* @returns The mock instance
|
|
354
|
-
* @throws Error if the class is not mocked
|
|
355
|
-
*
|
|
356
|
-
* @example
|
|
357
|
-
* ```ts
|
|
358
|
-
* const mock = getMockInstance(UserService)
|
|
359
|
-
* mock.getUser.mockReturnValue({ id: 1 })
|
|
360
|
-
* ```
|
|
361
|
-
*/
|
|
362
61
|
export declare function getMockInstance<T>(clazzOrName: InjectionToken<T>, ...params: any[]): T
|
|
363
|
-
|
|
364
|
-
/**
|
|
365
|
-
* Unregister a class or name from the container.
|
|
366
|
-
* @param clazzOrName The class or name to unregister
|
|
367
|
-
* @returns true if the registration was removed, false if it wasn't registered
|
|
368
|
-
*/
|
|
369
62
|
export declare function unregister<T>(clazzOrName: InjectionToken<T>): boolean
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* List all registrations in the container.
|
|
373
|
-
* Useful for debugging and introspection.
|
|
374
|
-
*/
|
|
375
63
|
export declare function listRegistrations(): RegistrationInfo[]
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Validate that all provided injection tokens are registered.
|
|
379
|
-
* Throws an error with details about missing registrations.
|
|
380
|
-
* Useful for fail-fast validation at application startup.
|
|
381
|
-
* @param tokens Array of classes or names to validate
|
|
382
|
-
* @throws Error if any token is not registered
|
|
383
|
-
*/
|
|
384
64
|
export declare function validateRegistrations<T extends InjectionToken[]>(...tokens: T): void
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
* Resolve and return an instance by class or name.
|
|
388
|
-
* This allows non-decorator code (plain functions, modules, etc.) to retrieve
|
|
389
|
-
* instances from the DI container.
|
|
390
|
-
*
|
|
391
|
-
* @param clazzOrName The class or name to resolve
|
|
392
|
-
* @param params Optional parameters to pass to the constructor
|
|
393
|
-
* @returns The resolved instance
|
|
394
|
-
* @throws Error if the class or name is not registered
|
|
395
|
-
*
|
|
396
|
-
* @example
|
|
397
|
-
* // In a plain function:
|
|
398
|
-
* function handleRequest(req: Request) {
|
|
399
|
-
* const userService = resolve(UserService)
|
|
400
|
-
* return userService.getUser(req.userId)
|
|
401
|
-
* }
|
|
402
|
-
*
|
|
403
|
-
* @example
|
|
404
|
-
* // With a named registration:
|
|
405
|
-
* const db = resolve<Database>('database')
|
|
406
|
-
*/
|
|
407
65
|
export declare function resolve<T>(clazzOrName: InjectionToken<T>, ...params: any[]): T
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* Create a proxy that delegates to the mock first, then falls back to the original.
|
|
411
|
-
* This is an internal utility but exported for advanced use cases.
|
|
412
|
-
*
|
|
413
|
-
* @param mock The mock instance
|
|
414
|
-
* @param original The original instance to fall back to
|
|
415
|
-
*/
|
|
416
66
|
export declare function createProxy<T extends object>(mock: T, original: T): T
|
|
67
|
+
export declare const defaultContainer: Container
|