@adonisjs/fold
Version:
Dependency manager and IoC container for your next NodeJs application
130 lines (129 loc) • 4.27 kB
JavaScript
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Registrar = void 0;
const path_1 = require("path");
const utils_1 = require("@poppinss/utils");
const helpers_1 = require("@poppinss/utils/build/helpers");
/**
* Registrar is used to register and boot the providers
*/
class Registrar {
constructor(providerConstructorParams, basePath) {
this.providerConstructorParams = providerConstructorParams;
this.basePath = basePath;
/**
* The first level of provider paths provided to the registrar
*/
this.providersPaths = [];
/**
* An array of loaded providers. Their can be more providers than the
* `_providersPaths` array, since each provider can provide it's
* own sub providers
*/
this.providers = [];
/**
* Method to instantiate provider instances. One can also defined
* a custom instantiater function
*/
this.providersInstantiater = (provider) => new provider(...this.providerConstructorParams);
/**
* Whether or not the providers can be collected
*/
this.collected = false;
}
/**
* Load the provider by requiring the file from the disk
* and instantiate it. If ioc container is using ES6
* imports, then default exports are handled
* automatically.
*/
async loadProvider(providerPath, basePath) {
providerPath = this.basePath
? (0, helpers_1.resolveFrom)(basePath || this.basePath, providerPath)
: providerPath;
const provider = (0, utils_1.esmRequire)(providerPath);
if (typeof provider !== 'function') {
throw new utils_1.Exception(`"${providerPath}" provider must use export default statement`);
}
return {
provider: this.providersInstantiater(provider),
resolvedPath: (0, path_1.dirname)(providerPath),
};
}
/**
* Loop's over an array of provider paths and pushes them to the
* `providers` collection. This collection is later used to
* register and boot providers
*/
async collect(providerPaths, basePath) {
for (let providerPath of providerPaths) {
const { provider, resolvedPath } = await this.loadProvider(providerPath, basePath);
this.providers.push(provider);
if (provider.provides) {
await this.collect(provider.provides, resolvedPath);
}
}
}
/**
* Register an array of provider paths
*/
useProviders(providersPaths, callback) {
this.providersPaths = providersPaths;
if (typeof callback === 'function') {
this.providersInstantiater = callback;
}
return this;
}
/**
* Register all the providers by instantiating them and
* calling the `register` method.
*
* The provider instance will be returned, which can be used
* to boot them as well.
*/
async register() {
if (this.collected) {
return this.providers;
}
this.collected = true;
await this.collect(this.providersPaths);
/**
* Register collected providers
*/
this.providers.forEach((provider) => {
if (typeof provider.register === 'function') {
provider.register();
}
});
return this.providers;
}
/**
* Boot all the providers by calling the `boot` method.
* Boot methods are called in series.
*/
async boot() {
const providers = await this.register();
for (let provider of providers) {
if (typeof provider.boot === 'function') {
await provider.boot();
}
}
}
/**
* Register an boot providers together.
*/
async registerAndBoot() {
const providers = await this.register();
await this.boot();
return providers;
}
}
exports.Registrar = Registrar;
;