UNPKG

12.5 kBJavaScriptView Raw
1"use strict";
2var _a;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.InstanceWrapper = exports.INSTANCE_ID_SYMBOL = exports.INSTANCE_METADATA_SYMBOL = void 0;
5const common_1 = require("@nestjs/common");
6const cli_colors_util_1 = require("@nestjs/common/utils/cli-colors.util");
7const random_string_generator_util_1 = require("@nestjs/common/utils/random-string-generator.util");
8const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
9const iterare_1 = require("iterare");
10const uuid_factory_1 = require("../inspector/uuid-factory");
11const constants_1 = require("./constants");
12const provider_classifier_1 = require("./helpers/provider-classifier");
13exports.INSTANCE_METADATA_SYMBOL = Symbol.for('instance_metadata:cache');
14exports.INSTANCE_ID_SYMBOL = Symbol.for('instance_metadata:id');
15class InstanceWrapper {
16 constructor(metadata = {}) {
17 this.isAlias = false;
18 this.scope = common_1.Scope.DEFAULT;
19 this.values = new WeakMap();
20 this[_a] = {};
21 this.initialize(metadata);
22 this[exports.INSTANCE_ID_SYMBOL] =
23 metadata[exports.INSTANCE_ID_SYMBOL] ?? this.generateUuid();
24 }
25 get id() {
26 return this[exports.INSTANCE_ID_SYMBOL];
27 }
28 set instance(value) {
29 this.values.set(constants_1.STATIC_CONTEXT, { instance: value });
30 }
31 get instance() {
32 const instancePerContext = this.getInstanceByContextId(constants_1.STATIC_CONTEXT);
33 return instancePerContext.instance;
34 }
35 get isNotMetatype() {
36 return !this.metatype || this.isFactory;
37 }
38 get isFactory() {
39 return this.metatype && !(0, shared_utils_1.isNil)(this.inject);
40 }
41 get isTransient() {
42 return this.scope === common_1.Scope.TRANSIENT;
43 }
44 getInstanceByContextId(contextId, inquirerId) {
45 if (this.scope === common_1.Scope.TRANSIENT && inquirerId) {
46 return this.getInstanceByInquirerId(contextId, inquirerId);
47 }
48 const instancePerContext = this.values.get(contextId);
49 return instancePerContext
50 ? instancePerContext
51 : this.cloneStaticInstance(contextId);
52 }
53 getInstanceByInquirerId(contextId, inquirerId) {
54 let collectionPerContext = this.transientMap.get(inquirerId);
55 if (!collectionPerContext) {
56 collectionPerContext = new WeakMap();
57 this.transientMap.set(inquirerId, collectionPerContext);
58 }
59 const instancePerContext = collectionPerContext.get(contextId);
60 return instancePerContext
61 ? instancePerContext
62 : this.cloneTransientInstance(contextId, inquirerId);
63 }
64 setInstanceByContextId(contextId, value, inquirerId) {
65 if (this.scope === common_1.Scope.TRANSIENT && inquirerId) {
66 return this.setInstanceByInquirerId(contextId, inquirerId, value);
67 }
68 this.values.set(contextId, value);
69 }
70 setInstanceByInquirerId(contextId, inquirerId, value) {
71 let collection = this.transientMap.get(inquirerId);
72 if (!collection) {
73 collection = new WeakMap();
74 this.transientMap.set(inquirerId, collection);
75 }
76 collection.set(contextId, value);
77 }
78 addCtorMetadata(index, wrapper) {
79 if (!this[exports.INSTANCE_METADATA_SYMBOL].dependencies) {
80 this[exports.INSTANCE_METADATA_SYMBOL].dependencies = [];
81 }
82 this[exports.INSTANCE_METADATA_SYMBOL].dependencies[index] = wrapper;
83 }
84 getCtorMetadata() {
85 return this[exports.INSTANCE_METADATA_SYMBOL].dependencies;
86 }
87 addPropertiesMetadata(key, wrapper) {
88 if (!this[exports.INSTANCE_METADATA_SYMBOL].properties) {
89 this[exports.INSTANCE_METADATA_SYMBOL].properties = [];
90 }
91 this[exports.INSTANCE_METADATA_SYMBOL].properties.push({
92 key,
93 wrapper,
94 });
95 }
96 getPropertiesMetadata() {
97 return this[exports.INSTANCE_METADATA_SYMBOL].properties;
98 }
99 addEnhancerMetadata(wrapper) {
100 if (!this[exports.INSTANCE_METADATA_SYMBOL].enhancers) {
101 this[exports.INSTANCE_METADATA_SYMBOL].enhancers = [];
102 }
103 this[exports.INSTANCE_METADATA_SYMBOL].enhancers.push(wrapper);
104 }
105 getEnhancersMetadata() {
106 return this[exports.INSTANCE_METADATA_SYMBOL].enhancers;
107 }
108 isDependencyTreeDurable(lookupRegistry = []) {
109 if (!(0, shared_utils_1.isUndefined)(this.isTreeDurable)) {
110 return this.isTreeDurable;
111 }
112 if (this.scope === common_1.Scope.REQUEST) {
113 this.isTreeDurable = this.durable === undefined ? false : this.durable;
114 if (this.isTreeDurable) {
115 this.printIntrospectedAsDurable();
116 }
117 return this.isTreeDurable;
118 }
119 const isStatic = this.isDependencyTreeStatic();
120 if (isStatic) {
121 return false;
122 }
123 const isTreeNonDurable = this.introspectDepsAttribute((collection, registry) => collection.some((item) => !item.isDependencyTreeStatic() &&
124 !item.isDependencyTreeDurable(registry)), lookupRegistry);
125 this.isTreeDurable = !isTreeNonDurable;
126 if (this.isTreeDurable) {
127 this.printIntrospectedAsDurable();
128 }
129 return this.isTreeDurable;
130 }
131 introspectDepsAttribute(callback, lookupRegistry = []) {
132 if (lookupRegistry.includes(this[exports.INSTANCE_ID_SYMBOL])) {
133 return false;
134 }
135 lookupRegistry = lookupRegistry.concat(this[exports.INSTANCE_ID_SYMBOL]);
136 const { dependencies, properties, enhancers } = this[exports.INSTANCE_METADATA_SYMBOL];
137 let introspectionResult = dependencies
138 ? callback(dependencies, lookupRegistry)
139 : false;
140 if (introspectionResult || !(properties || enhancers)) {
141 return introspectionResult;
142 }
143 introspectionResult = properties
144 ? callback(properties.map(item => item.wrapper), lookupRegistry)
145 : false;
146 if (introspectionResult || !enhancers) {
147 return introspectionResult;
148 }
149 return enhancers ? callback(enhancers, lookupRegistry) : false;
150 }
151 isDependencyTreeStatic(lookupRegistry = []) {
152 if (!(0, shared_utils_1.isUndefined)(this.isTreeStatic)) {
153 return this.isTreeStatic;
154 }
155 if (this.scope === common_1.Scope.REQUEST) {
156 this.isTreeStatic = false;
157 this.printIntrospectedAsRequestScoped();
158 return this.isTreeStatic;
159 }
160 this.isTreeStatic = !this.introspectDepsAttribute((collection, registry) => collection.some((item) => !item.isDependencyTreeStatic(registry)), lookupRegistry);
161 if (!this.isTreeStatic) {
162 this.printIntrospectedAsRequestScoped();
163 }
164 return this.isTreeStatic;
165 }
166 cloneStaticInstance(contextId) {
167 const staticInstance = this.getInstanceByContextId(constants_1.STATIC_CONTEXT);
168 if (this.isDependencyTreeStatic()) {
169 return staticInstance;
170 }
171 const instancePerContext = {
172 ...staticInstance,
173 instance: undefined,
174 isResolved: false,
175 isPending: false,
176 };
177 if (this.isNewable()) {
178 instancePerContext.instance = Object.create(this.metatype.prototype);
179 }
180 this.setInstanceByContextId(contextId, instancePerContext);
181 return instancePerContext;
182 }
183 cloneTransientInstance(contextId, inquirerId) {
184 const staticInstance = this.getInstanceByContextId(constants_1.STATIC_CONTEXT);
185 const instancePerContext = {
186 ...staticInstance,
187 instance: undefined,
188 isResolved: false,
189 isPending: false,
190 };
191 if (this.isNewable()) {
192 instancePerContext.instance = Object.create(this.metatype.prototype);
193 }
194 this.setInstanceByInquirerId(contextId, inquirerId, instancePerContext);
195 return instancePerContext;
196 }
197 createPrototype(contextId) {
198 const host = this.getInstanceByContextId(contextId);
199 if (!this.isNewable() || host.isResolved) {
200 return;
201 }
202 return Object.create(this.metatype.prototype);
203 }
204 isInRequestScope(contextId, inquirer) {
205 const isDependencyTreeStatic = this.isDependencyTreeStatic();
206 return (!isDependencyTreeStatic &&
207 contextId !== constants_1.STATIC_CONTEXT &&
208 (!this.isTransient || (this.isTransient && !!inquirer)));
209 }
210 isLazyTransient(contextId, inquirer) {
211 const isInquirerRequestScoped = inquirer && !inquirer.isDependencyTreeStatic();
212 return (this.isDependencyTreeStatic() &&
213 contextId !== constants_1.STATIC_CONTEXT &&
214 this.isTransient &&
215 isInquirerRequestScoped);
216 }
217 isExplicitlyRequested(contextId, inquirer) {
218 const isSelfRequested = inquirer === this;
219 return (this.isDependencyTreeStatic() &&
220 contextId !== constants_1.STATIC_CONTEXT &&
221 (isSelfRequested || (inquirer && inquirer.scope === common_1.Scope.TRANSIENT)));
222 }
223 isStatic(contextId, inquirer) {
224 const isInquirerRequestScoped = inquirer && !inquirer.isDependencyTreeStatic();
225 const isStaticTransient = this.isTransient && !isInquirerRequestScoped;
226 return (this.isDependencyTreeStatic() &&
227 contextId === constants_1.STATIC_CONTEXT &&
228 (!this.isTransient ||
229 (isStaticTransient && !!inquirer && !inquirer.isTransient)));
230 }
231 getStaticTransientInstances() {
232 if (!this.transientMap) {
233 return [];
234 }
235 const instances = [...this.transientMap.values()];
236 return (0, iterare_1.iterate)(instances)
237 .map(item => item.get(constants_1.STATIC_CONTEXT))
238 .filter(item => !!item)
239 .toArray();
240 }
241 mergeWith(provider) {
242 if ((0, provider_classifier_1.isValueProvider)(provider)) {
243 this.metatype = null;
244 this.inject = null;
245 this.scope = common_1.Scope.DEFAULT;
246 this.setInstanceByContextId(constants_1.STATIC_CONTEXT, {
247 instance: provider.useValue,
248 isResolved: true,
249 isPending: false,
250 });
251 }
252 else if ((0, provider_classifier_1.isClassProvider)(provider)) {
253 this.inject = null;
254 this.metatype = provider.useClass;
255 }
256 else if ((0, provider_classifier_1.isFactoryProvider)(provider)) {
257 this.metatype = provider.useFactory;
258 this.inject = provider.inject || [];
259 }
260 }
261 isNewable() {
262 return (0, shared_utils_1.isNil)(this.inject) && this.metatype && this.metatype.prototype;
263 }
264 initialize(metadata) {
265 const { instance, isResolved, ...wrapperPartial } = metadata;
266 Object.assign(this, wrapperPartial);
267 this.setInstanceByContextId(constants_1.STATIC_CONTEXT, {
268 instance,
269 isResolved,
270 });
271 this.scope === common_1.Scope.TRANSIENT && (this.transientMap = new Map());
272 }
273 printIntrospectedAsRequestScoped() {
274 if (!this.isDebugMode() || this.name === 'REQUEST') {
275 return;
276 }
277 if ((0, shared_utils_1.isString)(this.name)) {
278 InstanceWrapper.logger.log(`${cli_colors_util_1.clc.cyanBright(this.name)}${cli_colors_util_1.clc.green(' introspected as ')}${cli_colors_util_1.clc.magentaBright('request-scoped')}`);
279 }
280 }
281 printIntrospectedAsDurable() {
282 if (!this.isDebugMode()) {
283 return;
284 }
285 if ((0, shared_utils_1.isString)(this.name)) {
286 InstanceWrapper.logger.log(`${cli_colors_util_1.clc.cyanBright(this.name)}${cli_colors_util_1.clc.green(' introspected as ')}${cli_colors_util_1.clc.magentaBright('durable')}`);
287 }
288 }
289 isDebugMode() {
290 return !!process.env.NEST_DEBUG;
291 }
292 generateUuid() {
293 let key = this.name?.toString() ?? this.token?.toString();
294 key += this.host?.name ?? '';
295 return key ? uuid_factory_1.UuidFactory.get(key) : (0, random_string_generator_util_1.randomStringGenerator)();
296 }
297}
298exports.InstanceWrapper = InstanceWrapper;
299_a = exports.INSTANCE_METADATA_SYMBOL;
300InstanceWrapper.logger = new common_1.Logger(InstanceWrapper.name);