UNPKG

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