@abdokouta/ts-container 1.0.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/LICENSE +21 -0
- package/dist/index.cjs +1125 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1576 -0
- package/dist/index.d.ts +1576 -0
- package/dist/index.js +1102 -0
- package/dist/index.js.map +1 -0
- package/package.json +59 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1576 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Type interface — represents a class constructor.
|
|
3
|
+
*
|
|
4
|
+
* This is the fundamental type used throughout the DI system to represent
|
|
5
|
+
* classes that can be instantiated with `new`.
|
|
6
|
+
*
|
|
7
|
+
* @module interfaces/type
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Represents a class constructor (a "newable" type).
|
|
11
|
+
*
|
|
12
|
+
* Used as the type for:
|
|
13
|
+
* - Provider metatypes (the class to instantiate)
|
|
14
|
+
* - Injection tokens (when using class-based tokens)
|
|
15
|
+
* - Module classes
|
|
16
|
+
*
|
|
17
|
+
* @typeParam T - The instance type that the constructor creates
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // Any class satisfies Type<T>
|
|
22
|
+
* class UserService {}
|
|
23
|
+
* const type: Type<UserService> = UserService;
|
|
24
|
+
*
|
|
25
|
+
* // Can be used to create instances
|
|
26
|
+
* const instance = new type();
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
interface Type<T = any> extends Function {
|
|
30
|
+
new (...args: any[]): T;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @fileoverview Injection token type — the key used to identify providers.
|
|
35
|
+
*
|
|
36
|
+
* An injection token is the identifier that the container uses to look up
|
|
37
|
+
* a provider binding. It can be a class reference, a string, or a symbol.
|
|
38
|
+
*
|
|
39
|
+
* @module interfaces/injection-token
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A token that uniquely identifies a provider in the DI container.
|
|
44
|
+
*
|
|
45
|
+
* Three forms are supported:
|
|
46
|
+
*
|
|
47
|
+
* 1. **Class reference** — the most common form. The class itself is the token.
|
|
48
|
+
* ```typescript
|
|
49
|
+
* @Injectable()
|
|
50
|
+
* class UserService {}
|
|
51
|
+
* // Token is: UserService (the class constructor)
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* 2. **String** — useful for configuration values or when you don't have a class.
|
|
55
|
+
* ```typescript
|
|
56
|
+
* { provide: 'DATABASE_URL', useValue: 'postgres://...' }
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* 3. **Symbol** — the recommended approach for non-class tokens. Prevents collisions.
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const CACHE_CONFIG = Symbol('CACHE_CONFIG');
|
|
62
|
+
* { provide: CACHE_CONFIG, useValue: { default: 'memory' } }
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* 4. **Function** — for factory-based tokens or abstract classes.
|
|
66
|
+
*/
|
|
67
|
+
type InjectionToken<T = any> = string | symbol | Type<T> | Function;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @fileoverview Provider scope enum.
|
|
71
|
+
*
|
|
72
|
+
* Defines the lifecycle scope of a provider instance.
|
|
73
|
+
* For client-side applications, DEFAULT (singleton) is the most common.
|
|
74
|
+
*
|
|
75
|
+
* @module interfaces/scope
|
|
76
|
+
*/
|
|
77
|
+
/**
|
|
78
|
+
* Determines how provider instances are shared.
|
|
79
|
+
*
|
|
80
|
+
* - `DEFAULT` — Singleton. One instance shared across the entire application.
|
|
81
|
+
* This is the default and most common scope for client-side apps.
|
|
82
|
+
*
|
|
83
|
+
* - `TRANSIENT` — A new instance is created every time the provider is injected.
|
|
84
|
+
* Useful for stateful services that shouldn't be shared.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* // Singleton (default) — one instance for the whole app
|
|
89
|
+
* @Injectable()
|
|
90
|
+
* class ConfigService {}
|
|
91
|
+
*
|
|
92
|
+
* // Transient — new instance per injection
|
|
93
|
+
* @Injectable({ scope: Scope.TRANSIENT })
|
|
94
|
+
* class RequestLogger {}
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
declare enum Scope {
|
|
98
|
+
/**
|
|
99
|
+
* Singleton scope. The provider is instantiated once and shared
|
|
100
|
+
* across all consumers. This is the default.
|
|
101
|
+
*/
|
|
102
|
+
DEFAULT = 0,
|
|
103
|
+
/**
|
|
104
|
+
* Transient scope. A new instance is created for every injection point.
|
|
105
|
+
* Each consumer gets its own dedicated instance.
|
|
106
|
+
*/
|
|
107
|
+
TRANSIENT = 1
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @fileoverview Provider types — the different ways to register a dependency.
|
|
112
|
+
*
|
|
113
|
+
* Providers are the fundamental building blocks of the DI system.
|
|
114
|
+
* They tell the container HOW to create an instance for a given token.
|
|
115
|
+
*
|
|
116
|
+
* Four provider types are supported (same as NestJS):
|
|
117
|
+
*
|
|
118
|
+
* 1. **Class provider** — `{ provide: Token, useClass: SomeClass }`
|
|
119
|
+
* 2. **Value provider** — `{ provide: Token, useValue: someValue }`
|
|
120
|
+
* 3. **Factory provider** — `{ provide: Token, useFactory: () => value, inject: [Dep1] }`
|
|
121
|
+
* 4. **Existing provider** (alias) — `{ provide: Token, useExisting: OtherToken }`
|
|
122
|
+
*
|
|
123
|
+
* Plus the shorthand: just passing a class directly (equivalent to `{ provide: Class, useClass: Class }`).
|
|
124
|
+
*
|
|
125
|
+
* @module interfaces/provider
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Class provider — binds a token to a class that will be instantiated by the container.
|
|
130
|
+
*
|
|
131
|
+
* The container will:
|
|
132
|
+
* 1. Read the class's constructor parameter types
|
|
133
|
+
* 2. Resolve each dependency recursively
|
|
134
|
+
* 3. Call `new useClass(...resolvedDeps)`
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* // Bind an interface token to a concrete implementation
|
|
139
|
+
* { provide: 'IUserRepository', useClass: PostgresUserRepository }
|
|
140
|
+
*
|
|
141
|
+
* // Bind a class to itself (same as just listing the class)
|
|
142
|
+
* { provide: UserService, useClass: UserService }
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
interface ClassProvider<T = any> {
|
|
146
|
+
/**
|
|
147
|
+
* The injection token (what consumers ask for).
|
|
148
|
+
*/
|
|
149
|
+
provide: InjectionToken;
|
|
150
|
+
/**
|
|
151
|
+
* The class to instantiate when this token is requested.
|
|
152
|
+
*/
|
|
153
|
+
useClass: Type<T>;
|
|
154
|
+
/**
|
|
155
|
+
* Optional scope override.
|
|
156
|
+
*/
|
|
157
|
+
scope?: Scope;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Value provider — binds a token to a pre-existing value.
|
|
161
|
+
*
|
|
162
|
+
* No instantiation occurs. The exact value is returned as-is.
|
|
163
|
+
* Useful for configuration objects, constants, and pre-built instances.
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* // Bind a configuration object
|
|
168
|
+
* { provide: CACHE_CONFIG, useValue: { default: 'memory', stores: { ... } } }
|
|
169
|
+
*
|
|
170
|
+
* // Bind a primitive
|
|
171
|
+
* { provide: 'API_URL', useValue: 'https://api.example.com' }
|
|
172
|
+
*
|
|
173
|
+
* // Bind a pre-built instance
|
|
174
|
+
* { provide: Logger, useValue: new Logger('app') }
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
interface ValueProvider<T = any> {
|
|
178
|
+
/**
|
|
179
|
+
* The injection token.
|
|
180
|
+
*/
|
|
181
|
+
provide: InjectionToken;
|
|
182
|
+
/**
|
|
183
|
+
* The value to inject. Returned as-is, no instantiation.
|
|
184
|
+
*/
|
|
185
|
+
useValue: T;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Factory provider — binds a token to a factory function.
|
|
189
|
+
*
|
|
190
|
+
* The factory function is called once (for singletons) or per-injection
|
|
191
|
+
* (for transients). Dependencies can be injected into the factory via
|
|
192
|
+
* the `inject` array.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* // Simple factory
|
|
197
|
+
* {
|
|
198
|
+
* provide: 'CONNECTION',
|
|
199
|
+
* useFactory: () => createConnection({ host: 'localhost' }),
|
|
200
|
+
* }
|
|
201
|
+
*
|
|
202
|
+
* // Factory with injected dependencies
|
|
203
|
+
* {
|
|
204
|
+
* provide: CacheManager,
|
|
205
|
+
* useFactory: (config: ConfigService) => new CacheManager(config.get('cache')),
|
|
206
|
+
* inject: [ConfigService],
|
|
207
|
+
* }
|
|
208
|
+
*
|
|
209
|
+
* // Async factory
|
|
210
|
+
* {
|
|
211
|
+
* provide: 'DB_CONNECTION',
|
|
212
|
+
* useFactory: async (config: ConfigService) => {
|
|
213
|
+
* const conn = await createConnection(config.get('database'));
|
|
214
|
+
* return conn;
|
|
215
|
+
* },
|
|
216
|
+
* inject: [ConfigService],
|
|
217
|
+
* }
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
interface FactoryProvider<T = any> {
|
|
221
|
+
/**
|
|
222
|
+
* The injection token.
|
|
223
|
+
*/
|
|
224
|
+
provide: InjectionToken;
|
|
225
|
+
/**
|
|
226
|
+
* Factory function that creates the value. Can be async.
|
|
227
|
+
*/
|
|
228
|
+
useFactory: (...args: any[]) => T | Promise<T>;
|
|
229
|
+
/**
|
|
230
|
+
* Tokens to inject as arguments to the factory function.
|
|
231
|
+
*/
|
|
232
|
+
inject?: InjectionToken[];
|
|
233
|
+
/**
|
|
234
|
+
* Optional scope override.
|
|
235
|
+
*/
|
|
236
|
+
scope?: Scope;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Existing provider (alias) — binds a token to another token.
|
|
240
|
+
*
|
|
241
|
+
* When the alias token is requested, the container resolves the
|
|
242
|
+
* target token instead. Useful for providing multiple tokens that
|
|
243
|
+
* resolve to the same instance.
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* ```typescript
|
|
247
|
+
* // Make CACHE_SERVICE resolve to the same instance as CacheManager
|
|
248
|
+
* { provide: CACHE_SERVICE, useExisting: CacheManager }
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
interface ExistingProvider<T = any> {
|
|
252
|
+
/**
|
|
253
|
+
* The alias injection token.
|
|
254
|
+
*/
|
|
255
|
+
provide: InjectionToken;
|
|
256
|
+
/**
|
|
257
|
+
* The target token to resolve instead.
|
|
258
|
+
*/
|
|
259
|
+
useExisting: InjectionToken<T>;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Union type of all provider forms.
|
|
263
|
+
*
|
|
264
|
+
* A provider can be:
|
|
265
|
+
* - A class reference (shorthand for `{ provide: Class, useClass: Class }`)
|
|
266
|
+
* - A ClassProvider
|
|
267
|
+
* - A ValueProvider
|
|
268
|
+
* - A FactoryProvider
|
|
269
|
+
* - An ExistingProvider
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* ```typescript
|
|
273
|
+
* const providers: Provider[] = [
|
|
274
|
+
* UserService, // class shorthand
|
|
275
|
+
* { provide: 'API_URL', useValue: 'https://...' }, // value
|
|
276
|
+
* { provide: CacheManager, useClass: CacheManager }, // class
|
|
277
|
+
* { provide: DB, useFactory: () => connect() }, // factory
|
|
278
|
+
* { provide: CACHE, useExisting: CacheManager }, // alias
|
|
279
|
+
* ];
|
|
280
|
+
* ```
|
|
281
|
+
*/
|
|
282
|
+
type Provider<T = any> = Type<T> | ClassProvider<T> | ValueProvider<T> | FactoryProvider<T> | ExistingProvider<T>;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* @fileoverview Dynamic module interface — for configurable modules.
|
|
286
|
+
*
|
|
287
|
+
* Dynamic modules are the mechanism for creating configurable, reusable modules.
|
|
288
|
+
* They're returned by static methods like `forRoot()` and `forFeature()`.
|
|
289
|
+
*
|
|
290
|
+
* @module interfaces/dynamic-module
|
|
291
|
+
*/
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* A module configuration object returned by `forRoot()`, `forFeature()`, etc.
|
|
295
|
+
*
|
|
296
|
+
* Extends `ModuleMetadata` with a `module` property that references the
|
|
297
|
+
* module class, and an optional `global` flag.
|
|
298
|
+
*
|
|
299
|
+
* ## How it works:
|
|
300
|
+
*
|
|
301
|
+
* When the scanner encounters a `DynamicModule` in an imports array, it:
|
|
302
|
+
* 1. Uses the `module` property to identify the module class
|
|
303
|
+
* 2. Merges the dynamic metadata (providers, imports, exports) with
|
|
304
|
+
* any static metadata from the `@Module()` decorator
|
|
305
|
+
* 3. Registers everything into the container
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* ```typescript
|
|
309
|
+
* @Module({})
|
|
310
|
+
* class CacheModule {
|
|
311
|
+
* static forRoot(config: CacheConfig): DynamicModule {
|
|
312
|
+
* return {
|
|
313
|
+
* module: CacheModule,
|
|
314
|
+
* global: true,
|
|
315
|
+
* providers: [
|
|
316
|
+
* { provide: CACHE_CONFIG, useValue: config },
|
|
317
|
+
* CacheManager,
|
|
318
|
+
* ],
|
|
319
|
+
* exports: [CacheManager],
|
|
320
|
+
* };
|
|
321
|
+
* }
|
|
322
|
+
* }
|
|
323
|
+
*
|
|
324
|
+
* // Usage:
|
|
325
|
+
* @Module({
|
|
326
|
+
* imports: [CacheModule.forRoot({ default: 'memory' })],
|
|
327
|
+
* })
|
|
328
|
+
* class AppModule {}
|
|
329
|
+
* ```
|
|
330
|
+
*/
|
|
331
|
+
interface DynamicModule extends ModuleMetadata {
|
|
332
|
+
/**
|
|
333
|
+
* The module class this dynamic configuration belongs to.
|
|
334
|
+
* This is how the scanner identifies which module to configure.
|
|
335
|
+
*/
|
|
336
|
+
module: Type<any>;
|
|
337
|
+
/**
|
|
338
|
+
* When `true`, this module's exported providers are available globally
|
|
339
|
+
* to all other modules without explicit imports.
|
|
340
|
+
*
|
|
341
|
+
* @default false
|
|
342
|
+
*/
|
|
343
|
+
global?: boolean;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* @fileoverview Forward reference — for resolving circular dependencies.
|
|
348
|
+
*
|
|
349
|
+
* @module interfaces/forward-reference
|
|
350
|
+
*/
|
|
351
|
+
/**
|
|
352
|
+
* A forward reference wraps a class reference in a function to break
|
|
353
|
+
* circular dependency chains in the module graph.
|
|
354
|
+
*
|
|
355
|
+
* @example
|
|
356
|
+
* ```typescript
|
|
357
|
+
* import { forwardRef } from '@abdokouta/ts-container';
|
|
358
|
+
*
|
|
359
|
+
* @Module({
|
|
360
|
+
* imports: [forwardRef(() => CatsModule)],
|
|
361
|
+
* })
|
|
362
|
+
* class DogsModule {}
|
|
363
|
+
* ```
|
|
364
|
+
*/
|
|
365
|
+
interface ForwardReference<T = any> {
|
|
366
|
+
forwardRef: () => T;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* @fileoverview Module metadata interface — the shape of @Module() options.
|
|
371
|
+
*
|
|
372
|
+
* @module interfaces/module-metadata
|
|
373
|
+
*/
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Configuration object passed to the `@Module()` decorator.
|
|
377
|
+
*
|
|
378
|
+
* Defines the module's dependency graph: what it imports, provides, and exports.
|
|
379
|
+
*
|
|
380
|
+
* @example
|
|
381
|
+
* ```typescript
|
|
382
|
+
* @Module({
|
|
383
|
+
* imports: [ConfigModule, RedisModule.forRoot(config)],
|
|
384
|
+
* providers: [
|
|
385
|
+
* UserService,
|
|
386
|
+
* { provide: CACHE_CONFIG, useValue: cacheConfig },
|
|
387
|
+
* ],
|
|
388
|
+
* exports: [UserService],
|
|
389
|
+
* })
|
|
390
|
+
* class UserModule {}
|
|
391
|
+
* ```
|
|
392
|
+
*/
|
|
393
|
+
interface ModuleMetadata {
|
|
394
|
+
/**
|
|
395
|
+
* Modules to import.
|
|
396
|
+
*
|
|
397
|
+
* Imported modules make their exported providers available to this module.
|
|
398
|
+
* Can be static module classes, dynamic modules (from `forRoot()`), or forward references.
|
|
399
|
+
*/
|
|
400
|
+
imports?: Array<Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference>;
|
|
401
|
+
/**
|
|
402
|
+
* Providers to register in this module.
|
|
403
|
+
*
|
|
404
|
+
* These providers are available for injection within this module.
|
|
405
|
+
* To make them available to other modules, add them to `exports`.
|
|
406
|
+
*/
|
|
407
|
+
providers?: Provider[];
|
|
408
|
+
/**
|
|
409
|
+
* Providers or modules to export.
|
|
410
|
+
*
|
|
411
|
+
* Exported providers become available to modules that import this module.
|
|
412
|
+
* You can export:
|
|
413
|
+
* - Provider tokens (class, string, symbol)
|
|
414
|
+
* - Entire modules (re-exporting their exports)
|
|
415
|
+
*/
|
|
416
|
+
exports?: Array<InjectionToken | Provider | DynamicModule | ForwardReference>;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* @fileoverview Lifecycle hook interfaces.
|
|
421
|
+
*
|
|
422
|
+
* Providers can implement these interfaces to hook into the application
|
|
423
|
+
* lifecycle. The container calls these methods at specific points during
|
|
424
|
+
* bootstrap and shutdown.
|
|
425
|
+
*
|
|
426
|
+
* ## Lifecycle order:
|
|
427
|
+
*
|
|
428
|
+
* **Bootstrap:**
|
|
429
|
+
* 1. All providers are instantiated (constructor injection)
|
|
430
|
+
* 2. `onModuleInit()` is called on all providers that implement it
|
|
431
|
+
*
|
|
432
|
+
* **Shutdown:**
|
|
433
|
+
* 1. `onModuleDestroy()` is called on all providers that implement it
|
|
434
|
+
* 2. Provider references are released
|
|
435
|
+
*
|
|
436
|
+
* @module interfaces/lifecycle
|
|
437
|
+
*/
|
|
438
|
+
/**
|
|
439
|
+
* Interface for providers that need initialization after construction.
|
|
440
|
+
*
|
|
441
|
+
* `onModuleInit()` is called after all providers in the module have been
|
|
442
|
+
* instantiated and their dependencies injected. This is the right place
|
|
443
|
+
* for async initialization like connecting to databases or warming caches.
|
|
444
|
+
*
|
|
445
|
+
* @example
|
|
446
|
+
* ```typescript
|
|
447
|
+
* @Injectable()
|
|
448
|
+
* class DatabaseService implements OnModuleInit {
|
|
449
|
+
* private connection: Connection;
|
|
450
|
+
*
|
|
451
|
+
* constructor(@Inject(DB_CONFIG) private config: DbConfig) {}
|
|
452
|
+
*
|
|
453
|
+
* async onModuleInit() {
|
|
454
|
+
* // All dependencies are available here
|
|
455
|
+
* this.connection = await createConnection(this.config);
|
|
456
|
+
* }
|
|
457
|
+
* }
|
|
458
|
+
* ```
|
|
459
|
+
*/
|
|
460
|
+
interface OnModuleInit {
|
|
461
|
+
onModuleInit(): any | Promise<any>;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Interface for providers that need cleanup before shutdown.
|
|
465
|
+
*
|
|
466
|
+
* `onModuleDestroy()` is called when the application is shutting down.
|
|
467
|
+
* Use this to close connections, flush buffers, and release resources.
|
|
468
|
+
*
|
|
469
|
+
* @example
|
|
470
|
+
* ```typescript
|
|
471
|
+
* @Injectable()
|
|
472
|
+
* class RedisManager implements OnModuleDestroy {
|
|
473
|
+
* async onModuleDestroy() {
|
|
474
|
+
* await this.disconnectAll();
|
|
475
|
+
* }
|
|
476
|
+
* }
|
|
477
|
+
* ```
|
|
478
|
+
*/
|
|
479
|
+
interface OnModuleDestroy {
|
|
480
|
+
onModuleDestroy(): any | Promise<any>;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* @fileoverview ContainerResolver — minimal interface for resolving providers.
|
|
485
|
+
*
|
|
486
|
+
* This is the contract that any DI resolver must implement. It's used by:
|
|
487
|
+
* - `@abdokouta/ts-container/react` (ContainerProvider accepts this)
|
|
488
|
+
* - `@pixielity/application` (ApplicationContext implements this)
|
|
489
|
+
* - Any custom resolver or testing mock
|
|
490
|
+
*
|
|
491
|
+
* By depending on this interface instead of a concrete class, consumers
|
|
492
|
+
* stay decoupled from the bootstrap implementation.
|
|
493
|
+
*
|
|
494
|
+
* @module interfaces/container-resolver
|
|
495
|
+
*/
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Minimal interface for resolving providers from a DI container.
|
|
499
|
+
*
|
|
500
|
+
* Any object that can look up providers by token can implement this.
|
|
501
|
+
* The React hooks (`useInject`, etc.) depend on this interface,
|
|
502
|
+
* not on the concrete `ApplicationContext`.
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* ```typescript
|
|
506
|
+
* // ApplicationContext implements this
|
|
507
|
+
* const app: ContainerResolver = await ApplicationContext.create(AppModule);
|
|
508
|
+
* const service = app.get(UserService);
|
|
509
|
+
*
|
|
510
|
+
* // You can also create a mock for testing
|
|
511
|
+
* const mock: ContainerResolver = {
|
|
512
|
+
* get: (token) => mockInstances.get(token),
|
|
513
|
+
* getOptional: (token) => mockInstances.get(token),
|
|
514
|
+
* has: (token) => mockInstances.has(token),
|
|
515
|
+
* };
|
|
516
|
+
* ```
|
|
517
|
+
*/
|
|
518
|
+
interface ContainerResolver {
|
|
519
|
+
/**
|
|
520
|
+
* Resolve a provider by its injection token.
|
|
521
|
+
*
|
|
522
|
+
* @param token - The injection token (class, string, or symbol)
|
|
523
|
+
* @returns The resolved provider instance
|
|
524
|
+
* @throws Error if the provider is not found
|
|
525
|
+
*/
|
|
526
|
+
get<T = any>(token: InjectionToken<T>): T;
|
|
527
|
+
/**
|
|
528
|
+
* Try to resolve a provider, returning `undefined` if not found.
|
|
529
|
+
*
|
|
530
|
+
* @param token - The injection token
|
|
531
|
+
* @returns The resolved instance or undefined
|
|
532
|
+
*/
|
|
533
|
+
getOptional<T = any>(token: InjectionToken<T>): T | undefined;
|
|
534
|
+
/**
|
|
535
|
+
* Check if a provider is registered.
|
|
536
|
+
*
|
|
537
|
+
* @param token - The injection token to check
|
|
538
|
+
* @returns `true` if the provider exists
|
|
539
|
+
*/
|
|
540
|
+
has(token: InjectionToken): boolean;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* @fileoverview Scope options for the @Injectable() decorator.
|
|
545
|
+
* @module interfaces/scope-options
|
|
546
|
+
*/
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Options that can be passed to `@Injectable()` to control provider scoping.
|
|
550
|
+
*
|
|
551
|
+
* @example
|
|
552
|
+
* ```typescript
|
|
553
|
+
* @Injectable({ scope: Scope.TRANSIENT })
|
|
554
|
+
* class TransientService {}
|
|
555
|
+
* ```
|
|
556
|
+
*/
|
|
557
|
+
interface ScopeOptions {
|
|
558
|
+
/**
|
|
559
|
+
* The scope of the provider.
|
|
560
|
+
* @default Scope.DEFAULT (singleton)
|
|
561
|
+
*/
|
|
562
|
+
scope?: Scope;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* @fileoverview @Injectable() decorator.
|
|
567
|
+
*
|
|
568
|
+
* Marks a class as a provider that can be managed by the DI container.
|
|
569
|
+
* This is the most fundamental decorator in the system — any class that
|
|
570
|
+
* needs to be injected or have dependencies injected into it must be
|
|
571
|
+
* decorated with `@Injectable()`.
|
|
572
|
+
*
|
|
573
|
+
* ## What it does:
|
|
574
|
+
*
|
|
575
|
+
* 1. Sets the `__injectable__` watermark on the class (so the scanner can identify it)
|
|
576
|
+
* 2. Stores scope options (singleton vs transient) as metadata
|
|
577
|
+
* 3. TypeScript's `emitDecoratorMetadata` automatically emits `design:paramtypes`
|
|
578
|
+
* (constructor parameter types) because a decorator is present on the class
|
|
579
|
+
*
|
|
580
|
+
* That third point is crucial — without `@Injectable()`, TypeScript won't emit
|
|
581
|
+
* the constructor parameter type metadata that the injector needs to auto-resolve
|
|
582
|
+
* dependencies.
|
|
583
|
+
*
|
|
584
|
+
* @module decorators/injectable
|
|
585
|
+
*/
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Decorator that marks a class as injectable (a provider).
|
|
589
|
+
*
|
|
590
|
+
* @param options - Optional scope configuration
|
|
591
|
+
*
|
|
592
|
+
* @example
|
|
593
|
+
* ```typescript
|
|
594
|
+
* // Basic usage — singleton by default
|
|
595
|
+
* @Injectable()
|
|
596
|
+
* class UserService {
|
|
597
|
+
* constructor(private config: ConfigService) {}
|
|
598
|
+
* }
|
|
599
|
+
*
|
|
600
|
+
* // Transient scope — new instance per injection
|
|
601
|
+
* @Injectable({ scope: Scope.TRANSIENT })
|
|
602
|
+
* class RequestLogger {
|
|
603
|
+
* private readonly id = Math.random();
|
|
604
|
+
* }
|
|
605
|
+
* ```
|
|
606
|
+
*/
|
|
607
|
+
declare function Injectable(options?: ScopeOptions): ClassDecorator;
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* @fileoverview @Inject() decorator.
|
|
611
|
+
*
|
|
612
|
+
* Explicitly specifies the injection token for a constructor parameter
|
|
613
|
+
* or class property. This is needed when:
|
|
614
|
+
*
|
|
615
|
+
* 1. The token is a string or symbol (not a class)
|
|
616
|
+
* 2. You want to inject a different implementation than the parameter type
|
|
617
|
+
* 3. The parameter type is an interface (interfaces are erased at runtime)
|
|
618
|
+
*
|
|
619
|
+
* ## How it works:
|
|
620
|
+
*
|
|
621
|
+
* **Constructor parameter injection:**
|
|
622
|
+
* Pushes `{ index, param: token }` into the `self:paramtypes` metadata array.
|
|
623
|
+
* During resolution, the injector merges `self:paramtypes` with `design:paramtypes`
|
|
624
|
+
* — explicit `@Inject()` tokens override the auto-detected types.
|
|
625
|
+
*
|
|
626
|
+
* **Property injection:**
|
|
627
|
+
* Pushes `{ key, type: token }` into the `self:properties_metadata` array.
|
|
628
|
+
* After construction, the injector resolves each property dependency and
|
|
629
|
+
* assigns it to the instance.
|
|
630
|
+
*
|
|
631
|
+
* @module decorators/inject
|
|
632
|
+
*/
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Decorator that specifies the injection token for a dependency.
|
|
636
|
+
*
|
|
637
|
+
* Can be used on constructor parameters or class properties.
|
|
638
|
+
*
|
|
639
|
+
* @param token - The injection token to use. If omitted, falls back to
|
|
640
|
+
* the TypeScript-emitted type or the property's design:type.
|
|
641
|
+
*
|
|
642
|
+
* @example
|
|
643
|
+
* ```typescript
|
|
644
|
+
* // Constructor parameter injection with a symbol token
|
|
645
|
+
* @Injectable()
|
|
646
|
+
* class CacheService {
|
|
647
|
+
* constructor(
|
|
648
|
+
* @Inject(CACHE_CONFIG) private config: CacheModuleOptions,
|
|
649
|
+
* @Inject(RedisManager) private redis: RedisManager,
|
|
650
|
+
* ) {}
|
|
651
|
+
* }
|
|
652
|
+
*
|
|
653
|
+
* // Property injection
|
|
654
|
+
* @Injectable()
|
|
655
|
+
* class UserService {
|
|
656
|
+
* @Inject(LoggerService)
|
|
657
|
+
* private logger!: LoggerService;
|
|
658
|
+
* }
|
|
659
|
+
*
|
|
660
|
+
* // Without explicit token — uses the TypeScript type
|
|
661
|
+
* @Injectable()
|
|
662
|
+
* class OrderService {
|
|
663
|
+
* constructor(private userService: UserService) {}
|
|
664
|
+
* // Equivalent to: @Inject(UserService) private userService: UserService
|
|
665
|
+
* }
|
|
666
|
+
* ```
|
|
667
|
+
*/
|
|
668
|
+
declare function Inject(token?: InjectionToken | ForwardReference): PropertyDecorator & ParameterDecorator;
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* @fileoverview @Optional() decorator.
|
|
672
|
+
*
|
|
673
|
+
* Marks a dependency as optional. If the container cannot resolve the
|
|
674
|
+
* dependency, `undefined` is injected instead of throwing an error.
|
|
675
|
+
*
|
|
676
|
+
* @module decorators/optional
|
|
677
|
+
*/
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Marks a constructor parameter or property dependency as optional.
|
|
681
|
+
*
|
|
682
|
+
* Without `@Optional()`, an unresolvable dependency throws an error.
|
|
683
|
+
* With `@Optional()`, `undefined` is injected instead.
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* ```typescript
|
|
687
|
+
* @Injectable()
|
|
688
|
+
* class CacheService {
|
|
689
|
+
* constructor(
|
|
690
|
+
* @Inject(CACHE_CONFIG) private config: CacheConfig,
|
|
691
|
+
* @Optional() @Inject(RedisManager) private redis?: RedisManager,
|
|
692
|
+
* ) {
|
|
693
|
+
* // redis will be undefined if RedisModule is not imported
|
|
694
|
+
* }
|
|
695
|
+
* }
|
|
696
|
+
* ```
|
|
697
|
+
*/
|
|
698
|
+
declare function Optional(): PropertyDecorator & ParameterDecorator;
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* @fileoverview @Module() decorator.
|
|
702
|
+
*
|
|
703
|
+
* Defines a module — the organizational unit of the DI system.
|
|
704
|
+
* Modules group related providers and define the dependency graph
|
|
705
|
+
* between different parts of the application.
|
|
706
|
+
*
|
|
707
|
+
* ## How it works:
|
|
708
|
+
*
|
|
709
|
+
* The decorator iterates over the metadata object and stores each
|
|
710
|
+
* property as a separate metadata entry on the class:
|
|
711
|
+
*
|
|
712
|
+
* ```
|
|
713
|
+
* @Module({ imports: [...], providers: [...], exports: [...] })
|
|
714
|
+
* class MyModule {}
|
|
715
|
+
*
|
|
716
|
+
* // Becomes:
|
|
717
|
+
* Reflect.defineMetadata('imports', [...], MyModule)
|
|
718
|
+
* Reflect.defineMetadata('providers', [...], MyModule)
|
|
719
|
+
* Reflect.defineMetadata('exports', [...], MyModule)
|
|
720
|
+
* ```
|
|
721
|
+
*
|
|
722
|
+
* The scanner later reads these metadata entries to build the module graph.
|
|
723
|
+
*
|
|
724
|
+
* @module decorators/module
|
|
725
|
+
*/
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Decorator that defines a module.
|
|
729
|
+
*
|
|
730
|
+
* @param metadata - Module configuration (imports, providers, exports)
|
|
731
|
+
*
|
|
732
|
+
* @example
|
|
733
|
+
* ```typescript
|
|
734
|
+
* @Module({
|
|
735
|
+
* imports: [ConfigModule.forRoot(config)],
|
|
736
|
+
* providers: [UserService, UserRepository],
|
|
737
|
+
* exports: [UserService],
|
|
738
|
+
* })
|
|
739
|
+
* class UserModule {}
|
|
740
|
+
* ```
|
|
741
|
+
*/
|
|
742
|
+
declare function Module$1(metadata: ModuleMetadata): ClassDecorator;
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* @fileoverview @Global() decorator.
|
|
746
|
+
*
|
|
747
|
+
* Makes a module's exported providers available globally to all other
|
|
748
|
+
* modules without requiring explicit imports.
|
|
749
|
+
*
|
|
750
|
+
* @module decorators/global
|
|
751
|
+
*/
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Decorator that makes a module global-scoped.
|
|
755
|
+
*
|
|
756
|
+
* Once a global module is imported anywhere (typically in the root module),
|
|
757
|
+
* its exported providers become available to ALL modules in the application
|
|
758
|
+
* without needing to import the module explicitly.
|
|
759
|
+
*
|
|
760
|
+
* Use sparingly — global modules reduce explicitness. Good candidates:
|
|
761
|
+
* - Configuration modules
|
|
762
|
+
* - Logger modules
|
|
763
|
+
* - Database connection modules
|
|
764
|
+
*
|
|
765
|
+
* @example
|
|
766
|
+
* ```typescript
|
|
767
|
+
* @Global()
|
|
768
|
+
* @Module({
|
|
769
|
+
* providers: [ConfigService],
|
|
770
|
+
* exports: [ConfigService],
|
|
771
|
+
* })
|
|
772
|
+
* class ConfigModule {
|
|
773
|
+
* static forRoot(config: AppConfig): DynamicModule {
|
|
774
|
+
* return {
|
|
775
|
+
* module: ConfigModule,
|
|
776
|
+
* global: true, // Can also be set here instead of @Global()
|
|
777
|
+
* providers: [{ provide: APP_CONFIG, useValue: config }, ConfigService],
|
|
778
|
+
* exports: [ConfigService],
|
|
779
|
+
* };
|
|
780
|
+
* }
|
|
781
|
+
* }
|
|
782
|
+
* ```
|
|
783
|
+
*/
|
|
784
|
+
declare function Global(): ClassDecorator;
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* @fileoverview forwardRef utility — resolves circular module dependencies.
|
|
788
|
+
*
|
|
789
|
+
* @module utils/forward-ref
|
|
790
|
+
*/
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* Creates a forward reference to break circular dependency chains.
|
|
794
|
+
*
|
|
795
|
+
* When two modules import each other, TypeScript may resolve one of them
|
|
796
|
+
* as `undefined` due to the ES module evaluation order. `forwardRef()`
|
|
797
|
+
* wraps the reference in a function that's called later, after both
|
|
798
|
+
* modules have been fully defined.
|
|
799
|
+
*
|
|
800
|
+
* @param fn - A function that returns the class reference
|
|
801
|
+
* @returns A ForwardReference object
|
|
802
|
+
*
|
|
803
|
+
* @example
|
|
804
|
+
* ```typescript
|
|
805
|
+
* // cats.module.ts
|
|
806
|
+
* @Module({
|
|
807
|
+
* imports: [forwardRef(() => DogsModule)],
|
|
808
|
+
* })
|
|
809
|
+
* class CatsModule {}
|
|
810
|
+
*
|
|
811
|
+
* // dogs.module.ts
|
|
812
|
+
* @Module({
|
|
813
|
+
* imports: [forwardRef(() => CatsModule)],
|
|
814
|
+
* })
|
|
815
|
+
* class DogsModule {}
|
|
816
|
+
* ```
|
|
817
|
+
*/
|
|
818
|
+
declare function forwardRef<T = any>(fn: () => T): ForwardReference<T>;
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* @fileoverview InstanceWrapper — wraps a provider binding with its metadata and instance.
|
|
822
|
+
*
|
|
823
|
+
* Every provider registered in a module gets wrapped in an InstanceWrapper.
|
|
824
|
+
* The wrapper tracks:
|
|
825
|
+
* - The injection token (how consumers ask for it)
|
|
826
|
+
* - The metatype (the class/factory to instantiate)
|
|
827
|
+
* - The resolved instance (once created)
|
|
828
|
+
* - The scope (singleton vs transient)
|
|
829
|
+
* - Whether it's been resolved yet
|
|
830
|
+
* - Factory dependencies (for useFactory providers)
|
|
831
|
+
*
|
|
832
|
+
* This is a simplified version of NestJS's InstanceWrapper — we don't need
|
|
833
|
+
* request scoping, context IDs, or transient maps for client-side use.
|
|
834
|
+
*
|
|
835
|
+
* @module injector/instance-wrapper
|
|
836
|
+
*/
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* Wraps a single provider binding with all its metadata.
|
|
840
|
+
*
|
|
841
|
+
* @typeParam T - The type of the provider instance
|
|
842
|
+
*/
|
|
843
|
+
declare class InstanceWrapper<T = any> {
|
|
844
|
+
/**
|
|
845
|
+
* The injection token used to look up this provider.
|
|
846
|
+
*/
|
|
847
|
+
readonly token: InjectionToken;
|
|
848
|
+
/**
|
|
849
|
+
* Human-readable name (class name or token string).
|
|
850
|
+
*/
|
|
851
|
+
readonly name: string;
|
|
852
|
+
/**
|
|
853
|
+
* The class constructor or factory function.
|
|
854
|
+
* - For class providers: the class to `new`
|
|
855
|
+
* - For factory providers: the factory function
|
|
856
|
+
* - For value providers: `null`
|
|
857
|
+
*/
|
|
858
|
+
metatype: Type<T> | Function | null;
|
|
859
|
+
/**
|
|
860
|
+
* The resolved instance.
|
|
861
|
+
* - `null` before resolution
|
|
862
|
+
* - The actual instance after resolution
|
|
863
|
+
* - For value providers: set immediately at registration
|
|
864
|
+
*/
|
|
865
|
+
instance: T | null;
|
|
866
|
+
/**
|
|
867
|
+
* Whether this provider has been fully resolved (instance created).
|
|
868
|
+
*/
|
|
869
|
+
isResolved: boolean;
|
|
870
|
+
/**
|
|
871
|
+
* The scope of this provider.
|
|
872
|
+
*/
|
|
873
|
+
scope: Scope;
|
|
874
|
+
/**
|
|
875
|
+
* For factory providers: the tokens to inject as factory arguments.
|
|
876
|
+
* `null` for class and value providers.
|
|
877
|
+
*/
|
|
878
|
+
inject: InjectionToken[] | null;
|
|
879
|
+
/**
|
|
880
|
+
* Whether this is an alias (useExisting) provider.
|
|
881
|
+
* Alias providers delegate resolution to another token.
|
|
882
|
+
*/
|
|
883
|
+
isAlias: boolean;
|
|
884
|
+
/**
|
|
885
|
+
* Whether the instance is a Promise (async factory).
|
|
886
|
+
*/
|
|
887
|
+
async: boolean;
|
|
888
|
+
/**
|
|
889
|
+
* The module this provider belongs to.
|
|
890
|
+
*/
|
|
891
|
+
host: Module | null;
|
|
892
|
+
/**
|
|
893
|
+
* Create a new InstanceWrapper.
|
|
894
|
+
*
|
|
895
|
+
* @param metadata - Initial values for the wrapper properties
|
|
896
|
+
*/
|
|
897
|
+
constructor(metadata?: Partial<InstanceWrapper<T>>);
|
|
898
|
+
/**
|
|
899
|
+
* Whether this provider is a factory (has an `inject` array).
|
|
900
|
+
* Factory providers are invoked as functions, not constructed with `new`.
|
|
901
|
+
*/
|
|
902
|
+
get isFactory(): boolean;
|
|
903
|
+
/**
|
|
904
|
+
* Whether this provider is transient (new instance per injection).
|
|
905
|
+
*/
|
|
906
|
+
get isTransient(): boolean;
|
|
907
|
+
/**
|
|
908
|
+
* Extract a human-readable name from a token.
|
|
909
|
+
*/
|
|
910
|
+
private getTokenName;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* @fileoverview Module — the runtime representation of a @Module() class.
|
|
915
|
+
*
|
|
916
|
+
* Each `@Module()` decorated class gets a corresponding `Module` instance
|
|
917
|
+
* at runtime. The Module holds:
|
|
918
|
+
* - All provider bindings (as InstanceWrappers)
|
|
919
|
+
* - References to imported modules
|
|
920
|
+
* - The set of exported tokens
|
|
921
|
+
*
|
|
922
|
+
* ## Module lifecycle:
|
|
923
|
+
*
|
|
924
|
+
* 1. **Registration** — The scanner creates a Module instance and registers
|
|
925
|
+
* providers, imports, and exports based on the @Module() metadata.
|
|
926
|
+
*
|
|
927
|
+
* 2. **Resolution** — The injector resolves all providers in the module,
|
|
928
|
+
* creating instances and injecting dependencies.
|
|
929
|
+
*
|
|
930
|
+
* 3. **Lifecycle hooks** — After all providers are resolved, onModuleInit()
|
|
931
|
+
* is called on providers that implement it.
|
|
932
|
+
*
|
|
933
|
+
* @module injector/module
|
|
934
|
+
*/
|
|
935
|
+
|
|
936
|
+
/**
|
|
937
|
+
* Runtime representation of a module.
|
|
938
|
+
*
|
|
939
|
+
* Created by the scanner for each `@Module()` class encountered during
|
|
940
|
+
* the module graph traversal.
|
|
941
|
+
*/
|
|
942
|
+
declare class Module {
|
|
943
|
+
/**
|
|
944
|
+
* Unique identifier for this module instance.
|
|
945
|
+
*/
|
|
946
|
+
readonly id: string;
|
|
947
|
+
/**
|
|
948
|
+
* The original class decorated with @Module().
|
|
949
|
+
*/
|
|
950
|
+
readonly metatype: Type<any>;
|
|
951
|
+
/**
|
|
952
|
+
* Whether this module is global (its exports are available everywhere).
|
|
953
|
+
*/
|
|
954
|
+
isGlobal: boolean;
|
|
955
|
+
/**
|
|
956
|
+
* The opaque token used to identify this module in the container.
|
|
957
|
+
*/
|
|
958
|
+
token: string;
|
|
959
|
+
/**
|
|
960
|
+
* All providers registered in this module.
|
|
961
|
+
* Key: injection token, Value: InstanceWrapper
|
|
962
|
+
*/
|
|
963
|
+
private readonly _providers;
|
|
964
|
+
/**
|
|
965
|
+
* Imported modules (their exports are available to this module).
|
|
966
|
+
*/
|
|
967
|
+
private readonly _imports;
|
|
968
|
+
/**
|
|
969
|
+
* Tokens that this module exports (available to modules that import this one).
|
|
970
|
+
*/
|
|
971
|
+
private readonly _exports;
|
|
972
|
+
constructor(metatype: Type<any>);
|
|
973
|
+
get name(): string;
|
|
974
|
+
get providers(): Map<InjectionToken, InstanceWrapper>;
|
|
975
|
+
get imports(): Set<Module>;
|
|
976
|
+
get exports(): Set<InjectionToken>;
|
|
977
|
+
/**
|
|
978
|
+
* Register a provider in this module.
|
|
979
|
+
*
|
|
980
|
+
* Handles all provider forms:
|
|
981
|
+
* - Class shorthand: `UserService`
|
|
982
|
+
* - Class provider: `{ provide: Token, useClass: UserService }`
|
|
983
|
+
* - Value provider: `{ provide: Token, useValue: someValue }`
|
|
984
|
+
* - Factory provider: `{ provide: Token, useFactory: fn, inject: [...] }`
|
|
985
|
+
* - Existing provider: `{ provide: Token, useExisting: OtherToken }`
|
|
986
|
+
*
|
|
987
|
+
* @param provider - The provider to register
|
|
988
|
+
* @returns The injection token for this provider
|
|
989
|
+
*/
|
|
990
|
+
addProvider(provider: Provider): InjectionToken;
|
|
991
|
+
/**
|
|
992
|
+
* Register a custom provider (one with a `provide` property).
|
|
993
|
+
*/
|
|
994
|
+
private addCustomProvider;
|
|
995
|
+
/**
|
|
996
|
+
* Register a class provider: `{ provide: Token, useClass: SomeClass }`
|
|
997
|
+
*/
|
|
998
|
+
private addClassProvider;
|
|
999
|
+
/**
|
|
1000
|
+
* Register a value provider: `{ provide: Token, useValue: value }`
|
|
1001
|
+
*
|
|
1002
|
+
* Value providers are immediately resolved — the value is stored as-is.
|
|
1003
|
+
*/
|
|
1004
|
+
private addValueProvider;
|
|
1005
|
+
/**
|
|
1006
|
+
* Register a factory provider: `{ provide: Token, useFactory: fn, inject: [...] }`
|
|
1007
|
+
*
|
|
1008
|
+
* The factory function is stored as the metatype and will be called
|
|
1009
|
+
* (not constructed with `new`) during resolution.
|
|
1010
|
+
*/
|
|
1011
|
+
private addFactoryProvider;
|
|
1012
|
+
/**
|
|
1013
|
+
* Register an existing (alias) provider: `{ provide: Token, useExisting: OtherToken }`
|
|
1014
|
+
*
|
|
1015
|
+
* Implemented as a factory that resolves the target token.
|
|
1016
|
+
*/
|
|
1017
|
+
private addExistingProvider;
|
|
1018
|
+
/**
|
|
1019
|
+
* Add an imported module.
|
|
1020
|
+
*/
|
|
1021
|
+
addImport(moduleRef: Module): void;
|
|
1022
|
+
/**
|
|
1023
|
+
* Add an exported token.
|
|
1024
|
+
*
|
|
1025
|
+
* @param token - The token to export (class, string, symbol, or module class)
|
|
1026
|
+
*/
|
|
1027
|
+
addExport(token: InjectionToken): void;
|
|
1028
|
+
/**
|
|
1029
|
+
* Check if this module has a provider for the given token.
|
|
1030
|
+
*/
|
|
1031
|
+
hasProvider(token: InjectionToken): boolean;
|
|
1032
|
+
/**
|
|
1033
|
+
* Get a provider wrapper by token.
|
|
1034
|
+
*/
|
|
1035
|
+
getProviderByToken<T = any>(token: InjectionToken): InstanceWrapper<T> | undefined;
|
|
1036
|
+
/**
|
|
1037
|
+
* Read the scope from a class's @Injectable() metadata.
|
|
1038
|
+
*/
|
|
1039
|
+
private getClassScope;
|
|
1040
|
+
/**
|
|
1041
|
+
* Get a human-readable name from a token.
|
|
1042
|
+
*/
|
|
1043
|
+
private getTokenName;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
/**
|
|
1047
|
+
* @fileoverview NestContainer — the top-level container that holds all modules.
|
|
1048
|
+
*
|
|
1049
|
+
* This is the central registry of the DI system. It holds:
|
|
1050
|
+
* - All registered modules (keyed by opaque token)
|
|
1051
|
+
* - The set of global modules
|
|
1052
|
+
* - Dynamic module metadata
|
|
1053
|
+
*
|
|
1054
|
+
* ## How the container is used:
|
|
1055
|
+
*
|
|
1056
|
+
* 1. The **scanner** calls `addModule()` for each module in the graph
|
|
1057
|
+
* 2. The **scanner** calls `addProvider()`, `addImport()`, `addExport()` to populate modules
|
|
1058
|
+
* 3. The **scanner** calls `bindGlobalScope()` to link global modules to all other modules
|
|
1059
|
+
* 4. The **injector** reads from modules to resolve dependencies
|
|
1060
|
+
*
|
|
1061
|
+
* The container itself does NOT resolve dependencies — that's the injector's job.
|
|
1062
|
+
* The container is purely a data structure that holds the module graph.
|
|
1063
|
+
*
|
|
1064
|
+
* @module injector/container
|
|
1065
|
+
*/
|
|
1066
|
+
|
|
1067
|
+
/**
|
|
1068
|
+
* The type of a module definition — can be a class, dynamic module, or promise.
|
|
1069
|
+
*/
|
|
1070
|
+
type ModuleMetatype = Type<any> | DynamicModule | Promise<DynamicModule>;
|
|
1071
|
+
/**
|
|
1072
|
+
* The top-level DI container.
|
|
1073
|
+
*
|
|
1074
|
+
* Holds all modules and their provider bindings. Created once during
|
|
1075
|
+
* application bootstrap and shared throughout the application lifetime.
|
|
1076
|
+
*/
|
|
1077
|
+
declare class NestContainer {
|
|
1078
|
+
/**
|
|
1079
|
+
* All registered modules, keyed by their opaque token.
|
|
1080
|
+
* The token is derived from the module class name (or a hash for dynamic modules).
|
|
1081
|
+
*/
|
|
1082
|
+
private readonly modules;
|
|
1083
|
+
/**
|
|
1084
|
+
* Global modules whose exports are available to all other modules.
|
|
1085
|
+
*/
|
|
1086
|
+
private readonly globalModules;
|
|
1087
|
+
/**
|
|
1088
|
+
* Dynamic module metadata, keyed by module token.
|
|
1089
|
+
* Stored separately because dynamic metadata is merged with static @Module() metadata.
|
|
1090
|
+
*/
|
|
1091
|
+
private readonly dynamicModulesMetadata;
|
|
1092
|
+
/**
|
|
1093
|
+
* Add a module to the container.
|
|
1094
|
+
*
|
|
1095
|
+
* If the module is already registered (by token), returns the existing one.
|
|
1096
|
+
* Otherwise, creates a new Module instance and registers it.
|
|
1097
|
+
*
|
|
1098
|
+
* @param metatype - The module class or dynamic module
|
|
1099
|
+
* @returns The Module instance and whether it was newly inserted
|
|
1100
|
+
*/
|
|
1101
|
+
addModule(metatype: ModuleMetatype): Promise<{
|
|
1102
|
+
moduleRef: Module;
|
|
1103
|
+
inserted: boolean;
|
|
1104
|
+
}>;
|
|
1105
|
+
/**
|
|
1106
|
+
* Add a provider to a module.
|
|
1107
|
+
*
|
|
1108
|
+
* @param provider - The provider to add
|
|
1109
|
+
* @param token - The module token to add the provider to
|
|
1110
|
+
*/
|
|
1111
|
+
addProvider(provider: Provider, token: string): void;
|
|
1112
|
+
/**
|
|
1113
|
+
* Add an import relationship between modules.
|
|
1114
|
+
*
|
|
1115
|
+
* @param relatedModule - The module being imported
|
|
1116
|
+
* @param token - The token of the module doing the importing
|
|
1117
|
+
*/
|
|
1118
|
+
addImport(relatedModule: Type<any> | DynamicModule, token: string): void;
|
|
1119
|
+
/**
|
|
1120
|
+
* Add an export to a module.
|
|
1121
|
+
*
|
|
1122
|
+
* @param toExport - The token or provider to export
|
|
1123
|
+
* @param token - The module token
|
|
1124
|
+
*/
|
|
1125
|
+
addExport(toExport: InjectionToken | Provider | DynamicModule, token: string): void;
|
|
1126
|
+
/**
|
|
1127
|
+
* Link all global modules to all non-global modules as imports.
|
|
1128
|
+
*
|
|
1129
|
+
* Called after all modules have been scanned. This makes global modules'
|
|
1130
|
+
* exports available everywhere without explicit imports.
|
|
1131
|
+
*/
|
|
1132
|
+
bindGlobalScope(): void;
|
|
1133
|
+
/**
|
|
1134
|
+
* Get all registered modules.
|
|
1135
|
+
*/
|
|
1136
|
+
getModules(): Map<string, Module>;
|
|
1137
|
+
/**
|
|
1138
|
+
* Get a module by its token.
|
|
1139
|
+
*/
|
|
1140
|
+
getModuleByToken(token: string): Module | undefined;
|
|
1141
|
+
/**
|
|
1142
|
+
* Get dynamic metadata for a module.
|
|
1143
|
+
*
|
|
1144
|
+
* @param token - The module token
|
|
1145
|
+
* @param key - Optional specific key to retrieve (e.g., 'imports', 'providers')
|
|
1146
|
+
*/
|
|
1147
|
+
getDynamicMetadata(token: string): Partial<DynamicModule> | undefined;
|
|
1148
|
+
getDynamicMetadata<K extends keyof DynamicModule>(token: string, key: K): DynamicModule[K] | undefined;
|
|
1149
|
+
/**
|
|
1150
|
+
* Clear all modules (for testing).
|
|
1151
|
+
*/
|
|
1152
|
+
clear(): void;
|
|
1153
|
+
/**
|
|
1154
|
+
* Extract the module class, dynamic metadata, and token from a module definition.
|
|
1155
|
+
*
|
|
1156
|
+
* Handles both static modules (just a class) and dynamic modules
|
|
1157
|
+
* (objects with a `module` property).
|
|
1158
|
+
*/
|
|
1159
|
+
private extractModuleMetadata;
|
|
1160
|
+
/**
|
|
1161
|
+
* Check if a module definition is a dynamic module (has a `module` property).
|
|
1162
|
+
*/
|
|
1163
|
+
private isDynamicModule;
|
|
1164
|
+
/**
|
|
1165
|
+
* Check if a module should be global.
|
|
1166
|
+
* A module is global if:
|
|
1167
|
+
* - It has the @Global() decorator, OR
|
|
1168
|
+
* - Its dynamic metadata has `global: true`
|
|
1169
|
+
*/
|
|
1170
|
+
private isGlobalModule;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
/**
|
|
1174
|
+
* @fileoverview Injector — resolves dependencies and creates provider instances.
|
|
1175
|
+
*
|
|
1176
|
+
* The injector is the engine that turns the module graph (built by the scanner)
|
|
1177
|
+
* into actual, live instances. For each provider, it:
|
|
1178
|
+
*
|
|
1179
|
+
* 1. Reads constructor parameter types from metadata
|
|
1180
|
+
* 2. Resolves each dependency (recursively)
|
|
1181
|
+
* 3. Creates the instance (via `new` for classes, or by calling the factory)
|
|
1182
|
+
* 4. Applies property injection
|
|
1183
|
+
* 5. Marks the provider as resolved
|
|
1184
|
+
*
|
|
1185
|
+
* ## Resolution algorithm:
|
|
1186
|
+
*
|
|
1187
|
+
* For a given token in a given module:
|
|
1188
|
+
* 1. Look in the module's own providers
|
|
1189
|
+
* 2. If not found, look in imported modules' exports (recursively)
|
|
1190
|
+
* 3. If still not found, throw UnknownDependencyError
|
|
1191
|
+
*
|
|
1192
|
+
* ## Singleton vs Transient:
|
|
1193
|
+
*
|
|
1194
|
+
* - Singleton (DEFAULT): resolved once, cached in the InstanceWrapper
|
|
1195
|
+
* - Transient: a new instance is created every time it's injected
|
|
1196
|
+
*
|
|
1197
|
+
* @module injector/injector
|
|
1198
|
+
*/
|
|
1199
|
+
|
|
1200
|
+
/**
|
|
1201
|
+
* The Injector resolves and instantiates providers.
|
|
1202
|
+
*
|
|
1203
|
+
* It's stateless — all state lives in the InstanceWrappers within modules.
|
|
1204
|
+
* The injector just reads metadata and creates instances.
|
|
1205
|
+
*/
|
|
1206
|
+
declare class Injector {
|
|
1207
|
+
/**
|
|
1208
|
+
* Tracks which wrappers are currently being resolved, to detect circular dependencies.
|
|
1209
|
+
* Uses a Set of tokens being resolved in the current chain.
|
|
1210
|
+
*/
|
|
1211
|
+
private readonly resolutionStack;
|
|
1212
|
+
/**
|
|
1213
|
+
* Resolve all providers in a module.
|
|
1214
|
+
*
|
|
1215
|
+
* Iterates over all providers and resolves each one.
|
|
1216
|
+
* Value providers are already resolved at registration time.
|
|
1217
|
+
*
|
|
1218
|
+
* @param moduleRef - The module whose providers to resolve
|
|
1219
|
+
*/
|
|
1220
|
+
resolveProviders(moduleRef: Module): Promise<void>;
|
|
1221
|
+
/**
|
|
1222
|
+
* Resolve a single provider instance.
|
|
1223
|
+
*
|
|
1224
|
+
* This is the core resolution method. It handles:
|
|
1225
|
+
* - Already-resolved singletons (returns cached instance)
|
|
1226
|
+
* - Circular dependency detection
|
|
1227
|
+
* - Factory providers (calls the factory function)
|
|
1228
|
+
* - Class providers (resolves constructor deps, then `new`)
|
|
1229
|
+
* - Property injection (after construction)
|
|
1230
|
+
* - Async factories (awaits the result)
|
|
1231
|
+
*
|
|
1232
|
+
* @param wrapper - The InstanceWrapper to resolve
|
|
1233
|
+
* @param moduleRef - The module context for dependency lookup
|
|
1234
|
+
*/
|
|
1235
|
+
resolveInstance<T>(wrapper: InstanceWrapper<T>, moduleRef: Module): Promise<T>;
|
|
1236
|
+
/**
|
|
1237
|
+
* Look up a provider by token, searching the module and its imports.
|
|
1238
|
+
*
|
|
1239
|
+
* Resolution order:
|
|
1240
|
+
* 1. The module's own providers
|
|
1241
|
+
* 2. Imported modules' exported providers (breadth-first)
|
|
1242
|
+
*
|
|
1243
|
+
* @param token - The injection token to look up
|
|
1244
|
+
* @param moduleRef - The module context
|
|
1245
|
+
* @returns The InstanceWrapper and the module it was found in
|
|
1246
|
+
*/
|
|
1247
|
+
lookupProvider(token: InjectionToken, moduleRef: Module): {
|
|
1248
|
+
wrapper: InstanceWrapper;
|
|
1249
|
+
host: Module;
|
|
1250
|
+
} | undefined;
|
|
1251
|
+
/**
|
|
1252
|
+
* Resolve a class provider by:
|
|
1253
|
+
* 1. Reading constructor parameter types from metadata
|
|
1254
|
+
* 2. Resolving each dependency
|
|
1255
|
+
* 3. Calling `new Class(...deps)`
|
|
1256
|
+
* 4. Applying property injection
|
|
1257
|
+
*/
|
|
1258
|
+
private resolveClass;
|
|
1259
|
+
/**
|
|
1260
|
+
* Resolve a factory provider by:
|
|
1261
|
+
* 1. Resolving the factory's `inject` dependencies
|
|
1262
|
+
* 2. Calling the factory function with the resolved deps
|
|
1263
|
+
* 3. Awaiting the result if it's a Promise
|
|
1264
|
+
*/
|
|
1265
|
+
private resolveFactory;
|
|
1266
|
+
/**
|
|
1267
|
+
* Resolve a single dependency token to its instance.
|
|
1268
|
+
*
|
|
1269
|
+
* Looks up the provider, resolves it if needed, and returns the instance.
|
|
1270
|
+
*/
|
|
1271
|
+
private resolveDependency;
|
|
1272
|
+
/**
|
|
1273
|
+
* Look up a provider in imported modules' exports.
|
|
1274
|
+
*
|
|
1275
|
+
* Searches breadth-first through the import tree, only considering
|
|
1276
|
+
* providers that are in the imported module's exports set.
|
|
1277
|
+
*/
|
|
1278
|
+
private lookupInImports;
|
|
1279
|
+
/**
|
|
1280
|
+
* Get the constructor dependencies for a class.
|
|
1281
|
+
*
|
|
1282
|
+
* Merges TypeScript's auto-emitted `design:paramtypes` with
|
|
1283
|
+
* explicitly declared `self:paramtypes` (from @Inject decorators).
|
|
1284
|
+
* Explicit declarations override auto-detected types.
|
|
1285
|
+
*
|
|
1286
|
+
* @param type - The class to read metadata from
|
|
1287
|
+
* @returns Array of injection tokens, one per constructor parameter
|
|
1288
|
+
*/
|
|
1289
|
+
private getConstructorDependencies;
|
|
1290
|
+
/**
|
|
1291
|
+
* Get the indices of optional constructor parameters.
|
|
1292
|
+
*/
|
|
1293
|
+
private getOptionalDependencies;
|
|
1294
|
+
/**
|
|
1295
|
+
* Resolve property-injected dependencies and assign them to the instance.
|
|
1296
|
+
*/
|
|
1297
|
+
private resolveProperties;
|
|
1298
|
+
/**
|
|
1299
|
+
* Format the resolution stack for error messages.
|
|
1300
|
+
*/
|
|
1301
|
+
private formatResolutionStack;
|
|
1302
|
+
/**
|
|
1303
|
+
* Get a human-readable name from a token.
|
|
1304
|
+
*/
|
|
1305
|
+
private getTokenName;
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
/**
|
|
1309
|
+
* @fileoverview InstanceLoader — orchestrates provider instantiation and lifecycle hooks.
|
|
1310
|
+
*
|
|
1311
|
+
* After the scanner has built the module graph, the InstanceLoader:
|
|
1312
|
+
* 1. Resolves all providers in all modules (via the Injector)
|
|
1313
|
+
* 2. Calls `onModuleInit()` on providers that implement it
|
|
1314
|
+
*
|
|
1315
|
+
* It also provides `destroy()` for calling `onModuleDestroy()` during shutdown.
|
|
1316
|
+
*
|
|
1317
|
+
* @module injector/instance-loader
|
|
1318
|
+
*/
|
|
1319
|
+
|
|
1320
|
+
/**
|
|
1321
|
+
* Loads (instantiates) all providers and runs lifecycle hooks.
|
|
1322
|
+
*/
|
|
1323
|
+
declare class InstanceLoader {
|
|
1324
|
+
private readonly container;
|
|
1325
|
+
private readonly injector;
|
|
1326
|
+
constructor(container: NestContainer);
|
|
1327
|
+
/**
|
|
1328
|
+
* Instantiate all providers in all modules.
|
|
1329
|
+
*
|
|
1330
|
+
* Iterates modules and resolves each module's providers.
|
|
1331
|
+
* After all providers are resolved, calls `onModuleInit()` lifecycle hooks.
|
|
1332
|
+
*/
|
|
1333
|
+
createInstances(): Promise<void>;
|
|
1334
|
+
/**
|
|
1335
|
+
* Call `onModuleDestroy()` on all providers that implement it.
|
|
1336
|
+
*
|
|
1337
|
+
* Called during application shutdown. Iterates modules in reverse
|
|
1338
|
+
* order (leaf modules first, root module last).
|
|
1339
|
+
*/
|
|
1340
|
+
destroy(): Promise<void>;
|
|
1341
|
+
/**
|
|
1342
|
+
* Get the injector instance (for direct resolution outside the module system).
|
|
1343
|
+
*/
|
|
1344
|
+
getInjector(): Injector;
|
|
1345
|
+
/**
|
|
1346
|
+
* Call `onModuleInit()` on all resolved providers in a module.
|
|
1347
|
+
*/
|
|
1348
|
+
private callModuleInitHooks;
|
|
1349
|
+
/**
|
|
1350
|
+
* Call `onModuleDestroy()` on all resolved providers in a module.
|
|
1351
|
+
*/
|
|
1352
|
+
private callModuleDestroyHooks;
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
/**
|
|
1356
|
+
* @fileoverview DependenciesScanner — recursively scans the module tree.
|
|
1357
|
+
*
|
|
1358
|
+
* The scanner is the first phase of the DI bootstrap. It walks the module
|
|
1359
|
+
* graph starting from the root module and:
|
|
1360
|
+
*
|
|
1361
|
+
* 1. Registers each module in the container
|
|
1362
|
+
* 2. Registers each module's providers
|
|
1363
|
+
* 3. Sets up import relationships between modules
|
|
1364
|
+
* 4. Sets up export declarations
|
|
1365
|
+
* 5. Links global modules to all other modules
|
|
1366
|
+
*
|
|
1367
|
+
* After scanning, the container has a complete picture of the module graph
|
|
1368
|
+
* but NO instances have been created yet. That's the injector's job.
|
|
1369
|
+
*
|
|
1370
|
+
* ## Scan algorithm:
|
|
1371
|
+
*
|
|
1372
|
+
* ```
|
|
1373
|
+
* scan(RootModule)
|
|
1374
|
+
* → scanForModules(RootModule) // recursive DFS
|
|
1375
|
+
* → addModule(RootModule)
|
|
1376
|
+
* → scanForModules(ImportedModule1) // recurse into imports
|
|
1377
|
+
* → scanForModules(ImportedModule2)
|
|
1378
|
+
* → scanModulesForDependencies() // second pass
|
|
1379
|
+
* → for each module:
|
|
1380
|
+
* → reflectImports()
|
|
1381
|
+
* → reflectProviders()
|
|
1382
|
+
* → reflectExports()
|
|
1383
|
+
* → bindGlobalScope() // link globals
|
|
1384
|
+
* ```
|
|
1385
|
+
*
|
|
1386
|
+
* @module injector/scanner
|
|
1387
|
+
*/
|
|
1388
|
+
|
|
1389
|
+
/**
|
|
1390
|
+
* Scans the module tree and populates the container.
|
|
1391
|
+
*/
|
|
1392
|
+
declare class DependenciesScanner {
|
|
1393
|
+
private readonly container;
|
|
1394
|
+
constructor(container: NestContainer);
|
|
1395
|
+
/**
|
|
1396
|
+
* Scan the entire module tree starting from the root module.
|
|
1397
|
+
*
|
|
1398
|
+
* This is the main entry point. After this method completes,
|
|
1399
|
+
* the container has all modules, providers, imports, and exports
|
|
1400
|
+
* registered — but no instances created.
|
|
1401
|
+
*
|
|
1402
|
+
* @param rootModule - The root module class (your AppModule)
|
|
1403
|
+
*/
|
|
1404
|
+
scan(rootModule: Type<any>): Promise<void>;
|
|
1405
|
+
/**
|
|
1406
|
+
* Recursively discover and register all modules in the graph.
|
|
1407
|
+
*
|
|
1408
|
+
* Uses DFS traversal. Tracks visited modules to avoid infinite loops
|
|
1409
|
+
* from circular imports.
|
|
1410
|
+
*
|
|
1411
|
+
* @param moduleDefinition - The module to scan (class or dynamic module)
|
|
1412
|
+
* @param ctxRegistry - Already-visited modules (for cycle detection)
|
|
1413
|
+
*/
|
|
1414
|
+
private scanForModules;
|
|
1415
|
+
/**
|
|
1416
|
+
* For each registered module, read its metadata and register
|
|
1417
|
+
* providers, imports, and exports.
|
|
1418
|
+
*/
|
|
1419
|
+
private scanModulesForDependencies;
|
|
1420
|
+
/**
|
|
1421
|
+
* Read and register a module's imports.
|
|
1422
|
+
*
|
|
1423
|
+
* Merges static @Module({ imports }) with dynamic module imports.
|
|
1424
|
+
*/
|
|
1425
|
+
private reflectImports;
|
|
1426
|
+
/**
|
|
1427
|
+
* Read and register a module's providers.
|
|
1428
|
+
*
|
|
1429
|
+
* Merges static @Module({ providers }) with dynamic module providers.
|
|
1430
|
+
*/
|
|
1431
|
+
private reflectProviders;
|
|
1432
|
+
/**
|
|
1433
|
+
* Read and register a module's exports.
|
|
1434
|
+
*
|
|
1435
|
+
* Merges static @Module({ exports }) with dynamic module exports.
|
|
1436
|
+
*/
|
|
1437
|
+
private reflectExports;
|
|
1438
|
+
/**
|
|
1439
|
+
* Get a module's imports from both static and dynamic sources.
|
|
1440
|
+
*/
|
|
1441
|
+
private getModuleImports;
|
|
1442
|
+
/**
|
|
1443
|
+
* Resolve a forward reference to its actual value.
|
|
1444
|
+
*/
|
|
1445
|
+
private resolveForwardRef;
|
|
1446
|
+
/**
|
|
1447
|
+
* Check if a module definition is a dynamic module.
|
|
1448
|
+
*/
|
|
1449
|
+
private isDynamicModule;
|
|
1450
|
+
/**
|
|
1451
|
+
* Get a human-readable name for a module.
|
|
1452
|
+
*/
|
|
1453
|
+
private getModuleName;
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
/**
|
|
1457
|
+
* @fileoverview Metadata keys and constants used throughout the DI system.
|
|
1458
|
+
*
|
|
1459
|
+
* These constants define the metadata keys that decorators write to classes
|
|
1460
|
+
* and that the injector reads during resolution. They mirror NestJS's
|
|
1461
|
+
* internal constants but are simplified for client-side use.
|
|
1462
|
+
*
|
|
1463
|
+
* ## How metadata flows:
|
|
1464
|
+
*
|
|
1465
|
+
* 1. **Decorators** write metadata using `Reflect.defineMetadata(KEY, value, target)`
|
|
1466
|
+
* 2. **Scanner** reads module metadata (`imports`, `providers`, `exports`) to build the module graph
|
|
1467
|
+
* 3. **Injector** reads constructor metadata (`design:paramtypes`, `self:paramtypes`) to resolve dependencies
|
|
1468
|
+
*
|
|
1469
|
+
* @module constants
|
|
1470
|
+
*/
|
|
1471
|
+
/**
|
|
1472
|
+
* Keys used by the `@Module()` decorator to store module configuration.
|
|
1473
|
+
*
|
|
1474
|
+
* The `@Module()` decorator iterates over the metadata object and calls
|
|
1475
|
+
* `Reflect.defineMetadata(key, value, target)` for each property.
|
|
1476
|
+
*
|
|
1477
|
+
* @example
|
|
1478
|
+
* ```typescript
|
|
1479
|
+
* // When you write:
|
|
1480
|
+
* @Module({ imports: [ConfigModule], providers: [UserService], exports: [UserService] })
|
|
1481
|
+
* class AppModule {}
|
|
1482
|
+
*
|
|
1483
|
+
* // The decorator stores:
|
|
1484
|
+
* Reflect.defineMetadata('imports', [ConfigModule], AppModule)
|
|
1485
|
+
* Reflect.defineMetadata('providers', [UserService], AppModule)
|
|
1486
|
+
* Reflect.defineMetadata('exports', [UserService], AppModule)
|
|
1487
|
+
* ```
|
|
1488
|
+
*/
|
|
1489
|
+
declare const MODULE_METADATA: {
|
|
1490
|
+
readonly IMPORTS: "imports";
|
|
1491
|
+
readonly PROVIDERS: "providers";
|
|
1492
|
+
readonly EXPORTS: "exports";
|
|
1493
|
+
};
|
|
1494
|
+
/**
|
|
1495
|
+
* Metadata key set by `@Global()` decorator.
|
|
1496
|
+
* When present and `true`, the module's exported providers are available
|
|
1497
|
+
* to all other modules without explicit imports.
|
|
1498
|
+
*/
|
|
1499
|
+
declare const GLOBAL_MODULE_METADATA = "__module:global__";
|
|
1500
|
+
/**
|
|
1501
|
+
* Watermark set by `@Injectable()` to mark a class as a provider.
|
|
1502
|
+
* The scanner uses this to validate that providers are properly decorated.
|
|
1503
|
+
*/
|
|
1504
|
+
declare const INJECTABLE_WATERMARK = "__injectable__";
|
|
1505
|
+
/**
|
|
1506
|
+
* Scope options metadata set by `@Injectable({ scope: Scope.REQUEST })`.
|
|
1507
|
+
* For client-side use, we primarily support DEFAULT (singleton) and TRANSIENT.
|
|
1508
|
+
*/
|
|
1509
|
+
declare const SCOPE_OPTIONS_METADATA = "scope:options";
|
|
1510
|
+
/**
|
|
1511
|
+
* TypeScript's built-in metadata key for constructor parameter types.
|
|
1512
|
+
* Automatically emitted when `emitDecoratorMetadata: true` in tsconfig.
|
|
1513
|
+
*
|
|
1514
|
+
* Contains an array of constructor parameter types (class references).
|
|
1515
|
+
* This is the primary source for auto-resolving dependencies.
|
|
1516
|
+
*
|
|
1517
|
+
* @example
|
|
1518
|
+
* ```typescript
|
|
1519
|
+
* @Injectable()
|
|
1520
|
+
* class UserService {
|
|
1521
|
+
* constructor(private config: ConfigService, private logger: LoggerService) {}
|
|
1522
|
+
* }
|
|
1523
|
+
* // TypeScript emits: Reflect.defineMetadata('design:paramtypes', [ConfigService, LoggerService], UserService)
|
|
1524
|
+
* ```
|
|
1525
|
+
*/
|
|
1526
|
+
declare const PARAMTYPES_METADATA = "design:paramtypes";
|
|
1527
|
+
/**
|
|
1528
|
+
* Metadata key for explicitly declared constructor dependencies.
|
|
1529
|
+
* Written by `@Inject(token)` decorator for constructor parameters.
|
|
1530
|
+
*
|
|
1531
|
+
* Contains an array of `{ index: number, param: InjectionToken }` objects.
|
|
1532
|
+
* These override the auto-detected types from `design:paramtypes`.
|
|
1533
|
+
*
|
|
1534
|
+
* @example
|
|
1535
|
+
* ```typescript
|
|
1536
|
+
* @Injectable()
|
|
1537
|
+
* class CacheService {
|
|
1538
|
+
* constructor(@Inject(CACHE_CONFIG) private config: CacheConfig) {}
|
|
1539
|
+
* }
|
|
1540
|
+
* // @Inject writes: [{ index: 0, param: CACHE_CONFIG }] to 'self:paramtypes'
|
|
1541
|
+
* ```
|
|
1542
|
+
*/
|
|
1543
|
+
declare const SELF_DECLARED_DEPS_METADATA = "self:paramtypes";
|
|
1544
|
+
/**
|
|
1545
|
+
* Metadata key for optional constructor dependencies.
|
|
1546
|
+
* Written by `@Optional()` decorator for constructor parameters.
|
|
1547
|
+
*
|
|
1548
|
+
* Contains an array of parameter indices that are optional.
|
|
1549
|
+
* If resolution fails for an optional dependency, `undefined` is injected instead of throwing.
|
|
1550
|
+
*/
|
|
1551
|
+
declare const OPTIONAL_DEPS_METADATA = "optional:paramtypes";
|
|
1552
|
+
/**
|
|
1553
|
+
* Metadata key for property-based injection targets.
|
|
1554
|
+
* Written by `@Inject(token)` when used on a class property.
|
|
1555
|
+
*
|
|
1556
|
+
* Contains an array of `{ key: string, type: InjectionToken }` objects.
|
|
1557
|
+
*
|
|
1558
|
+
* @example
|
|
1559
|
+
* ```typescript
|
|
1560
|
+
* @Injectable()
|
|
1561
|
+
* class UserService {
|
|
1562
|
+
* @Inject(LoggerService)
|
|
1563
|
+
* private logger!: LoggerService;
|
|
1564
|
+
* }
|
|
1565
|
+
* ```
|
|
1566
|
+
*/
|
|
1567
|
+
declare const PROPERTY_DEPS_METADATA = "self:properties_metadata";
|
|
1568
|
+
/**
|
|
1569
|
+
* Metadata key for optional property dependencies.
|
|
1570
|
+
* Written by `@Optional()` when used on a class property.
|
|
1571
|
+
*
|
|
1572
|
+
* Contains an array of property keys that are optional.
|
|
1573
|
+
*/
|
|
1574
|
+
declare const OPTIONAL_PROPERTY_DEPS_METADATA = "optional:properties_metadata";
|
|
1575
|
+
|
|
1576
|
+
export { type ClassProvider, type ContainerResolver, DependenciesScanner, type DynamicModule, type ExistingProvider, type FactoryProvider, type ForwardReference, GLOBAL_MODULE_METADATA, Global, INJECTABLE_WATERMARK, Inject, Injectable, type InjectionToken, Injector, InstanceLoader, InstanceWrapper, MODULE_METADATA, Module$1 as Module, type ModuleMetadata, Module as ModuleRef, NestContainer, OPTIONAL_DEPS_METADATA, OPTIONAL_PROPERTY_DEPS_METADATA, type OnModuleDestroy, type OnModuleInit, Optional, PARAMTYPES_METADATA, PROPERTY_DEPS_METADATA, type Provider, SCOPE_OPTIONS_METADATA, SELF_DECLARED_DEPS_METADATA, Scope, type ScopeOptions, type Type, type ValueProvider, forwardRef };
|