tempalte strings & bugfixes

This commit is contained in:
2020-01-20 04:21:18 +01:00
parent 98b271758b
commit d36f2053c3
3 changed files with 65 additions and 65 deletions
+17 -24
View File
@@ -4,7 +4,7 @@ import bsock = require('bsock');
import * as T from './Types'; import * as T from './Types';
import * as I from './Interfaces'; import * as I from './Interfaces';
import { stripAfterEquals } from './Utils'; import { stripAfterEquals, appendComma } from './Utils';
@@ -127,10 +127,9 @@ export class RPCSocket implements I.Socket{
private callGenerator(fnName: string, fnArgs:string[], sesame?:string): T.AnyFunction{ private callGenerator(fnName: string, fnArgs:string[], sesame?:string): T.AnyFunction{
const headerArgs = fnArgs.join(",") const headerArgs = fnArgs.join(",")
const argParams = fnArgs.map(stripAfterEquals).join(",") const argParams = fnArgs.map(stripAfterEquals).join(",")
if(!sesame) sesame = appendComma(sesame)
return eval( '( () => async ('+headerArgs+') => { return await this.socket.call("'+fnName+'", '+argParams+')} )()' )
else return eval(`async (${headerArgs}) => { return await this.socket.call("${fnName}", ${sesame} ${argParams})}`)
return eval( '( () => async ('+headerArgs+') => { return await this.socket.call("'+fnName+'", "'+sesame+'", '+argParams+')} )()' )
} }
/** /**
@@ -140,25 +139,19 @@ export class RPCSocket implements I.Socket{
*/ */
private frontEndHookGenerator(fnName: string, fnArgs:string[], sesame?:string): T.HookFunction{ private frontEndHookGenerator(fnName: string, fnArgs:string[], sesame?:string): T.HookFunction{
fnArgs.pop() fnArgs.pop()
const headerArgs = fnArgs.join(",") let headerArgs = fnArgs.join(",")
const argParams = fnArgs.map(stripAfterEquals).join(",") const argParams = fnArgs.map(stripAfterEquals).join(",")
sesame = appendComma(sesame)
headerArgs = appendComma(headerArgs)
if(!sesame){ return eval( `
return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => { async (${headerArgs} callback) => {
const r = await this.socket.call("`+fnName+`", `+argParams+`) const r = await this.socket.call("${fnName}", ${sesame} ${argParams})
if(r && r.result === 'Success'){ if(r && r.result === 'Success'){
this.socket.hook(r.uuid, callback) this.socket.hook(r.uuid, callback)
} this.socket.on('error', e => this.socket.unhook(r.uuid))
return r }
} )()` ) return r
}else{ }`)
return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
const r = await this.socket.call("`+fnName+`", "`+sesame+`", `+argParams+`)
if(r && r.result === 'Success'){
this.socket.hook(r.uuid, callback)
}
return r
} )()` )
}
} }
} }
+23 -26
View File
@@ -10,7 +10,7 @@ import { SubscriptionResponse } from "./Types";
* @param owner The owning RPC group's name * @param owner The owning RPC group's name
* @throws Error on RPC without name property * @throws Error on RPC without name property
*/ */
export const rpcToRpcinfo = <SubResT = {}>(rpc : T.RPC<any, any, SubResT>, owner: string, errorHandler: T.ErrorHandler, sesame?:T.SesameFunction):T.RpcInfo => { export const rpcToRpcinfo = <SubResT = {}>(socket: I.Socket, rpc : T.RPC<any, any, SubResT>, owner: string, errorHandler: T.ErrorHandler, sesame?:T.SesameFunction):T.RpcInfo => {
switch (typeof rpc){ switch (typeof rpc){
case "object": case "object":
if(rpc['call']){ if(rpc['call']){
@@ -19,7 +19,7 @@ export const rpcToRpcinfo = <SubResT = {}>(rpc : T.RPC<any, any, SubResT>, owner
argNames: extractArgs(rpc['call']), argNames: extractArgs(rpc['call']),
type: "Call", type: "Call",
name: rpc.name, name: rpc.name,
call: sesame?async (_sesame, ...args) => {if(sesame(_sesame)) return await rpc['call'].apply({}, args); throw makeError(rpc.name)}:rpc['call'], // check & remove sesame call: sesame?async (_sesame, ...args) => {if(sesame(_sesame)) return await rpc['call'].apply({}, args); socket.destroy()}:rpc['call'], // check & remove sesame
} }
}else{ }else{
const generator = hookGenerator(<T.HookRPC<any, any, any>>rpc, errorHandler, sesame) const generator = hookGenerator(<T.HookRPC<any, any, any>>rpc, errorHandler, sesame)
@@ -37,7 +37,7 @@ RPC did not provide a name.
\nUse 'funtion name(..){ .. }' syntax instead. \nUse 'funtion name(..){ .. }' syntax instead.
\n \n
\n<------------OFFENDING RPC: \n<------------OFFENDING RPC:
\n`+rpc.toString()+` \n${rpc.toString()}
\n>------------OFFENDING RPC`) \n>------------OFFENDING RPC`)
return { return {
owner : owner, owner : owner,
@@ -61,7 +61,7 @@ export function rpcHooker<SubResT = {}>(socket: I.Socket, exporter:I.RPCExporter
const RPCs = [...exporter.exportRPCs()] const RPCs = [...exporter.exportRPCs()]
return RPCs.map(rpc => rpcToRpcinfo(rpc, owner, errorHandler, sesame)) return RPCs.map(rpc => rpcToRpcinfo(socket, rpc, owner, errorHandler, sesame))
.map(info => { .map(info => {
const suffix = makeUnique?"-"+uuidv4().substr(0,4):"" const suffix = makeUnique?"-"+uuidv4().substr(0,4):""
const ret:any = info const ret:any = info
@@ -111,41 +111,33 @@ export function stripAfterEquals(str:string):string{
* @returns A {@link HookFunction} * @returns A {@link HookFunction}
*/ */
const hookGenerator = (rpc:T.HookRPC<any, any, any>, errorHandler: T.ErrorHandler, sesameFn?: T.SesameFunction): T.HookInfo['generator'] => { const hookGenerator = (rpc:T.HookRPC<any, any, any>, errorHandler: T.ErrorHandler, sesameFn?: T.SesameFunction): T.HookInfo['generator'] => {
const argsArr = extractArgs(rpc.hook) let argsArr = extractArgs(rpc.hook)
argsArr.pop() //remove 'callback' from the end argsArr.pop() //remove 'callback' from the end
const argsStr = argsArr.join(',') let callArgs = argsArr.join(',')
if(sesameFn){ const args = sesameFn?(['sesame', ...argsArr].join(','))
const args = ['sesame', ...argsArr].join(',') :callArgs
return eval(`(socket) => async (`+args+`) => {
try{ callArgs = appendComma(callArgs)
if(!sesameFn(sesame)) return
const res = await rpc.hook(`+argsStr+(argsStr.length!==0?',':'')+` (...cbargs) => { //note rpc.hook is the associated RPC, not a socket.hook
if(rpc.onCallback) rpc.onCallback.apply({}, cbargs) return eval(`
socket.call.apply(socket, [res.uuid, ...cbargs]) (socket) => async (${args}) => {
})
return res
}catch(e){
errorHandler(socket)(e, rpc.name, [`+args+`])
}
}`)
}
const args = argsArr.join(',')
return eval(`(socket) => async (`+args+`) => {
try{ try{
const res = await rpc.hook(`+args+(args.length!==0?',':'')+` (...cbargs) => { if(sesameFn && !sesameFn(sesame)) return
const res = await rpc.hook(${callArgs} (...cbargs) => {
if(rpc.onCallback) rpc.onCallback.apply({}, cbargs) if(rpc.onCallback) rpc.onCallback.apply({}, cbargs)
socket.call.apply(socket, [res.uuid, ...cbargs]) socket.call.apply(socket, [res.uuid, ...cbargs])
}) })
return res return res
}catch(e){ }catch(e){
errorHandler(socket)(e, rpc.name, [`+args+`]) errorHandler(socket)(e, ${rpc.name}, [${args}])
} }
}`) }`)
} }
const makeError = (callName: string) => { const makeError = (callName: string) => {
return new Error("Unhandled Promise rejection: Call not found: "+callName+". ; Zone: <root> ; Task: Promise.then ; Value: Error: Call not found: "+callName) return new Error("Call not found: "+callName+". ; Zone: <root> ; Task: Promise.then ; Value: Error: Call not found: "+callName)
} }
/** /**
@@ -179,3 +171,8 @@ export function makeSesameFunction (sesame : T.SesameFunction | string) : T.Sesa
return testSesame === sesame return testSesame === sesame
} }
} }
export function appendComma(s?:string):string{
return s?`'${s}',`:""
}
+25 -15
View File
@@ -48,13 +48,12 @@ function makeServer(){
describe('RPCServer', () => { describe('RPCServer', () => {
let server: RPCServer<{ topic: string }, any> let server: RPCServer<{ topic: string }, any>
before((done) => { before(() => {
server = makeServer() server = makeServer()
done()
}) })
after(async() => { after(() => {
await server.destroy() server.destroy()
}) })
it('should be able to use all kinds of RPC definitions', (done) => { it('should be able to use all kinds of RPC definitions', (done) => {
@@ -239,7 +238,7 @@ describe('Sesame should unlock the socket', () => {
let server: RPCServer let server: RPCServer
let cb = (...args) => {} let cb = (...args) => {}
before(async() => { before((done) => {
server = new RPCServer(21004, [{ server = new RPCServer(21004, [{
name: "test", name: "test",
exportRPCs: () => [ exportRPCs: () => [
@@ -261,7 +260,10 @@ describe('Sesame should unlock the socket', () => {
sesame: (_sesame) => _sesame === 'sesame!' sesame: (_sesame) => _sesame === 'sesame!'
}) })
const sock = new RPCSocket(21004, "localhost") const sock = new RPCSocket(21004, "localhost")
client = await sock.connect<SesameTestIfc>('sesame!') sock.connect<SesameTestIfc>('sesame!').then(cli => {
client = cli
done()
})
}) })
after(() => { after(() => {
@@ -282,13 +284,14 @@ describe('Sesame should unlock the socket', () => {
it('should not work without sesame', (done) => { it('should not work without sesame', (done) => {
const sock = new RPCSocket(21004, "localhost") const sock = new RPCSocket(21004, "localhost")
sock.connect<SesameTestIfc>( /* no sesame */).then(async (c) => { sock.connect<SesameTestIfc>( /* no sesame */).then(async (cli) => {
c.test.checkCandy().then(d => { cli.test.checkCandy().then(d => {
done() done(d)
}).catch(e => { }).catch(e => {
//console.log("EXPECTED CLIENT EXCEPTION", String(e)); //console.log("EXPECTED CLIENT EXCEPTION", String(e));
done() done()
}).finally(() => { }).finally(() => {
cli.destroy()
sock.destroy() sock.destroy()
}) })
}) })
@@ -296,14 +299,15 @@ describe('Sesame should unlock the socket', () => {
it('should fail with wrong sesame', (done) => { it('should fail with wrong sesame', (done) => {
const sock = new RPCSocket(21004, "localhost") const sock = new RPCSocket(21004, "localhost")
sock.connect<SesameTestIfc>('abasd').then(async (c) => { sock.connect<SesameTestIfc>('abasd').then(async (cli) => {
c.test.checkCandy().then(d => { cli.test.checkCandy().then(d => {
done("should not be able to get candy") done("should not be able to get candy")
}).catch(e => { }).catch(e => {
//console.log("EXPECTED CLIENT EXCEPTION", String(e)); //console.log("EXPECTED CLIENT EXCEPTION", String(e));
done() done()
}).finally(() => { }).finally(() => {
sock.destroy() sock.destroy()
cli.destroy()
}) })
}) })
}) })
@@ -323,8 +327,8 @@ describe('Sesame should unlock the socket', () => {
it('callback should not work without sesame', (done) => { it('callback should not work without sesame', (done) => {
const sock = new RPCSocket(21004, "localhost") const sock = new RPCSocket(21004, "localhost")
sock.connect<SesameTestIfc>( /* no sesame */).then(async (c) => { sock.connect<SesameTestIfc>( /* no sesame */).then(async (cli) => {
c.test.subscribe((c) => { cli.test.subscribe((c) => {
console.log("CALLBACK TRIGGERED UNEXPECTED"); console.log("CALLBACK TRIGGERED UNEXPECTED");
if(c === candy) if(c === candy)
@@ -333,16 +337,17 @@ describe('Sesame should unlock the socket', () => {
await client.test.checkCandy() await client.test.checkCandy()
if(d == null){ if(d == null){
done() done()
}else }else
done('unexpected valid response '+(d) ) done('unexpected valid response '+(d) )
c.destroy() }).finally(() => {
sock.destroy()
}) })
}) })
}) })
}) })
describe('Error handling', ()=>{ describe('Error handling', ()=>{
let createUser = async( user: {a:any,b:any}) => { let createUser = async( user: {a:any,b:any}) => {
@@ -374,6 +379,7 @@ describe('Error handling', ()=>{
done() done()
}) })
.finally(() => { .finally(() => {
cli.destroy()
sock.destroy() sock.destroy()
server.destroy() server.destroy()
}) })
@@ -407,6 +413,7 @@ describe('Error handling', ()=>{
done(e) done(e)
}) })
.finally(() => { .finally(() => {
cli.destroy()
sock.destroy() sock.destroy()
server.destroy() server.destroy()
}) })
@@ -414,6 +421,7 @@ describe('Error handling', ()=>{
}) })
}) })
describe("Errorhandler functionality", ()=>{ describe("Errorhandler functionality", ()=>{
let createUser = async( user: {a:any,b:any}) => { let createUser = async( user: {a:any,b:any}) => {
throw new Error("BAD BAD BAD") throw new Error("BAD BAD BAD")
@@ -447,6 +455,7 @@ describe("Errorhandler functionality", ()=>{
done(e) done(e)
}) })
.finally(() => { .finally(() => {
cli.destroy()
sock.destroy() sock.destroy()
server.destroy() server.destroy()
}) })
@@ -484,6 +493,7 @@ describe("Errorhandler functionality", ()=>{
done(e) done(e)
}) })
.finally(() => { .finally(() => {
cli.destroy()
sock.destroy() sock.destroy()
server.destroy() server.destroy()
}) })