UNPKG

8.6 kBTypeScriptView Raw
1import type { Make, BindingKey, Constructor, ErrorCreator, HookCallback, BindingResolver, ExtractFunctions, ContainerOptions, AbstractConstructor } from './types.js';
2import { ContainerResolver } from './resolver.js';
3import { ContextBindingsBuilder } from './contextual_bindings_builder.js';
4/**
5 * The container class exposes the API to register bindings, values
6 * and resolve them.
7 *
8 * Known bindings types can be defined at the time of the constructing
9 * the container.
10 *
11 * ```ts
12 * new Container<{ 'route': Route, encryption: Encryption }>()
13 * ```
14 *
15 * You can resolve bindings and construct classes as follows
16 *
17 * ```ts
18 * await container.make(BINDING_NAME)
19 * await container.make(CLASS_CONSTRUCTOR)
20 * ```
21 */
22export declare class Container<KnownBindings extends Record<any, any>> {
23 #private;
24 constructor(options?: ContainerOptions);
25 /**
26 * Define an emitter instance to use
27 */
28 useEmitter(emitter: Exclude<ContainerOptions['emitter'], undefined>): this;
29 /**
30 * Create a container resolver to resolve bindings, or make classes.
31 *
32 * ```ts
33 * const resolver = container.createResolver()
34 * await resolver.make(CLASS_CONSTRUCTOR)
35 * ```
36 *
37 * Bind values with the resolver. Resolver values are isolated from the
38 * container.
39 *
40 * ```ts
41 * resolver.bindValue(HttpContext, new HttpContext())
42 * await resolver.make(UsersController)
43 * ```
44 */
45 createResolver(): ContainerResolver<KnownBindings>;
46 /**
47 * Find if the container has a binding registered using the
48 * "bind", the "singleton", or the "bindValue" methods.
49 */
50 hasBinding<Binding extends keyof KnownBindings>(binding: Binding): boolean;
51 hasBinding(binding: BindingKey): boolean;
52 /**
53 * Find if the container has all the bindings registered using the
54 * "bind", the "singleton", or the "bindValue" methods.
55 */
56 hasAllBindings<Binding extends keyof KnownBindings>(bindings: Binding[]): boolean;
57 hasAllBindings(binding: BindingKey[]): boolean;
58 /**
59 * Resolves the binding or constructor a class instance as follows.
60 *
61 * - Resolve the binding from the values (if registered)
62 * - Resolve the binding from the bindings (if registered)
63 * - If binding is a class, then create a instance of it. The constructor
64 * dependencies are further resolved as well.
65 * - All other values are returned as it is.
66 *
67 * ```ts
68 * await container.make('route')
69 * await container.make(Database)
70 * ```
71 */
72 make<Binding extends keyof KnownBindings>(binding: Binding, runtimeValues?: any[], createError?: ErrorCreator): Promise<Binding extends string | symbol ? KnownBindings[Binding] : Make<Binding>>;
73 make<Binding>(binding: Binding, runtimeValues?: any[], createError?: ErrorCreator): Promise<Make<Binding>>;
74 /**
75 * Call a method on an object by injecting its dependencies. The method
76 * dependencies are resolved in the same manner as a class constructor
77 * dependencies.
78 *
79 * ```ts
80 * await container.call(await container.make(UsersController), 'index')
81 * ```
82 */
83 call<Value extends Record<any, any>, Method extends ExtractFunctions<Value>>(value: Value, method: Method, runtimeValues?: any[], createError?: ErrorCreator): Promise<ReturnType<Value[Method]>>;
84 /**
85 * Register an alias for a binding. The value can be a reference
86 * to an existing binding or to a class constructor that will
87 * instantiate to the same value as the alias.
88 */
89 alias<Alias extends keyof KnownBindings>(
90 /**
91 * An alias must always be defined as a string or a symbol. Classes cannot be
92 * aliases
93 */
94 alias: Alias extends string | symbol ? Alias : never,
95 /**
96 * The value should either be the constructor point to the alias value
97 * or reference to binding that has the same value as the alias
98 */
99 value: AbstractConstructor<KnownBindings[Alias]> | Exclude<{
100 [K in keyof KnownBindings]: KnownBindings[K] extends KnownBindings[Alias] ? K : never;
101 }[keyof KnownBindings], Alias>): void;
102 /**
103 * Register a binding inside the container. The method receives a
104 * key-value pair.
105 *
106 * - Key can be a string, symbol or a constructor.
107 * - The value is always a factory function to construct the dependency.
108 *
109 * ```ts
110 * container.bind('route', () => new Route())
111 * await container.make('route')
112 *
113 * container.bind(Route, () => new Route())
114 * await container.make(Route)
115 *
116 * const routeSymbol = Symbol('route')
117 * container.bind(routeSymbol, () => new Route())
118 * await container.make(routeSymbol)
119 * ```
120 */
121 bind<Binding extends keyof KnownBindings>(
122 /**
123 * Need to narrow down the "Binding" for the case where "KnownBindings" are <any, any>
124 */
125 binding: Binding extends string | symbol ? Binding : never, resolver: BindingResolver<KnownBindings, KnownBindings[Binding]>): void;
126 bind<Binding extends AbstractConstructor<any>>(binding: Binding, resolver: BindingResolver<KnownBindings, InstanceType<Binding>>): void;
127 /**
128 * Register a binding as a value
129 *
130 * ```ts
131 * container.bindValue(Route, new Route())
132 * ```
133 */
134 bindValue<Binding extends keyof KnownBindings>(
135 /**
136 * Need to narrow down the "Binding" for the case where "KnownBindings" are <any, any>
137 */
138 binding: Binding extends string | symbol ? Binding : never, value: KnownBindings[Binding]): void;
139 bindValue<Binding extends AbstractConstructor<any>>(binding: Binding, value: InstanceType<Binding>): void;
140 /**
141 * Register a binding as a single. The singleton method is same
142 * as the bind method, but the factory function is invoked
143 * only once.
144 *
145 * ```ts
146 * container.singleton('route', () => new Route())
147 * await container.make('route')
148 *
149 * container.singleton(Route, () => new Route())
150 * await container.make(Route)
151 *
152 * const routeSymbol = Symbol('route')
153 * container.singleton(routeSymbol, () => new Route())
154 * await container.make(routeSymbol)
155 * ```
156 */
157 singleton<Binding extends keyof KnownBindings>(
158 /**
159 * Need to narrow down the "Binding" for the case where "KnownBindings" are <any, any>
160 */
161 binding: Binding extends string | symbol ? Binding : never, resolver: BindingResolver<KnownBindings, KnownBindings[Binding]>): void;
162 singleton<Binding extends AbstractConstructor<any>>(binding: Binding, resolver: BindingResolver<KnownBindings, InstanceType<Binding>>): void;
163 /**
164 * Define a fake implementation for a binding or a class constructor.
165 * Fakes have the highest priority when resolving dependencies
166 * from the container.
167 */
168 swap<Binding extends AbstractConstructor<any>>(binding: Binding, resolver: BindingResolver<KnownBindings, InstanceType<Binding>>): void;
169 /**
170 * Restore binding by removing its swap
171 */
172 restore(binding: AbstractConstructor<any>): void;
173 /**
174 * Restore mentioned or all bindings by removing
175 * their swaps
176 */
177 restoreAll(bindings?: AbstractConstructor<any>[]): void;
178 /**
179 * Define hooks to be executed after a binding has been resolved
180 * from the container.
181 *
182 * The hooks are executed for
183 *
184 * - Bindings
185 * - Only once for singletons
186 * - And class constructor
187 *
188 * In other words, the hooks are not executed for direct values registered
189 * with the container
190 */
191 resolving<Binding extends keyof KnownBindings>(binding: Binding extends string | symbol ? Binding : never, callback: HookCallback<KnownBindings, KnownBindings[Binding]>): void;
192 resolving<Binding extends AbstractConstructor<any>>(binding: Binding, callback: HookCallback<KnownBindings, InstanceType<Binding>>): void;
193 /**
194 * Create a contextual builder to define contextual bindings
195 */
196 when(parent: Constructor<any>): ContextBindingsBuilder<KnownBindings, AbstractConstructor<any>>;
197 /**
198 * Add a contextual binding for a given class constructor. A
199 * contextual takes a parent, parent's dependency and a callback
200 * to self resolve the dependency.
201 *
202 * For example:
203 * - When "UsersController"
204 * - Asks for "Hash class"
205 * - Provide "Argon2" implementation
206 */
207 contextualBinding<Binding extends AbstractConstructor<any>>(parent: Constructor<any>, binding: Binding, resolver: BindingResolver<KnownBindings, Make<Binding>>): void;
208}