UNPKG

@athenna/core

Version:

One foundation for multiple applications.

128 lines (127 loc) 4.63 kB
/** * @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')); } }