109 lines
4.0 KiB
TypeScript
109 lines
4.0 KiB
TypeScript
import { parseSubResponse, parseResponse } from "frontblock-generic/Types";
|
|
import { ExtendedRpcInfo, UnhookFunction, callbackFunction, AsyncFunction } from "frontblock-generic/RPC";
|
|
var bsock = require('bsock')
|
|
|
|
//fix args with defaults like "force = true" -> "force"
|
|
function stripAfterEquals(str:string){
|
|
return str.split("=")[0]
|
|
}
|
|
|
|
/**
|
|
* Dynamic library to communicate with FrontblockService remotely
|
|
*
|
|
* This will be automatically injected into the webpages served by FrontblockService
|
|
* Will ask it's service for available RPCs and parse them into methods of this object
|
|
* for convenient access.
|
|
*/
|
|
export class FrontblockConfigLib{
|
|
private socket
|
|
|
|
constructor(){
|
|
this.socket = bsock.connect(20000, 'localhost', false/*tls*/)
|
|
this.init()
|
|
}
|
|
|
|
// need this-context for eval-magic below
|
|
// DO NOT REMOVE. They're not really unused
|
|
private parseSubResponse = parseSubResponse
|
|
private parseResponse = parseResponse
|
|
|
|
private async init(){
|
|
const info:ExtendedRpcInfo[] = await this.info()
|
|
info.forEach(i => {
|
|
let f: any
|
|
switch (i.type) {
|
|
case 'call':
|
|
f = this.callGenerator(i.uniqueName, i.argNames)
|
|
break
|
|
case 'hook':
|
|
f = this.hookGenerator(i.uniqueName, i.argNames)
|
|
break
|
|
case 'unhook':
|
|
f = this.unhookGenerator(i.uniqueName, i.argNames)
|
|
break
|
|
}
|
|
if(this[i.owner] == null)
|
|
this[i.owner] = {}
|
|
this[i.owner][i.name] = f
|
|
this[i.owner][i.name].bind(this)
|
|
})
|
|
}
|
|
|
|
async info(){
|
|
return await this.socket.call('info')
|
|
}
|
|
|
|
private callGenerator(fnName, fnArgs:string[]): AsyncFunction{
|
|
const headerArgs = fnArgs.join(",")
|
|
const argParams = fnArgs.map(stripAfterEquals).join(",")
|
|
return eval( '( () => async ('+headerArgs+') => { return await this.socket.call("'+fnName+'", '+argParams+')} )()' )
|
|
}
|
|
|
|
private hookGenerator(fnName, fnArgs:string[]): callbackFunction{
|
|
const headerArgs = fnArgs.join(",")
|
|
const argParams = fnArgs.map(stripAfterEquals).join(",")
|
|
return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
|
|
const r = await this.socket.call("`+fnName+`", `+argParams+`)
|
|
const res = await this.parseSubResponse(r);
|
|
if(res.uid != null){
|
|
this.socket.hook(res.uid, callback)
|
|
}
|
|
return res
|
|
} )()` )
|
|
}
|
|
|
|
private unhookGenerator(fnName, fnArgs:string[]): UnhookFunction{
|
|
const headerArgs = fnArgs.join(",")
|
|
const argParams = fnArgs.map(stripAfterEquals).join(",")
|
|
if(fnArgs.length != 1)
|
|
console.error("UnhookFunction", fnName, "specified more than one argument: ("+headerArgs+")")
|
|
|
|
return eval( `( () => async (`+headerArgs+`) => {
|
|
const r = await this.socket.call("`+fnName+`", `+argParams+`)
|
|
const res = await this.parseResponse(r)
|
|
this.socket.unhook(`+argParams+`)
|
|
return res
|
|
} )()` )
|
|
}
|
|
|
|
}
|
|
|
|
window['fb'] = new FrontblockConfigLib()
|
|
declare const fb:{Admin:any}
|
|
window['setup'] = async() => {
|
|
const i = await Promise.all([
|
|
fb.Admin.installPlugin("ApiClient"),
|
|
fb.Admin.installPlugin("HtmlSupplier"),
|
|
fb.Admin.installPlugin("PaymentManager"),
|
|
fb.Admin.installPlugin("Wallet"),
|
|
])
|
|
console.log(i)
|
|
const s = await Promise.all([
|
|
fb.Admin.startPlugin("ApiClient"),
|
|
fb.Admin.startPlugin("HtmlSupplier"),
|
|
fb.Admin.startPlugin("PaymentManager"),
|
|
fb.Admin.startPlugin("Wallet"),
|
|
])
|
|
if(s.reduce((p,c) => p && c), true)
|
|
location.reload();
|
|
} |