浏览代码

before adding plugin logic

master
peter 6 年前
父节点
当前提交
0857f1ec25
共有 8 个文件被更改,包括 175 次插入12 次删除
  1. 3
    3
      package-lock.json
  2. 1
    1
      package.json
  3. 60
    8
      src/backend/Admin.ts
  4. 60
    0
      src/backend/Eventbus.ts
  5. 5
    0
      src/backend/Interfaces.ts
  6. 22
    0
      src/backend/Plugin.ts
  7. 19
    0
      src/backend/PluginLoader.ts
  8. 5
    0
      src/backend/Types.ts

+ 3
- 3
package-lock.json 查看文件

@@ -5763,9 +5763,9 @@
5763 5763
       "dev": true
5764 5764
     },
5765 5765
     "upgiter": {
5766
-      "version": "1.0.1",
5767
-      "resolved": "https://registry.npmjs.org/upgiter/-/upgiter-1.0.1.tgz",
5768
-      "integrity": "sha512-HHWZ4/SWXVXC80fnNW/E1gsNT8D5mlAG6i2JcGG9akr5Q+sDrt+NPbaeMuLMSJJY6LI0CiIbzE59duWEQQINJg==",
5766
+      "version": "1.0.4",
5767
+      "resolved": "https://registry.npmjs.org/upgiter/-/upgiter-1.0.4.tgz",
5768
+      "integrity": "sha512-+6McoJqbKvEr32ixlX/+r+z7v2JTmoCooxvDPBm3kv2uWQ/s+XDVMgxR69QRDYrTyc1nTyqlNJ+fNVxfm2bDKw==",
5769 5769
       "requires": {
5770 5770
         "fs": "0.0.1-security",
5771 5771
         "git-describe": "^4.0.4",

+ 1
- 1
package.json 查看文件

@@ -42,7 +42,7 @@
42 42
     "spawn-sync": "^2.0.0",
43 43
     "sqlite3": "^4.1.0",
44 44
     "trash": "^6.0.0",
45
-    "upgiter": "^1.0.1",
45
+    "upgiter": "^1.0.4",
46 46
     "uuid": "^3.3.2"
47 47
   },
48 48
   "devDependencies": {

+ 60
- 8
src/backend/Admin.ts 查看文件

@@ -1,10 +1,9 @@
1 1
 'use strict'
2 2
 
3 3
 import { getLogger } from 'frontblock-generic/Types';
4
-import { ConfigLoader } from 'loadson';
5
-import { promises as fs } from "fs"
4
+import { promises as fs, mkdirSync } from "fs"
6 5
 import { RPCServer } from 'rpclibrary/js/src/Backend'
7
-import { AdminConf } from './Types';
6
+import { AdminConf, TableDefiniton } from './Types';
8 7
 import { RPCConfigLoader } from './RPCConfigLoader';
9 8
 
10 9
 import * as Path from 'path'
@@ -12,20 +11,47 @@ import * as Path from 'path'
12 11
 import Knex = require('knex');
13 12
 import http = require('http');
14 13
 import express = require('express');
14
+import { TableDefinitionExporter } from './Interfaces';
15
+import { FrontworkEventBus } from './Eventbus';
16
+import { Plugin } from './Plugin';
15 17
 
16 18
 const logger = getLogger("admin", 'debug') 
17 19
 
18
-export class FrontworkAdmin {
20
+export class FrontworkAdmin 
21
+implements TableDefinitionExporter {
22
+
19 23
     private express
20 24
     private httpServer
21
-    private config: RPCConfigLoader<AdminConf>
25
+    private eventBus:FrontworkEventBus = new FrontworkEventBus(this)
26
+    private plugins: Plugin[] = []
27
+    config: RPCConfigLoader<AdminConf>
28
+    knex:Knex
22 29
 
23 30
     constructor(){
31
+        this.eventBus = new FrontworkEventBus(this)
32
+    }
33
+
34
+    async start(){
24 35
         this.initConfig()
36
+        await this.makeKnex()
25 37
         this.startWebsocket()
26 38
         this.startWebserver()
27 39
     }
28 40
 
41
+    protected configChangeHandler = (conf:AdminConf, key?:string) => {
42
+        if(key === 'dbConf'){
43
+            this.makeKnex()
44
+        }
45
+    }
46
+
47
+    getConfigKey(key:string){
48
+        return this.config.getConfigKey(key)
49
+    }
50
+
51
+    setConfigKey(key:string, value:any){
52
+        return this.config.setConfigKey(key, value)
53
+    }
54
+
29 55
     private initConfig(){
30 56
         this.config = new RPCConfigLoader<AdminConf>({
31 57
             name: "FrontworkAdminConf", 
@@ -42,13 +68,13 @@ export class FrontworkAdmin {
42 68
                     }
43 69
                 }   
44 70
             }
45
-        }, './config', console.log) 
71
+        }, './config', this.configChangeHandler) 
46 72
     }
47 73
 
48 74
     private startWebsocket(){
49
-        console.log()
50 75
         new RPCServer(20000, [
51
-            this.config
76
+            this.config,
77
+            ...this.plugins
52 78
         ])
53 79
     }
54 80
 
@@ -108,6 +134,32 @@ export class FrontworkAdmin {
108 134
         logger.info("Webserver stopped")
109 135
     }
110 136
 
137
+    protected async makeKnex():Promise<Knex>{
138
+        const conf:Knex.Config = this.config.getConfigKey("dbConf")
139
+
140
+        logger.debug("Making new knex:", conf)        
141
+        if(conf.client === 'sqlite3'){
142
+            mkdirSync(Path.dirname((<any>conf.connection).filename), {recursive: true})
143
+        }
144
+
145
+        this.knex = Knex(conf)
146
+    
147
+        await Promise.all(this.getTableDefinitions().map(async (def)=>{
148
+            const hasTable = await this.knex.schema.hasTable(def.name)
149
+            if(!hasTable){
150
+                await this.knex.schema.createTable(def.name, def.tableBuilder)
151
+            }
152
+        }))
153
+        
154
+        return this.knex
155
+    }
156
+
157
+    getTableDefinitions(): TableDefiniton[]{
158
+        return [
159
+            this.eventBus,
160
+            ...this.plugins
161
+        ].flatMap(exporter => exporter.getTableDefinitions())
162
+    }
111 163
 }
112 164
 
113 165
 process.on( 'SIGINT', function() {

+ 60
- 0
src/backend/Eventbus.ts 查看文件

@@ -0,0 +1,60 @@
1
+import { RPCExporter } from "rpclibrary/js/src/Interfaces";
2
+import { SubscriptionResponse, ErrorResponse } from "rpclibrary/js/src/Types";
3
+import { makeSubResponse } from "rpclibrary/js/src/Utils";
4
+import { FrontworkAdmin } from "./Admin";
5
+import { TableDefinitionExporter } from "./Interfaces";
6
+
7
+export type NotificationSeverity = 'Info' | 'Important' | 'Error'
8
+
9
+export type Notification = { 
10
+    ID?:number, 
11
+    severity: NotificationSeverity, 
12
+    topic: string,
13
+    message:string,
14
+    time?: number
15
+}
16
+
17
+export type EventbusIfc = {
18
+    Eventbus: {
19
+        getNotificationLog: () => Promise<Notification[]>
20
+        pushNotification: (notification:Notification) => Promise<void>
21
+        subscribeNotifications: (callback:Function) => Promise<SubscriptionResponse | ErrorResponse>
22
+    }
23
+} 
24
+
25
+export class FrontworkEventBus 
26
+implements RPCExporter<EventbusIfc, "Eventbus">, TableDefinitionExporter {
27
+    name = "Eventbus" as "Eventbus" 
28
+    
29
+    constructor(private admin: FrontworkAdmin){
30
+        this.admin
31
+    }
32
+
33
+    exportRPCs(){
34
+        return [{
35
+            name: 'getNotificationLog' as 'getNotificationLog',
36
+            call: async () => []
37
+        },{
38
+            name: 'pushNotification' as 'pushNotification',
39
+            call: async () => {}
40
+        },{
41
+            name: 'subscribeNotificaitons' as 'subscribeNotifications',
42
+            hook: async (callback: Function) => {
43
+                return makeSubResponse({})
44
+            }
45
+        }]
46
+    }
47
+
48
+    getTableDefinitions(){
49
+        return [{
50
+            name: 'notifications',
51
+            tableBuilder: (table) => {
52
+                table.increments('ID');
53
+                table.string('severity');
54
+                table.string('topic');
55
+                table.string('message');
56
+                table.timestamp('time');
57
+            }
58
+        }]
59
+    }
60
+}

+ 5
- 0
src/backend/Interfaces.ts 查看文件

@@ -0,0 +1,5 @@
1
+import { TableDefiniton } from "./Types";
2
+
3
+export interface TableDefinitionExporter{
4
+    getTableDefinitions(): TableDefiniton[]
5
+}

+ 22
- 0
src/backend/Plugin.ts 查看文件

@@ -0,0 +1,22 @@
1
+import { FrontworkAdmin } from "./Admin"
2
+import { RPC } from "rpclibrary/js/src/Types"
3
+import { TableDefiniton } from "./Types"
4
+import { RPCExporter } from "rpclibrary/js/src/Interfaces"
5
+import { TableDefinitionExporter } from "./Interfaces"
6
+import { ConfigExporter } from "loadson"
7
+
8
+export abstract class Plugin<ConfType = {}> 
9
+implements ConfigExporter<ConfType>, RPCExporter<any,any,any>, TableDefinitionExporter{
10
+    
11
+    constructor (protected admin: FrontworkAdmin, public name:string){
12
+        if(!this.getConfig()){
13
+            this.setConfig(this.getDefaultConfig())
14
+        }
15
+    }
16
+    public setConfig = (conf:ConfType) => this.admin.setConfigKey(this.name, conf) 
17
+    public getConfig = () => this.admin.getConfigKey(this.name) 
18
+
19
+    abstract getTableDefinitions(): TableDefiniton[]
20
+    abstract getDefaultConfig(): ConfType
21
+    abstract exportRPCs(): RPC<any,any>[]
22
+}

+ 19
- 0
src/backend/PluginLoader.ts 查看文件

@@ -0,0 +1,19 @@
1
+import { RPCExporter } from "rpclibrary/js/src/Interfaces";
2
+import { Git, Types } from "upgiter"
3
+
4
+export type GitUpdaterIfc = {
5
+    cloneRepo: (force:boolean) => Promise<Types.FolderStatus>
6
+    getStatus: () => Promise<Types.FolderStatus>
7
+    checkoutTag: (tag:string) => Promise<Types.FolderStatus>
8
+    isOutdated: () => Promise<boolean> 
9
+}
10
+
11
+class RPCUpgiter
12
+extends Git.Updater
13
+implements RPCExporter<any, "PluginLoader">{
14
+    name = "PluginLoader" as "PluginLoader";
15
+
16
+    exportRPCs(){
17
+        return []
18
+    }
19
+}

+ 5
- 0
src/backend/Types.ts 查看文件

@@ -6,4 +6,9 @@ export type AdminConf = {
6 6
     httpPort: number,
7 7
     dbConf:Knex.Config, 
8 8
     eventBusConf: { [topic in string]: NotificationSeverity}
9
+}
10
+
11
+export type TableDefiniton = {
12
+    name: string, 
13
+    tableBuilder: (table: Knex.CreateTableBuilder) => void
9 14
 }

正在加载...
取消
保存