@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.
@@ -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 };