import { Container } from 'inversify'; import 'reflect-metadata'; import deepmerge from 'deepmerge'; import { v4 as uuidv4 } from 'uuid'; import Config from './config/Config'; import defaultConfig from './config/defaultConfig'; import PmPlugins from './PmPlugins'; export default class Application { constructor(container) { this.id = uuidv4(); this.container = container; this.PmPlugins = container.get('PmPlugins'); } registerServices() { let count = 0; while (count < this.config.get('config.services').length) { const allServices = this.config.get('config.services'); const service = this.config.get('config.services')[count]; /* set App to every service so services can have access to containers and config */ service.setApp(this); if (service.dependencies) { const servicePos = count; allServices.splice(servicePos + 1, 0, ...service.dependencies); } if (service.register) { service.register(); } count += 1; } } setConfig() { this.config = this.container.get('Config'); } setContext(context) { this.context = context; } bootServices() { const services = this.config.get('config.services'); services.forEach(plugin => { if (plugin.boot) { plugin.boot(); } }); } getPlugins() { return this.PmPlugins.getAll(); } getSchema() { this.schema = this.container.get('Schema'); return this.schema.getSchema(); } getShortCuts() { this.shortCuts = this.container.get('ShortCuts'); this.PmPlugins.add('shortcuts', this.shortCuts.createShortCuts()); } getRules() { this.rules = this.container.get('Rules'); this.PmPlugins.add('rules', this.rules.createRules()); } resetApp() { this.container = {}; this.config = {}; this.PmPlugins = {}; this.schema = {}; this.shortCuts = {}; this.rules = {}; } static create(config) { /* Merge Core Config with User Config */ const appConfig = deepmerge({ config: defaultConfig() }, config, { customMerge: key => { if (key === 'services') { return (coreService, configService) => { return coreService.concat(configService); }; } return true; }, }); /* Create Container */ const container = new Container(); /* Set base bindings for the App to work */ container.bind('PmPlugins').to(PmPlugins); container.bind('Wax').toFactory(() => new Application(container)); container.bind('config').toFactory(() => appConfig); container.bind('Config').to(Config); /* Start the App */ const app = container.get('Wax'); app.setConfig(); if (appConfig.config.PmPlugins) { appConfig.config.PmPlugins.forEach(configPlugin => { app.PmPlugins.add(configPlugin.key, configPlugin); }); } app.registerServices(); return app; } }