hello
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
'use strict'
|
||||
|
||||
import { getLogger } from 'frontblock-generic/Types';
|
||||
import { ConfigLoader } from 'loadson';
|
||||
import { promises as fs } from "fs"
|
||||
import { RPCServer } from 'rpclibrary/js/src/Backend'
|
||||
import { AdminConf } from './Types';
|
||||
import { RPCConfigLoader } from './RPCConfigLoader';
|
||||
|
||||
import * as Path from 'path'
|
||||
|
||||
import Knex = require('knex');
|
||||
import http = require('http');
|
||||
import express = require('express');
|
||||
|
||||
const logger = getLogger("admin", 'debug')
|
||||
|
||||
export class FrontworkAdmin {
|
||||
private express
|
||||
private httpServer
|
||||
private config: RPCConfigLoader<AdminConf>
|
||||
|
||||
constructor(){
|
||||
this.initConfig()
|
||||
this.startWebsocket()
|
||||
this.startWebserver()
|
||||
}
|
||||
|
||||
private initConfig(){
|
||||
this.config = new RPCConfigLoader<AdminConf>({
|
||||
name: "FrontworkAdminConf",
|
||||
getDefaultConfig: () => {
|
||||
return {
|
||||
httpPort: 8080,
|
||||
eventBusConf: {},
|
||||
dbConf: {
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: Path.join(__dirname, "data/frontworkAdmin.sqlite")
|
||||
},
|
||||
useNullAsDefault: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}, './config', console.log)
|
||||
}
|
||||
|
||||
private startWebsocket(){
|
||||
console.log()
|
||||
new RPCServer(20000, [
|
||||
this.config
|
||||
])
|
||||
}
|
||||
|
||||
private startWebserver(){
|
||||
if(this.httpServer != null || this.express != null){
|
||||
logger.warn("Webserver is already running")
|
||||
return
|
||||
}
|
||||
|
||||
let port:number = this.config.getConfig().httpPort
|
||||
this.express = express()
|
||||
this.express.use('/', express.static('dist/static'))
|
||||
|
||||
/**
|
||||
* get the compiled FrontendPlugins.js
|
||||
*/
|
||||
this.express.get('/plugins/:id'+".js", async (request, response) => {
|
||||
const pth = Path.resolve("plugins/"+request.params.id, "FrontendPlugin.js");
|
||||
const file = await fs.readFile(pth)
|
||||
const frontend = file.toString()
|
||||
|
||||
response.status(200)
|
||||
response.set('Content-Type', 'application/javascript')
|
||||
response.send(frontend)
|
||||
})
|
||||
|
||||
/**
|
||||
* serve the index.html from the static folder
|
||||
*/
|
||||
this.express.get("/", (request, response) => {
|
||||
response.status(200)
|
||||
response.sendFile('index.html');
|
||||
})
|
||||
|
||||
/**
|
||||
* redirect all the other traffic to the single page app
|
||||
*/
|
||||
this.express.get("*", (request, response) => {
|
||||
response.status(301)
|
||||
response.redirect('/')
|
||||
})
|
||||
|
||||
this.httpServer = new http.Server(this.express)
|
||||
this.httpServer.listen(port, () => {
|
||||
logger.info('Admin panel listening for HTTP on *'+port)
|
||||
})
|
||||
}
|
||||
|
||||
private stopWebserver(){
|
||||
if(this.httpServer == null || this.express == null){
|
||||
logger.warn("Webserver is not running")
|
||||
return
|
||||
}
|
||||
this.httpServer.close()
|
||||
this.httpServer = null
|
||||
this.express = null
|
||||
logger.info("Webserver stopped")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
process.on( 'SIGINT', function() {
|
||||
logger.info("Shutting down from SIGINT (Ctrl-C)" );
|
||||
// some other closing procedures go here
|
||||
process.exit(0);
|
||||
})
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Plugin } from "frontblock-generic/Plugin"
|
||||
import { getLogger } from "frontblock-generic/Types"
|
||||
var exec = require('child-process-promise').exec;
|
||||
|
||||
const logger = getLogger("installer", 'info')
|
||||
|
||||
export type NPMPkgName = string
|
||||
export type NPMVersion = string
|
||||
|
||||
export const installAdmin = (plugins: Plugin[] = []) => {
|
||||
|
||||
const npmPkgs:[NPMPkgName, NPMVersion][] = [['sqlite3', '4.1.0'], ['knex', '0.19.2']]
|
||||
const deps = npmPkgs.map(tuple => tuple.join('@') ).join(" ")
|
||||
logger.info("Installing plaform dependencies: "+deps)
|
||||
|
||||
exec("npm i " + deps).then(async process => {
|
||||
logger.debug(process.stdout)
|
||||
const Admin = require("./Admin").FrontworkAdmin
|
||||
const fbAdmin = new Admin(plugins)
|
||||
})
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
import { installAdmin } from "./Installer";
|
||||
installAdmin()
|
||||
@@ -0,0 +1,42 @@
|
||||
import { ConfigLoader } from 'loadson'
|
||||
import { RPCExporter } from 'rpclibrary/js/src/Interfaces'
|
||||
|
||||
export type ConfigLoaderIfc<ConfT> = {
|
||||
Config : {
|
||||
getConfig: () => ConfT
|
||||
resetConfig: () => ConfT
|
||||
setConfig: (conf:ConfT) => ConfT
|
||||
setConfigKey: (key:string, value:any) => ConfT
|
||||
deleteConfigKey: (key:string) => ConfT
|
||||
getConfigKey: (key:string) => any
|
||||
}
|
||||
}
|
||||
|
||||
export class RPCConfigLoader<ConfT>
|
||||
extends ConfigLoader<ConfT>
|
||||
implements RPCExporter<ConfigLoaderIfc<ConfT>, "Config">{
|
||||
|
||||
name = "Config" as "Config"
|
||||
|
||||
exportRPCs() {
|
||||
return [{
|
||||
name: "getConfig" as "getConfig",
|
||||
call: () => { return this.getConfig() }
|
||||
},{
|
||||
name: "resetConfig" as "resetConfig",
|
||||
call: () => { return this.resetConfig() }
|
||||
},{
|
||||
name: "setConfig" as "setConfig",
|
||||
call: (conf:ConfT) => { return this.setConfig(conf) }
|
||||
},{
|
||||
name: "setConfigKey" as "setConfigKey",
|
||||
call: (key:string, value:any) => { return this.setConfigKey(key, value) }
|
||||
},{
|
||||
name: "deleteConfigKey" as "deleteConfigKey",
|
||||
call: (key:string) => { return this.deleteConfigKey(key) }
|
||||
},{
|
||||
name: "getConfigKey" as "getConfigKey",
|
||||
call: (key:string) => { return this.getConfigKey(key) }
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import Knex = require("knex")
|
||||
|
||||
export declare type NotificationSeverity = 'Info' | 'Important' | 'Error';
|
||||
|
||||
export type AdminConf = {
|
||||
httpPort: number,
|
||||
dbConf:Knex.Config,
|
||||
eventBusConf: { [topic in string]: NotificationSeverity}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = [{
|
||||
mode: 'production',
|
||||
target: "node",
|
||||
node: {
|
||||
global: true,
|
||||
process: true,
|
||||
__filename: false,
|
||||
__dirname: false,
|
||||
Buffer: true,
|
||||
},
|
||||
|
||||
resolve: {
|
||||
// Add `.ts` and `.tsx` as a resolvable extension.
|
||||
|
||||
extensions: [".ts", ".tsx", ".js"]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.ts?$/, loader: "ts-loader" }
|
||||
]
|
||||
},
|
||||
|
||||
externals: ['knex'],
|
||||
optimization: {
|
||||
minimize: false
|
||||
},
|
||||
entry: path.resolve(__dirname, 'Installer.ts'),
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../../dist'),
|
||||
filename: 'Installer.js',
|
||||
libraryTarget: 'commonjs',
|
||||
}
|
||||
},{
|
||||
mode: 'production',
|
||||
target: "node",
|
||||
node: {
|
||||
global: true,
|
||||
process: true,
|
||||
__filename: false,
|
||||
__dirname: false,
|
||||
Buffer: true,
|
||||
},
|
||||
|
||||
|
||||
resolve: {
|
||||
// Add `.ts` and `.tsx` as a resolvable extension.
|
||||
|
||||
extensions: [".ts", ".tsx", ".js"]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.ts?$/, loader: "ts-loader" }
|
||||
]
|
||||
},
|
||||
|
||||
externals:["./Installer"],
|
||||
optimization: {
|
||||
minimize: false
|
||||
},
|
||||
entry: path.resolve(__dirname, 'Launcher.ts'),
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../../dist'),
|
||||
filename: 'FrontblockAdmin.js',
|
||||
libraryTarget: 'commonjs',
|
||||
}
|
||||
}]
|
||||
Reference in New Issue
Block a user