"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const unknown_element_exception_1 = require("../errors/exceptions/unknown-element.exception");
const container_scanner_1 = require("./container-scanner");
const injector_1 = require("./injector");
const instance_wrapper_1 = require("./instance-wrapper");
class ModuleRef {
constructor(container) {
this.container = container;
this.injector = new injector_1.Injector();
this.containerScanner = new container_scanner_1.ContainerScanner(container);
}
find(typeOrToken) {
return this.containerScanner.find(typeOrToken);
}
async instantiateClass(type, moduleRef) {
const wrapper = new instance_wrapper_1.InstanceWrapper({
name: type && type.name,
metatype: type,
instance: undefined,
isResolved: false,
host: moduleRef,
});
return new Promise(async (resolve, reject) => {
try {
const callback = async (instances) => {
const properties = await this.injector.resolveProperties(wrapper, moduleRef);
const instance = new type(...instances);
this.injector.applyProperties(instance, properties);
resolve(instance);
};
await this.injector.resolveConstructorParams(wrapper, moduleRef, undefined, callback);
}
catch (err) {
reject(err);
}
});
}
findInstanceByToken(metatypeOrToken, contextModule) {
return this.containerScanner.findInstanceByToken(metatypeOrToken, contextModule);
}
async resolvePerContext(typeOrToken, contextModule, contextId, options) {
let wrapper, collection;
if (!(options && options.strict)) {
[wrapper, collection] = this.containerScanner.getWrapperCollectionPair(typeOrToken);
}
else {
[
wrapper,
collection,
] = this.containerScanner.getWrapperCollectionPairByHost(typeOrToken, contextModule);
}
const instance = await this.injector.loadPerContext(wrapper.instance, wrapper.host, collection, contextId, wrapper);
if (!instance) {
throw new unknown_element_exception_1.UnknownElementException();
}
return instance;
}
}
exports.ModuleRef = ModuleRef;