@athenna/core
Version:
One foundation for multiple applications.
128 lines (127 loc) • 4.63 kB
JavaScript
/**
* @athenna/core
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { parse } from 'node:path';
import { debug } from '#src/debug';
import { Log } from '@athenna/logger';
import { Module } from '@athenna/common';
import { ServiceProvider } from '@athenna/ioc';
export class LoadHelper {
/**
* The providers modules loaded.
*/
static { this.providers = []; }
/**
* The file paths that are already preloaded.
*/
static { this.alreadyPreloaded = []; }
/**
* REGOOT (Register and Boot) providers.
*/
static async regootProviders() {
await this.loadBootableProviders();
await this.registerProviders();
await this.bootProviders();
if (Config.is('rc.bootLogs', true)) {
this.providers.forEach(Provider => Log.channelOrVanilla('application').success(`Provider ({yellow} ${Provider.name}) successfully booted`));
}
}
/**
* Execute the "boot" method of all the providers loaded.
*/
static async bootProviders() {
await this.providers.athenna.concurrently(Provider => {
debug('running boot() method of provider %s.', Provider.name);
return new Provider().boot();
});
}
/**
* Execute the "register" method of all the providers loaded.
*/
static async registerProviders() {
await this.providers.athenna.concurrently(Provider => {
debug('running register() method of provider %s.', Provider.name);
return new Provider().register();
});
}
/**
* Execute the "shutdown" method of all the providers loaded.
*/
static async shutdownProviders() {
await this.providers.athenna.concurrently(Provider => {
debug('running shutdown() method of provider %s.', Provider.name);
const log = () => {
Log.channelOrVanilla('application').success(`Provider ({yellow} ${Provider.name}) successfully shutdown`);
};
const shutdown = new Provider().shutdown();
if (!shutdown?.then) {
log();
return;
}
return shutdown.then(() => log());
});
}
/**
* Preload all the files inside "rc.preloads" configuration by importing.
*/
static async preloadFiles() {
await Config.get('rc.preloads', []).athenna.concurrently(path => {
debug('preloading path %s.', path);
if (this.alreadyPreloaded.includes(path)) {
debug('path %s has already been preloaded and will be skipped.', path);
return;
}
if (Config.is('rc.bootLogs', true)) {
Log.channelOrVanilla('application').success(`File ({yellow} ${parse(path).base}) successfully preloaded`);
}
return this.resolvePath(path).then(() => this.alreadyPreloaded.push(path));
});
}
/**
* Get all the providers from .athennarc.json file. Also, will return only
* the providers have the same value of "rc.s".
*/
static async loadBootableProviders() {
const paths = Config.get('rc.providers', []);
const providers = await paths.athenna.concurrently(this.resolvePath);
this.providers = providers.filter(Provider => {
debug('loading provider %s.', Provider.name);
if (!this.isRegistered(Provider) && this.canBeBootstrapped(Provider)) {
return true;
}
debug('provider %s will not be loaded because it is already registered or it cannot bootstrap in the current environment.', Provider.name);
return false;
});
}
/**
* Verify if provider is already registered.
*/
static isRegistered(Provider) {
return !!this.providers.find(P => P === Provider);
}
/**
* Verify if provider can be bootstrapped.
*/
static canBeBootstrapped(Provider) {
const provider = new Provider();
if (provider.environment[0] === '*') {
return true;
}
const envs = Config.get('rc.environments');
if (!envs || !envs.length || envs[0] === '*') {
return true;
}
return envs.some(env => provider.environment.indexOf(env) >= 0);
}
/**
* Resolve the import path by meta URL and import it.
*/
static async resolvePath(path) {
return Module.resolve(path, Config.get('rc.parentURL'));
}
}