@nebulae/cli
Version:
Tools and code generators for microservices developed by Nebula Engineering (http://www.nebulae.com.co)
129 lines (118 loc) • 5.19 kB
JavaScript
'use strict'
const Rx = require('rxjs');
const gitRootDir = require('git-root-dir');
const TarTools = require('../crosscuting/TarTools');
const GitTools = require('../crosscuting/GitTools');
const MicroFrontEndsSetupCompendium = require('./MicroFrontEndsSetupCompendium');
const fs = require('fs-extra');
const os = require('os');
class ProductionUiComposition {
constructor({
shellType, shellRepo, frontEndId, outputDir,
storeType, googleAppCredentials, finalEnvFile = undefined, namespace = 'core',
shellRepoBranch = "master", shellRepoUser, shellRepoPsw
}) {
this.shellType = shellType;
this.shellRepo = shellRepo;
this.frontEndId = frontEndId;
this.outputDir = outputDir;
this.finalEnvFile = finalEnvFile;
this.shellRepoBranch = shellRepoBranch;
this.shellRepoUser = shellRepoUser;
this.shellRepoPsw = shellRepoPsw;
//define the service directory store
switch (storeType) {
case 'GCP_DATASTORE':
const GcpServiceDirectory = require('../register/GcpServiceDirectory');
this.store = new GcpServiceDirectory({ googleAppCredentials, namespace });
break;
}
//define the shell to use
switch (shellType) {
case 'FUSE2_ANGULAR':
const Fuse2AngularShell = require('./shell/Fuse2AngularShell');
this.shell = new Fuse2AngularShell();
break;
case 'FUSE_REACT':
const FuseReactShell = require('./shell/FuseReactShell');
this.shell = new FuseReactShell();
break;
}
}
/**
* Compose an integrated UI using all the micro-frontends fragments found in the store
*/
composeUI$() {
/*
- Donwload shell repo and put it in the output dir
- Download microfront-ends packages
- Download each microfrontend package
- untar to temp directories
- Download microfront-ends setup objects
- Get every microfrontend setup
- Apply each setup on a volatile object
- buil shell
- move every microfront end content to shell
- apply setup object into shell (write changes to disk)
- install dependencies
- build integrated shell
- run test
*/
return Rx.Observable.forkJoin(
this.downloadShell$(this.outputDir),
this.mergeMicroFrontendSetups$(),
this.downloadMicroFrontendPackages$())
.mergeMap(([shellPath, mfeSetups, [mfeContentPaths, mfeAssetsPaths]]) => this.buildShell$(shellPath, mfeContentPaths, mfeAssetsPaths, mfeSetups, this.finalEnvFile))
;
}
/**
* Download the shell git repository, extract the shell and put it in the output dir
* Returns an Observable that resolve to the shell path
* @param {*} outputDir
*/
downloadShell$(outputDir) {
const tmpDir = `${os.tmpdir()}/${Math.random()}/shell_project/`;
return GitTools.clone$(this.shellRepo, tmpDir, this.shellRepoBranch, this.shellRepoUser, this.shellRepoPsw)
.concat(Rx.Observable.bindNodeCallback(fs.move)(`${tmpDir}/frontend/${this.frontEndId}`, outputDir))
.mapTo(outputDir)
}
/**
* Downloads all the micro-frontends contentts from the storage and put them on local temporal directories
* Returns an Observable that resolve to an array of the content's local directories
*/
downloadMicroFrontendPackages$() {
return Rx.Observable.forkJoin(
this.store.downloadMicroFrontendContents$(this.frontEndId),
this.store.downloadMicroFrontendAssets$(this.frontEndId)
);
}
/**
* Gets all the microservices registers,
* extract the MicroFront-end setup,
* and merge all of them.
* return an observable that resolves to the merge setup
*/
mergeMicroFrontendSetups$() {
return this.store.findAllMicroserviceRegisters$()
//Selects microservices with micro-fronend for the current frontend
.filter(register => register.frontend && register.frontend[this.frontEndId])
//Only interested in micro-frontend setup
.pluck('frontend', this.frontEndId)
//Process each setup and build a ]Compendium
.reduce((acc, mfeSetup) => {
acc.processSetup(mfeSetup);
return acc;
}, new MicroFrontEndsSetupCompendium());
}
/**
* Builds the shell using the downloaded shell, downloaded contents and the setup compendium
* return an observable that resolves to the builded shell path
* @param {string} shellPath
* @param {string[]} mfeContentPaths
* @param {MicroFrontEndsSetupCompendium} mfeSetups
*/
buildShell$(shellPath, mfeContentPaths, mfeAssetsPaths, mfeSetups, finalEnvFile) {
return this.shell.buildShellProduction$(shellPath, mfeContentPaths, mfeAssetsPaths, mfeSetups, finalEnvFile);
}
}
module.exports = ProductionUiComposition;