UNPKG

lakutata

Version:

An IoC-based universal application framework.

290 lines (283 loc) 8.49 kB
/** * Injection mode type. */ type InjectionModeType = 'PROXY' | 'CLASSIC'; /** * Lifetime type. */ type LifetimeType = 'APPLICATION_SINGLETON' | 'MODULE_SINGLETON' | 'SINGLETON' | 'TRANSIENT' | 'SCOPED'; /** * Gets passed the container and is expected to return an object * whose properties are accessible at construction time for the * configured resolver. * * @type {Function} */ type InjectorFunction = <T extends object>(container: IDependencyInjectionContainer<T>) => object; /** * A resolver object returned by asClass(), asFunction() or asValue(). */ interface Resolver<T> extends ResolverOptions<T> { resolve<U extends object>(container: IDependencyInjectionContainer<U>): T; } /** * Options for disposable resolvers. */ interface DisposableResolverOptions<T> extends ResolverOptions<T> { dispose?: Disposer<T>; } /** * Disposer function type. */ type Disposer<T> = (value: T) => any | Promise<any>; /** * The options when registering a class, function or value. * @type RegistrationOptions */ interface ResolverOptions<T> { /** * Only used for inline configuration with `loadModules`. */ name?: string; /** * Lifetime setting. */ lifetime?: LifetimeType; /** * Registration function to use. Only used for inline configuration with `loadModules`. */ register?: (...args: any[]) => Resolver<T>; /** * True if this resolver should be excluded from lifetime leak checking. Used by resolvers that * wish to uphold the anti-leakage contract themselves. Defaults to false. */ isLeakSafe?: boolean; } /** * Builder resolver options. */ interface BuildResolverOptions<T> extends ResolverOptions<T>, DisposableResolverOptions<T> { /** * Resolution mode. */ injectionMode?: InjectionModeType; /** * Injector function to provide additional parameters. */ injector?: InjectorFunction; } /** * A class constructor. For example: * * class MyClass {} * * container.registerClass('myClass', MyClass) * ^^^^^^^ */ type Constructor<T> = { new (...args: any[]): T; }; /** * An object containing the module name and path (full path to module). * * @interface ModuleDescriptor */ interface ModuleDescriptor { name: string; path: string; opts: any; } /** * A glob pattern with associated registration options. */ type GlobWithOptions = [string] | [string, BuildResolverOptions<any> | LifetimeType]; /** * Metadata of the module as well as the loaded module itself. * @interface LoadedModuleDescriptor */ interface LoadedModuleDescriptor extends ModuleDescriptor { value: unknown; } /** * The options when invoking loadModules(). * @interface LoadModulesOptions */ interface LoadModulesOptions<ESM extends boolean = false> { cwd?: string; formatName?: NameFormatter | BuiltInNameFormatters; resolverOptions?: BuildResolverOptions<any>; esModules?: ESM; } /** * Name formatting options when using loadModules(). * @type BuiltInNameFormatters */ type BuiltInNameFormatters = 'camelCase'; /** * Takes in the filename of the module being loaded as well as the module descriptor, * and returns a string which is used to register the module in the container. * * `descriptor.name` is the same as `name`. * * @type {NameFormatter} */ type NameFormatter = (name: string, descriptor: LoadedModuleDescriptor) => string; /** * The container returned from createContainer has some methods and properties. * @interface IDependencyInjectionContainer */ interface IDependencyInjectionContainer<Cradle extends object = any> { /** * 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>(): IDependencyInjectionContainer<Cradle & T>; /** * Used by `util.inspect`. */ inspect(depth: number, opts?: any): string; /** * Binds `lib/loadModules` to this container, and provides * real implementations of its 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<T>(name: string | symbol, registration: Resolver<T>): this; /** * Pairs resolvers to registration names and registers them. */ register(nameAndRegistrationPair: NameAndRegistrationPair<Cradle>): this; /** * 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. */ interface ResolveOptions { /** * If `true` and `resolve` cannot find the requested dependency, * returns `undefined` rather than throwing an error. */ allowUnregistered?: boolean; } /** * Cache entry. */ interface CacheEntry<T = any> { /** * The resolver that resolved the value. */ resolver: Resolver<T>; /** * The resolved value. */ value: T; } /** * Register a Registration * @interface NameAndRegistrationPair */ type NameAndRegistrationPair<T> = { [U in keyof T]?: Resolver<T[U]>; }; /** * Function that returns T. */ type FunctionReturning<T> = (...args: Array<any>) => T; /** * A class or function returning T. */ type ClassOrFunctionReturning<T> = FunctionReturning<T> | Constructor<T>; /** * The options for the createContainer function. */ interface ContainerOptions { require?: (id: string) => any; injectionMode?: InjectionModeType; strict?: boolean; } /** * Contains a hash of registrations where the name is the key. */ type RegistrationHash = Record<string | symbol | number, Resolver<any>>; export type { BuildResolverOptions, LifetimeType, NameAndRegistrationPair };