UNPKG

4.73 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.Injector = void 0;
12const helpers_1 = require("../helpers");
13const helpers_2 = require("@poppinss/utils/build/helpers");
14const InvalidInjectionException_1 = require("../Exceptions/InvalidInjectionException");
15/**
16 * Exposes the API to injecting dependencies to a class or a method
17 */
18class Injector {
19 constructor(container) {
20 this.container = container;
21 }
22 /**
23 * Resolves the injections to be injected to a method or the
24 * class constructor
25 */
26 resolve(targetName, injections, runtimeValues) {
27 /**
28 * If the runtime values length is greater or same as the length
29 * of injections, then we treat them as the source of truth
30 * and inject them as it is
31 */
32 if (runtimeValues.length >= injections.length) {
33 return runtimeValues;
34 }
35 /**
36 * Loop over all the injections and give preference to runtime value
37 * for a given index, otherwise fallback to `container.make`.
38 */
39 return injections.map((injection, index) => {
40 if (runtimeValues[index] !== undefined) {
41 return runtimeValues[index];
42 }
43 /**
44 * Disallow object and primitive constructors
45 */
46 if ((0, helpers_1.isPrimtiveConstructor)(injection)) {
47 throw InvalidInjectionException_1.InvalidInjectionException.invoke(injections[index], targetName, index);
48 }
49 return this.container.make(injection);
50 });
51 }
52 /**
53 * Resolves the injections to be injected to a method or the
54 * class constructor
55 */
56 async resolveAsync(targetName, injections, runtimeValues) {
57 /**
58 * If the runtime values length is greater or same as the length
59 * of injections, then we treat them as the source of truth
60 * and inject them as it is
61 */
62 if (runtimeValues.length >= injections.length) {
63 return runtimeValues;
64 }
65 /**
66 * Loop over all the injections and give preference to runtime value
67 * for a given index, otherwise fallback to `container.makeAsync`.
68 */
69 return Promise.all(injections.map((injection, index) => {
70 if (runtimeValues[index] !== undefined) {
71 return runtimeValues[index];
72 }
73 /**
74 * Disallow object and primitive constructors
75 */
76 if ((0, helpers_1.isPrimtiveConstructor)(injection)) {
77 throw InvalidInjectionException_1.InvalidInjectionException.invoke(injections[index], targetName, index);
78 }
79 return this.container.makeAsync(injection);
80 }));
81 }
82 /**
83 * Find if the value can be instantiated
84 */
85 isNewable(target) {
86 return (helpers_2.types.isFunction(target) || helpers_2.types.isClass(target)) && target.makePlain !== true;
87 }
88 /**
89 * Get injections for a given property from the target
90 */
91 getInjections(target, prop) {
92 return target.hasOwnProperty('inject') ? target.inject[prop] || [] : [];
93 }
94 /**
95 * Inject dependencies to the constructor of the class
96 */
97 make(target, runtimeValues) {
98 if (!this.isNewable(target)) {
99 return target;
100 }
101 return new target(...this.resolve(target.name, this.getInjections(target, 'instance'), runtimeValues));
102 }
103 /**
104 * Inject dependencies asynchronously to the constructor of the class
105 */
106 async makeAsync(target, runtimeValues) {
107 if (!this.isNewable(target)) {
108 return target;
109 }
110 return new target(...(await this.resolveAsync(target.name, this.getInjections(target, 'instance'), runtimeValues)));
111 }
112 /**
113 * Injects dependencies to the class method
114 */
115 call(target, method, runtimeValues) {
116 const constructor = target.constructor;
117 return target[method](...this.resolve(`${constructor.name}.${method}`, this.getInjections(constructor, method), runtimeValues));
118 }
119 /**
120 * Injects dependencies asynchronously to the class method
121 */
122 async callAsync(target, method, runtimeValues) {
123 const constructor = target.constructor;
124 return target[method](...(await this.resolveAsync(`${constructor.name}.${method}`, this.getInjections(constructor, method), runtimeValues)));
125 }
126}
127exports.Injector = Injector;
128
\No newline at end of file