import { FactoryType } from "../utils/factory_type"; declare namespace interfaces { export type DynamicValue = (context: interfaces.Context) => T | Promise; export type ContainerResolution = T | Promise | (T | Promise)[]; type AsyncCallback = TCallback extends (...args: infer TArgs) => infer TResult ? (...args: TArgs) => Promise : never; export type BindingScope = "Singleton" | "Transient" | "Request"; export type BindingType = "ConstantValue" | "Constructor" | "DynamicValue" | "Factory" | "Function" | "Instance" | "Invalid" | "Provider"; export type TargetType = "ConstructorArgument" | "ClassProperty" | "Variable"; export interface BindingScopeEnum { Request: interfaces.BindingScope; Singleton: interfaces.BindingScope; Transient: interfaces.BindingScope; } export interface BindingTypeEnum { ConstantValue: interfaces.BindingType; Constructor: interfaces.BindingType; DynamicValue: interfaces.BindingType; Factory: interfaces.BindingType; Function: interfaces.BindingType; Instance: interfaces.BindingType; Invalid: interfaces.BindingType; Provider: interfaces.BindingType; } export interface TargetTypeEnum { ConstructorArgument: interfaces.TargetType; ClassProperty: interfaces.TargetType; Variable: interfaces.TargetType; } export type Newable = new (...args: never[]) => T; export interface Abstract { prototype: T; } export type ServiceIdentifier = (string | symbol | Newable | Abstract); export interface Clonable { clone(): T; } export type BindingActivation = (context: interfaces.Context, injectable: T) => T | Promise; export type BindingDeactivation = (injectable: T) => void | Promise; export interface Binding extends Clonable> { id: number; moduleId: ContainerModuleBase["id"]; activated: boolean; serviceIdentifier: ServiceIdentifier; constraint: ConstraintFunction; dynamicValue: DynamicValue | null; scope: BindingScope; type: BindingType; implementationType: Newable | TActivated | null; factory: FactoryCreator | null; provider: ProviderCreator | null; onActivation: BindingActivation | null; onDeactivation: BindingDeactivation | null; cache: null | TActivated | Promise; } export type SimpleFactory = (...args: U) => T; export type MultiFactory = (...args: U) => SimpleFactory; export type Factory = SimpleFactory | MultiFactory; export type FactoryCreator = (context: Context) => Factory; export type AutoNamedFactory = SimpleFactory; export type AutoFactory = SimpleFactory; export type FactoryTypeFunction = (context: interfaces.Context) => T | Promise; export interface FactoryDetails { factoryType: FactoryType; factory: FactoryTypeFunction | null; } export type Provider = (...args: any[]) => (((...args: any[]) => Promise) | Promise); export type ProviderCreator = (context: Context) => Provider; export interface NextArgs { avoidConstraints: boolean; contextInterceptor: ((contexts: Context) => Context); isMultiInject: boolean; targetType: TargetType; serviceIdentifier: interfaces.ServiceIdentifier; key?: string | number | symbol; value?: unknown; } export type Next = (args: NextArgs) => (any | any[]); export type Middleware = (next: Next) => Next; export type ContextInterceptor = (context: interfaces.Context) => interfaces.Context; export interface Context { id: number; container: Container; plan: Plan; currentRequest: Request; addPlan(plan: Plan): void; setCurrentRequest(request: Request): void; } export type MetadataOrMetadataArray = Metadata | Metadata[]; export interface Metadata { key: string | number | symbol; value: TValue; } export interface Plan { parentContext: Context; rootRequest: Request; } export interface QueryableString { startsWith(searchString: string): boolean; endsWith(searchString: string): boolean; contains(searchString: string): boolean; equals(compareString: string): boolean; value(): string; } export type ResolveRequestHandler = (request: interfaces.Request) => unknown; export type RequestScope = Map; export interface Request { id: number; serviceIdentifier: ServiceIdentifier; parentContext: Context; parentRequest: Request | null; childRequests: Request[]; target: Target; bindings: Binding[]; requestScope: RequestScope | null; addChildRequest(serviceIdentifier: ServiceIdentifier, bindings: (Binding | Binding[]), target: Target): Request; } export interface Target { id: number; serviceIdentifier: ServiceIdentifier; type: TargetType; name: QueryableString; identifier: string | symbol; metadata: Metadata[]; getNamedTag(): interfaces.Metadata | null; getCustomTags(): interfaces.Metadata[] | null; hasTag(key: string | number | symbol): boolean; isArray(): boolean; matchesArray(name: interfaces.ServiceIdentifier): boolean; isNamed(): boolean; isTagged(): boolean; isOptional(): boolean; matchesNamedTag(name: string): boolean; matchesTag(key: string | number | symbol): (value: unknown) => boolean; } export interface ContainerOptions { autoBindInjectable?: boolean; defaultScope?: BindingScope; skipBaseClassChecks?: boolean; } export interface Container { id: number; parent: Container | null; options: ContainerOptions; bind(serviceIdentifier: ServiceIdentifier): BindingToSyntax; rebind(serviceIdentifier: interfaces.ServiceIdentifier): interfaces.BindingToSyntax; rebindAsync(serviceIdentifier: interfaces.ServiceIdentifier): Promise>; unbind(serviceIdentifier: ServiceIdentifier): void; unbindAsync(serviceIdentifier: interfaces.ServiceIdentifier): Promise; unbindAll(): void; unbindAllAsync(): Promise; isBound(serviceIdentifier: ServiceIdentifier): boolean; isCurrentBound(serviceIdentifier: ServiceIdentifier): boolean; isBoundNamed(serviceIdentifier: ServiceIdentifier, named: string | number | symbol): boolean; isBoundTagged(serviceIdentifier: ServiceIdentifier, key: string | number | symbol, value: unknown): boolean; get(serviceIdentifier: ServiceIdentifier): T; getNamed(serviceIdentifier: ServiceIdentifier, named: string | number | symbol): T; getTagged(serviceIdentifier: ServiceIdentifier, key: string | number | symbol, value: unknown): T; getAll(serviceIdentifier: ServiceIdentifier): T[]; getAllTagged(serviceIdentifier: ServiceIdentifier, key: string | number | symbol, value: unknown): T[]; getAllNamed(serviceIdentifier: ServiceIdentifier, named: string | number | symbol): T[]; getAsync(serviceIdentifier: ServiceIdentifier): Promise; getNamedAsync(serviceIdentifier: ServiceIdentifier, named: string | number | symbol): Promise; getTaggedAsync(serviceIdentifier: ServiceIdentifier, key: string | number | symbol, value: unknown): Promise; getAllAsync(serviceIdentifier: ServiceIdentifier): Promise; getAllTaggedAsync(serviceIdentifier: ServiceIdentifier, key: string | number | symbol, value: unknown): Promise; getAllNamedAsync(serviceIdentifier: ServiceIdentifier, named: string | number | symbol): Promise; onActivation(serviceIdentifier: ServiceIdentifier, onActivation: BindingActivation): void; onDeactivation(serviceIdentifier: ServiceIdentifier, onDeactivation: BindingDeactivation): void; resolve(constructorFunction: interfaces.Newable): T; load(...modules: ContainerModule[]): void; loadAsync(...modules: AsyncContainerModule[]): Promise; unload(...modules: ContainerModuleBase[]): void; unloadAsync(...modules: ContainerModuleBase[]): Promise; applyCustomMetadataReader(metadataReader: MetadataReader): void; applyMiddleware(...middleware: Middleware[]): void; snapshot(): void; restore(): void; createChild(): Container; } export type Bind = (serviceIdentifier: ServiceIdentifier) => BindingToSyntax; export type Rebind = (serviceIdentifier: ServiceIdentifier) => BindingToSyntax; export type Unbind = (serviceIdentifier: ServiceIdentifier) => void; export type UnbindAsync = (serviceIdentifier: ServiceIdentifier) => Promise; export type IsBound = (serviceIdentifier: ServiceIdentifier) => boolean; export interface ContainerModuleBase { id: number; } export interface ContainerModule extends ContainerModuleBase { registry: ContainerModuleCallBack; } export interface AsyncContainerModule extends ContainerModuleBase { registry: AsyncContainerModuleCallBack; } export interface ModuleActivationHandlers { onActivations: Lookup>; onDeactivations: Lookup>; } export interface ModuleActivationStore extends Clonable { addDeactivation(moduleId: ContainerModuleBase["id"], serviceIdentifier: ServiceIdentifier, onDeactivation: interfaces.BindingDeactivation): void; addActivation(moduleId: ContainerModuleBase["id"], serviceIdentifier: ServiceIdentifier, onActivation: interfaces.BindingActivation): void; remove(moduleId: ContainerModuleBase["id"]): ModuleActivationHandlers; } export type ContainerModuleCallBack = (bind: interfaces.Bind, unbind: interfaces.Unbind, isBound: interfaces.IsBound, rebind: interfaces.Rebind, unbindAsync: interfaces.UnbindAsync, onActivation: interfaces.Container["onActivation"], onDeactivation: interfaces.Container["onDeactivation"]) => void; export type AsyncContainerModuleCallBack = AsyncCallback; export interface ContainerSnapshot { bindings: Lookup>; activations: Lookup>; deactivations: Lookup>; middleware: Next | null; moduleActivationStore: interfaces.ModuleActivationStore; } export interface Lookup extends Clonable> { add(serviceIdentifier: ServiceIdentifier, value: T): void; getMap(): Map; get(serviceIdentifier: ServiceIdentifier): T[]; remove(serviceIdentifier: interfaces.ServiceIdentifier): void; removeByCondition(condition: (item: T) => boolean): T[]; removeIntersection(lookup: interfaces.Lookup): void; hasKey(serviceIdentifier: ServiceIdentifier): boolean; clone(): Lookup; traverse(func: (key: interfaces.ServiceIdentifier, value: T[]) => void): void; } export interface BindingOnSyntax { onActivation(fn: (context: Context, injectable: T) => T | Promise): BindingWhenSyntax; onDeactivation(fn: (injectable: T) => void | Promise): BindingWhenSyntax; } export interface BindingWhenSyntax { when(constraint: (request: Request) => boolean): BindingOnSyntax; whenTargetNamed(name: string | number | symbol): BindingOnSyntax; whenTargetIsDefault(): BindingOnSyntax; whenTargetTagged(tag: string | number | symbol, value: unknown): BindingOnSyntax; whenInjectedInto(parent: (NewableFunction | string)): BindingOnSyntax; whenParentNamed(name: string | number | symbol): BindingOnSyntax; whenParentTagged(tag: string | number | symbol, value: unknown): BindingOnSyntax; whenAnyAncestorIs(ancestor: (NewableFunction | string)): BindingOnSyntax; whenNoAncestorIs(ancestor: (NewableFunction | string)): BindingOnSyntax; whenAnyAncestorNamed(name: string | number | symbol): BindingOnSyntax; whenAnyAncestorTagged(tag: string | number | symbol, value: unknown): BindingOnSyntax; whenNoAncestorNamed(name: string | number | symbol): BindingOnSyntax; whenNoAncestorTagged(tag: string | number | symbol, value: unknown): BindingOnSyntax; whenAnyAncestorMatches(constraint: (request: Request) => boolean): BindingOnSyntax; whenNoAncestorMatches(constraint: (request: Request) => boolean): BindingOnSyntax; } export interface BindingWhenOnSyntax extends BindingWhenSyntax, BindingOnSyntax { } export interface BindingInSyntax { inSingletonScope(): BindingWhenOnSyntax; inTransientScope(): BindingWhenOnSyntax; inRequestScope(): BindingWhenOnSyntax; } export interface BindingInWhenOnSyntax extends BindingInSyntax, BindingWhenOnSyntax { } export interface BindingToSyntax { to(constructor: new (...args: never[]) => T): BindingInWhenOnSyntax; toSelf(): BindingInWhenOnSyntax; toConstantValue(value: T): BindingWhenOnSyntax; toDynamicValue(func: DynamicValue): BindingInWhenOnSyntax; toConstructor(constructor: Newable): BindingWhenOnSyntax; toFactory(factory: FactoryCreator): BindingWhenOnSyntax; toFunction(func: T): BindingWhenOnSyntax; toAutoFactory(serviceIdentifier: ServiceIdentifier): BindingWhenOnSyntax; toAutoNamedFactory(serviceIdentifier: ServiceIdentifier): BindingWhenOnSyntax; toProvider(provider: ProviderCreator): BindingWhenOnSyntax; toService(service: ServiceIdentifier): void; } export interface ConstraintFunction { metaData?: Metadata; (request: Request | null): boolean; } export interface MetadataReader { getConstructorMetadata(constructorFunc: NewableFunction): ConstructorMetadata; getPropertiesMetadata(constructorFunc: NewableFunction): MetadataMap; } export interface MetadataMap { [propertyNameOrArgumentIndex: string | symbol]: Metadata[]; } export interface ConstructorMetadata { compilerGeneratedMetadata: NewableFunction[] | undefined; userGeneratedMetadata: MetadataMap; } export {}; } export { interfaces };