@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants/tokens.constant.ts","../src/decorators/injectable.decorator.ts","../src/decorators/inject.decorator.ts","../src/decorators/optional.decorator.ts","../src/decorators/module.decorator.ts","../src/decorators/global.decorator.ts","../src/interfaces/scope.enum.ts","../src/utils/forward-ref.util.ts","../src/interfaces/provider.interface.ts","../src/injector/instance-wrapper.ts","../src/injector/module.ts","../src/injector/container.ts","../src/injector/injector.ts","../src/interfaces/lifecycle.interface.ts","../src/injector/instance-loader.ts","../src/injector/scanner.ts"],"names":["Scope","Module"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @fileoverview Metadata keys and constants used throughout the DI system.\n *\n * These constants define the metadata keys that decorators write to classes\n * and that the injector reads during resolution. They mirror NestJS's\n * internal constants but are simplified for client-side use.\n *\n * ## How metadata flows:\n *\n * 1. **Decorators** write metadata using `Reflect.defineMetadata(KEY, value, target)`\n * 2. **Scanner** reads module metadata (`imports`, `providers`, `exports`) to build the module graph\n * 3. **Injector** reads constructor metadata (`design:paramtypes`, `self:paramtypes`) to resolve dependencies\n *\n * @module constants\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Module metadata keys\n// Written by @Module() decorator, read by DependenciesScanner\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Keys used by the `@Module()` decorator to store module configuration.\n *\n * The `@Module()` decorator iterates over the metadata object and calls\n * `Reflect.defineMetadata(key, value, target)` for each property.\n *\n * @example\n * ```typescript\n * // When you write:\n * @Module({ imports: [ConfigModule], providers: [UserService], exports: [UserService] })\n * class AppModule {}\n *\n * // The decorator stores:\n * Reflect.defineMetadata('imports', [ConfigModule], AppModule)\n * Reflect.defineMetadata('providers', [UserService], AppModule)\n * Reflect.defineMetadata('exports', [UserService], AppModule)\n * ```\n */\nexport const MODULE_METADATA = {\n IMPORTS: 'imports',\n PROVIDERS: 'providers',\n EXPORTS: 'exports',\n} as const;\n\n/**\n * Metadata key set by `@Global()` decorator.\n * When present and `true`, the module's exported providers are available\n * to all other modules without explicit imports.\n */\nexport const GLOBAL_MODULE_METADATA = '__module:global__';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Injectable metadata keys\n// Written by @Injectable() decorator, read by Injector\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Watermark set by `@Injectable()` to mark a class as a provider.\n * The scanner uses this to validate that providers are properly decorated.\n */\nexport const INJECTABLE_WATERMARK = '__injectable__';\n\n/**\n * Scope options metadata set by `@Injectable({ scope: Scope.REQUEST })`.\n * For client-side use, we primarily support DEFAULT (singleton) and TRANSIENT.\n */\nexport const SCOPE_OPTIONS_METADATA = 'scope:options';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Constructor injection metadata keys\n// Written by @Inject() and TypeScript's emitDecoratorMetadata\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * TypeScript's built-in metadata key for constructor parameter types.\n * Automatically emitted when `emitDecoratorMetadata: true` in tsconfig.\n *\n * Contains an array of constructor parameter types (class references).\n * This is the primary source for auto-resolving dependencies.\n *\n * @example\n * ```typescript\n * @Injectable()\n * class UserService {\n * constructor(private config: ConfigService, private logger: LoggerService) {}\n * }\n * // TypeScript emits: Reflect.defineMetadata('design:paramtypes', [ConfigService, LoggerService], UserService)\n * ```\n */\nexport const PARAMTYPES_METADATA = 'design:paramtypes';\n\n/**\n * Metadata key for explicitly declared constructor dependencies.\n * Written by `@Inject(token)` decorator for constructor parameters.\n *\n * Contains an array of `{ index: number, param: InjectionToken }` objects.\n * These override the auto-detected types from `design:paramtypes`.\n *\n * @example\n * ```typescript\n * @Injectable()\n * class CacheService {\n * constructor(@Inject(CACHE_CONFIG) private config: CacheConfig) {}\n * }\n * // @Inject writes: [{ index: 0, param: CACHE_CONFIG }] to 'self:paramtypes'\n * ```\n */\nexport const SELF_DECLARED_DEPS_METADATA = 'self:paramtypes';\n\n/**\n * Metadata key for optional constructor dependencies.\n * Written by `@Optional()` decorator for constructor parameters.\n *\n * Contains an array of parameter indices that are optional.\n * If resolution fails for an optional dependency, `undefined` is injected instead of throwing.\n */\nexport const OPTIONAL_DEPS_METADATA = 'optional:paramtypes';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Property injection metadata keys\n// Written by @Inject() on class properties\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Metadata key for property-based injection targets.\n * Written by `@Inject(token)` when used on a class property.\n *\n * Contains an array of `{ key: string, type: InjectionToken }` objects.\n *\n * @example\n * ```typescript\n * @Injectable()\n * class UserService {\n * @Inject(LoggerService)\n * private logger!: LoggerService;\n * }\n * ```\n */\nexport const PROPERTY_DEPS_METADATA = 'self:properties_metadata';\n\n/**\n * Metadata key for optional property dependencies.\n * Written by `@Optional()` when used on a class property.\n *\n * Contains an array of property keys that are optional.\n */\nexport const OPTIONAL_PROPERTY_DEPS_METADATA = 'optional:properties_metadata';\n","/**\n * @fileoverview @Injectable() decorator.\n *\n * Marks a class as a provider that can be managed by the DI container.\n * This is the most fundamental decorator in the system — any class that\n * needs to be injected or have dependencies injected into it must be\n * decorated with `@Injectable()`.\n *\n * ## What it does:\n *\n * 1. Sets the `__injectable__` watermark on the class (so the scanner can identify it)\n * 2. Stores scope options (singleton vs transient) as metadata\n * 3. TypeScript's `emitDecoratorMetadata` automatically emits `design:paramtypes`\n * (constructor parameter types) because a decorator is present on the class\n *\n * That third point is crucial — without `@Injectable()`, TypeScript won't emit\n * the constructor parameter type metadata that the injector needs to auto-resolve\n * dependencies.\n *\n * @module decorators/injectable\n */\n\nimport 'reflect-metadata';\nimport { INJECTABLE_WATERMARK, SCOPE_OPTIONS_METADATA } from '@/constants';\nimport type { ScopeOptions } from '@/interfaces';\n\n/**\n * Decorator that marks a class as injectable (a provider).\n *\n * @param options - Optional scope configuration\n *\n * @example\n * ```typescript\n * // Basic usage — singleton by default\n * @Injectable()\n * class UserService {\n * constructor(private config: ConfigService) {}\n * }\n *\n * // Transient scope — new instance per injection\n * @Injectable({ scope: Scope.TRANSIENT })\n * class RequestLogger {\n * private readonly id = Math.random();\n * }\n * ```\n */\nexport function Injectable(options?: ScopeOptions): ClassDecorator {\n return (target: Function) => {\n Reflect.defineMetadata(INJECTABLE_WATERMARK, true, target);\n Reflect.defineMetadata(SCOPE_OPTIONS_METADATA, options, target);\n };\n}\n","/**\n * @fileoverview @Inject() decorator.\n *\n * Explicitly specifies the injection token for a constructor parameter\n * or class property. This is needed when:\n *\n * 1. The token is a string or symbol (not a class)\n * 2. You want to inject a different implementation than the parameter type\n * 3. The parameter type is an interface (interfaces are erased at runtime)\n *\n * ## How it works:\n *\n * **Constructor parameter injection:**\n * Pushes `{ index, param: token }` into the `self:paramtypes` metadata array.\n * During resolution, the injector merges `self:paramtypes` with `design:paramtypes`\n * — explicit `@Inject()` tokens override the auto-detected types.\n *\n * **Property injection:**\n * Pushes `{ key, type: token }` into the `self:properties_metadata` array.\n * After construction, the injector resolves each property dependency and\n * assigns it to the instance.\n *\n * @module decorators/inject\n */\n\nimport 'reflect-metadata';\nimport {\n PARAMTYPES_METADATA,\n PROPERTY_DEPS_METADATA,\n SELF_DECLARED_DEPS_METADATA,\n} from '@/constants';\nimport type { InjectionToken, ForwardReference } from '@/interfaces';\n\n/**\n * Decorator that specifies the injection token for a dependency.\n *\n * Can be used on constructor parameters or class properties.\n *\n * @param token - The injection token to use. If omitted, falls back to\n * the TypeScript-emitted type or the property's design:type.\n *\n * @example\n * ```typescript\n * // Constructor parameter injection with a symbol token\n * @Injectable()\n * class CacheService {\n * constructor(\n * @Inject(CACHE_CONFIG) private config: CacheModuleOptions,\n * @Inject(RedisManager) private redis: RedisManager,\n * ) {}\n * }\n *\n * // Property injection\n * @Injectable()\n * class UserService {\n * @Inject(LoggerService)\n * private logger!: LoggerService;\n * }\n *\n * // Without explicit token — uses the TypeScript type\n * @Injectable()\n * class OrderService {\n * constructor(private userService: UserService) {}\n * // Equivalent to: @Inject(UserService) private userService: UserService\n * }\n * ```\n */\nexport function Inject(\n token?: InjectionToken | ForwardReference,\n): PropertyDecorator & ParameterDecorator {\n const hasExplicitToken = arguments.length > 0;\n\n return (target: object, key: string | symbol | undefined, index?: number) => {\n // Resolve the token: explicit > design:type > design:paramtypes[index]\n let resolvedToken = token;\n\n if (!resolvedToken && !hasExplicitToken) {\n // Try to infer from TypeScript metadata\n if (key !== undefined) {\n // Property injection — use design:type\n resolvedToken = Reflect.getMetadata('design:type', target, key);\n } else if (index !== undefined) {\n // Constructor injection — use design:paramtypes[index]\n const paramTypes = Reflect.getMetadata(PARAMTYPES_METADATA, target) || [];\n resolvedToken = paramTypes[index];\n }\n }\n\n // Handle forward references\n if (resolvedToken && typeof resolvedToken === 'object' && 'forwardRef' in resolvedToken) {\n resolvedToken = (resolvedToken as ForwardReference).forwardRef();\n }\n\n if (index !== undefined) {\n // ── Constructor parameter injection ──────────────────────────────\n // Store in self:paramtypes — these override design:paramtypes\n const existingDeps =\n Reflect.getMetadata(SELF_DECLARED_DEPS_METADATA, target) || [];\n\n Reflect.defineMetadata(\n SELF_DECLARED_DEPS_METADATA,\n [...existingDeps, { index, param: resolvedToken }],\n target,\n );\n } else {\n // ── Property injection ───────────────────────────────────────────\n // Store in self:properties_metadata\n const existingProps =\n Reflect.getMetadata(PROPERTY_DEPS_METADATA, target.constructor) || [];\n\n Reflect.defineMetadata(\n PROPERTY_DEPS_METADATA,\n [...existingProps, { key, type: resolvedToken }],\n target.constructor,\n );\n }\n };\n}\n","/**\n * @fileoverview @Optional() decorator.\n *\n * Marks a dependency as optional. If the container cannot resolve the\n * dependency, `undefined` is injected instead of throwing an error.\n *\n * @module decorators/optional\n */\n\nimport 'reflect-metadata';\nimport {\n OPTIONAL_DEPS_METADATA,\n OPTIONAL_PROPERTY_DEPS_METADATA,\n} from '@/constants';\n\n/**\n * Marks a constructor parameter or property dependency as optional.\n *\n * Without `@Optional()`, an unresolvable dependency throws an error.\n * With `@Optional()`, `undefined` is injected instead.\n *\n * @example\n * ```typescript\n * @Injectable()\n * class CacheService {\n * constructor(\n * @Inject(CACHE_CONFIG) private config: CacheConfig,\n * @Optional() @Inject(RedisManager) private redis?: RedisManager,\n * ) {\n * // redis will be undefined if RedisModule is not imported\n * }\n * }\n * ```\n */\nexport function Optional(): PropertyDecorator & ParameterDecorator {\n return (target: object, key: string | symbol | undefined, index?: number) => {\n if (index !== undefined) {\n // Constructor parameter — store the index\n const existingOptional =\n Reflect.getMetadata(OPTIONAL_DEPS_METADATA, target) || [];\n Reflect.defineMetadata(\n OPTIONAL_DEPS_METADATA,\n [...existingOptional, index],\n target,\n );\n } else {\n // Property — store the property key\n const existingOptional =\n Reflect.getMetadata(OPTIONAL_PROPERTY_DEPS_METADATA, target.constructor) || [];\n Reflect.defineMetadata(\n OPTIONAL_PROPERTY_DEPS_METADATA,\n [...existingOptional, key],\n target.constructor,\n );\n }\n };\n}\n","/**\n * @fileoverview @Module() decorator.\n *\n * Defines a module — the organizational unit of the DI system.\n * Modules group related providers and define the dependency graph\n * between different parts of the application.\n *\n * ## How it works:\n *\n * The decorator iterates over the metadata object and stores each\n * property as a separate metadata entry on the class:\n *\n * ```\n * @Module({ imports: [...], providers: [...], exports: [...] })\n * class MyModule {}\n *\n * // Becomes:\n * Reflect.defineMetadata('imports', [...], MyModule)\n * Reflect.defineMetadata('providers', [...], MyModule)\n * Reflect.defineMetadata('exports', [...], MyModule)\n * ```\n *\n * The scanner later reads these metadata entries to build the module graph.\n *\n * @module decorators/module\n */\n\nimport 'reflect-metadata';\nimport type { ModuleMetadata } from '@/interfaces';\n\n/** \n * Valid keys for @Module() metadata. \n */\nconst VALID_MODULE_KEYS = new Set(['imports', 'providers', 'exports']);\n\n/**\n * Decorator that defines a module.\n *\n * @param metadata - Module configuration (imports, providers, exports)\n *\n * @example\n * ```typescript\n * @Module({\n * imports: [ConfigModule.forRoot(config)],\n * providers: [UserService, UserRepository],\n * exports: [UserService],\n * })\n * class UserModule {}\n * ```\n */\nexport function Module(metadata: ModuleMetadata): ClassDecorator {\n // Validate that only known keys are used\n const invalidKeys = Object.keys(metadata).filter(key => !VALID_MODULE_KEYS.has(key));\n if (invalidKeys.length > 0) {\n throw new Error(\n `Invalid property '${invalidKeys.join(\"', '\")}' passed into the @Module() decorator. ` +\n `Valid properties are: ${[...VALID_MODULE_KEYS].join(', ')}.`,\n );\n }\n\n return (target: Function) => {\n for (const property in metadata) {\n if (Object.prototype.hasOwnProperty.call(metadata, property)) {\n Reflect.defineMetadata(property, (metadata as any)[property], target);\n }\n }\n };\n}\n","/**\n * @fileoverview @Global() decorator.\n *\n * Makes a module's exported providers available globally to all other\n * modules without requiring explicit imports.\n *\n * @module decorators/global\n */\n\nimport 'reflect-metadata';\nimport { GLOBAL_MODULE_METADATA } from '@/constants';\n\n/**\n * Decorator that makes a module global-scoped.\n *\n * Once a global module is imported anywhere (typically in the root module),\n * its exported providers become available to ALL modules in the application\n * without needing to import the module explicitly.\n *\n * Use sparingly — global modules reduce explicitness. Good candidates:\n * - Configuration modules\n * - Logger modules\n * - Database connection modules\n *\n * @example\n * ```typescript\n * @Global()\n * @Module({\n * providers: [ConfigService],\n * exports: [ConfigService],\n * })\n * class ConfigModule {\n * static forRoot(config: AppConfig): DynamicModule {\n * return {\n * module: ConfigModule,\n * global: true, // Can also be set here instead of @Global()\n * providers: [{ provide: APP_CONFIG, useValue: config }, ConfigService],\n * exports: [ConfigService],\n * };\n * }\n * }\n * ```\n */\nexport function Global(): ClassDecorator {\n return (target: Function) => {\n Reflect.defineMetadata(GLOBAL_MODULE_METADATA, true, target);\n };\n}\n","/**\n * @fileoverview Provider scope enum.\n *\n * Defines the lifecycle scope of a provider instance.\n * For client-side applications, DEFAULT (singleton) is the most common.\n *\n * @module interfaces/scope\n */\n\n/**\n * Determines how provider instances are shared.\n *\n * - `DEFAULT` — Singleton. One instance shared across the entire application.\n * This is the default and most common scope for client-side apps.\n *\n * - `TRANSIENT` — A new instance is created every time the provider is injected.\n * Useful for stateful services that shouldn't be shared.\n *\n * @example\n * ```typescript\n * // Singleton (default) — one instance for the whole app\n * @Injectable()\n * class ConfigService {}\n *\n * // Transient — new instance per injection\n * @Injectable({ scope: Scope.TRANSIENT })\n * class RequestLogger {}\n * ```\n */\nexport enum Scope {\n /**\n * Singleton scope. The provider is instantiated once and shared\n * across all consumers. This is the default.\n */\n DEFAULT = 0,\n\n /**\n * Transient scope. A new instance is created for every injection point.\n * Each consumer gets its own dedicated instance.\n */\n TRANSIENT = 1,\n}\n","/**\n * @fileoverview forwardRef utility — resolves circular module dependencies.\n *\n * @module utils/forward-ref\n */\n\nimport type { ForwardReference } from '@/interfaces';\n\n/**\n * Creates a forward reference to break circular dependency chains.\n *\n * When two modules import each other, TypeScript may resolve one of them\n * as `undefined` due to the ES module evaluation order. `forwardRef()`\n * wraps the reference in a function that's called later, after both\n * modules have been fully defined.\n *\n * @param fn - A function that returns the class reference\n * @returns A ForwardReference object\n *\n * @example\n * ```typescript\n * // cats.module.ts\n * @Module({\n * imports: [forwardRef(() => DogsModule)],\n * })\n * class CatsModule {}\n *\n * // dogs.module.ts\n * @Module({\n * imports: [forwardRef(() => CatsModule)],\n * })\n * class DogsModule {}\n * ```\n */\nexport function forwardRef<T = any>(fn: () => T): ForwardReference<T> {\n return { forwardRef: fn };\n}\n","/**\n * @fileoverview Provider types — the different ways to register a dependency.\n *\n * Providers are the fundamental building blocks of the DI system.\n * They tell the container HOW to create an instance for a given token.\n *\n * Four provider types are supported (same as NestJS):\n *\n * 1. **Class provider** — `{ provide: Token, useClass: SomeClass }`\n * 2. **Value provider** — `{ provide: Token, useValue: someValue }`\n * 3. **Factory provider** — `{ provide: Token, useFactory: () => value, inject: [Dep1] }`\n * 4. **Existing provider** (alias) — `{ provide: Token, useExisting: OtherToken }`\n *\n * Plus the shorthand: just passing a class directly (equivalent to `{ provide: Class, useClass: Class }`).\n *\n * @module interfaces/provider\n */\n\nimport type { Type } from './type.interface';\nimport type { InjectionToken } from './injection-token.interface';\nimport type { Scope } from './scope.enum';\n\n/**\n * Class provider — binds a token to a class that will be instantiated by the container.\n *\n * The container will:\n * 1. Read the class's constructor parameter types\n * 2. Resolve each dependency recursively\n * 3. Call `new useClass(...resolvedDeps)`\n *\n * @example\n * ```typescript\n * // Bind an interface token to a concrete implementation\n * { provide: 'IUserRepository', useClass: PostgresUserRepository }\n *\n * // Bind a class to itself (same as just listing the class)\n * { provide: UserService, useClass: UserService }\n * ```\n */\nexport interface ClassProvider<T = any> {\n /** \n * The injection token (what consumers ask for). \n */\n provide: InjectionToken;\n /** \n * The class to instantiate when this token is requested. \n */\n useClass: Type<T>;\n /** \n * Optional scope override. \n */\n scope?: Scope;\n}\n\n/**\n * Value provider — binds a token to a pre-existing value.\n *\n * No instantiation occurs. The exact value is returned as-is.\n * Useful for configuration objects, constants, and pre-built instances.\n *\n * @example\n * ```typescript\n * // Bind a configuration object\n * { provide: CACHE_CONFIG, useValue: { default: 'memory', stores: { ... } } }\n *\n * // Bind a primitive\n * { provide: 'API_URL', useValue: 'https://api.example.com' }\n *\n * // Bind a pre-built instance\n * { provide: Logger, useValue: new Logger('app') }\n * ```\n */\nexport interface ValueProvider<T = any> {\n /** \n * The injection token. \n */\n provide: InjectionToken;\n /** \n * The value to inject. Returned as-is, no instantiation. \n */\n useValue: T;\n}\n\n/**\n * Factory provider — binds a token to a factory function.\n *\n * The factory function is called once (for singletons) or per-injection\n * (for transients). Dependencies can be injected into the factory via\n * the `inject` array.\n *\n * @example\n * ```typescript\n * // Simple factory\n * {\n * provide: 'CONNECTION',\n * useFactory: () => createConnection({ host: 'localhost' }),\n * }\n *\n * // Factory with injected dependencies\n * {\n * provide: CacheManager,\n * useFactory: (config: ConfigService) => new CacheManager(config.get('cache')),\n * inject: [ConfigService],\n * }\n *\n * // Async factory\n * {\n * provide: 'DB_CONNECTION',\n * useFactory: async (config: ConfigService) => {\n * const conn = await createConnection(config.get('database'));\n * return conn;\n * },\n * inject: [ConfigService],\n * }\n * ```\n */\nexport interface FactoryProvider<T = any> {\n /** \n * The injection token. \n */\n provide: InjectionToken;\n /** \n * Factory function that creates the value. Can be async. \n */\n useFactory: (...args: any[]) => T | Promise<T>;\n /** \n * Tokens to inject as arguments to the factory function. \n */\n inject?: InjectionToken[];\n /** \n * Optional scope override. \n */\n scope?: Scope;\n}\n\n/**\n * Existing provider (alias) — binds a token to another token.\n *\n * When the alias token is requested, the container resolves the\n * target token instead. Useful for providing multiple tokens that\n * resolve to the same instance.\n *\n * @example\n * ```typescript\n * // Make CACHE_SERVICE resolve to the same instance as CacheManager\n * { provide: CACHE_SERVICE, useExisting: CacheManager }\n * ```\n */\nexport interface ExistingProvider<T = any> {\n /** \n * The alias injection token. \n */\n provide: InjectionToken;\n /** \n * The target token to resolve instead. \n */\n useExisting: InjectionToken<T>;\n}\n\n/**\n * Union type of all provider forms.\n *\n * A provider can be:\n * - A class reference (shorthand for `{ provide: Class, useClass: Class }`)\n * - A ClassProvider\n * - A ValueProvider\n * - A FactoryProvider\n * - An ExistingProvider\n *\n * @example\n * ```typescript\n * const providers: Provider[] = [\n * UserService, // class shorthand\n * { provide: 'API_URL', useValue: 'https://...' }, // value\n * { provide: CacheManager, useClass: CacheManager }, // class\n * { provide: DB, useFactory: () => connect() }, // factory\n * { provide: CACHE, useExisting: CacheManager }, // alias\n * ];\n * ```\n */\nexport type Provider<T = any> =\n | Type<T>\n | ClassProvider<T>\n | ValueProvider<T>\n | FactoryProvider<T>\n | ExistingProvider<T>;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Type guards for provider classification\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** \n * Check if a provider is a custom provider (has a `provide` property). \n */\nexport function isCustomProvider(provider: Provider): provider is ClassProvider | ValueProvider | FactoryProvider | ExistingProvider {\n return provider !== null && typeof provider === 'object' && 'provide' in provider;\n}\n\n/** \n * Check if a provider is a class shorthand (just a class reference). \n */\nexport function isClassShorthand(provider: Provider): provider is Type {\n return typeof provider === 'function';\n}\n\n/** \n * Check if a provider uses `useClass`. \n */\nexport function isClassProvider(provider: Provider): provider is ClassProvider {\n return isCustomProvider(provider) && 'useClass' in provider && (provider as any).useClass !== undefined;\n}\n\n/** \n * Check if a provider uses `useValue`. \n */\nexport function isValueProvider(provider: Provider): provider is ValueProvider {\n return isCustomProvider(provider) && 'useValue' in provider;\n}\n\n/** \n * Check if a provider uses `useFactory`. \n */\nexport function isFactoryProvider(provider: Provider): provider is FactoryProvider {\n return isCustomProvider(provider) && 'useFactory' in provider && typeof (provider as any).useFactory === 'function';\n}\n\n/** \n * Check if a provider uses `useExisting`. \n */\nexport function isExistingProvider(provider: Provider): provider is ExistingProvider {\n return isCustomProvider(provider) && 'useExisting' in provider && (provider as any).useExisting !== undefined;\n}\n","/**\n * @fileoverview InstanceWrapper — wraps a provider binding with its metadata and instance.\n *\n * Every provider registered in a module gets wrapped in an InstanceWrapper.\n * The wrapper tracks:\n * - The injection token (how consumers ask for it)\n * - The metatype (the class/factory to instantiate)\n * - The resolved instance (once created)\n * - The scope (singleton vs transient)\n * - Whether it's been resolved yet\n * - Factory dependencies (for useFactory providers)\n *\n * This is a simplified version of NestJS's InstanceWrapper — we don't need\n * request scoping, context IDs, or transient maps for client-side use.\n *\n * @module injector/instance-wrapper\n */\n\nimport type { InjectionToken, Type } from '@/interfaces';\nimport { Scope } from '@/interfaces';\nimport type { Module } from './module';\n\n/**\n * Wraps a single provider binding with all its metadata.\n *\n * @typeParam T - The type of the provider instance\n */\nexport class InstanceWrapper<T = any> {\n /** \n * The injection token used to look up this provider. \n */\n public readonly token: InjectionToken;\n\n /** \n * Human-readable name (class name or token string). \n */\n public readonly name: string;\n\n /**\n * The class constructor or factory function.\n * - For class providers: the class to `new`\n * - For factory providers: the factory function\n * - For value providers: `null`\n */\n public metatype: Type<T> | Function | null;\n\n /**\n * The resolved instance.\n * - `null` before resolution\n * - The actual instance after resolution\n * - For value providers: set immediately at registration\n */\n public instance: T | null = null;\n\n /** \n * Whether this provider has been fully resolved (instance created). \n */\n public isResolved: boolean = false;\n\n /** \n * The scope of this provider. \n */\n public scope: Scope = Scope.DEFAULT;\n\n /**\n * For factory providers: the tokens to inject as factory arguments.\n * `null` for class and value providers.\n */\n public inject: InjectionToken[] | null = null;\n\n /**\n * Whether this is an alias (useExisting) provider.\n * Alias providers delegate resolution to another token.\n */\n public isAlias: boolean = false;\n\n /** \n * Whether the instance is a Promise (async factory). \n */\n public async: boolean = false;\n\n /** \n * The module this provider belongs to. \n */\n public host: Module | null = null;\n\n /**\n * Create a new InstanceWrapper.\n *\n * @param metadata - Initial values for the wrapper properties\n */\n constructor(metadata: Partial<InstanceWrapper<T>> = {}) {\n this.token = metadata.token!;\n this.name = metadata.name ?? this.getTokenName(metadata.token!);\n this.metatype = metadata.metatype ?? null;\n this.instance = metadata.instance ?? null;\n this.isResolved = metadata.isResolved ?? false;\n this.scope = metadata.scope ?? Scope.DEFAULT;\n this.inject = metadata.inject ?? null;\n this.isAlias = metadata.isAlias ?? false;\n this.async = metadata.async ?? false;\n this.host = metadata.host ?? null;\n }\n\n /**\n * Whether this provider is a factory (has an `inject` array).\n * Factory providers are invoked as functions, not constructed with `new`.\n */\n get isFactory(): boolean {\n return this.inject !== null;\n }\n\n /**\n * Whether this provider is transient (new instance per injection).\n */\n get isTransient(): boolean {\n return this.scope === Scope.TRANSIENT;\n }\n\n /**\n * Extract a human-readable name from a token.\n */\n private getTokenName(token: InjectionToken): string {\n if (typeof token === 'function') return token.name;\n if (typeof token === 'symbol') return token.toString();\n return String(token);\n }\n}\n","/**\n * @fileoverview Module — the runtime representation of a @Module() class.\n *\n * Each `@Module()` decorated class gets a corresponding `Module` instance\n * at runtime. The Module holds:\n * - All provider bindings (as InstanceWrappers)\n * - References to imported modules\n * - The set of exported tokens\n *\n * ## Module lifecycle:\n *\n * 1. **Registration** — The scanner creates a Module instance and registers\n * providers, imports, and exports based on the @Module() metadata.\n *\n * 2. **Resolution** — The injector resolves all providers in the module,\n * creating instances and injecting dependencies.\n *\n * 3. **Lifecycle hooks** — After all providers are resolved, onModuleInit()\n * is called on providers that implement it.\n *\n * @module injector/module\n */\n\nimport type {\n InjectionToken,\n Type,\n Provider,\n ClassProvider,\n ValueProvider,\n FactoryProvider,\n ExistingProvider,\n} from '@/interfaces';\nimport { Scope } from '@/interfaces';\nimport {\n isCustomProvider,\n isClassProvider,\n isValueProvider,\n isFactoryProvider,\n isExistingProvider,\n} from '@/interfaces/provider.interface';\nimport { SCOPE_OPTIONS_METADATA } from '@/constants';\nimport { InstanceWrapper } from './instance-wrapper';\n\n/**\n * Runtime representation of a module.\n *\n * Created by the scanner for each `@Module()` class encountered during\n * the module graph traversal.\n */\nexport class Module {\n /** \n * Unique identifier for this module instance. \n */\n public readonly id: string;\n\n /** \n * The original class decorated with @Module(). \n */\n public readonly metatype: Type<any>;\n\n /** \n * Whether this module is global (its exports are available everywhere). \n */\n public isGlobal: boolean = false;\n\n /** \n * The opaque token used to identify this module in the container. \n */\n public token: string = '';\n\n /**\n * All providers registered in this module.\n * Key: injection token, Value: InstanceWrapper\n */\n private readonly _providers = new Map<InjectionToken, InstanceWrapper>();\n\n /** \n * Imported modules (their exports are available to this module). \n */\n private readonly _imports = new Set<Module>();\n\n /** \n * Tokens that this module exports (available to modules that import this one). \n */\n private readonly _exports = new Set<InjectionToken>();\n\n constructor(metatype: Type<any>) {\n this.metatype = metatype;\n this.id = `${metatype.name}_${Math.random().toString(36).slice(2, 8)}`;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Accessors\n // ─────────────────────────────────────────────────────────────────────────\n\n get name(): string {\n return this.metatype.name;\n }\n\n get providers(): Map<InjectionToken, InstanceWrapper> {\n return this._providers;\n }\n\n get imports(): Set<Module> {\n return this._imports;\n }\n\n get exports(): Set<InjectionToken> {\n return this._exports;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Provider registration\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Register a provider in this module.\n *\n * Handles all provider forms:\n * - Class shorthand: `UserService`\n * - Class provider: `{ provide: Token, useClass: UserService }`\n * - Value provider: `{ provide: Token, useValue: someValue }`\n * - Factory provider: `{ provide: Token, useFactory: fn, inject: [...] }`\n * - Existing provider: `{ provide: Token, useExisting: OtherToken }`\n *\n * @param provider - The provider to register\n * @returns The injection token for this provider\n */\n public addProvider(provider: Provider): InjectionToken {\n if (isCustomProvider(provider)) {\n return this.addCustomProvider(provider);\n }\n\n // Class shorthand — the class itself is both the token and the implementation\n const classRef = provider as Type<any>;\n const scope = this.getClassScope(classRef);\n\n this._providers.set(\n classRef,\n new InstanceWrapper({\n token: classRef,\n name: classRef.name,\n metatype: classRef,\n instance: null,\n isResolved: false,\n scope,\n host: this,\n }),\n );\n\n return classRef;\n }\n\n /**\n * Register a custom provider (one with a `provide` property).\n */\n private addCustomProvider(\n provider: ClassProvider | ValueProvider | FactoryProvider | ExistingProvider,\n ): InjectionToken {\n if (isClassProvider(provider)) {\n this.addClassProvider(provider);\n } else if (isValueProvider(provider)) {\n this.addValueProvider(provider);\n } else if (isFactoryProvider(provider)) {\n this.addFactoryProvider(provider);\n } else if (isExistingProvider(provider)) {\n this.addExistingProvider(provider);\n }\n return provider.provide;\n }\n\n /**\n * Register a class provider: `{ provide: Token, useClass: SomeClass }`\n */\n private addClassProvider(provider: ClassProvider): void {\n const scope = provider.scope ?? this.getClassScope(provider.useClass);\n\n this._providers.set(\n provider.provide,\n new InstanceWrapper({\n token: provider.provide,\n name: provider.useClass?.name ?? String(provider.provide),\n metatype: provider.useClass,\n instance: null,\n isResolved: false,\n scope,\n host: this,\n }),\n );\n }\n\n /**\n * Register a value provider: `{ provide: Token, useValue: value }`\n *\n * Value providers are immediately resolved — the value is stored as-is.\n */\n private addValueProvider(provider: ValueProvider): void {\n this._providers.set(\n provider.provide,\n new InstanceWrapper({\n token: provider.provide,\n name: this.getTokenName(provider.provide),\n metatype: null,\n instance: provider.useValue,\n isResolved: true,\n async: provider.useValue instanceof Promise,\n host: this,\n }),\n );\n }\n\n /**\n * Register a factory provider: `{ provide: Token, useFactory: fn, inject: [...] }`\n *\n * The factory function is stored as the metatype and will be called\n * (not constructed with `new`) during resolution.\n */\n private addFactoryProvider(provider: FactoryProvider): void {\n this._providers.set(\n provider.provide,\n new InstanceWrapper({\n token: provider.provide,\n name: this.getTokenName(provider.provide),\n metatype: provider.useFactory as any,\n instance: null,\n isResolved: false,\n inject: provider.inject ?? [],\n scope: provider.scope ?? Scope.DEFAULT,\n host: this,\n }),\n );\n }\n\n /**\n * Register an existing (alias) provider: `{ provide: Token, useExisting: OtherToken }`\n *\n * Implemented as a factory that resolves the target token.\n */\n private addExistingProvider(provider: ExistingProvider): void {\n this._providers.set(\n provider.provide,\n new InstanceWrapper({\n token: provider.provide,\n name: this.getTokenName(provider.provide),\n metatype: ((instance: any) => instance) as any,\n instance: null,\n isResolved: false,\n inject: [provider.useExisting],\n isAlias: true,\n host: this,\n }),\n );\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Imports & Exports\n // ─────────────────────────────────────────────────────────────────────────\n\n /** \n * Add an imported module. \n */\n public addImport(moduleRef: Module): void {\n this._imports.add(moduleRef);\n }\n\n /**\n * Add an exported token.\n *\n * @param token - The token to export (class, string, symbol, or module class)\n */\n public addExport(token: InjectionToken): void {\n this._exports.add(token);\n }\n\n /**\n * Check if this module has a provider for the given token.\n */\n public hasProvider(token: InjectionToken): boolean {\n return this._providers.has(token);\n }\n\n /**\n * Get a provider wrapper by token.\n */\n public getProviderByToken<T = any>(token: InjectionToken): InstanceWrapper<T> | undefined {\n return this._providers.get(token) as InstanceWrapper<T> | undefined;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Helpers\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Read the scope from a class's @Injectable() metadata.\n */\n private getClassScope(type: Type<any>): Scope {\n const options = Reflect.getMetadata(SCOPE_OPTIONS_METADATA, type);\n return options?.scope ?? Scope.DEFAULT;\n }\n\n /**\n * Get a human-readable name from a token.\n */\n private getTokenName(token: InjectionToken): string {\n if (typeof token === 'function') return token.name;\n if (typeof token === 'symbol') return token.toString();\n return String(token);\n }\n}\n","/**\n * @fileoverview NestContainer — the top-level container that holds all modules.\n *\n * This is the central registry of the DI system. It holds:\n * - All registered modules (keyed by opaque token)\n * - The set of global modules\n * - Dynamic module metadata\n *\n * ## How the container is used:\n *\n * 1. The **scanner** calls `addModule()` for each module in the graph\n * 2. The **scanner** calls `addProvider()`, `addImport()`, `addExport()` to populate modules\n * 3. The **scanner** calls `bindGlobalScope()` to link global modules to all other modules\n * 4. The **injector** reads from modules to resolve dependencies\n *\n * The container itself does NOT resolve dependencies — that's the injector's job.\n * The container is purely a data structure that holds the module graph.\n *\n * @module injector/container\n */\n\nimport 'reflect-metadata';\nimport type { Type, Provider, DynamicModule, InjectionToken } from '@/interfaces';\nimport { GLOBAL_MODULE_METADATA } from '@/constants';\nimport { Module } from './module';\n\n/**\n * The type of a module definition — can be a class, dynamic module, or promise.\n */\nexport type ModuleMetatype = Type<any> | DynamicModule | Promise<DynamicModule>;\n\n/**\n * The top-level DI container.\n *\n * Holds all modules and their provider bindings. Created once during\n * application bootstrap and shared throughout the application lifetime.\n */\nexport class NestContainer {\n /**\n * All registered modules, keyed by their opaque token.\n * The token is derived from the module class name (or a hash for dynamic modules).\n */\n private readonly modules = new Map<string, Module>();\n\n /**\n * Global modules whose exports are available to all other modules.\n */\n private readonly globalModules = new Set<Module>();\n\n /**\n * Dynamic module metadata, keyed by module token.\n * Stored separately because dynamic metadata is merged with static @Module() metadata.\n */\n private readonly dynamicModulesMetadata = new Map<string, Partial<DynamicModule>>();\n\n // ─────────────────────────────────────────────────────────────────────────\n // Module registration\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Add a module to the container.\n *\n * If the module is already registered (by token), returns the existing one.\n * Otherwise, creates a new Module instance and registers it.\n *\n * @param metatype - The module class or dynamic module\n * @returns The Module instance and whether it was newly inserted\n */\n public async addModule(\n metatype: ModuleMetatype,\n ): Promise<{ moduleRef: Module; inserted: boolean }> {\n // Resolve promises (for async dynamic modules)\n const resolved = metatype instanceof Promise ? await metatype : metatype;\n\n // Extract the class and dynamic metadata\n const { type, dynamicMetadata, token } = this.extractModuleMetadata(resolved);\n\n // Check if already registered\n if (this.modules.has(token)) {\n return { moduleRef: this.modules.get(token)!, inserted: false };\n }\n\n // Create and register the module\n const moduleRef = new Module(type);\n moduleRef.token = token;\n this.modules.set(token, moduleRef);\n\n // Store dynamic metadata for later merging\n if (dynamicMetadata) {\n this.dynamicModulesMetadata.set(token, dynamicMetadata);\n }\n\n // Check if this is a global module\n if (this.isGlobalModule(type, dynamicMetadata)) {\n moduleRef.isGlobal = true;\n this.globalModules.add(moduleRef);\n }\n\n return { moduleRef, inserted: true };\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Provider, Import, Export registration\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Add a provider to a module.\n *\n * @param provider - The provider to add\n * @param token - The module token to add the provider to\n */\n public addProvider(provider: Provider, token: string): void {\n const moduleRef = this.modules.get(token);\n if (!moduleRef) {\n throw new Error(`Module [${token}] not found in container.`);\n }\n moduleRef.addProvider(provider);\n }\n\n /**\n * Add an import relationship between modules.\n *\n * @param relatedModule - The module being imported\n * @param token - The token of the module doing the importing\n */\n public addImport(relatedModule: Type<any> | DynamicModule, token: string): void {\n const moduleRef = this.modules.get(token);\n if (!moduleRef) return;\n\n const { token: relatedToken } = this.extractModuleMetadata(relatedModule);\n const related = this.modules.get(relatedToken);\n if (related) {\n moduleRef.addImport(related);\n }\n }\n\n /**\n * Add an export to a module.\n *\n * @param toExport - The token or provider to export\n * @param token - The module token\n */\n public addExport(toExport: InjectionToken | Provider | DynamicModule, token: string): void {\n const moduleRef = this.modules.get(token);\n if (!moduleRef) return;\n\n if (typeof toExport === 'object' && toExport !== null && 'module' in toExport) {\n // Exporting a dynamic module — export the module class\n moduleRef.addExport((toExport as DynamicModule).module);\n } else if (typeof toExport === 'object' && toExport !== null && 'provide' in toExport) {\n // Exporting a custom provider — export its token\n moduleRef.addExport((toExport as any).provide);\n } else {\n // Exporting a token directly (class, string, symbol)\n moduleRef.addExport(toExport as InjectionToken);\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Global scope binding\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Link all global modules to all non-global modules as imports.\n *\n * Called after all modules have been scanned. This makes global modules'\n * exports available everywhere without explicit imports.\n */\n public bindGlobalScope(): void {\n for (const moduleRef of this.modules.values()) {\n for (const globalModule of this.globalModules) {\n if (moduleRef !== globalModule) {\n moduleRef.addImport(globalModule);\n }\n }\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Accessors\n // ─────────────────────────────────────────────────────────────────────────\n\n /** \n * Get all registered modules. \n */\n public getModules(): Map<string, Module> {\n return this.modules;\n }\n\n /** \n * Get a module by its token. \n */\n public getModuleByToken(token: string): Module | undefined {\n return this.modules.get(token);\n }\n\n /**\n * Get dynamic metadata for a module.\n *\n * @param token - The module token\n * @param key - Optional specific key to retrieve (e.g., 'imports', 'providers')\n */\n public getDynamicMetadata(token: string): Partial<DynamicModule> | undefined;\n public getDynamicMetadata<K extends keyof DynamicModule>(token: string, key: K): DynamicModule[K] | undefined;\n public getDynamicMetadata(token: string, key?: string): any {\n const metadata = this.dynamicModulesMetadata.get(token);\n if (!metadata) return key ? [] : undefined;\n return key ? (metadata as any)[key] ?? [] : metadata;\n }\n\n /** \n * Clear all modules (for testing). \n */\n public clear(): void {\n this.modules.clear();\n this.globalModules.clear();\n this.dynamicModulesMetadata.clear();\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Private helpers\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Extract the module class, dynamic metadata, and token from a module definition.\n *\n * Handles both static modules (just a class) and dynamic modules\n * (objects with a `module` property).\n */\n private extractModuleMetadata(metatype: Type<any> | DynamicModule): {\n type: Type<any>;\n dynamicMetadata: Partial<DynamicModule> | undefined;\n token: string;\n } {\n if (this.isDynamicModule(metatype)) {\n const { module: type, ...dynamicMetadata } = metatype as DynamicModule;\n return {\n type,\n dynamicMetadata,\n token: type.name,\n };\n }\n\n return {\n type: metatype as Type<any>,\n dynamicMetadata: undefined,\n token: (metatype as Type<any>).name,\n };\n }\n\n /**\n * Check if a module definition is a dynamic module (has a `module` property).\n */\n private isDynamicModule(metatype: any): metatype is DynamicModule {\n return metatype && !!(metatype as DynamicModule).module;\n }\n\n /**\n * Check if a module should be global.\n * A module is global if:\n * - It has the @Global() decorator, OR\n * - Its dynamic metadata has `global: true`\n */\n private isGlobalModule(type: Type<any>, dynamicMetadata?: Partial<DynamicModule>): boolean {\n if (dynamicMetadata?.global) return true;\n return !!Reflect.getMetadata(GLOBAL_MODULE_METADATA, type);\n }\n}\n","/**\n * @fileoverview Injector — resolves dependencies and creates provider instances.\n *\n * The injector is the engine that turns the module graph (built by the scanner)\n * into actual, live instances. For each provider, it:\n *\n * 1. Reads constructor parameter types from metadata\n * 2. Resolves each dependency (recursively)\n * 3. Creates the instance (via `new` for classes, or by calling the factory)\n * 4. Applies property injection\n * 5. Marks the provider as resolved\n *\n * ## Resolution algorithm:\n *\n * For a given token in a given module:\n * 1. Look in the module's own providers\n * 2. If not found, look in imported modules' exports (recursively)\n * 3. If still not found, throw UnknownDependencyError\n *\n * ## Singleton vs Transient:\n *\n * - Singleton (DEFAULT): resolved once, cached in the InstanceWrapper\n * - Transient: a new instance is created every time it's injected\n *\n * @module injector/injector\n */\n\nimport 'reflect-metadata';\nimport type { InjectionToken, Type } from '@/interfaces';\nimport {\n PARAMTYPES_METADATA,\n SELF_DECLARED_DEPS_METADATA,\n OPTIONAL_DEPS_METADATA,\n PROPERTY_DEPS_METADATA,\n OPTIONAL_PROPERTY_DEPS_METADATA,\n} from '@/constants';\nimport { InstanceWrapper } from './instance-wrapper';\nimport { Module } from './module';\n\n/**\n * The Injector resolves and instantiates providers.\n *\n * It's stateless — all state lives in the InstanceWrappers within modules.\n * The injector just reads metadata and creates instances.\n */\nexport class Injector {\n /**\n * Tracks which wrappers are currently being resolved, to detect circular dependencies.\n * Uses a Set of tokens being resolved in the current chain.\n */\n private readonly resolutionStack = new Set<InjectionToken>();\n\n // ─────────────────────────────────────────────────────────────────────────\n // Public API\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Resolve all providers in a module.\n *\n * Iterates over all providers and resolves each one.\n * Value providers are already resolved at registration time.\n *\n * @param moduleRef - The module whose providers to resolve\n */\n public async resolveProviders(moduleRef: Module): Promise<void> {\n const providers = moduleRef.providers;\n\n for (const [_token, wrapper] of providers) {\n if (!wrapper.isResolved) {\n await this.resolveInstance(wrapper, moduleRef);\n }\n }\n }\n\n /**\n * Resolve a single provider instance.\n *\n * This is the core resolution method. It handles:\n * - Already-resolved singletons (returns cached instance)\n * - Circular dependency detection\n * - Factory providers (calls the factory function)\n * - Class providers (resolves constructor deps, then `new`)\n * - Property injection (after construction)\n * - Async factories (awaits the result)\n *\n * @param wrapper - The InstanceWrapper to resolve\n * @param moduleRef - The module context for dependency lookup\n */\n public async resolveInstance<T>(\n wrapper: InstanceWrapper<T>,\n moduleRef: Module,\n ): Promise<T> {\n // Already resolved singleton — return cached instance\n if (wrapper.isResolved && !wrapper.isTransient) {\n return wrapper.instance!;\n }\n\n // Circular dependency detection\n if (this.resolutionStack.has(wrapper.token)) {\n throw new Error(\n `Circular dependency detected: ${this.formatResolutionStack(wrapper.token)}`,\n );\n }\n\n this.resolutionStack.add(wrapper.token);\n\n try {\n let instance: T;\n\n if (wrapper.isFactory) {\n // ── Factory provider ─────────────────────────────────────────\n instance = await this.resolveFactory(wrapper, moduleRef);\n } else if (wrapper.metatype) {\n // ── Class provider ───────────────────────────────────────────\n instance = await this.resolveClass(wrapper, moduleRef);\n } else {\n // ── Value provider (should already be resolved) ──────────────\n instance = wrapper.instance!;\n }\n\n // Cache the instance\n // For singletons: cached permanently\n // For transients: cached as the \"last created\" instance,\n // but get() will create fresh instances on each call\n wrapper.instance = instance;\n wrapper.isResolved = true;\n\n return instance;\n } finally {\n this.resolutionStack.delete(wrapper.token);\n }\n }\n\n /**\n * Look up a provider by token, searching the module and its imports.\n *\n * Resolution order:\n * 1. The module's own providers\n * 2. Imported modules' exported providers (breadth-first)\n *\n * @param token - The injection token to look up\n * @param moduleRef - The module context\n * @returns The InstanceWrapper and the module it was found in\n */\n public lookupProvider(\n token: InjectionToken,\n moduleRef: Module,\n ): { wrapper: InstanceWrapper; host: Module } | undefined {\n // 1. Check own providers\n if (moduleRef.providers.has(token)) {\n return { wrapper: moduleRef.providers.get(token)!, host: moduleRef };\n }\n\n // 2. Check imported modules' exports\n return this.lookupInImports(token, moduleRef, new Set());\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Private: Class resolution\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Resolve a class provider by:\n * 1. Reading constructor parameter types from metadata\n * 2. Resolving each dependency\n * 3. Calling `new Class(...deps)`\n * 4. Applying property injection\n */\n private async resolveClass<T>(\n wrapper: InstanceWrapper<T>,\n moduleRef: Module,\n ): Promise<T> {\n const metatype = wrapper.metatype as Type<T>;\n\n // Get constructor dependencies\n const deps = this.getConstructorDependencies(metatype);\n const optionalIndices = this.getOptionalDependencies(metatype);\n\n // Resolve each dependency\n const resolvedDeps = await Promise.all(\n deps.map(async (dep, index) => {\n if (dep === undefined || dep === null || dep === Object) {\n if (optionalIndices.includes(index)) return undefined;\n throw new Error(\n `Cannot resolve dependency at index [${index}] of ${metatype.name}. ` +\n `The dependency is undefined — this usually means a circular import or missing @Inject() decorator.`,\n );\n }\n\n try {\n return await this.resolveDependency(dep, moduleRef);\n } catch (err) {\n if (optionalIndices.includes(index)) return undefined;\n throw new Error(\n `Cannot resolve dependency '${this.getTokenName(dep)}' at index [${index}] of ${metatype.name}. ` +\n `Make sure it is provided in the module or imported. Original: ${(err as Error).message}`,\n );\n }\n }),\n );\n\n // Instantiate\n const instance = new metatype(...resolvedDeps);\n\n // Property injection\n await this.resolveProperties(instance, metatype, moduleRef);\n\n return instance;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Private: Factory resolution\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Resolve a factory provider by:\n * 1. Resolving the factory's `inject` dependencies\n * 2. Calling the factory function with the resolved deps\n * 3. Awaiting the result if it's a Promise\n */\n private async resolveFactory<T>(\n wrapper: InstanceWrapper<T>,\n moduleRef: Module,\n ): Promise<T> {\n const factory = wrapper.metatype as Function;\n const injectTokens = wrapper.inject ?? [];\n\n // Resolve factory dependencies\n const resolvedDeps = await Promise.all(\n injectTokens.map(async (token) => {\n try {\n return await this.resolveDependency(token, moduleRef);\n } catch (err) {\n throw new Error(\n `Cannot resolve factory dependency '${this.getTokenName(token)}' ` +\n `for provider '${wrapper.name}'. ${(err as Error).message}`,\n );\n }\n }),\n );\n\n // Call the factory\n const result = factory(...resolvedDeps);\n\n // Handle async factories\n return result instanceof Promise ? await result : result;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Private: Dependency resolution\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Resolve a single dependency token to its instance.\n *\n * Looks up the provider, resolves it if needed, and returns the instance.\n */\n private async resolveDependency(\n token: InjectionToken,\n moduleRef: Module,\n ): Promise<any> {\n const result = this.lookupProvider(token, moduleRef);\n\n if (!result) {\n throw new Error(\n `Provider '${this.getTokenName(token)}' not found. ` +\n `Is it provided in the current module or an imported module?`,\n );\n }\n\n const { wrapper, host } = result;\n\n // Resolve if not yet resolved, or if transient (always create new)\n if (!wrapper.isResolved || wrapper.isTransient) {\n return this.resolveInstance(wrapper, host);\n }\n\n // Handle async values (Promise instances stored as values)\n if (wrapper.async && wrapper.instance instanceof Promise) {\n wrapper.instance = await wrapper.instance;\n }\n\n return wrapper.instance;\n }\n\n /**\n * Look up a provider in imported modules' exports.\n *\n * Searches breadth-first through the import tree, only considering\n * providers that are in the imported module's exports set.\n */\n private lookupInImports(\n token: InjectionToken,\n moduleRef: Module,\n visited: Set<string>,\n ): { wrapper: InstanceWrapper; host: Module } | undefined {\n for (const importedModule of moduleRef.imports) {\n if (visited.has(importedModule.id)) continue;\n visited.add(importedModule.id);\n\n // Check if the imported module exports this token AND has a provider for it\n if (importedModule.exports.has(token) && importedModule.providers.has(token)) {\n return {\n wrapper: importedModule.providers.get(token)!,\n host: importedModule,\n };\n }\n\n // Recurse into the imported module's imports (for re-exported modules)\n const result = this.lookupInImports(token, importedModule, visited);\n if (result) return result;\n }\n\n return undefined;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Private: Metadata reading\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Get the constructor dependencies for a class.\n *\n * Merges TypeScript's auto-emitted `design:paramtypes` with\n * explicitly declared `self:paramtypes` (from @Inject decorators).\n * Explicit declarations override auto-detected types.\n *\n * @param type - The class to read metadata from\n * @returns Array of injection tokens, one per constructor parameter\n */\n private getConstructorDependencies(type: Type<any>): InjectionToken[] {\n // Auto-detected types from TypeScript's emitDecoratorMetadata\n const paramTypes: any[] = [\n ...(Reflect.getMetadata(PARAMTYPES_METADATA, type) || []),\n ];\n\n // Explicit overrides from @Inject() decorators\n const selfDeclared: Array<{ index: number; param: InjectionToken }> =\n Reflect.getMetadata(SELF_DECLARED_DEPS_METADATA, type) || [];\n\n // Merge: explicit @Inject() overrides auto-detected types\n for (const { index, param } of selfDeclared) {\n paramTypes[index] = param;\n }\n\n return paramTypes;\n }\n\n /**\n * Get the indices of optional constructor parameters.\n */\n private getOptionalDependencies(type: Type<any>): number[] {\n return Reflect.getMetadata(OPTIONAL_DEPS_METADATA, type) || [];\n }\n\n /**\n * Resolve property-injected dependencies and assign them to the instance.\n */\n private async resolveProperties<T>(\n instance: T,\n type: Type<T>,\n moduleRef: Module,\n ): Promise<void> {\n const properties: Array<{ key: string | symbol; type: InjectionToken }> =\n Reflect.getMetadata(PROPERTY_DEPS_METADATA, type) || [];\n\n const optionalKeys: Array<string | symbol> =\n Reflect.getMetadata(OPTIONAL_PROPERTY_DEPS_METADATA, type) || [];\n\n for (const prop of properties) {\n const isOptional = optionalKeys.includes(prop.key);\n\n try {\n const resolved = await this.resolveDependency(prop.type, moduleRef);\n (instance as any)[prop.key] = resolved;\n } catch (err) {\n if (!isOptional) throw err;\n // Optional property — leave as undefined\n }\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Private: Helpers\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Format the resolution stack for error messages.\n */\n private formatResolutionStack(token: InjectionToken): string {\n const stack = [...this.resolutionStack, token];\n return stack.map(t => this.getTokenName(t)).join(' → ');\n }\n\n /**\n * Get a human-readable name from a token.\n */\n private getTokenName(token: InjectionToken): string {\n if (typeof token === 'function') return token.name;\n if (typeof token === 'symbol') return token.toString();\n return String(token);\n }\n}\n","/**\n * @fileoverview Lifecycle hook interfaces.\n *\n * Providers can implement these interfaces to hook into the application\n * lifecycle. The container calls these methods at specific points during\n * bootstrap and shutdown.\n *\n * ## Lifecycle order:\n *\n * **Bootstrap:**\n * 1. All providers are instantiated (constructor injection)\n * 2. `onModuleInit()` is called on all providers that implement it\n *\n * **Shutdown:**\n * 1. `onModuleDestroy()` is called on all providers that implement it\n * 2. Provider references are released\n *\n * @module interfaces/lifecycle\n */\n\n/**\n * Interface for providers that need initialization after construction.\n *\n * `onModuleInit()` is called after all providers in the module have been\n * instantiated and their dependencies injected. This is the right place\n * for async initialization like connecting to databases or warming caches.\n *\n * @example\n * ```typescript\n * @Injectable()\n * class DatabaseService implements OnModuleInit {\n * private connection: Connection;\n *\n * constructor(@Inject(DB_CONFIG) private config: DbConfig) {}\n *\n * async onModuleInit() {\n * // All dependencies are available here\n * this.connection = await createConnection(this.config);\n * }\n * }\n * ```\n */\nexport interface OnModuleInit {\n onModuleInit(): any | Promise<any>;\n}\n\n/**\n * Interface for providers that need cleanup before shutdown.\n *\n * `onModuleDestroy()` is called when the application is shutting down.\n * Use this to close connections, flush buffers, and release resources.\n *\n * @example\n * ```typescript\n * @Injectable()\n * class RedisManager implements OnModuleDestroy {\n * async onModuleDestroy() {\n * await this.disconnectAll();\n * }\n * }\n * ```\n */\nexport interface OnModuleDestroy {\n onModuleDestroy(): any | Promise<any>;\n}\n\n/**\n * Type guard: check if an object implements OnModuleInit.\n */\nexport function hasOnModuleInit(instance: any): instance is OnModuleInit {\n return instance && typeof instance.onModuleInit === 'function';\n}\n\n/**\n * Type guard: check if an object implements OnModuleDestroy.\n */\nexport function hasOnModuleDestroy(instance: any): instance is OnModuleDestroy {\n return instance && typeof instance.onModuleDestroy === 'function';\n}\n","/**\n * @fileoverview InstanceLoader — orchestrates provider instantiation and lifecycle hooks.\n *\n * After the scanner has built the module graph, the InstanceLoader:\n * 1. Resolves all providers in all modules (via the Injector)\n * 2. Calls `onModuleInit()` on providers that implement it\n *\n * It also provides `destroy()` for calling `onModuleDestroy()` during shutdown.\n *\n * @module injector/instance-loader\n */\n\nimport { hasOnModuleInit, hasOnModuleDestroy } from '@/interfaces/lifecycle.interface';\nimport { NestContainer } from './container';\nimport { Injector } from './injector';\nimport { Module } from './module';\n\n/**\n * Loads (instantiates) all providers and runs lifecycle hooks.\n */\nexport class InstanceLoader {\n private readonly injector: Injector;\n\n constructor(private readonly container: NestContainer) {\n this.injector = new Injector();\n }\n\n /**\n * Instantiate all providers in all modules.\n *\n * Iterates modules and resolves each module's providers.\n * After all providers are resolved, calls `onModuleInit()` lifecycle hooks.\n */\n public async createInstances(): Promise<void> {\n const modules = this.container.getModules();\n\n // Phase 1: Resolve all providers\n for (const [, moduleRef] of modules) {\n await this.injector.resolveProviders(moduleRef);\n }\n\n // Phase 2: Call onModuleInit() lifecycle hooks\n for (const [, moduleRef] of modules) {\n await this.callModuleInitHooks(moduleRef);\n }\n }\n\n /**\n * Call `onModuleDestroy()` on all providers that implement it.\n *\n * Called during application shutdown. Iterates modules in reverse\n * order (leaf modules first, root module last).\n */\n public async destroy(): Promise<void> {\n const modules = [...this.container.getModules().values()].reverse();\n\n for (const moduleRef of modules) {\n await this.callModuleDestroyHooks(moduleRef);\n }\n }\n\n /**\n * Get the injector instance (for direct resolution outside the module system).\n */\n public getInjector(): Injector {\n return this.injector;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Private: Lifecycle hooks\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Call `onModuleInit()` on all resolved providers in a module.\n */\n private async callModuleInitHooks(moduleRef: Module): Promise<void> {\n for (const [, wrapper] of moduleRef.providers) {\n if (wrapper.isResolved && wrapper.instance && hasOnModuleInit(wrapper.instance)) {\n await wrapper.instance.onModuleInit();\n }\n }\n }\n\n /**\n * Call `onModuleDestroy()` on all resolved providers in a module.\n */\n private async callModuleDestroyHooks(moduleRef: Module): Promise<void> {\n for (const [, wrapper] of moduleRef.providers) {\n if (wrapper.isResolved && wrapper.instance && hasOnModuleDestroy(wrapper.instance)) {\n await wrapper.instance.onModuleDestroy();\n }\n }\n }\n}\n","/**\n * @fileoverview DependenciesScanner — recursively scans the module tree.\n *\n * The scanner is the first phase of the DI bootstrap. It walks the module\n * graph starting from the root module and:\n *\n * 1. Registers each module in the container\n * 2. Registers each module's providers\n * 3. Sets up import relationships between modules\n * 4. Sets up export declarations\n * 5. Links global modules to all other modules\n *\n * After scanning, the container has a complete picture of the module graph\n * but NO instances have been created yet. That's the injector's job.\n *\n * ## Scan algorithm:\n *\n * ```\n * scan(RootModule)\n * → scanForModules(RootModule) // recursive DFS\n * → addModule(RootModule)\n * → scanForModules(ImportedModule1) // recurse into imports\n * → scanForModules(ImportedModule2)\n * → scanModulesForDependencies() // second pass\n * → for each module:\n * → reflectImports()\n * → reflectProviders()\n * → reflectExports()\n * → bindGlobalScope() // link globals\n * ```\n *\n * @module injector/scanner\n */\n\nimport 'reflect-metadata';\nimport type { Type, DynamicModule, Provider, ForwardReference } from '@/interfaces';\nimport { MODULE_METADATA } from '@/constants';\nimport { NestContainer, type ModuleMetatype } from './container';\n\n/**\n * Scans the module tree and populates the container.\n */\nexport class DependenciesScanner {\n constructor(private readonly container: NestContainer) {}\n\n /**\n * Scan the entire module tree starting from the root module.\n *\n * This is the main entry point. After this method completes,\n * the container has all modules, providers, imports, and exports\n * registered — but no instances created.\n *\n * @param rootModule - The root module class (your AppModule)\n */\n public async scan(rootModule: Type<any>): Promise<void> {\n // Phase 1: Discover all modules (recursive DFS)\n await this.scanForModules(rootModule, []);\n\n // Phase 2: Register providers, imports, exports for each module\n await this.scanModulesForDependencies();\n\n // Phase 3: Link global modules to all other modules\n this.container.bindGlobalScope();\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Phase 1: Module discovery\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Recursively discover and register all modules in the graph.\n *\n * Uses DFS traversal. Tracks visited modules to avoid infinite loops\n * from circular imports.\n *\n * @param moduleDefinition - The module to scan (class or dynamic module)\n * @param ctxRegistry - Already-visited modules (for cycle detection)\n */\n private async scanForModules(\n moduleDefinition: ModuleMetatype,\n ctxRegistry: any[],\n ): Promise<void> {\n // Resolve forward references\n const resolved = this.resolveForwardRef(moduleDefinition);\n if (!resolved) return;\n\n // Skip if already visited (circular import protection)\n if (ctxRegistry.includes(resolved)) return;\n ctxRegistry.push(resolved);\n\n // Register this module in the container\n await this.container.addModule(resolved);\n\n // Get this module's imports (from both static @Module() and dynamic metadata)\n const imports = this.getModuleImports(resolved);\n\n // Recurse into each import\n for (const importedModule of imports) {\n if (importedModule === undefined || importedModule === null) {\n const moduleName = this.getModuleName(resolved);\n throw new Error(\n `An undefined module was imported by ${moduleName}. ` +\n `This is usually caused by a circular dependency. Use forwardRef() to resolve it.`,\n );\n }\n await this.scanForModules(importedModule, ctxRegistry);\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Phase 2: Dependency registration\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * For each registered module, read its metadata and register\n * providers, imports, and exports.\n */\n private async scanModulesForDependencies(): Promise<void> {\n const modules = this.container.getModules();\n\n for (const [token, moduleRef] of modules) {\n // Register imports (module relationships)\n await this.reflectImports(moduleRef.metatype, token);\n\n // Register providers\n this.reflectProviders(moduleRef.metatype, token);\n\n // Register exports\n this.reflectExports(moduleRef.metatype, token);\n }\n }\n\n /**\n * Read and register a module's imports.\n *\n * Merges static @Module({ imports }) with dynamic module imports.\n */\n private async reflectImports(metatype: Type<any>, token: string): Promise<void> {\n const staticImports: any[] =\n Reflect.getMetadata(MODULE_METADATA.IMPORTS, metatype) || [];\n const dynamicImports: any[] =\n this.container.getDynamicMetadata(token, 'imports' as any) || [];\n\n const allImports = [...staticImports, ...dynamicImports];\n\n for (const related of allImports) {\n const resolved = this.resolveForwardRef(related);\n if (resolved) {\n this.container.addImport(resolved, token);\n }\n }\n }\n\n /**\n * Read and register a module's providers.\n *\n * Merges static @Module({ providers }) with dynamic module providers.\n */\n private reflectProviders(metatype: Type<any>, token: string): void {\n const staticProviders: Provider[] =\n Reflect.getMetadata(MODULE_METADATA.PROVIDERS, metatype) || [];\n const dynamicProviders: Provider[] =\n this.container.getDynamicMetadata(token, 'providers' as any) || [];\n\n const allProviders = [...staticProviders, ...dynamicProviders];\n\n for (const provider of allProviders) {\n this.container.addProvider(provider, token);\n }\n }\n\n /**\n * Read and register a module's exports.\n *\n * Merges static @Module({ exports }) with dynamic module exports.\n */\n private reflectExports(metatype: Type<any>, token: string): void {\n const staticExports: any[] =\n Reflect.getMetadata(MODULE_METADATA.EXPORTS, metatype) || [];\n const dynamicExports: any[] =\n this.container.getDynamicMetadata(token, 'exports' as any) || [];\n\n const allExports = [...staticExports, ...dynamicExports];\n\n for (const exported of allExports) {\n const resolved = this.resolveForwardRef(exported);\n this.container.addExport(resolved ?? exported, token);\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Helpers\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Get a module's imports from both static and dynamic sources.\n */\n private getModuleImports(moduleDefinition: any): any[] {\n if (this.isDynamicModule(moduleDefinition)) {\n const staticImports: any[] =\n Reflect.getMetadata(MODULE_METADATA.IMPORTS, moduleDefinition.module) || [];\n const dynamicImports: any[] = moduleDefinition.imports || [];\n return [...staticImports, ...dynamicImports];\n }\n\n return Reflect.getMetadata(MODULE_METADATA.IMPORTS, moduleDefinition) || [];\n }\n\n /**\n * Resolve a forward reference to its actual value.\n */\n private resolveForwardRef(ref: any): any {\n if (ref && typeof ref === 'object' && 'forwardRef' in ref) {\n return (ref as ForwardReference).forwardRef();\n }\n return ref;\n }\n\n /**\n * Check if a module definition is a dynamic module.\n */\n private isDynamicModule(module: any): module is DynamicModule {\n return module && !!(module as DynamicModule).module;\n }\n\n /**\n * Get a human-readable name for a module.\n */\n private getModuleName(module: any): string {\n if (this.isDynamicModule(module)) return module.module.name;\n if (typeof module === 'function') return module.name;\n return String(module);\n }\n}\n"]}
|