UNPKG

3.63 kBJavaScriptView Raw
1"use strict";
2/*
3 * @adonisjs/fold
4 *
5 * (c) Harminder Virk <virk@adonisjs.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10Object.defineProperty(exports, "__esModule", { value: true });
11exports.IocResolver = void 0;
12/**
13 * Exposes the API to resolve and call bindings from the IoC container. The resolver
14 * internally caches the IoC container lookup nodes to boost performance.
15 */
16class IocResolver {
17 constructor(container, fallbackMethod, rcNamespaceKey, fallbackNamespace) {
18 this.container = container;
19 this.fallbackMethod = fallbackMethod;
20 this.rcNamespaceKey = rcNamespaceKey;
21 this.fallbackNamespace = fallbackNamespace;
22 this.lookupCache = {};
23 /**
24 * The namespace that will be used as a prefix when resolving
25 * bindings
26 */
27 this.prefixNamespace = this.getPrefixNamespace();
28 }
29 /**
30 * Returns the prefix namespace by giving preference to the
31 * `.adonisrc.json` file
32 */
33 getPrefixNamespace() {
34 /**
35 * Use fallback namespace, when lookup inside rcFile is not required
36 */
37 if (!this.rcNamespaceKey) {
38 return this.fallbackNamespace;
39 }
40 /**
41 * If container doesn't have `Application` binding, then there is no
42 * way for us to read rcFile namespaces and hence we use the fallback
43 * namespace
44 */
45 if (!this.container.hasBinding('Adonis/Core/Application')) {
46 return this.fallbackNamespace;
47 }
48 /**
49 * Attempt to resolve the rcNamespace key from the rcFile
50 * For example: The rc file has following namespaces
51 * {
52 * "controllers": "App/Controllers/Http"
53 * }
54 * We will use the value next to the `controllers` key
55 */
56 const application = this.container.use('Adonis/Core/Application');
57 return application.namespacesMap.get(this.rcNamespaceKey) || this.fallbackNamespace;
58 }
59 /**
60 * Resolves the namespace and returns it's lookup node
61 */
62 resolve(namespace, prefixNamespace = this.prefixNamespace) {
63 const cacheKey = prefixNamespace ? `${prefixNamespace}/${namespace}` : namespace;
64 /**
65 * Return from cache, when the node exists
66 */
67 const cacheNode = this.lookupCache[cacheKey];
68 if (cacheNode) {
69 return cacheNode;
70 }
71 let method = this.fallbackMethod || 'handle';
72 /**
73 * Split the namespace to lookup the method on it. If method isn't
74 * defined, we will use the conventional `handle` method.
75 */
76 const tokens = namespace.split('.');
77 if (tokens.length > 1) {
78 method = tokens.pop();
79 }
80 const lookupNode = this.container.lookupOrFail(tokens.join('.'), prefixNamespace);
81 this.lookupCache[cacheKey] = { ...lookupNode, method };
82 return this.lookupCache[cacheKey];
83 }
84 /**
85 * Calls the namespace.method expression with any arguments that needs to
86 * be passed. Also supports type-hinting dependencies.
87 */
88 async call(namespace, prefixNamespace, args) {
89 const lookupNode = typeof namespace === 'string' ? this.resolve(namespace, prefixNamespace) : namespace;
90 const instance = await this.container.makeAsync(lookupNode.namespace);
91 args = typeof args === 'function' ? args(instance) : args;
92 return this.container.callAsync(instance, lookupNode.method, args);
93 }
94}
95exports.IocResolver = IocResolver;