UNPKG

12 kBTypeScriptView Raw
1export declare type ExtractFunctions<T> = {
2 [P in keyof T]: T[P] extends (...args: any[]) => any ? P : never;
3}[keyof T];
4/**
5 * Unwraps the promise
6 */
7declare type UnWrapPromise<T> = T extends Promise<infer U> ? U : T;
8/**
9 * Shape of the bind callback method
10 */
11export declare type BindCallback<ReturnValue extends any, Container extends IocContract> = (container: Container) => ReturnValue;
12/**
13 * Shape of the fake callback method
14 */
15export declare type FakeCallback<ReturnValue extends any, Container extends IocContract> = (container: Container, originalValue: ReturnValue) => ReturnValue;
16/**
17 * Shape of resolved lookup node, resolved using `getResolver().resolve()`
18 * method.
19 */
20export declare type IocResolverLookupNode<Namespace extends string> = {
21 namespace: Namespace;
22 type: 'binding' | 'alias';
23 method: string;
24};
25/**
26 * Shape of class constructor
27 */
28export declare type Constructor<T> = new (...args: any[]) => T;
29/**
30 * Shape of class constructor with `makePlain` property
31 */
32export declare type PlainConstructor = {
33 makePlain: true;
34};
35/**
36 * Type of the "withBindings" method
37 */
38export interface WithBindings<ContainerBindings extends any> {
39 <Bindings extends (keyof ContainerBindings)[]>(namespaces: [...Bindings], cb: (...args: {
40 [M in keyof Bindings]: Bindings[M] extends keyof ContainerBindings ? ContainerBindings[Bindings[M]] : any;
41 }) => void): void;
42 <Namespace extends (keyof ContainerBindings | string)[]>(namespaces: readonly [...Namespace], cb: (...args: {
43 [M in keyof Namespace]: Namespace[M] extends keyof ContainerBindings ? ContainerBindings[Namespace[M]] : any;
44 }) => void): void;
45}
46/**
47 * Finding return type of the `ioc.make` method based upon the
48 * input argument.
49 *
50 * - String and LookupNode = Returns any
51 * - Class constructor with "makePlain" are returned as it is
52 * - Otherwise an instance of the class constructor is returned
53 * - All other values are returned as it is
54 */
55export declare type InferMakeType<T> = T extends string | LookupNode<string> ? any : T extends PlainConstructor ? T : T extends Constructor<infer A> ? A : T;
56/**
57 * Shape of lookup node pulled using `ioc.lookup` method. This node
58 * can be passed to `ioc.use`, or `ioc.make` to skip many checks
59 * and resolve the binding right away.
60 */
61export declare type LookupNode<Namespace extends string> = {
62 namespace: Namespace;
63 type: 'binding' | 'alias';
64};
65/**
66 * Ioc container interface
67 */
68export interface IocContract<ContainerBindings extends any = any> {
69 /**
70 * Registered aliases. The key is the alias and value is the
71 * absolute directory path
72 */
73 importAliases: {
74 [alias: string]: string;
75 };
76 /**
77 * Enable/disable proxies. Proxies are mainly required for fakes to
78 * work
79 */
80 useProxies(enable?: boolean): this;
81 /**
82 * Define the module type for resolving auto import aliases. Defaults
83 * to `cjs`
84 */
85 module: 'cjs' | 'esm';
86 /**
87 * Register a binding with a callback. The callback return value will be
88 * used when binding is resolved
89 */
90 bind<Binding extends keyof ContainerBindings>(binding: Binding, callback: BindCallback<ContainerBindings[Binding], this>): this;
91 bind<Binding extends string>(binding: Binding, callback: BindCallback<Binding extends keyof ContainerBindings ? ContainerBindings[Binding] : any, this>): this;
92 /**
93 * Same as the [[bind]] method, but registers a singleton only. Singleton's callback
94 * is invoked only for the first time and then the cached value is used
95 */
96 singleton<Binding extends keyof ContainerBindings>(binding: Binding, callback: BindCallback<ContainerBindings[Binding], this>): this;
97 singleton<Binding extends string>(binding: Binding, callback: BindCallback<Binding extends keyof ContainerBindings ? ContainerBindings[Binding] : any, this>): this;
98 /**
99 * Define an import alias
100 */
101 alias(absolutePath: string, alias: string): this;
102 /**
103 * Register a fake for a namespace. Fakes works both for "bindings" and "import aliases".
104 * Fakes only work when proxies are enabled using "useProxies".
105 */
106 fake<Namespace extends keyof ContainerBindings>(namespace: Namespace, callback: FakeCallback<ContainerBindings[Namespace], this>): this;
107 fake<Namespace extends string>(namespace: Namespace, callback: FakeCallback<Namespace extends keyof ContainerBindings ? ContainerBindings[Namespace] : any, this>): this;
108 /**
109 * Clear selected or all the fakes. Calling the method with no arguments
110 * will clear all the fakes
111 */
112 restore<Namespace extends keyof ContainerBindings>(namespace?: Namespace): this;
113 restore(namespace?: string): this;
114 /**
115 * Find if a fake has been registered for a given namespace
116 */
117 hasFake<Namespace extends keyof ContainerBindings>(namespace: Namespace): boolean;
118 hasFake(namespace: string): boolean;
119 /**
120 * Find if a binding exists for a given namespace
121 */
122 hasBinding<Binding extends keyof ContainerBindings>(namespace: Binding): boolean;
123 hasBinding(namespace: string): boolean;
124 /**
125 * Find if a namespace is part of the auto import aliases. Returns false, when namespace
126 * is an alias path but has an explicit binding too
127 */
128 isAliasPath(namespace: string): boolean;
129 /**
130 * Lookup a namespace. The output contains the complete namespace,
131 * along with its type. The type is an "alias" or a "binding".
132 *
133 * Null is returned when unable to lookup the namespace inside the container
134 *
135 * Note: This method just checks if a namespace is registered or binding
136 * or can be it resolved from auto import aliases or not. However,
137 * it doesn't check for the module existence on the disk.
138 *
139 * Optionally you can define a prefix namespace
140 * to be used to build the complete namespace. For example:
141 *
142 * - namespace: UsersController
143 * - prefixNamespace: App/Controllers/Http
144 * - Output: App/Controllers/Http/UsersController
145 *
146 * Prefix namespace is ignored for absolute namespaces. For example:
147 *
148 * - namespace: /App/UsersController
149 * - prefixNamespace: App/Controllers/Http
150 * - Output: App/UsersController
151 */
152 lookup<Namespace extends Extract<keyof ContainerBindings, string>>(namespace: Namespace | LookupNode<Namespace>, prefixNamespace?: string): LookupNode<Namespace>;
153 lookup<Namespace extends string>(namespace: Namespace | LookupNode<Namespace>, prefixNamespace?: string): Namespace extends keyof ContainerBindings ? LookupNode<Namespace> : LookupNode<string> | null;
154 /**
155 * Same as [[lookup]]. But raises exception instead of returning null
156 */
157 lookupOrFail<Namespace extends Extract<keyof ContainerBindings, string>>(namespace: Namespace | LookupNode<Namespace>, prefixNamespace?: string): LookupNode<Namespace>;
158 lookupOrFail<Namespace extends string>(namespace: Namespace | LookupNode<Namespace>, prefixNamespace?: string): Namespace extends keyof ContainerBindings ? LookupNode<Namespace> : LookupNode<string>;
159 /**
160 * Resolve a binding by invoking the binding factory function. An exception
161 * is raised, if the binding namespace is unregistered.
162 */
163 resolveBinding<Binding extends Extract<keyof ContainerBindings, string>>(binding: Binding): ContainerBindings[Binding];
164 resolveBinding<Binding extends string>(namespace: Binding): Binding extends keyof ContainerBindings ? ContainerBindings[Binding] : any;
165 /**
166 * Import namespace from the auto import aliases. This method assumes you are
167 * using native ES modules
168 */
169 import(namespace: string): Promise<any>;
170 /**
171 * Same as the "import" method, but uses CJS for requiring the module from its
172 * path
173 */
174 require(namespace: string): any;
175 /**
176 * The use method looks up a namespace inside both the bindings and the
177 * auto import aliases
178 */
179 use<Binding extends Extract<keyof ContainerBindings, string>>(lookupNode: Binding | LookupNode<Binding>): ContainerBindings[Binding];
180 use<Binding extends string>(lookupNode: Binding | LookupNode<Binding>): Binding extends keyof ContainerBindings ? ContainerBindings[Binding] : any;
181 /**
182 * Same as the [[use]] method, but instead uses ES modules for resolving
183 * the auto import aliases
184 */
185 useAsync<Binding extends Extract<keyof ContainerBindings, string>>(lookupNode: Binding | LookupNode<Binding>): Promise<ContainerBindings[Binding]>;
186 useAsync<Binding extends string>(lookupNode: Binding | LookupNode<Binding>): Promise<Binding extends keyof ContainerBindings ? ContainerBindings[Binding] : any>;
187 /**
188 * Makes an instance of the class by first resolving it.
189 */
190 make<Binding extends Extract<keyof ContainerBindings, string>>(lookupNode: Binding | LookupNode<Binding>, args?: any[]): ContainerBindings[Binding];
191 make<T extends any>(value: T | LookupNode<string>, args?: any[]): T extends keyof ContainerBindings ? ContainerBindings[T] : InferMakeType<T>;
192 /**
193 * Same as the [[make]] method, but instead uses ES modules for resolving
194 * the auto import aliases
195 */
196 makeAsync<Binding extends Extract<keyof ContainerBindings, string>>(lookupNode: Binding | LookupNode<Binding>, args?: any[]): Promise<ContainerBindings[Binding]>;
197 makeAsync<T extends any>(value: T | LookupNode<string>, args?: any[]): Promise<T extends keyof ContainerBindings ? ContainerBindings[T] : InferMakeType<T>>;
198 /**
199 * The "withBindings" method invokes the defined callback when it is
200 * able to resolve all the mentioned bindings.
201 */
202 withBindings: WithBindings<ContainerBindings>;
203 /**
204 * @deprecated: Use "withBindings" instead
205 */
206 with: WithBindings<ContainerBindings>;
207 /**
208 * Call a method on an object and automatically inject its depdencies
209 */
210 call<T extends any, Method extends ExtractFunctions<T>>(target: T, method: Method, args?: any[]): ReturnType<T[Method]>;
211 /**
212 * Call a method on an object and automatically inject its depdencies
213 */
214 callAsync<T extends any, Method extends ExtractFunctions<T>>(target: T, method: Method, args?: any[]): Promise<UnWrapPromise<ReturnType<T[Method]>>>;
215 /**
216 * Trap container lookup calls. It includes
217 *
218 * - Ioc.use
219 * - Ioc.useAsync
220 * - Ioc.make
221 * - Ioc.makeAsync
222 * - Ioc.require
223 * - Ioc.import
224 * - Ioc.resolveBinding
225 */
226 trap(callback: (namespace: string) => any): this;
227 /**
228 * Returns the resolver instance to resolve Ioc container bindings with
229 * little ease. Since, the IocResolver uses an in-memory cache to
230 * improve the lookup speed, we suggest keeping a reference to
231 * the output of this method to leverage caching
232 */
233 getResolver(fallbackMethod?: string, rcNamespaceKey?: string, fallbackNamespace?: string): IocResolverContract<ContainerBindings>;
234}
235/**
236 * IoC resolver allows resolving IoC container bindings by defining
237 * prefix namespaces
238 */
239export interface IocResolverContract<ContainerBindings extends any> {
240 /**
241 * Resolve IoC container binding
242 */
243 resolve<Namespace extends Extract<keyof ContainerBindings, string>>(namespace: Namespace, prefixNamespace?: string): IocResolverLookupNode<Namespace>;
244 resolve<Namespace extends string>(namespace: Namespace, prefixNamespace?: string): Namespace extends keyof ContainerBindings ? IocResolverLookupNode<Namespace> : IocResolverLookupNode<string>;
245 /**
246 * Call method on an IoC container binding
247 */
248 call<Namespace extends Extract<keyof ContainerBindings, string>>(namespace: Namespace | string, prefixNamespace?: string, args?: any[]): Promise<any>;
249 call<Namespace extends Extract<keyof ContainerBindings, string>>(namespace: IocResolverLookupNode<Namespace | string>, prefixNamespace: undefined, args?: any[]): Promise<any>;
250}
251export {};