import { primitive } from "../../safe"; import { TypeOfService, ContainerKeys, ActivationType, ILifetime, ServiceContainer } from "../interfaces"; import { ICancellation } from "../../interfaces"; export interface DependencyOptions { optional?: boolean; default?: any; } export interface LazyDependencyOptions extends DependencyOptions { lazy: true; } export type ExtractService = K extends keyof S ? S[K] : never; export type ExtractDependency = D extends { $dependency: infer K } ? D extends { lazy: true } ? () => ExtractService : ExtractService : D extends { $type: new (...args: any[]) => infer I } ? I : D extends { $factory: (...args: any[]) => infer R } ? R : WalkDependencies; export type WalkDependencies = D extends primitive ? D : { [K in keyof D]: ExtractDependency }; export type InferReferenceType, O> = O extends { default: infer X } ? (TypeOfService | X) : O extends { optional: true } ? (TypeOfService | undefined) : TypeOfService; export interface Resolver { , O extends LazyDependencyOptions>(this: void, name: K, opts: O): () => InferReferenceType; , O extends DependencyOptions>(this: void, name: K, opts?: O): InferReferenceType; } export interface DescriptorBuilder { factory(f: (resolve: Resolver) => T): void; build(): DescriptorBuilder; override(name: K, builder: RegistrationBuilder): this; override(services: { [name in K]: RegistrationBuilder }): this; lifetime(lifetime: "singleton", typeId: any): this; lifetime(lifetime: ILifetime | Exclude): this; cleanup(cb: (item: T) => void): this; value(v: T): void; } export interface ContainerConfiguration { apply(target: ServiceContainer, ct?: ICancellation): Promise>; } export type RegistrationBuilder = (d: DescriptorBuilder, ct?: ICancellation) => void | Promise; export type FluentRegistrations = { [k in K]: RegistrationBuilder };