injectkit 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -276,6 +276,15 @@ Resolves an instance of the specified type.
276
276
  const service = container.get(MyService);
277
277
  ```
278
278
 
279
+ #### `hasRegistration<T>(identifier): boolean`
280
+
281
+ Checks if a service has a registration with the container.
282
+
283
+ ```typescript
284
+ container.hasRegistration(MyService); // true
285
+ container.hasRegistration(UnregisteredService); // false
286
+ ```
287
+
279
288
  #### `createScopedContainer(): ScopedContainer`
280
289
 
281
290
  Creates a child container for scoped instance management.
@@ -45,6 +45,13 @@ export declare class InjectKitContainer implements ScopedContainer, Container {
45
45
  * @throws {Error} If no registration is found for the specified identifier.
46
46
  */
47
47
  get<T>(id: Identifier<T>): T;
48
+ /**
49
+ * Checks if a service has a registration with the container.
50
+ * @template T The type of the service to check.
51
+ * @param id The identifier (constructor or abstract class) for the type to check.
52
+ * @returns True if the service has a registration, false otherwise.
53
+ */
54
+ hasRegistration<T>(id: Identifier<T>): boolean;
48
55
  /**
49
56
  * Creates a new scoped container that inherits all registrations from this container.
50
57
  * Scoped containers allow for per-scope instance management, where scoped services
@@ -1 +1 @@
1
- {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,eAAe,EAAE,SAAS;IAUjE,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAV1B,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2C;IAErE;;;;OAIG;gBAEgB,aAAa,EAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,EAC9D,MAAM,CAAC,EAAE,kBAAkB,YAAA;IAG9C;;;;;;;;;;OAUG;IACH,OAAO,CAAC,cAAc;IA8CtB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;;;;;OAQG;IACI,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;IAgBnC;;;;;OAKG;IACI,qBAAqB,IAAI,eAAe;IAI/C;;;;;OAKG;IACI,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI;CAYnE"}
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,eAAe,EAAE,SAAS;IAUjE,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAV1B,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2C;IAErE;;;;OAIG;gBAEgB,aAAa,EAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,EAC9D,MAAM,CAAC,EAAE,kBAAkB,YAAA;IAG9C;;;;;;;;;;OAUG;IACH,OAAO,CAAC,cAAc;IA8CtB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;;;;;OAQG;IACI,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;IAgBnC;;;;;OAKG;IACI,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO;IAIrD;;;;;OAKG;IACI,qBAAqB,IAAI,eAAe;IAI/C;;;;;OAKG;IACI,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI;CAYnE"}
package/dist/index.js CHANGED
@@ -122,6 +122,15 @@ var InjectKitContainer = class _InjectKitContainer {
122
122
  return this.createInstance(id, registration);
123
123
  }
124
124
  /**
125
+ * Checks if a service has a registration with the container.
126
+ * @template T The type of the service to check.
127
+ * @param id The identifier (constructor or abstract class) for the type to check.
128
+ * @returns True if the service has a registration, false otherwise.
129
+ */
130
+ hasRegistration(id) {
131
+ return this.registrations.has(id);
132
+ }
133
+ /**
125
134
  * Creates a new scoped container that inherits all registrations from this container.
126
135
  * Scoped containers allow for per-scope instance management, where scoped services
127
136
  * are shared within a scope but isolated between different scopes.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/injectable.ts","../src/interfaces.ts","../src/registry.ts","../src/container.ts"],"sourcesContent":["/**\n * Decorator for injectable classes. Every registered service must\n * be decorated because without decorators TypeScript won't emit\n * constructor parameter metadata required for dependency injection.\n *\n * @returns A class decorator that marks the class as injectable.\n *\n * @example\n * ```typescript\n * @Injectable()\n * class UserService {\n * constructor(private db: DatabaseService) {}\n * }\n * ```\n *\n * @remarks\n * This decorator is required for classes registered with `useClass()`.\n * Without it, the container cannot determine constructor dependencies.\n */\nexport const Injectable = (): ClassDecorator => {\n return <TFunction extends Function>(target: TFunction): TFunction => {\n return target;\n };\n};\n","/**\n * Represents a constructor function that can be instantiated with the `new` operator.\n * @template T The type of instance that this constructor creates.\n */\nexport interface Constructor<T> extends Function {\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\n new (...args: any[]): T;\n}\n\n/**\n * Represents an abstract class or interface that cannot be directly instantiated.\n * @template T The type of the prototype.\n */\nexport interface Abstract<T> extends Function {\n prototype: T;\n}\n\n/**\n * A type identifier used to resolve dependencies in the container.\n * Can be either a concrete constructor or an abstract class/interface.\n * @template T The type being identified.\n */\nexport type Identifier<T> = Constructor<T> | Abstract<T>;\n\n/**\n * Represents an instance of type T that is also an object.\n * @template T The type of the instance.\n */\nexport type Instance<T> = T & object;\n\n/**\n * Extracts the element type from an array type.\n * @template T The array type to extract the element type from.\n * @example\n * ArrayType<Array<string>> // string\n * ArrayType<string[]> // string\n */\nexport type ArrayType<T> = T extends Array<infer I> ? I : never;\n\n/**\n * Extracts the key and value types from a map type.\n * @template T The map type to extract the key and value types from.\n * @example\n * MapType<Map<string, number>> // [string, number]\n * MapType<Map<symbol, AbstractService>> // [symbol, AbstractService]\n */\nexport type MapType<T> = T extends Map<infer I, infer O> ? [I, O] : never;\n\n/**\n * Dependency injection container that manages the creation and lifetime of registered services.\n */\nexport abstract class Container {\n /**\n * Retrieves an instance of the specified type from the container.\n * For singleton and scoped lifetimes, returns cached instances when available.\n * For transient lifetimes, creates a new instance each time.\n * @template T The type of instance to retrieve.\n * @param id The identifier (constructor or abstract class) for the type to resolve.\n * @returns An instance of type T.\n */\n abstract get<T>(id: Identifier<T>): T;\n\n /**\n * Creates a new scoped container that inherits all registrations from this container.\n * Scoped containers allow for per-scope instance management, where scoped services\n * are shared within a scope but isolated between different scopes.\n * @returns A new scoped container instance with this container as its parent.\n */\n abstract createScopedContainer(): ScopedContainer;\n}\n\n/**\n * Scoped container that extends the base container with the ability to override registrations.\n */\nexport type ScopedContainer = Container & {\n /**\n * Overrides the registration for the specified identifier with a new instance.\n * @template T The type of the instance to override.\n * @param id The identifier of the registration to override.\n * @param instance The instance to use for the registration.\n */\n override<T>(id: Identifier<T>, instance: Instance<T>): void;\n};\n\n/**\n * Factory function that creates an instance of type T using the provided container.\n * @template T The type of instance the factory creates.\n * @param container The container to use for resolving dependencies.\n * @returns An instance of type T.\n */\nexport type Factory<T> = (container: Container) => T;\n\n/**\n * Defines the lifetime management strategy for a registered service.\n * - 'singleton': One instance shared across the entire container\n * - 'transient': A new instance created every time it's requested\n * - 'scoped': One instance per scoped container\n */\nexport type Lifetime = 'singleton' | 'transient' | 'scoped';\n\n/**\n * Fluent interface for configuring registration lifetime.\n * Allows chaining of configuration methods to set the lifetime of a registration.\n * @template T The type being registered.\n */\nexport interface RegistrationLifeTime {\n /**\n * Sets the lifetime to singleton (one instance shared across the container).\n */\n asSingleton(): void;\n\n /**\n * Sets the lifetime to transient (new instance created each time).\n */\n asTransient(): void;\n\n /**\n * Sets the lifetime to scoped (one instance per scoped container).\n */\n asScoped(): void;\n}\n\n/**\n * Fluent interface for configuring array-based registrations.\n * Allows chaining of push() calls to add multiple implementations to an array.\n * @template T The element type of the array being registered.\n */\nexport interface RegistrationArray<T> {\n /**\n * Adds an implementation identifier to the array collection.\n * The resolved instance will be pushed to the array when the service is created.\n * @param id The identifier of the implementation to add.\n * @returns Registration array options for method chaining.\n */\n push(id: Identifier<T>): RegistrationArray<T>;\n}\n\n/**\n * Fluent interface for configuring map-based registrations.\n * Allows chaining of set() calls to add multiple implementations to a map.\n * @template K The key type of the map being registered.\n * @template V The value type of the map being registered.\n */\nexport interface RegistrationMap<K, V> {\n /**\n * Adds an implementation identifier to the map collection.\n * The resolved instance will be stored in the map with the provided key when the service is created.\n * @param key The key of the implementation to add.\n * @param id The identifier of the implementation to add.\n * @returns Registration map options for method chaining.\n */\n set(key: K, id: Identifier<V>): RegistrationMap<K, V>;\n}\n\n/**\n * Fluent interface for specifying how a service should be created.\n * Provides methods to register a service using a class, factory, or instance.\n * @template T The type being registered.\n */\nexport interface RegistrationType<T> {\n /**\n * Registers a service using a constructor class.\n * @param constructor The constructor function to use for creating instances.\n * @returns Registration options for further configuration.\n */\n useClass(constructor: Constructor<T>): RegistrationLifeTime;\n\n /**\n * Registers a service using a factory function.\n * @param factory The factory function that creates instances.\n * @returns Registration options for further configuration.\n */\n useFactory(factory: Factory<T>): RegistrationLifeTime;\n\n /**\n * Registers a service using an existing instance.\n * @param instance The instance to register (will be used as a singleton).\n */\n useInstance(instance: Instance<T>): void;\n\n /**\n * Registers a service as an array type, allowing multiple implementations to be collected.\n * Use this when you need to register a service that extends Array and collect multiple implementations.\n * The array will be populated with instances resolved from the identifiers added via push().\n * @template U The array element type extracted from T.\n * @param constructor The constructor function for the array type (must extend Array).\n * @returns Registration array options for chaining push() calls to add implementations.\n */\n useArray<U extends ArrayType<T>>(constructor: Constructor<T>): RegistrationArray<U>;\n\n /**\n * Registers a service as a map type, allowing multiple implementations to be collected.\n * Use this when you need to register a service that extends Map and collect multiple implementations.\n * The map will be populated with instances resolved from the identifiers added via set().\n * @template U The map element type extracted from T.\n * @param constructor The constructor function for the map type (must extend Map).\n * @returns Registration map options for chaining set() calls to add implementations.\n */\n useMap<U extends MapType<T>>(constructor: Constructor<T>): RegistrationMap<U[0], U[1]>;\n}\n\n/**\n * Service registry that manages service registrations before building a container.\n * Allows registration, removal, and checking of services, and provides a method to build a container\n * with all registered services.\n */\nexport interface Registry {\n /**\n * Registers a service with the registry.\n * @template T The type of the service to register.\n * @param id The identifier (constructor or abstract class) for the type to register.\n * @returns The registration type for configuring how the service should be created.\n */\n register<T>(id: Identifier<T>): RegistrationType<T>;\n\n /**\n * Removes a service registration from the registry.\n * @template T The type of the service to remove.\n * @param id The identifier (constructor or abstract class) for the type to remove.\n */\n remove<T>(id: Identifier<T>): void;\n\n /**\n * Checks if a service is registered with the registry.\n * @template T The type of the service to check.\n * @param id The identifier (constructor or abstract class) for the type to check.\n * @returns True if the service is registered, false otherwise.\n */\n isRegistered<T>(id: Identifier<T>): boolean;\n\n /**\n * Builds a container from the registry.\n * @returns A container instance.\n */\n build(): Container;\n}\n","import 'reflect-metadata';\nimport {\n Constructor,\n Factory,\n Identifier,\n Instance,\n Lifetime,\n RegistrationType,\n Container,\n Abstract,\n RegistrationLifeTime,\n Registry,\n ArrayType,\n RegistrationArray,\n MapType,\n RegistrationMap,\n} from './interfaces.js';\nimport { InjectKitContainer } from './container.js';\nimport { Registration } from './internal.js';\n\n/**\n * Registry implementation for managing service registrations.\n * Allows registration of services with various creation strategies (class, factory, instance)\n * and lifetime management (singleton, transient, scoped).\n * Validates registrations for missing dependencies, circular dependencies, and tag conflicts\n * before building the container.\n */\nexport class InjectKitRegistry implements Registry {\n /** Internal map storing all service registrations by their identifier. */\n private readonly registrations: Map<Identifier<unknown>, InjectKitRegistration<unknown>> = new Map();\n\n /**\n * Registers a service with the registry.\n * @template T The type of the service to register.\n * @param id The identifier (constructor or abstract class) for the type to register.\n * @returns The registration type for configuring how the service should be created.\n * @throws {Error} If a registration for the given identifier already exists.\n */\n public register<T>(id: Identifier<T>): RegistrationType<T> {\n if (this.registrations.has(id)) {\n throw new Error(`Registration for ${id.name} already exists`);\n }\n const registration = new InjectKitRegistration<T>();\n this.registrations.set(id, registration);\n\n return registration;\n }\n\n /**\n * Removes a service registration from the registry.\n * @template T The type of the service to remove.\n * @param id The identifier (constructor or abstract class) for the type to remove.\n * @throws {Error} If the registration for the given identifier is not found.\n */\n public remove<T>(id: Identifier<T>): void {\n if (!this.registrations.delete(id)) {\n throw new Error(`Registration for ${id.name} not found`);\n }\n }\n\n /**\n * Checks if a service is registered with the registry.\n * @template T The type of the service to check.\n * @param id The identifier (constructor or abstract class) for the type to check.\n * @returns True if the service is registered, false otherwise.\n */\n public isRegistered<T>(id: Identifier<T>): boolean {\n return this.registrations.has(id);\n }\n\n /**\n * Verifies that all dependencies for registered services are also registered.\n * @param registrations Map of all registrations to verify.\n * @throws {Error} If any service has dependencies that are not registered.\n */\n private static verifyRegistrations(registrations: Map<Identifier<unknown>, Registration<unknown>>) {\n const missingDependencies: string[] = [];\n\n for (const [id, config] of registrations.entries()) {\n for (const dependency of config.dependencies) {\n if (!registrations.has(dependency)) {\n missingDependencies.push(dependency.name);\n }\n }\n\n if (missingDependencies.length > 0) {\n throw new Error(`Missing dependencies for ${id.name}: ${missingDependencies.join(', ')}`);\n }\n }\n }\n\n /**\n * Verifies that there are no circular dependencies in the registration graph.\n * Uses depth-first search to detect cycles in the dependency graph.\n * @param registrations Map of all registrations to verify.\n * @throws {Error} If a circular dependency is detected.\n */\n private static verifyNoCircularDependencies(registrations: Map<Identifier<unknown>, Registration<unknown>>) {\n /**\n * Recursively checks for circular dependencies starting from a given identifier.\n * @param id The identifier to check for circular dependencies.\n * @param registration The registration configuration for the identifier.\n * @param dependencies The path of dependencies traversed so far (for error reporting).\n */\n const checkCircularDependencies = (id: Identifier<unknown>, registration: Registration<unknown>, dependencies: string[]) => {\n for (const dependency of registration.dependencies) {\n if (id === dependency) {\n throw new Error(`Circular dependency found: ${[id.name, ...dependencies, id.name].join(' -> ')}`);\n }\n\n const dependencyRegistration = registrations.get(dependency);\n if (dependencyRegistration && dependencyRegistration.dependencies.length > 0) {\n checkCircularDependencies(id, dependencyRegistration, [...dependencies, dependency.name]);\n }\n }\n };\n\n for (const [id, config] of registrations.entries()) {\n checkCircularDependencies(id, config, []);\n }\n }\n\n /**\n * Builds a container from all registered services.\n * Performs validation checks for missing dependencies and circular dependencies.\n * @returns A configured container instance ready to resolve services.\n * @throws {Error} If validation fails (missing dependencies, circular dependencies).\n */\n public build(): Container {\n const registrations = new Map<Identifier<unknown>, Registration<unknown>>();\n\n for (const [id, registration] of this.registrations.entries()) {\n const config = registration.build();\n registrations.set(id, config);\n }\n\n if (!this.isRegistered(Container)) {\n registrations.set(Container, {\n lifetime: 'singleton',\n dependencies: [],\n ctorDependencies: [],\n collectionDependencies: undefined,\n constructor: undefined,\n factory: (container: Container) => container,\n instance: undefined,\n });\n }\n\n InjectKitRegistry.verifyRegistrations(registrations);\n InjectKitRegistry.verifyNoCircularDependencies(registrations);\n\n return new InjectKitContainer(registrations);\n }\n}\n\n/**\n * Internal registration builder that implements the fluent registration API.\n * Allows chaining of configuration methods to set up how a service should be created\n * and managed.\n * @template T The type being registered.\n * @internal\n */\nclass InjectKitRegistration<T> implements RegistrationType<T>, RegistrationLifeTime, RegistrationArray<T>, RegistrationMap<unknown, T> {\n /** Optional constructor function for class-based registration. */\n private ctor: Constructor<T> | undefined = undefined;\n /** Optional factory function for factory-based registration. */\n private factory: Factory<T> | undefined = undefined;\n /** Optional instance for instance-based registration. */\n private instance: Instance<T> | undefined = undefined;\n /** Optional collection of identifiers for array-based registration. */\n private collection: Array<Identifier<T>> | undefined = undefined;\n /** Optional collection of identifiers for map-based registration. */\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\n private map: Map<any, Identifier<T>> | undefined = undefined;\n /** The lifetime management strategy for this registration. */\n private lifetime: Lifetime = 'transient';\n\n /**\n * Registers a service using a constructor class.\n * @param constructor The constructor function to use for creating instances.\n * @returns Registration lifetime options for further configuration.\n */\n useClass(constructor: Constructor<T>): RegistrationLifeTime {\n this.ctor = constructor;\n return this;\n }\n\n /**\n * Registers a service using a factory function.\n * @param factory The factory function that creates instances using the container.\n * @returns Registration lifetime options for further configuration.\n */\n useFactory(factory: Factory<T>): RegistrationLifeTime {\n this.factory = factory;\n return this;\n }\n\n /**\n * Registers a service using an existing instance.\n * @param instance The instance to register (will be used as a singleton).\n */\n useInstance(instance: Instance<T>): void {\n this.instance = instance;\n this.lifetime = 'singleton';\n }\n\n /**\n * Registers a service as an array type, allowing multiple implementations to be collected.\n * Use this when you need to register a service that extends Array and collect multiple implementations.\n * The array will be populated with instances resolved from the identifiers added via push().\n * @template U The array element type extracted from T.\n * @param constructor The constructor function for the array type (must extend Array).\n * @returns Registration array options for chaining push() calls to add implementations.\n * @example\n * ```typescript\n * @Injectable()\n * class NotificationService extends Array<Notifier> {}\n *\n * registry.register(NotificationService)\n * .useArray(NotificationService)\n * .push(EmailNotifier)\n * .push(SmsNotifier);\n * ```\n */\n useArray<U extends ArrayType<T>>(constructor: Constructor<T>): RegistrationArray<U> {\n this.collection = [];\n this.ctor = constructor;\n return this as unknown as RegistrationArray<U>;\n }\n\n /**\n * Registers a service as a map type, allowing multiple implementations to be collected.\n * Use this when you need to register a service that extends Map and collect multiple implementations.\n * The map will be populated with instances resolved from the identifiers added via set().\n * @template U The map element type extracted from T.\n * @param constructor The constructor function for the map type (must extend Map).\n * @returns Registration map options for chaining set() calls to add implementations.\n * @example\n * ```typescript\n * @Injectable()\n * class ServiceMap extends Map<string, AbstractService> {}\n *\n * registry.register(ServiceMap)\n * .useMap(ServiceMap)\n * .set('email', EmailService)\n * .set('sms', SmsService);\n * ```\n */\n useMap<U extends MapType<T>>(constructor: Constructor<T>): RegistrationMap<U[0], U[1]> {\n this.map = new Map();\n this.ctor = constructor;\n return this as unknown as RegistrationMap<U[0], U[1]>;\n }\n\n /**\n * Sets the lifetime to singleton (one instance shared across the container).\n */\n asSingleton(): void {\n this.lifetime = 'singleton';\n }\n\n /**\n * Sets the lifetime to transient (new instance created each time).\n */\n asTransient(): void {\n this.lifetime = 'transient';\n }\n\n /**\n * Sets the lifetime to scoped (one instance per scoped container).\n */\n asScoped(): void {\n this.lifetime = 'scoped';\n }\n\n /**\n * Adds an implementation identifier to the array collection.\n * Can be called multiple times to add multiple implementations.\n * The resolved instance will be pushed to the array when the service is created.\n * @param id The identifier of the implementation to add to the array.\n * @returns Registration array options for method chaining.\n * @example\n * ```typescript\n * registry.register(NotificationService)\n * .useArray(NotificationService)\n * .push(EmailNotifier)\n * .push(SmsNotifier);\n * ```\n */\n push(id: Identifier<T>): RegistrationArray<T> {\n this.collection!.push(id);\n return this;\n }\n\n /**\n * Adds an implementation identifier to the map collection.\n * The resolved instance will be stored in the map with the provided key when the service is created.\n * @param key The key of the implementation to add to the map.\n * @param id The identifier of the implementation to add to the map.\n * @returns Registration map options for method chaining.\n * @example\n * ```typescript\n * registry.register(ServiceMap)\n * .useMap(ServiceMap)\n * .set('email', EmailService)\n * .set('sms', SmsService);\n * ```\n */\n set(key: unknown, id: Identifier<T>): RegistrationMap<unknown, T> {\n this.map!.set(key, id);\n return this;\n }\n\n /**\n * Gets the base class of a given target class by inspecting its prototype chain.\n * @template T The type of the target.\n * @template B The type of the base class.\n * @param target The abstract class or constructor to get the base class for.\n * @returns The base class constructor, or undefined if the target extends Object directly.\n */\n private static getBaseClass<T extends B, B>(target: Abstract<T>) {\n const baseClass = Object.getPrototypeOf(target.prototype).constructor;\n if (baseClass === Object) {\n return undefined;\n }\n\n return baseClass;\n }\n\n /**\n * Extracts dependencies from a constructor using reflection metadata.\n * Handles inheritance by checking base classes if the current class has no dependencies.\n * Special handling for classes extending Array or Map - these don't require constructor dependency checks.\n * @template T The type of the target.\n * @param target The constructor or abstract class to extract dependencies from.\n * @param parents Array of parent class names for error reporting in case of missing decorators.\n * @returns Array of dependency identifiers.\n * @throws {Error} If the service is not properly decorated with dependency injection metadata.\n */\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\n private static getDependencies<T>(target: Abstract<T>, parents: string[]): any {\n const dependencies = Reflect.getMetadata('design:paramtypes', target) ?? [];\n\n if (dependencies.length < target.length) {\n throw new Error(`Service not decorated: ${[...parents, target.name].join(' -> ')}`);\n }\n\n if (dependencies.length > 0) {\n return dependencies;\n }\n\n // If the target has a constructor with no parameters, return an empty array\n if (target.length > 0) {\n return [];\n }\n // Special handling for classes extending Array or Map - they don't need constructor dependencies\n const baseClass = this.getBaseClass(target);\n if (baseClass === Array || baseClass === Map) {\n return [];\n } else if (baseClass) {\n return this.getDependencies(baseClass, [...parents, target.name]);\n }\n\n return [];\n }\n\n /**\n * Builds the final registration configuration from the current builder state.\n * Extracts dependencies from the constructor if one is registered.\n * @returns A complete registration configuration object.\n */\n build(): Registration<T> {\n let ctorDependencies = [];\n\n // if (this._collection) {\n // dependencies = this._collection;\n // } else if (this._map) {\n // dependencies = Array.from(this._map);\n // } else\n if (this.ctor) {\n ctorDependencies = InjectKitRegistration.getDependencies(this.ctor, []);\n }\n\n const dependencies = [...ctorDependencies];\n if (this.collection) {\n dependencies.push(...this.collection);\n } else if (this.map) {\n dependencies.push(...Array.from(this.map.values()));\n }\n\n return {\n constructor: this.ctor,\n factory: this.factory,\n instance: this.instance,\n lifetime: this.lifetime,\n dependencies: dependencies,\n ctorDependencies: ctorDependencies,\n collectionDependencies: this.collection ?? this.map,\n };\n }\n}\n","import { Container, Identifier, Instance, ScopedContainer } from './interfaces.js';\nimport { Registration } from './internal.js';\n\n/**\n * Implementation of the dependency injection container.\n * Manages service registrations and resolves instances based on their lifetime strategy.\n */\nexport class InjectKitContainer implements ScopedContainer, Container {\n /** Map storing cached instances for singleton and scoped lifetimes. */\n private readonly instances = new Map<Identifier<unknown>, unknown>();\n\n /**\n * Creates a new container instance.\n * @param registrations Map of registered services and their configurations.\n * @param parent Optional parent container for scoped container hierarchies.\n */\n constructor(\n private readonly registrations: Map<Identifier<unknown>, Registration<unknown>>,\n private readonly parent?: InjectKitContainer,\n ) {}\n\n /**\n * Creates a new instance of the specified type based on its registration configuration.\n * Handles constructor-based, factory-based, and instance-based registrations.\n * Manages singleton and scoped instance caching.\n * Also handles array and map collection dependencies by populating them with resolved instances.\n * @template T The type of instance to create.\n * @param id The identifier for the type to instantiate.\n * @param registration The registration configuration containing creation strategy.\n * @returns A new or cached instance of type T.\n * @throws {Error} If the registration is invalid (no constructor, factory, or instance provided).\n */\n private createInstance<T>(id: Identifier<T>, registration: Registration<T>): T {\n let instance: T;\n\n if (registration.constructor) {\n const dependencies = [];\n for (const dependency of registration.ctorDependencies || []) {\n dependencies.push(this.get(dependency));\n }\n\n instance = new registration.constructor(...dependencies);\n } else if (registration.factory) {\n instance = registration.factory(this);\n } else if (registration.instance) {\n instance = registration.instance;\n } else {\n throw new Error(`Invalid registration for ${id.name}`);\n }\n\n if (registration.collectionDependencies) {\n if (Array.isArray(registration.collectionDependencies) && instance instanceof Array) {\n for (const dependency of registration.collectionDependencies) {\n instance.push(this.get(dependency));\n }\n } else if (registration.collectionDependencies instanceof Map && instance instanceof Map) {\n for (const [key, dependency] of registration.collectionDependencies) {\n instance.set(key, this.get(dependency));\n }\n }\n }\n\n if (registration.lifetime === 'singleton') {\n // @eslint-disable-next-line @typescript-eslint/no-this-alias\n let container: InjectKitContainer = this;\n\n while (container.parent) {\n container = container.parent;\n }\n\n container.instances.set(id, instance);\n } else if (registration.lifetime === 'scoped') {\n this.instances.set(id, instance);\n }\n\n return instance;\n }\n\n /**\n * Retrieves a cached scoped instance by traversing up the container hierarchy.\n * For scoped lifetimes, instances are stored in the container where they were created.\n * @template T The type of instance to retrieve.\n * @param id The identifier for the type to retrieve.\n * @returns The cached scoped instance, or undefined if not found.\n */\n private getScopedInstance<T>(id: Identifier<T>): T {\n const instance = this.instances.get(id) as T;\n\n if (!instance && this.parent) {\n return this.parent.getScopedInstance(id);\n } else {\n return instance;\n }\n }\n\n /**\n * Retrieves an instance of the specified type from the container.\n * For singleton and scoped lifetimes, returns cached instances when available.\n * For transient lifetimes, creates a new instance each time.\n * @template T The type of instance to retrieve.\n * @param id The identifier (constructor or abstract class) for the type to resolve.\n * @returns An instance of type T.\n * @throws {Error} If no registration is found for the specified identifier.\n */\n public get<T>(id: Identifier<T>): T {\n const registration = this.registrations.get(id) as Registration<T>;\n if (!registration) {\n throw new Error(`Registration for ${id.name} not found`);\n }\n\n if (registration.lifetime !== 'transient') {\n const instance = this.getScopedInstance<T>(id);\n if (instance) {\n return instance;\n }\n }\n\n return this.createInstance<T>(id, registration);\n }\n\n /**\n * Creates a new scoped container that inherits all registrations from this container.\n * Scoped containers allow for per-scope instance management, where scoped services\n * are shared within a scope but isolated between different scopes.\n * @returns A new scoped container instance with this container as its parent.\n */\n public createScopedContainer(): ScopedContainer {\n return new InjectKitContainer(this.registrations, this);\n }\n\n /**\n * Overrides the instance of the specified type in the container.\n * @template T The type of instance to override.\n * @param id The identifier for the type to override.\n * @param instance The instance to override.\n */\n public override<T>(id: Identifier<T>, instance: Instance<T>): void {\n this.registrations.set(id, {\n constructor: undefined,\n lifetime: 'scoped',\n dependencies: [],\n ctorDependencies: [],\n factory: undefined,\n instance,\n collectionDependencies: undefined,\n });\n this.instances.set(id, instance);\n }\n}\n"],"mappings":"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","names":["Injectable","target","Container","InjectKitContainer","instances","Map","registrations","parent","createInstance","id","registration","instance","dependencies","dependency","ctorDependencies","push","get","factory","Error","name","collectionDependencies","Array","isArray","key","set","lifetime","container","getScopedInstance","createScopedContainer","override","undefined","InjectKitRegistry","registrations","Map","register","id","has","Error","name","registration","InjectKitRegistration","set","remove","delete","isRegistered","verifyRegistrations","missingDependencies","config","entries","dependency","dependencies","push","length","join","verifyNoCircularDependencies","checkCircularDependencies","dependencyRegistration","get","build","Container","lifetime","ctorDependencies","collectionDependencies","undefined","factory","container","instance","InjectKitContainer","ctor","collection","map","useClass","constructor","useFactory","useInstance","useArray","useMap","asSingleton","asTransient","asScoped","key","getBaseClass","target","baseClass","Object","getPrototypeOf","prototype","getDependencies","parents","Reflect","getMetadata","Array","from","values"]}
1
+ {"version":3,"sources":["../src/injectable.ts","../src/interfaces.ts","../src/registry.ts","../src/container.ts"],"sourcesContent":["/**\n * Decorator for injectable classes. Every registered service must\n * be decorated because without decorators TypeScript won't emit\n * constructor parameter metadata required for dependency injection.\n *\n * @returns A class decorator that marks the class as injectable.\n *\n * @example\n * ```typescript\n * @Injectable()\n * class UserService {\n * constructor(private db: DatabaseService) {}\n * }\n * ```\n *\n * @remarks\n * This decorator is required for classes registered with `useClass()`.\n * Without it, the container cannot determine constructor dependencies.\n */\nexport const Injectable = (): ClassDecorator => {\n return <TFunction extends Function>(target: TFunction): TFunction => {\n return target;\n };\n};\n","/**\n * Represents a constructor function that can be instantiated with the `new` operator.\n * @template T The type of instance that this constructor creates.\n */\nexport interface Constructor<T> extends Function {\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\n new (...args: any[]): T;\n}\n\n/**\n * Represents an abstract class or interface that cannot be directly instantiated.\n * @template T The type of the prototype.\n */\nexport interface Abstract<T> extends Function {\n prototype: T;\n}\n\n/**\n * A type identifier used to resolve dependencies in the container.\n * Can be either a concrete constructor or an abstract class/interface.\n * @template T The type being identified.\n */\nexport type Identifier<T> = Constructor<T> | Abstract<T>;\n\n/**\n * Represents an instance of type T that is also an object.\n * @template T The type of the instance.\n */\nexport type Instance<T> = T & object;\n\n/**\n * Extracts the element type from an array type.\n * @template T The array type to extract the element type from.\n * @example\n * ArrayType<Array<string>> // string\n * ArrayType<string[]> // string\n */\nexport type ArrayType<T> = T extends Array<infer I> ? I : never;\n\n/**\n * Extracts the key and value types from a map type.\n * @template T The map type to extract the key and value types from.\n * @example\n * MapType<Map<string, number>> // [string, number]\n * MapType<Map<symbol, AbstractService>> // [symbol, AbstractService]\n */\nexport type MapType<T> = T extends Map<infer I, infer O> ? [I, O] : never;\n\n/**\n * Dependency injection container that manages the creation and lifetime of registered services.\n */\nexport abstract class Container {\n /**\n * Retrieves an instance of the specified type from the container.\n * For singleton and scoped lifetimes, returns cached instances when available.\n * For transient lifetimes, creates a new instance each time.\n * @template T The type of instance to retrieve.\n * @param id The identifier (constructor or abstract class) for the type to resolve.\n * @returns An instance of type T.\n */\n abstract get<T>(id: Identifier<T>): T;\n\n /**\n * Creates a new scoped container that inherits all registrations from this container.\n * Scoped containers allow for per-scope instance management, where scoped services\n * are shared within a scope but isolated between different scopes.\n * @returns A new scoped container instance with this container as its parent.\n */\n abstract createScopedContainer(): ScopedContainer;\n\n /**\n * Checks if a service has a registration with the container.\n * @template T The type of the service to check.\n * @param id The identifier (constructor or abstract class) for the type to check.\n * @returns True if the service has a registration, false otherwise.\n */\n abstract hasRegistration<T>(id: Identifier<T>): boolean;\n}\n\n/**\n * Scoped container that extends the base container with the ability to override registrations.\n */\nexport type ScopedContainer = Container & {\n /**\n * Overrides the registration for the specified identifier with a new instance.\n * @template T The type of the instance to override.\n * @param id The identifier of the registration to override.\n * @param instance The instance to use for the registration.\n */\n override<T>(id: Identifier<T>, instance: Instance<T>): void;\n};\n\n/**\n * Factory function that creates an instance of type T using the provided container.\n * @template T The type of instance the factory creates.\n * @param container The container to use for resolving dependencies.\n * @returns An instance of type T.\n */\nexport type Factory<T> = (container: Container) => T;\n\n/**\n * Defines the lifetime management strategy for a registered service.\n * - 'singleton': One instance shared across the entire container\n * - 'transient': A new instance created every time it's requested\n * - 'scoped': One instance per scoped container\n */\nexport type Lifetime = 'singleton' | 'transient' | 'scoped';\n\n/**\n * Fluent interface for configuring registration lifetime.\n * Allows chaining of configuration methods to set the lifetime of a registration.\n * @template T The type being registered.\n */\nexport interface RegistrationLifeTime {\n /**\n * Sets the lifetime to singleton (one instance shared across the container).\n */\n asSingleton(): void;\n\n /**\n * Sets the lifetime to transient (new instance created each time).\n */\n asTransient(): void;\n\n /**\n * Sets the lifetime to scoped (one instance per scoped container).\n */\n asScoped(): void;\n}\n\n/**\n * Fluent interface for configuring array-based registrations.\n * Allows chaining of push() calls to add multiple implementations to an array.\n * @template T The element type of the array being registered.\n */\nexport interface RegistrationArray<T> {\n /**\n * Adds an implementation identifier to the array collection.\n * The resolved instance will be pushed to the array when the service is created.\n * @param id The identifier of the implementation to add.\n * @returns Registration array options for method chaining.\n */\n push(id: Identifier<T>): RegistrationArray<T>;\n}\n\n/**\n * Fluent interface for configuring map-based registrations.\n * Allows chaining of set() calls to add multiple implementations to a map.\n * @template K The key type of the map being registered.\n * @template V The value type of the map being registered.\n */\nexport interface RegistrationMap<K, V> {\n /**\n * Adds an implementation identifier to the map collection.\n * The resolved instance will be stored in the map with the provided key when the service is created.\n * @param key The key of the implementation to add.\n * @param id The identifier of the implementation to add.\n * @returns Registration map options for method chaining.\n */\n set(key: K, id: Identifier<V>): RegistrationMap<K, V>;\n}\n\n/**\n * Fluent interface for specifying how a service should be created.\n * Provides methods to register a service using a class, factory, or instance.\n * @template T The type being registered.\n */\nexport interface RegistrationType<T> {\n /**\n * Registers a service using a constructor class.\n * @param constructor The constructor function to use for creating instances.\n * @returns Registration options for further configuration.\n */\n useClass(constructor: Constructor<T>): RegistrationLifeTime;\n\n /**\n * Registers a service using a factory function.\n * @param factory The factory function that creates instances.\n * @returns Registration options for further configuration.\n */\n useFactory(factory: Factory<T>): RegistrationLifeTime;\n\n /**\n * Registers a service using an existing instance.\n * @param instance The instance to register (will be used as a singleton).\n */\n useInstance(instance: Instance<T>): void;\n\n /**\n * Registers a service as an array type, allowing multiple implementations to be collected.\n * Use this when you need to register a service that extends Array and collect multiple implementations.\n * The array will be populated with instances resolved from the identifiers added via push().\n * @template U The array element type extracted from T.\n * @param constructor The constructor function for the array type (must extend Array).\n * @returns Registration array options for chaining push() calls to add implementations.\n */\n useArray<U extends ArrayType<T>>(constructor: Constructor<T>): RegistrationArray<U>;\n\n /**\n * Registers a service as a map type, allowing multiple implementations to be collected.\n * Use this when you need to register a service that extends Map and collect multiple implementations.\n * The map will be populated with instances resolved from the identifiers added via set().\n * @template U The map element type extracted from T.\n * @param constructor The constructor function for the map type (must extend Map).\n * @returns Registration map options for chaining set() calls to add implementations.\n */\n useMap<U extends MapType<T>>(constructor: Constructor<T>): RegistrationMap<U[0], U[1]>;\n}\n\n/**\n * Service registry that manages service registrations before building a container.\n * Allows registration, removal, and checking of services, and provides a method to build a container\n * with all registered services.\n */\nexport interface Registry {\n /**\n * Registers a service with the registry.\n * @template T The type of the service to register.\n * @param id The identifier (constructor or abstract class) for the type to register.\n * @returns The registration type for configuring how the service should be created.\n */\n register<T>(id: Identifier<T>): RegistrationType<T>;\n\n /**\n * Removes a service registration from the registry.\n * @template T The type of the service to remove.\n * @param id The identifier (constructor or abstract class) for the type to remove.\n */\n remove<T>(id: Identifier<T>): void;\n\n /**\n * Checks if a service is registered with the registry.\n * @template T The type of the service to check.\n * @param id The identifier (constructor or abstract class) for the type to check.\n * @returns True if the service is registered, false otherwise.\n */\n isRegistered<T>(id: Identifier<T>): boolean;\n\n /**\n * Builds a container from the registry.\n * @returns A container instance.\n */\n build(): Container;\n}\n","import 'reflect-metadata';\nimport {\n Constructor,\n Factory,\n Identifier,\n Instance,\n Lifetime,\n RegistrationType,\n Container,\n Abstract,\n RegistrationLifeTime,\n Registry,\n ArrayType,\n RegistrationArray,\n MapType,\n RegistrationMap,\n} from './interfaces.js';\nimport { InjectKitContainer } from './container.js';\nimport { Registration } from './internal.js';\n\n/**\n * Registry implementation for managing service registrations.\n * Allows registration of services with various creation strategies (class, factory, instance)\n * and lifetime management (singleton, transient, scoped).\n * Validates registrations for missing dependencies, circular dependencies, and tag conflicts\n * before building the container.\n */\nexport class InjectKitRegistry implements Registry {\n /** Internal map storing all service registrations by their identifier. */\n private readonly registrations: Map<Identifier<unknown>, InjectKitRegistration<unknown>> = new Map();\n\n /**\n * Registers a service with the registry.\n * @template T The type of the service to register.\n * @param id The identifier (constructor or abstract class) for the type to register.\n * @returns The registration type for configuring how the service should be created.\n * @throws {Error} If a registration for the given identifier already exists.\n */\n public register<T>(id: Identifier<T>): RegistrationType<T> {\n if (this.registrations.has(id)) {\n throw new Error(`Registration for ${id.name} already exists`);\n }\n const registration = new InjectKitRegistration<T>();\n this.registrations.set(id, registration);\n\n return registration;\n }\n\n /**\n * Removes a service registration from the registry.\n * @template T The type of the service to remove.\n * @param id The identifier (constructor or abstract class) for the type to remove.\n * @throws {Error} If the registration for the given identifier is not found.\n */\n public remove<T>(id: Identifier<T>): void {\n if (!this.registrations.delete(id)) {\n throw new Error(`Registration for ${id.name} not found`);\n }\n }\n\n /**\n * Checks if a service is registered with the registry.\n * @template T The type of the service to check.\n * @param id The identifier (constructor or abstract class) for the type to check.\n * @returns True if the service is registered, false otherwise.\n */\n public isRegistered<T>(id: Identifier<T>): boolean {\n return this.registrations.has(id);\n }\n\n /**\n * Verifies that all dependencies for registered services are also registered.\n * @param registrations Map of all registrations to verify.\n * @throws {Error} If any service has dependencies that are not registered.\n */\n private static verifyRegistrations(registrations: Map<Identifier<unknown>, Registration<unknown>>) {\n const missingDependencies: string[] = [];\n\n for (const [id, config] of registrations.entries()) {\n for (const dependency of config.dependencies) {\n if (!registrations.has(dependency)) {\n missingDependencies.push(dependency.name);\n }\n }\n\n if (missingDependencies.length > 0) {\n throw new Error(`Missing dependencies for ${id.name}: ${missingDependencies.join(', ')}`);\n }\n }\n }\n\n /**\n * Verifies that there are no circular dependencies in the registration graph.\n * Uses depth-first search to detect cycles in the dependency graph.\n * @param registrations Map of all registrations to verify.\n * @throws {Error} If a circular dependency is detected.\n */\n private static verifyNoCircularDependencies(registrations: Map<Identifier<unknown>, Registration<unknown>>) {\n /**\n * Recursively checks for circular dependencies starting from a given identifier.\n * @param id The identifier to check for circular dependencies.\n * @param registration The registration configuration for the identifier.\n * @param dependencies The path of dependencies traversed so far (for error reporting).\n */\n const checkCircularDependencies = (id: Identifier<unknown>, registration: Registration<unknown>, dependencies: string[]) => {\n for (const dependency of registration.dependencies) {\n if (id === dependency) {\n throw new Error(`Circular dependency found: ${[id.name, ...dependencies, id.name].join(' -> ')}`);\n }\n\n const dependencyRegistration = registrations.get(dependency);\n if (dependencyRegistration && dependencyRegistration.dependencies.length > 0) {\n checkCircularDependencies(id, dependencyRegistration, [...dependencies, dependency.name]);\n }\n }\n };\n\n for (const [id, config] of registrations.entries()) {\n checkCircularDependencies(id, config, []);\n }\n }\n\n /**\n * Builds a container from all registered services.\n * Performs validation checks for missing dependencies and circular dependencies.\n * @returns A configured container instance ready to resolve services.\n * @throws {Error} If validation fails (missing dependencies, circular dependencies).\n */\n public build(): Container {\n const registrations = new Map<Identifier<unknown>, Registration<unknown>>();\n\n for (const [id, registration] of this.registrations.entries()) {\n const config = registration.build();\n registrations.set(id, config);\n }\n\n if (!this.isRegistered(Container)) {\n registrations.set(Container, {\n lifetime: 'singleton',\n dependencies: [],\n ctorDependencies: [],\n collectionDependencies: undefined,\n constructor: undefined,\n factory: (container: Container) => container,\n instance: undefined,\n });\n }\n\n InjectKitRegistry.verifyRegistrations(registrations);\n InjectKitRegistry.verifyNoCircularDependencies(registrations);\n\n return new InjectKitContainer(registrations);\n }\n}\n\n/**\n * Internal registration builder that implements the fluent registration API.\n * Allows chaining of configuration methods to set up how a service should be created\n * and managed.\n * @template T The type being registered.\n * @internal\n */\nclass InjectKitRegistration<T> implements RegistrationType<T>, RegistrationLifeTime, RegistrationArray<T>, RegistrationMap<unknown, T> {\n /** Optional constructor function for class-based registration. */\n private ctor: Constructor<T> | undefined = undefined;\n /** Optional factory function for factory-based registration. */\n private factory: Factory<T> | undefined = undefined;\n /** Optional instance for instance-based registration. */\n private instance: Instance<T> | undefined = undefined;\n /** Optional collection of identifiers for array-based registration. */\n private collection: Array<Identifier<T>> | undefined = undefined;\n /** Optional collection of identifiers for map-based registration. */\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\n private map: Map<any, Identifier<T>> | undefined = undefined;\n /** The lifetime management strategy for this registration. */\n private lifetime: Lifetime = 'transient';\n\n /**\n * Registers a service using a constructor class.\n * @param constructor The constructor function to use for creating instances.\n * @returns Registration lifetime options for further configuration.\n */\n useClass(constructor: Constructor<T>): RegistrationLifeTime {\n this.ctor = constructor;\n return this;\n }\n\n /**\n * Registers a service using a factory function.\n * @param factory The factory function that creates instances using the container.\n * @returns Registration lifetime options for further configuration.\n */\n useFactory(factory: Factory<T>): RegistrationLifeTime {\n this.factory = factory;\n return this;\n }\n\n /**\n * Registers a service using an existing instance.\n * @param instance The instance to register (will be used as a singleton).\n */\n useInstance(instance: Instance<T>): void {\n this.instance = instance;\n this.lifetime = 'singleton';\n }\n\n /**\n * Registers a service as an array type, allowing multiple implementations to be collected.\n * Use this when you need to register a service that extends Array and collect multiple implementations.\n * The array will be populated with instances resolved from the identifiers added via push().\n * @template U The array element type extracted from T.\n * @param constructor The constructor function for the array type (must extend Array).\n * @returns Registration array options for chaining push() calls to add implementations.\n * @example\n * ```typescript\n * @Injectable()\n * class NotificationService extends Array<Notifier> {}\n *\n * registry.register(NotificationService)\n * .useArray(NotificationService)\n * .push(EmailNotifier)\n * .push(SmsNotifier);\n * ```\n */\n useArray<U extends ArrayType<T>>(constructor: Constructor<T>): RegistrationArray<U> {\n this.collection = [];\n this.ctor = constructor;\n return this as unknown as RegistrationArray<U>;\n }\n\n /**\n * Registers a service as a map type, allowing multiple implementations to be collected.\n * Use this when you need to register a service that extends Map and collect multiple implementations.\n * The map will be populated with instances resolved from the identifiers added via set().\n * @template U The map element type extracted from T.\n * @param constructor The constructor function for the map type (must extend Map).\n * @returns Registration map options for chaining set() calls to add implementations.\n * @example\n * ```typescript\n * @Injectable()\n * class ServiceMap extends Map<string, AbstractService> {}\n *\n * registry.register(ServiceMap)\n * .useMap(ServiceMap)\n * .set('email', EmailService)\n * .set('sms', SmsService);\n * ```\n */\n useMap<U extends MapType<T>>(constructor: Constructor<T>): RegistrationMap<U[0], U[1]> {\n this.map = new Map();\n this.ctor = constructor;\n return this as unknown as RegistrationMap<U[0], U[1]>;\n }\n\n /**\n * Sets the lifetime to singleton (one instance shared across the container).\n */\n asSingleton(): void {\n this.lifetime = 'singleton';\n }\n\n /**\n * Sets the lifetime to transient (new instance created each time).\n */\n asTransient(): void {\n this.lifetime = 'transient';\n }\n\n /**\n * Sets the lifetime to scoped (one instance per scoped container).\n */\n asScoped(): void {\n this.lifetime = 'scoped';\n }\n\n /**\n * Adds an implementation identifier to the array collection.\n * Can be called multiple times to add multiple implementations.\n * The resolved instance will be pushed to the array when the service is created.\n * @param id The identifier of the implementation to add to the array.\n * @returns Registration array options for method chaining.\n * @example\n * ```typescript\n * registry.register(NotificationService)\n * .useArray(NotificationService)\n * .push(EmailNotifier)\n * .push(SmsNotifier);\n * ```\n */\n push(id: Identifier<T>): RegistrationArray<T> {\n this.collection!.push(id);\n return this;\n }\n\n /**\n * Adds an implementation identifier to the map collection.\n * The resolved instance will be stored in the map with the provided key when the service is created.\n * @param key The key of the implementation to add to the map.\n * @param id The identifier of the implementation to add to the map.\n * @returns Registration map options for method chaining.\n * @example\n * ```typescript\n * registry.register(ServiceMap)\n * .useMap(ServiceMap)\n * .set('email', EmailService)\n * .set('sms', SmsService);\n * ```\n */\n set(key: unknown, id: Identifier<T>): RegistrationMap<unknown, T> {\n this.map!.set(key, id);\n return this;\n }\n\n /**\n * Gets the base class of a given target class by inspecting its prototype chain.\n * @template T The type of the target.\n * @template B The type of the base class.\n * @param target The abstract class or constructor to get the base class for.\n * @returns The base class constructor, or undefined if the target extends Object directly.\n */\n private static getBaseClass<T extends B, B>(target: Abstract<T>) {\n const baseClass = Object.getPrototypeOf(target.prototype).constructor;\n if (baseClass === Object) {\n return undefined;\n }\n\n return baseClass;\n }\n\n /**\n * Extracts dependencies from a constructor using reflection metadata.\n * Handles inheritance by checking base classes if the current class has no dependencies.\n * Special handling for classes extending Array or Map - these don't require constructor dependency checks.\n * @template T The type of the target.\n * @param target The constructor or abstract class to extract dependencies from.\n * @param parents Array of parent class names for error reporting in case of missing decorators.\n * @returns Array of dependency identifiers.\n * @throws {Error} If the service is not properly decorated with dependency injection metadata.\n */\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\n private static getDependencies<T>(target: Abstract<T>, parents: string[]): any {\n const dependencies = Reflect.getMetadata('design:paramtypes', target) ?? [];\n\n if (dependencies.length < target.length) {\n throw new Error(`Service not decorated: ${[...parents, target.name].join(' -> ')}`);\n }\n\n if (dependencies.length > 0) {\n return dependencies;\n }\n\n // If the target has a constructor with no parameters, return an empty array\n if (target.length > 0) {\n return [];\n }\n // Special handling for classes extending Array or Map - they don't need constructor dependencies\n const baseClass = this.getBaseClass(target);\n if (baseClass === Array || baseClass === Map) {\n return [];\n } else if (baseClass) {\n return this.getDependencies(baseClass, [...parents, target.name]);\n }\n\n return [];\n }\n\n /**\n * Builds the final registration configuration from the current builder state.\n * Extracts dependencies from the constructor if one is registered.\n * @returns A complete registration configuration object.\n */\n build(): Registration<T> {\n let ctorDependencies = [];\n\n // if (this._collection) {\n // dependencies = this._collection;\n // } else if (this._map) {\n // dependencies = Array.from(this._map);\n // } else\n if (this.ctor) {\n ctorDependencies = InjectKitRegistration.getDependencies(this.ctor, []);\n }\n\n const dependencies = [...ctorDependencies];\n if (this.collection) {\n dependencies.push(...this.collection);\n } else if (this.map) {\n dependencies.push(...Array.from(this.map.values()));\n }\n\n return {\n constructor: this.ctor,\n factory: this.factory,\n instance: this.instance,\n lifetime: this.lifetime,\n dependencies: dependencies,\n ctorDependencies: ctorDependencies,\n collectionDependencies: this.collection ?? this.map,\n };\n }\n}\n","import { Container, Identifier, Instance, ScopedContainer } from './interfaces.js';\nimport { Registration } from './internal.js';\n\n/**\n * Implementation of the dependency injection container.\n * Manages service registrations and resolves instances based on their lifetime strategy.\n */\nexport class InjectKitContainer implements ScopedContainer, Container {\n /** Map storing cached instances for singleton and scoped lifetimes. */\n private readonly instances = new Map<Identifier<unknown>, unknown>();\n\n /**\n * Creates a new container instance.\n * @param registrations Map of registered services and their configurations.\n * @param parent Optional parent container for scoped container hierarchies.\n */\n constructor(\n private readonly registrations: Map<Identifier<unknown>, Registration<unknown>>,\n private readonly parent?: InjectKitContainer,\n ) {}\n\n /**\n * Creates a new instance of the specified type based on its registration configuration.\n * Handles constructor-based, factory-based, and instance-based registrations.\n * Manages singleton and scoped instance caching.\n * Also handles array and map collection dependencies by populating them with resolved instances.\n * @template T The type of instance to create.\n * @param id The identifier for the type to instantiate.\n * @param registration The registration configuration containing creation strategy.\n * @returns A new or cached instance of type T.\n * @throws {Error} If the registration is invalid (no constructor, factory, or instance provided).\n */\n private createInstance<T>(id: Identifier<T>, registration: Registration<T>): T {\n let instance: T;\n\n if (registration.constructor) {\n const dependencies = [];\n for (const dependency of registration.ctorDependencies || []) {\n dependencies.push(this.get(dependency));\n }\n\n instance = new registration.constructor(...dependencies);\n } else if (registration.factory) {\n instance = registration.factory(this);\n } else if (registration.instance) {\n instance = registration.instance;\n } else {\n throw new Error(`Invalid registration for ${id.name}`);\n }\n\n if (registration.collectionDependencies) {\n if (Array.isArray(registration.collectionDependencies) && instance instanceof Array) {\n for (const dependency of registration.collectionDependencies) {\n instance.push(this.get(dependency));\n }\n } else if (registration.collectionDependencies instanceof Map && instance instanceof Map) {\n for (const [key, dependency] of registration.collectionDependencies) {\n instance.set(key, this.get(dependency));\n }\n }\n }\n\n if (registration.lifetime === 'singleton') {\n // @eslint-disable-next-line @typescript-eslint/no-this-alias\n let container: InjectKitContainer = this;\n\n while (container.parent) {\n container = container.parent;\n }\n\n container.instances.set(id, instance);\n } else if (registration.lifetime === 'scoped') {\n this.instances.set(id, instance);\n }\n\n return instance;\n }\n\n /**\n * Retrieves a cached scoped instance by traversing up the container hierarchy.\n * For scoped lifetimes, instances are stored in the container where they were created.\n * @template T The type of instance to retrieve.\n * @param id The identifier for the type to retrieve.\n * @returns The cached scoped instance, or undefined if not found.\n */\n private getScopedInstance<T>(id: Identifier<T>): T {\n const instance = this.instances.get(id) as T;\n\n if (!instance && this.parent) {\n return this.parent.getScopedInstance(id);\n } else {\n return instance;\n }\n }\n\n /**\n * Retrieves an instance of the specified type from the container.\n * For singleton and scoped lifetimes, returns cached instances when available.\n * For transient lifetimes, creates a new instance each time.\n * @template T The type of instance to retrieve.\n * @param id The identifier (constructor or abstract class) for the type to resolve.\n * @returns An instance of type T.\n * @throws {Error} If no registration is found for the specified identifier.\n */\n public get<T>(id: Identifier<T>): T {\n const registration = this.registrations.get(id) as Registration<T>;\n if (!registration) {\n throw new Error(`Registration for ${id.name} not found`);\n }\n\n if (registration.lifetime !== 'transient') {\n const instance = this.getScopedInstance<T>(id);\n if (instance) {\n return instance;\n }\n }\n\n return this.createInstance<T>(id, registration);\n }\n\n /**\n * Checks if a service has a registration with the container.\n * @template T The type of the service to check.\n * @param id The identifier (constructor or abstract class) for the type to check.\n * @returns True if the service has a registration, false otherwise.\n */\n public hasRegistration<T>(id: Identifier<T>): boolean {\n return this.registrations.has(id);\n }\n\n /**\n * Creates a new scoped container that inherits all registrations from this container.\n * Scoped containers allow for per-scope instance management, where scoped services\n * are shared within a scope but isolated between different scopes.\n * @returns A new scoped container instance with this container as its parent.\n */\n public createScopedContainer(): ScopedContainer {\n return new InjectKitContainer(this.registrations, this);\n }\n\n /**\n * Overrides the instance of the specified type in the container.\n * @template T The type of instance to override.\n * @param id The identifier for the type to override.\n * @param instance The instance to override.\n */\n public override<T>(id: Identifier<T>, instance: Instance<T>): void {\n this.registrations.set(id, {\n constructor: undefined,\n lifetime: 'scoped',\n dependencies: [],\n ctorDependencies: [],\n factory: undefined,\n instance,\n collectionDependencies: undefined,\n });\n this.instances.set(id, instance);\n }\n}\n"],"mappings":"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","names":["Injectable","target","Container","InjectKitContainer","instances","Map","registrations","parent","createInstance","id","registration","instance","dependencies","dependency","ctorDependencies","push","get","factory","Error","name","collectionDependencies","Array","isArray","key","set","lifetime","container","getScopedInstance","hasRegistration","has","createScopedContainer","override","undefined","InjectKitRegistry","registrations","Map","register","id","has","Error","name","registration","InjectKitRegistration","set","remove","delete","isRegistered","verifyRegistrations","missingDependencies","config","entries","dependency","dependencies","push","length","join","verifyNoCircularDependencies","checkCircularDependencies","dependencyRegistration","get","build","Container","lifetime","ctorDependencies","collectionDependencies","undefined","factory","container","instance","InjectKitContainer","ctor","collection","map","useClass","constructor","useFactory","useInstance","useArray","useMap","asSingleton","asTransient","asScoped","key","getBaseClass","target","baseClass","Object","getPrototypeOf","prototype","getDependencies","parents","Reflect","getMetadata","Array","from","values"]}
@@ -59,6 +59,13 @@ export declare abstract class Container {
59
59
  * @returns A new scoped container instance with this container as its parent.
60
60
  */
61
61
  abstract createScopedContainer(): ScopedContainer;
62
+ /**
63
+ * Checks if a service has a registration with the container.
64
+ * @template T The type of the service to check.
65
+ * @param id The identifier (constructor or abstract class) for the type to check.
66
+ * @returns True if the service has a registration, false otherwise.
67
+ */
68
+ abstract hasRegistration<T>(id: Identifier<T>): boolean;
62
69
  }
63
70
  /**
64
71
  * Scoped container that extends the base container with the ability to override registrations.
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "injectkit",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Lightweight, type-safe dependency injection container for TypeScript with constructor injection, factory functions, and lifetime management.",
5
5
  "author": {
6
6
  "name": "Marooned Software",
@@ -40,18 +40,18 @@
40
40
  },
41
41
  "devDependencies": {
42
42
  "@changesets/cli": "^2.29.8",
43
- "@eslint/js": "^9.39.2",
44
- "@vitest/coverage-v8": "^4.0.16",
45
- "eslint": "^9.39.2",
43
+ "@eslint/js": "^10.0.1",
44
+ "@vitest/coverage-v8": "^4.0.18",
45
+ "eslint": "^10.0.1",
46
46
  "eslint-config-prettier": "^10.1.8",
47
47
  "eslint-plugin-only-warn": "^1.1.0",
48
- "globals": "^16.5.0",
49
- "prettier": "^3.7.4",
48
+ "globals": "^17.3.0",
49
+ "prettier": "^3.8.1",
50
50
  "tsup": "^8.5.1",
51
51
  "typescript": "^5.9.3",
52
- "typescript-eslint": "^8.50.0",
52
+ "typescript-eslint": "^8.56.0",
53
53
  "unplugin-swc": "^1.5.9",
54
- "vitest": "^4.0.16"
54
+ "vitest": "^4.0.18"
55
55
  },
56
56
  "scripts": {
57
57
  "build": "tsup src/index.ts --format esm --sourcemap --dts && tsc --emitDeclarationOnly --declaration",