import { ContainerModule } from 'inversify'; import type { ServiceIdentifier } from 'inversify'; /** * Framework-only DI provider decorators — a SEPARATE registry from the client-facing * @provideSingleton (which uses @inversifyjs/binding-decorators' single global registry). * * WHY: binding-decorators registers every @provideSingleton class under ONE global * reflect-metadata key, and buildProviderModule() scoops up that whole key. If webpieces * framework classes (RouteBuilderImpl, the filters, WebpiecesRouter) used @provideSingleton, * a CLIENT app's buildProviderModule() would drag those framework internals into its own * container. To keep the two worlds separate: * - packages/** (framework libs) MUST use provideFrameworkSingleton (this registry), * enforced by the no-global-providesingleton-in-packages ESLint rule. * - apps/** (and downstream client projects) use plain @provideSingleton (the global one). * The router loads BOTH buildFrameworkModule() and buildProviderModule(), so everything * resolves — but a client's buildProviderModule() only ever sees the client's own classes. */ type AnyCtor = new (...args: any[]) => unknown; /** How a framework binding is scoped. Always explicit — never inherited from the container. */ export type FrameworkScope = 'singleton' | 'transient'; /** * Framework equivalent of @provideSingleton: registers the class as a singleton bound to * itself, into the webpieces framework registry (NOT the binding-decorators global one). */ export declare function provideFrameworkSingleton(): ClassDecorator; /** * Framework equivalent of @provideSingletonDefaultForApi: marks this class as the DEFAULT (overridable) * singleton implementation OF a contract token (Symbol or abstract class), into the webpieces * framework registry. Binds `token -> thisClass` as a singleton. * * An app overrides it via appOverrides (loaded LAST), same idiom as AuthConfig: * `(await options.rebind(TOKEN)).to(OtherImpl)`. * * The DI-graph designer reads this in pass 1, so `@inject(TOKEN)` renders as `TOKEN (thisClass)` * and expands this class's own dependencies. */ export declare function provideFrameworkSingletonDefaultForApi(serviceIdentifier: ServiceIdentifier): ClassDecorator; /** * Framework equivalent of @provideTransient: a NEW instance on every resolve. Use it for a * class a {@link Provider} hands out per call — e.g. one ProxyClient per API contract. */ export declare function provideFrameworkTransient(): ClassDecorator; /** * Register a {@link Provider} subclass as the DI token that hands out `target` instances. * * The provider caches nothing; `target`'s own binding scope decides whether callers share one * instance (provideFrameworkSingleton -> lazy singleton) or get a fresh one each `get()` * (provideFrameworkTransient -> 1-to-many). * * The provider itself is a singleton — it holds only the resolve-lambda. * * `Provider` is erased at runtime and cannot be its own token, so name one after T. The DI-graph * analyzer reads `target` from HERE, which is why it can draw `Consumer -> T` with no provider box: * a Provider is DI plumbing, not wiring anyone needs to see. * * ```typescript * // webpieces-disable no-symbol-di-tokens -- Provider is erased at runtime; T names the token * export const PROXY_CLIENT_PROVIDER = Symbol.for('ProxyClientProvider'); * bindFrameworkProvider(PROXY_CLIENT_PROVIDER, NodeProxyClient); * * constructor(@inject(PROXY_CLIENT_PROVIDER) private readonly provider: Provider) {} * ``` */ export declare function bindFrameworkProvider(token: ServiceIdentifier, target: AnyCtor): void; /** * Build a ContainerModule binding every provideFrameworkSingleton(As)/Transient class, then * every registered Provider. Load this into the webpieces framework + app containers (the * router does this) alongside the client's own buildProviderModule(). */ export declare function buildFrameworkModule(): ContainerModule; export {};