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/eslint.config.js CHANGED
@@ -62,7 +62,10 @@ export default defineConfig([
62
62
  beforeEach: "readonly",
63
63
  afterEach: "readonly",
64
64
  jest: "readonly",
65
- fail: "readonly"
65
+ fail: "readonly",
66
+ setTimeout: "readonly",
67
+ clearTimeout: "readonly",
68
+ Promise: "readonly"
66
69
  }
67
70
  },
68
71
  rules: {
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
- * Inject a singleton or factory instance into a class field or accessor.
195
- *
196
- * Supports:
197
- * - Public fields: `@Inject(MyClass) myField`
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