before adding plugin logic

This commit is contained in:
peter
2019-10-28 19:45:59 +01:00
parent e07f001514
commit 0857f1ec25
8 changed files with 175 additions and 12 deletions
+3 -3
View File
@@ -5763,9 +5763,9 @@
"dev": true
},
"upgiter": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/upgiter/-/upgiter-1.0.1.tgz",
"integrity": "sha512-HHWZ4/SWXVXC80fnNW/E1gsNT8D5mlAG6i2JcGG9akr5Q+sDrt+NPbaeMuLMSJJY6LI0CiIbzE59duWEQQINJg==",
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/upgiter/-/upgiter-1.0.4.tgz",
"integrity": "sha512-+6McoJqbKvEr32ixlX/+r+z7v2JTmoCooxvDPBm3kv2uWQ/s+XDVMgxR69QRDYrTyc1nTyqlNJ+fNVxfm2bDKw==",
"requires": {
"fs": "0.0.1-security",
"git-describe": "^4.0.4",
+1 -1
View File
@@ -42,7 +42,7 @@
"spawn-sync": "^2.0.0",
"sqlite3": "^4.1.0",
"trash": "^6.0.0",
"upgiter": "^1.0.1",
"upgiter": "^1.0.4",
"uuid": "^3.3.2"
},
"devDependencies": {
+60 -8
View File
@@ -1,10 +1,9 @@
'use strict'
import { getLogger } from 'frontblock-generic/Types';
import { ConfigLoader } from 'loadson';
import { promises as fs } from "fs"
import { promises as fs, mkdirSync } from "fs"
import { RPCServer } from 'rpclibrary/js/src/Backend'
import { AdminConf } from './Types';
import { AdminConf, TableDefiniton } from './Types';
import { RPCConfigLoader } from './RPCConfigLoader';
import * as Path from 'path'
@@ -12,20 +11,47 @@ import * as Path from 'path'
import Knex = require('knex');
import http = require('http');
import express = require('express');
import { TableDefinitionExporter } from './Interfaces';
import { FrontworkEventBus } from './Eventbus';
import { Plugin } from './Plugin';
const logger = getLogger("admin", 'debug')
export class FrontworkAdmin {
export class FrontworkAdmin
implements TableDefinitionExporter {
private express
private httpServer
private config: RPCConfigLoader<AdminConf>
private eventBus:FrontworkEventBus = new FrontworkEventBus(this)
private plugins: Plugin[] = []
config: RPCConfigLoader<AdminConf>
knex:Knex
constructor(){
this.eventBus = new FrontworkEventBus(this)
}
async start(){
this.initConfig()
await this.makeKnex()
this.startWebsocket()
this.startWebserver()
}
protected configChangeHandler = (conf:AdminConf, key?:string) => {
if(key === 'dbConf'){
this.makeKnex()
}
}
getConfigKey(key:string){
return this.config.getConfigKey(key)
}
setConfigKey(key:string, value:any){
return this.config.setConfigKey(key, value)
}
private initConfig(){
this.config = new RPCConfigLoader<AdminConf>({
name: "FrontworkAdminConf",
@@ -42,13 +68,13 @@ export class FrontworkAdmin {
}
}
}
}, './config', console.log)
}, './config', this.configChangeHandler)
}
private startWebsocket(){
console.log()
new RPCServer(20000, [
this.config
this.config,
...this.plugins
])
}
@@ -108,6 +134,32 @@ export class FrontworkAdmin {
logger.info("Webserver stopped")
}
protected async makeKnex():Promise<Knex>{
const conf:Knex.Config = this.config.getConfigKey("dbConf")
logger.debug("Making new knex:", conf)
if(conf.client === 'sqlite3'){
mkdirSync(Path.dirname((<any>conf.connection).filename), {recursive: true})
}
this.knex = Knex(conf)
await Promise.all(this.getTableDefinitions().map(async (def)=>{
const hasTable = await this.knex.schema.hasTable(def.name)
if(!hasTable){
await this.knex.schema.createTable(def.name, def.tableBuilder)
}
}))
return this.knex
}
getTableDefinitions(): TableDefiniton[]{
return [
this.eventBus,
...this.plugins
].flatMap(exporter => exporter.getTableDefinitions())
}
}
process.on( 'SIGINT', function() {
+60
View File
@@ -0,0 +1,60 @@
import { RPCExporter } from "rpclibrary/js/src/Interfaces";
import { SubscriptionResponse, ErrorResponse } from "rpclibrary/js/src/Types";
import { makeSubResponse } from "rpclibrary/js/src/Utils";
import { FrontworkAdmin } from "./Admin";
import { TableDefinitionExporter } from "./Interfaces";
export type NotificationSeverity = 'Info' | 'Important' | 'Error'
export type Notification = {
ID?:number,
severity: NotificationSeverity,
topic: string,
message:string,
time?: number
}
export type EventbusIfc = {
Eventbus: {
getNotificationLog: () => Promise<Notification[]>
pushNotification: (notification:Notification) => Promise<void>
subscribeNotifications: (callback:Function) => Promise<SubscriptionResponse | ErrorResponse>
}
}
export class FrontworkEventBus
implements RPCExporter<EventbusIfc, "Eventbus">, TableDefinitionExporter {
name = "Eventbus" as "Eventbus"
constructor(private admin: FrontworkAdmin){
this.admin
}
exportRPCs(){
return [{
name: 'getNotificationLog' as 'getNotificationLog',
call: async () => []
},{
name: 'pushNotification' as 'pushNotification',
call: async () => {}
},{
name: 'subscribeNotificaitons' as 'subscribeNotifications',
hook: async (callback: Function) => {
return makeSubResponse({})
}
}]
}
getTableDefinitions(){
return [{
name: 'notifications',
tableBuilder: (table) => {
table.increments('ID');
table.string('severity');
table.string('topic');
table.string('message');
table.timestamp('time');
}
}]
}
}
+5
View File
@@ -0,0 +1,5 @@
import { TableDefiniton } from "./Types";
export interface TableDefinitionExporter{
getTableDefinitions(): TableDefiniton[]
}
+22
View File
@@ -0,0 +1,22 @@
import { FrontworkAdmin } from "./Admin"
import { RPC } from "rpclibrary/js/src/Types"
import { TableDefiniton } from "./Types"
import { RPCExporter } from "rpclibrary/js/src/Interfaces"
import { TableDefinitionExporter } from "./Interfaces"
import { ConfigExporter } from "loadson"
export abstract class Plugin<ConfType = {}>
implements ConfigExporter<ConfType>, RPCExporter<any,any,any>, TableDefinitionExporter{
constructor (protected admin: FrontworkAdmin, public name:string){
if(!this.getConfig()){
this.setConfig(this.getDefaultConfig())
}
}
public setConfig = (conf:ConfType) => this.admin.setConfigKey(this.name, conf)
public getConfig = () => this.admin.getConfigKey(this.name)
abstract getTableDefinitions(): TableDefiniton[]
abstract getDefaultConfig(): ConfType
abstract exportRPCs(): RPC<any,any>[]
}
+19
View File
@@ -0,0 +1,19 @@
import { RPCExporter } from "rpclibrary/js/src/Interfaces";
import { Git, Types } from "upgiter"
export type GitUpdaterIfc = {
cloneRepo: (force:boolean) => Promise<Types.FolderStatus>
getStatus: () => Promise<Types.FolderStatus>
checkoutTag: (tag:string) => Promise<Types.FolderStatus>
isOutdated: () => Promise<boolean>
}
class RPCUpgiter
extends Git.Updater
implements RPCExporter<any, "PluginLoader">{
name = "PluginLoader" as "PluginLoader";
exportRPCs(){
return []
}
}
+5
View File
@@ -7,3 +7,8 @@ export type AdminConf = {
dbConf:Knex.Config,
eventBusConf: { [topic in string]: NotificationSeverity}
}
export type TableDefiniton = {
name: string,
tableBuilder: (table: Knex.CreateTableBuilder) => void
}