import ngModule from '../module'; import moduleImport from 'module-import'; factory.$inject = ['$http', '$window', '$ocLazyLoad', '$translatePartialLoader', '$translate', '$q']; export function factory($http, $window, $ocLazyLoad, $translatePartialLoader, $translate, $q) { /** * Used to load application modules lazily. */ class ModuleLoader { constructor() { this.loaded = {}; this.imports = {}; this.moduleImport = moduleImport; this.modelInfo = $http.get(`modelInfo`) .then(json => { this.onModelInfoReady(json); this.modelInfo = true; }); } /** * Loads the passed module and it's dependencies. Loading a module * implies load the webpack chunk, translations, recursively load * module dependencies and finally register all of them into Angular. * * @param {String} mod The module name to load * @return {Promise} Will be resolved when loaded, when module is * already loaded it returns a resolved promise */ load(mod) { let mods = []; return this.loadRec(mod, mods); } loadRec(mod, mods) { let loaded = this.loaded[mod]; if (loaded === true || mods.indexOf(mod) != -1) return $q.resolve(true); if (loaded instanceof $q) return loaded; let moduleConf = $window.routes.find(i => i && i.module == mod); if (!moduleConf) return $q.reject(new Error(`Module not found: ${mod}`)); let promises = []; if (this.modelInfo instanceof $q) promises.push(this.modelInfo); $translatePartialLoader.addPart(mod); promises.push($translate.refresh()); let modImport = this.imports[mod]; if (!modImport) { modImport = this.imports[mod] = this.moduleImport(mod) .then(() => this.imports[mod] = true); } if (modImport && modImport.then) promises.push(modImport); let deps = moduleConf.dependencies; if (deps) { mods.push(mod); for (let dep of deps) promises.push(this.loadRec(dep, mods)); mods.pop(); } this.loaded[mod] = $q.all(promises) .then(() => $ocLazyLoad.load({name: mod})) .then(() => this.loaded[mod] = true); return this.loaded[mod]; } onModelInfoReady(json) { let entities = json.data; for (let entity in entities) { let fields = entities[entity].validations; for (let field in fields) { let validations = fields[field]; for (let validation of validations) this.parseValidation(validation); } } Object.assign($window.validations, json.data); } parseValidation(val) { switch (val.validation) { case 'custom': // TODO: Don't use eval() because it's "evil". // How to do the same without eval? val.bindedFunction = eval(`(${val.bindedFunction})`); break; case 'format': val.with = new RegExp(val.with); break; } } } return new ModuleLoader(); } ngModule.factory('vnModuleLoader', factory);