before adding plugin logic
This commit is contained in:
Generated
+3
-3
@@ -5763,9 +5763,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"upgiter": {
|
"upgiter": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/upgiter/-/upgiter-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/upgiter/-/upgiter-1.0.4.tgz",
|
||||||
"integrity": "sha512-HHWZ4/SWXVXC80fnNW/E1gsNT8D5mlAG6i2JcGG9akr5Q+sDrt+NPbaeMuLMSJJY6LI0CiIbzE59duWEQQINJg==",
|
"integrity": "sha512-+6McoJqbKvEr32ixlX/+r+z7v2JTmoCooxvDPBm3kv2uWQ/s+XDVMgxR69QRDYrTyc1nTyqlNJ+fNVxfm2bDKw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"fs": "0.0.1-security",
|
"fs": "0.0.1-security",
|
||||||
"git-describe": "^4.0.4",
|
"git-describe": "^4.0.4",
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@
|
|||||||
"spawn-sync": "^2.0.0",
|
"spawn-sync": "^2.0.0",
|
||||||
"sqlite3": "^4.1.0",
|
"sqlite3": "^4.1.0",
|
||||||
"trash": "^6.0.0",
|
"trash": "^6.0.0",
|
||||||
"upgiter": "^1.0.1",
|
"upgiter": "^1.0.4",
|
||||||
"uuid": "^3.3.2"
|
"uuid": "^3.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
+60
-8
@@ -1,10 +1,9 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
import { getLogger } from 'frontblock-generic/Types';
|
import { getLogger } from 'frontblock-generic/Types';
|
||||||
import { ConfigLoader } from 'loadson';
|
import { promises as fs, mkdirSync } from "fs"
|
||||||
import { promises as fs } from "fs"
|
|
||||||
import { RPCServer } from 'rpclibrary/js/src/Backend'
|
import { RPCServer } from 'rpclibrary/js/src/Backend'
|
||||||
import { AdminConf } from './Types';
|
import { AdminConf, TableDefiniton } from './Types';
|
||||||
import { RPCConfigLoader } from './RPCConfigLoader';
|
import { RPCConfigLoader } from './RPCConfigLoader';
|
||||||
|
|
||||||
import * as Path from 'path'
|
import * as Path from 'path'
|
||||||
@@ -12,20 +11,47 @@ import * as Path from 'path'
|
|||||||
import Knex = require('knex');
|
import Knex = require('knex');
|
||||||
import http = require('http');
|
import http = require('http');
|
||||||
import express = require('express');
|
import express = require('express');
|
||||||
|
import { TableDefinitionExporter } from './Interfaces';
|
||||||
|
import { FrontworkEventBus } from './Eventbus';
|
||||||
|
import { Plugin } from './Plugin';
|
||||||
|
|
||||||
const logger = getLogger("admin", 'debug')
|
const logger = getLogger("admin", 'debug')
|
||||||
|
|
||||||
export class FrontworkAdmin {
|
export class FrontworkAdmin
|
||||||
|
implements TableDefinitionExporter {
|
||||||
|
|
||||||
private express
|
private express
|
||||||
private httpServer
|
private httpServer
|
||||||
private config: RPCConfigLoader<AdminConf>
|
private eventBus:FrontworkEventBus = new FrontworkEventBus(this)
|
||||||
|
private plugins: Plugin[] = []
|
||||||
|
config: RPCConfigLoader<AdminConf>
|
||||||
|
knex:Knex
|
||||||
|
|
||||||
constructor(){
|
constructor(){
|
||||||
|
this.eventBus = new FrontworkEventBus(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
async start(){
|
||||||
this.initConfig()
|
this.initConfig()
|
||||||
|
await this.makeKnex()
|
||||||
this.startWebsocket()
|
this.startWebsocket()
|
||||||
this.startWebserver()
|
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(){
|
private initConfig(){
|
||||||
this.config = new RPCConfigLoader<AdminConf>({
|
this.config = new RPCConfigLoader<AdminConf>({
|
||||||
name: "FrontworkAdminConf",
|
name: "FrontworkAdminConf",
|
||||||
@@ -42,13 +68,13 @@ export class FrontworkAdmin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, './config', console.log)
|
}, './config', this.configChangeHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
private startWebsocket(){
|
private startWebsocket(){
|
||||||
console.log()
|
|
||||||
new RPCServer(20000, [
|
new RPCServer(20000, [
|
||||||
this.config
|
this.config,
|
||||||
|
...this.plugins
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +134,32 @@ export class FrontworkAdmin {
|
|||||||
logger.info("Webserver stopped")
|
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() {
|
process.on( 'SIGINT', function() {
|
||||||
|
|||||||
@@ -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');
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { TableDefiniton } from "./Types";
|
||||||
|
|
||||||
|
export interface TableDefinitionExporter{
|
||||||
|
getTableDefinitions(): TableDefiniton[]
|
||||||
|
}
|
||||||
@@ -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>[]
|
||||||
|
}
|
||||||
@@ -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 []
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,3 +7,8 @@ export type AdminConf = {
|
|||||||
dbConf:Knex.Config,
|
dbConf:Knex.Config,
|
||||||
eventBusConf: { [topic in string]: NotificationSeverity}
|
eventBusConf: { [topic in string]: NotificationSeverity}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TableDefiniton = {
|
||||||
|
name: string,
|
||||||
|
tableBuilder: (table: Knex.CreateTableBuilder) => void
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user