import { IProvider } from "./_provider"; import { IProviderWithMetadata } from "./_provider-metadata"; import { IBinding } from "./_binding"; import { IContext } from "./_context"; import { Scope } from "./_scope"; import { Service } from "./_service"; import { Constructor } from "./_constructor"; /** * Wraps a tuple type to convert each element to IFluentProviderArgumentBuilder | IProviderWithMetadata * This allows the builder callback to return either fluent builders or metadata objects */ export type FluentProviderBuilderWrap = T extends readonly any[] ? { readonly [P in keyof T]: IFluentProviderArgumentBuilder | IProviderWithMetadata; } : readonly []; /** * Fluent interface for adding metadata to a provider argument * Used when building constructor/function arguments */ export interface IFluentProviderArgumentBuilder { /** Specify the parameter name for this argument */ as(parameterName: string): IProviderWithMetadata; /** Add a custom when predicate (wraps provider) */ when(predicate: (ctx: IContext) => boolean): IFluentProviderArgumentBuilder; } /** * Helper type to extract the result type from a generic type constructor */ type Apply = F extends { __type: infer R; } ? R : never; /** * Type constructor for IFluentProviderBuilder */ interface FluentProviderBuilderCtor { __type: IFluentProviderBuilder; __arg: unknown; } /** * Type constructor for IFluentBindingConditionsScope */ interface FluentBindingConditionsScopeCtor { __type: IFluentBindingConditionsScope; __arg: unknown; } /** * Type constructor for IFluentProviderArgumentBuilder */ interface FluentProviderArgumentBuilderCtor { __type: IFluentProviderArgumentBuilder; __arg: unknown; } /** * Common interface for fluent provider construction methods * @param T - The default type for this builder/factory * @param R - A type constructor that maps from a type U to the return type */ interface IFluentProviderConstructionMethods { /** Bind to resolve another service (runtime symbol) */ to(service: Service): Apply; /** Bind to resolve another service (transformer API - type gets converted to Symbol.for("U")) */ to(): Apply; /** Bind to a constant value */ toConst(value: U): Apply; /** Bind to a custom provider */ toProvider(provider: IProvider): Apply; /** Resolve to a class instance with type-safe constructor arguments */ toClass(ctor: C, builder: (inject: IFluentProviderBuilderFactory) => [...FluentProviderBuilderWrap>]): Apply; }, InstanceType>; /** Resolve to a function result with type-safe function arguments */ toFunc any)>(func: F, builder: (inject: IFluentProviderBuilderFactory) => [...FluentProviderBuilderWrap>]): Apply; }, ReturnType>; } /** * Fluent provider builder that can construct nested dependencies */ export interface IFluentProviderBuilder extends IFluentProviderConstructionMethods { } /** * Factory for creating fluent provider builders * This is the inject parameter passed to builder callbacks * Returns IFluentProviderArgumentBuilder to allow .named() and .when() on arguments */ export interface IFluentProviderBuilderFactory extends IFluentProviderConstructionMethods { } /** * Fluent interface for selecting a provider after binding a service */ export interface IFluentBindingProviderSelection extends IFluentProviderConstructionMethods { } /** * Fluent interface for adding conditions and scope to a binding * This is stateless - each method modifies the underlying binding */ export interface IFluentBindingConditionsScope { /** Add a condition to the binding */ when(predicate: (ctx: IContext) => boolean): IFluentBindingConditionsScope; /** Set the scope for the binding */ inScope(scope: Scope): IFluentBindingConditionsScope; /** Set the binding to singleton scope */ inSingletonScope(): IFluentBindingConditionsScope; /** Set the binding to transient scope (default) */ inTransientScope(): IFluentBindingConditionsScope; /** Get the underlying binding (for advanced scenarios) */ getBinding(): IBinding; } export {};