UNPKG

awilix

Version:

Extremely powerful dependency injection container.

217 lines (216 loc) 7.37 kB
import { type InjectionModeType } from './injection-mode'; import { type LifetimeType } from './lifetime'; import { type GlobWithOptions } from './list-modules'; import { type LoadModulesOptions } from './load-modules'; import { type BuildResolverOptions, type Constructor, type Resolver } from './resolvers'; /** * The container returned from createContainer has some methods and properties. * @interface AwilixContainer */ export interface AwilixContainer<Cradle extends object = {}> { /** * Options the container was configured with. */ options: ContainerOptions; /** * The proxy injected when using `PROXY` injection mode. * Can be used as-is. */ readonly cradle: Cradle; /** * Getter for the rolled up registrations that merges the container family tree. */ readonly registrations: RegistrationHash; /** * Resolved modules cache. */ readonly cache: Map<string | symbol, CacheEntry>; /** * Creates a scoped container with this one as the parent. */ createScope<T extends object = object>(): AwilixContainer<Cradle & T>; /** * Used by `util.inspect`. */ inspect(depth: number, opts?: any): string; /** * Binds `lib/loadModules` to this container, and provides * real implementations of it's dependencies. * * Additionally, any modules using the `dependsOn` API * will be resolved. * * @see src/load-modules.ts documentation. */ loadModules<ESM extends boolean = false>(globPatterns: Array<string | GlobWithOptions>, options?: LoadModulesOptions<ESM>): ESM extends false ? this : Promise<this>; /** * Adds a single registration that using a pre-constructed resolver. */ register<N extends string | symbol, T>(name: N, registration: Resolver<T>): AwilixContainer<Cradle & Record<N, T>>; /** * Pairs resolvers to registration names and registers them. * Mutates and returns the same container, but with an expanded type * that includes the newly registered types, enabling incremental * type building via chaining. */ register<R extends Record<string, Resolver<any>>>(nameAndRegistrationPair: R): AwilixContainer<Cradle & InferCradleFromResolvers<R>>; /** * Resolves the registration with the given name. * * @param {string} name * The name of the registration to resolve. * * @return {*} * Whatever was resolved. */ resolve<K extends keyof Cradle>(name: K, resolveOptions?: ResolveOptions): Cradle[K]; /** * Resolves the registration with the given name. * * @param {string} name * The name of the registration to resolve. * * @return {*} * Whatever was resolved. */ resolve<T>(name: string | symbol, resolveOptions?: ResolveOptions): T; /** * Checks if the registration with the given name exists. * * @param {string | symbol} name * The name of the registration to resolve. * * @return {boolean} * Whether or not the registration exists. */ hasRegistration(name: string | symbol): boolean; /** * Recursively gets a registration by name if it exists in the * current container or any of its' parents. * * @param name {string | symbol} The registration name. */ getRegistration<K extends keyof Cradle>(name: K): Resolver<Cradle[K]> | null; /** * Recursively gets a registration by name if it exists in the * current container or any of its' parents. * * @param name {string | symbol} The registration name. */ getRegistration<T = unknown>(name: string | symbol): Resolver<T> | null; /** * Given a resolver, class or function, builds it up and returns it. * Does not cache it, this means that any lifetime configured in case of passing * a resolver will not be used. * * @param {Resolver|Class|Function} targetOrResolver * @param {ResolverOptions} opts */ build<T>(targetOrResolver: ClassOrFunctionReturning<T> | Resolver<T>, opts?: BuildResolverOptions<T>): T; /** * Disposes this container and it's children, calling the disposer * on all disposable registrations and clearing the cache. * Only applies to registrations with `SCOPED` or `SINGLETON` lifetime. */ dispose(): Promise<void>; } /** * Optional resolve options. */ export interface ResolveOptions { /** * If `true` and `resolve` cannot find the requested dependency, * returns `undefined` rather than throwing an error. */ allowUnregistered?: boolean; } /** * Cache entry. */ export interface CacheEntry<T = any> { /** * The resolver that resolved the value. */ resolver: Resolver<T>; /** * The resolved value. */ value: T; } /** * Register a Registration * @interface NameAndRegistrationPair */ export type NameAndRegistrationPair<T> = { [U in keyof T]?: Resolver<T[U]>; }; /** * Extracts the resolved type from a Resolver. */ export type InferResolverType<T> = T extends Resolver<infer U> ? U : never; /** * Extracts the Cradle type from an AwilixContainer type. * * @example * const container = createContainer() * .register({ * userService: asClass(UserService), * logger: asValue(new Logger()), * }) * type MyCradle = InferCradleFromContainer<typeof container> * // => { userService: UserService; logger: Logger } */ export type InferCradleFromContainer<T extends AwilixContainer<any>> = T extends AwilixContainer<infer C> ? C : never; /** * Given an object whose values are Resolvers, produces the corresponding * cradle type by extracting the resolved type from each resolver. * * @example * const resolvers = { * userService: asClass(UserService), * logger: asValue(new Logger()), * } * type MyCradle = InferCradleFromResolvers<typeof resolvers> * // => { userService: UserService; logger: Logger } */ export type InferCradleFromResolvers<T extends Record<string, Resolver<any>>> = { [K in keyof T]: InferResolverType<T[K]>; }; /** * Function that returns T. */ export type FunctionReturning<T> = (...args: Array<any>) => T; /** * A class or function returning T. */ export type ClassOrFunctionReturning<T> = FunctionReturning<T> | Constructor<T>; /** * The options for the createContainer function. */ export interface ContainerOptions { require?: (id: string) => any; injectionMode?: InjectionModeType; strict?: boolean; } /** * Contains a hash of registrations where the name is the key. */ export type RegistrationHash = Record<string | symbol | number, Resolver<any>>; export type ResolutionStack = Array<{ name: string | symbol; lifetime: LifetimeType; }>; /** * Creates an Awilix container instance. * * @param {Function} options.require The require function to use. Defaults to require. * * @param {string} options.injectionMode The mode used by the container to resolve dependencies. * Defaults to 'Proxy'. * * @param {boolean} options.strict True if the container should run in strict mode with additional * validation for resolver configuration correctness. Defaults to false. * * @return {AwilixContainer<T>} The container. */ export declare function createContainer<T extends object = {}>(options?: ContainerOptions): AwilixContainer<T>;