Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Application.js 2.91 KiB
import { Container } from 'inversify';
// import 'reflect-metadata';
import deepmerge from 'deepmerge';
import Config from './config/Config';
import defaultConfig from './config/defaultConfig';
import PmPlugins from './PmPlugins';

export default class Application {
  constructor(container) {
    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).inSingletonScope();

    container.bind('Wax').toFactory(() => new Application(container));

    container.bind('config').toConstantValue(appConfig);
    container.bind('Config').to(Config).inSingletonScope();

    /*
    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;
  }
}