fix subscribe+sesame
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "rpclibrary",
|
"name": "rpclibrary",
|
||||||
"version": "1.5.1",
|
"version": "1.5.2",
|
||||||
"description": "rpclibrary is a websocket on steroids!",
|
"description": "rpclibrary is a websocket on steroids!",
|
||||||
"main": "./js/Index.js",
|
"main": "./js/Index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ export class RPCServer<
|
|||||||
if(!conf.visibility) this.visibility = "127.0.0.1"
|
if(!conf.visibility) this.visibility = "127.0.0.1"
|
||||||
|
|
||||||
if(conf.sesame){
|
if(conf.sesame){
|
||||||
console.log("Setting Sesame")
|
|
||||||
this.sesame = U.makeSesameFunction(conf.sesame)
|
this.sesame = U.makeSesameFunction(conf.sesame)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-5
@@ -106,7 +106,7 @@ export class RPCSocket implements I.Socket{
|
|||||||
f = this.callGenerator(i.uniqueName, i.argNames, sesame)
|
f = this.callGenerator(i.uniqueName, i.argNames, sesame)
|
||||||
break
|
break
|
||||||
case 'Hook':
|
case 'Hook':
|
||||||
f = this.hookGenerator(i.uniqueName, i.argNames, sesame)
|
f = this.frontEndHookGenerator(i.uniqueName, i.argNames, sesame)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if(this[i.owner] == null)
|
if(this[i.owner] == null)
|
||||||
@@ -143,21 +143,28 @@ export class RPCSocket implements I.Socket{
|
|||||||
* @param fnName The function name
|
* @param fnName The function name
|
||||||
* @param fnArgs A string-list of parameters
|
* @param fnArgs A string-list of parameters
|
||||||
*/
|
*/
|
||||||
private hookGenerator(fnName: string, fnArgs:string[], sesame?:string): T.HookFunction{
|
private frontEndHookGenerator(fnName: string, fnArgs:string[], sesame?:string): T.HookFunction{
|
||||||
|
fnArgs.pop()
|
||||||
const headerArgs = fnArgs.join(",")
|
const headerArgs = fnArgs.join(",")
|
||||||
const argParams = fnArgs.map(stripAfterEquals).join(",")
|
const argParams = fnArgs.map(stripAfterEquals).join(",")
|
||||||
|
|
||||||
if(!sesame){
|
if(!sesame){
|
||||||
return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
|
const headerArgs = fnArgs.join(",")
|
||||||
|
const argParams = fnArgs.map(stripAfterEquals).join(",")
|
||||||
|
|
||||||
|
const f = eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
|
||||||
const r = await this.socket.call("`+fnName+`", `+argParams+`)
|
const r = await this.socket.call("`+fnName+`", `+argParams+`)
|
||||||
if(r.result === 'Success'){
|
if(r && r.result === 'Success'){
|
||||||
this.socket.hook(r.uuid, callback)
|
this.socket.hook(r.uuid, callback)
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
} )()` )
|
} )()` )
|
||||||
|
return f
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
|
return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
|
||||||
const r = await this.socket.call("`+fnName+`", "`+sesame+`", `+argParams+`)
|
const r = await this.socket.call("`+fnName+`", "`+sesame+`", `+argParams+`)
|
||||||
if(r.result === 'Success'){
|
if(r && r.result === 'Success'){
|
||||||
this.socket.hook(r.uuid, callback)
|
this.socket.hook(r.uuid, callback)
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
|
|||||||
+20
-18
@@ -82,37 +82,38 @@ export function rpcHooker<SubResT = {}>(socket: I.Socket, exporter:I.RPCExporter
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Utility function to generate {@link HookFunction} from a RPC
|
* Utility function to generate {@link HookFunction} from a RPC for backend
|
||||||
* @param rpc The RPC to transform
|
* @param rpc The RPC to transform
|
||||||
* @returns A {@link HookFunction}
|
* @returns A {@link HookFunction}
|
||||||
*/
|
*/
|
||||||
const hookGenerator = (rpc:T.HookRPC<any, any, any>, sesame?:T.SesameFunction): T.HookInfo['generator'] => {
|
const hookGenerator = (rpc:T.HookRPC<any, any, any>, sesameFn?: T.SesameFunction): T.HookInfo['generator'] => {
|
||||||
const argsArr = extractArgs(rpc.hook)
|
const argsArr = extractArgs(rpc.hook)
|
||||||
if(sesame){
|
|
||||||
const _sesame = argsArr.shift()
|
|
||||||
if(!sesame(_sesame!)){
|
|
||||||
throw new Error('Bad sesame')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
argsArr.pop() //remove 'callback' from the end
|
argsArr.pop() //remove 'callback' from the end
|
||||||
const args = argsArr.join(',')
|
const argsStr = argsArr.join(',')
|
||||||
|
|
||||||
return eval(`(socket) => async (`+args+`) => {
|
if(sesameFn){
|
||||||
|
const args = ['sesame', ...argsArr].join(',')
|
||||||
|
const f = eval(`(socket) => async (`+args+`) => {
|
||||||
|
if(!sesameFn(sesame)) return
|
||||||
|
const res = await rpc.hook(`+argsStr+(argsStr.length!==0?',':'')+` (...cbargs) => {
|
||||||
|
if(rpc.onCallback) rpc.onCallback.apply({}, cbargs)
|
||||||
|
socket.call.apply(socket, [res.uuid, ...cbargs])
|
||||||
|
})
|
||||||
|
return res
|
||||||
|
}`)
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
const args = argsArr.join(',')
|
||||||
|
return eval(`(socket) => async (`+args+`) => {
|
||||||
const res = await rpc.hook(`+args+(args.length!==0?',':'')+` (...cbargs) => {
|
const res = await rpc.hook(`+args+(args.length!==0?',':'')+` (...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])
|
||||||
})
|
})
|
||||||
if(res.result === 'Success'){
|
|
||||||
if(rpc.onClose){
|
|
||||||
socket.on('close', async () => {
|
|
||||||
rpc.onClose(res, rpc)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res
|
return res
|
||||||
}`)
|
}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract a string list of parameters from a function
|
* Extract a string list of parameters from a function
|
||||||
* @param f The source function
|
* @param f The source function
|
||||||
@@ -134,6 +135,7 @@ export function makeSubResponse<T extends {} = {}>(extension:T):SubscriptionResp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function makeSesameFunction (sesame : T.SesameFunction | string) : T.SesameFunction {
|
export function makeSesameFunction (sesame : T.SesameFunction | string) : T.SesameFunction {
|
||||||
if(typeof sesame === 'function'){
|
if(typeof sesame === 'function'){
|
||||||
return sesame
|
return sesame
|
||||||
@@ -142,4 +144,4 @@ export function makeSesameFunction (sesame : T.SesameFunction | string) : T.Sesa
|
|||||||
return (testSesame : string) => {
|
return (testSesame : string) => {
|
||||||
return testSesame === sesame
|
return testSesame === sesame
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+57
-8
@@ -1,4 +1,4 @@
|
|||||||
import { describe, it } from "mocha";
|
import { describe, it, Func } from "mocha";
|
||||||
|
|
||||||
import { RPCServer, RPCSocket, SubscriptionResponse, makeSubResponse } from '../Index'
|
import { RPCServer, RPCSocket, SubscriptionResponse, makeSubResponse } from '../Index'
|
||||||
import * as uuidv4 from "uuid/v4"
|
import * as uuidv4 from "uuid/v4"
|
||||||
@@ -226,18 +226,35 @@ describe('It should do unhook', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
type SesameTestIfc = { test: { checkCandy: ()=>Promise<string>} }
|
type SesameTestIfc = {
|
||||||
|
test: {
|
||||||
|
checkCandy: ()=>Promise<string>
|
||||||
|
subscribe: (callback) => Promise<SubscriptionResponse<{ topic: string; }>>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
describe('Sesame should unlock the socket', () => {
|
describe('Sesame should unlock the socket', () => {
|
||||||
let candy = "OK"
|
let candy = "OK"
|
||||||
let client: RPCSocket & SesameTestIfc
|
let client: RPCSocket & SesameTestIfc
|
||||||
let server: RPCServer<{topic: string}, SesameTestIfc>
|
let server: RPCServer
|
||||||
|
let cb = (...args) => {}
|
||||||
|
|
||||||
before(async() => {
|
before(async() => {
|
||||||
server = new RPCServer<{ topic: string }, SesameTestIfc>(20004, [{
|
server = new RPCServer(20004, [{
|
||||||
name: "test",
|
name: "test",
|
||||||
exportRPCs: () => [
|
exportRPCs: () => [
|
||||||
async function checkCandy():Promise<string> { return candy },
|
{
|
||||||
|
name: 'subscribe',
|
||||||
|
hook: async(callback) => {
|
||||||
|
cb = callback
|
||||||
|
return <SubscriptionResponse>{
|
||||||
|
result: "Success",
|
||||||
|
uuid: uuidv4(),
|
||||||
|
topic: 'test'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async function checkCandy():Promise<string> { cb(candy); cb=()=>{}; return candy },
|
||||||
]}
|
]}
|
||||||
],{
|
],{
|
||||||
sesame: (_sesame) => _sesame === 'sesame!'
|
sesame: (_sesame) => _sesame === 'sesame!'
|
||||||
@@ -251,6 +268,10 @@ describe('Sesame should unlock the socket', () => {
|
|||||||
server.destroy()
|
server.destroy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should work with sesame', (done) => {
|
||||||
|
client.test.checkCandy().then(c => done())
|
||||||
|
})
|
||||||
|
|
||||||
it('should not work without sesame', (done) => {
|
it('should not work without sesame', (done) => {
|
||||||
const sock = new RPCSocket(20004, "localhost")
|
const sock = new RPCSocket(20004, "localhost")
|
||||||
sock.connect<SesameTestIfc>( /* no sesame */).then(async (c) => {
|
sock.connect<SesameTestIfc>( /* no sesame */).then(async (c) => {
|
||||||
@@ -264,7 +285,35 @@ describe('Sesame should unlock the socket', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should work with sesame', (done) => {
|
it('callback should work with sesame', (done) => {
|
||||||
client.test.checkCandy().then(c => done())
|
client.test.subscribe((c) => {
|
||||||
|
if(c === candy){
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
}).then(d => {
|
||||||
|
if(d.result !== 'Success')
|
||||||
|
done('expected valid response')
|
||||||
|
|
||||||
|
client.test.checkCandy()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
|
||||||
|
it('callback should not work without sesame', (done) => {
|
||||||
|
const sock = new RPCSocket(20004, "localhost")
|
||||||
|
sock.connect<SesameTestIfc>( /* no sesame */).then(async (c) => {
|
||||||
|
c.test.subscribe((c) => {
|
||||||
|
console.log("CALLBACK TRIGGERED UNEXPECTED");
|
||||||
|
|
||||||
|
if(c === candy)
|
||||||
|
done("super not")
|
||||||
|
}).then(async d => {
|
||||||
|
await client.test.checkCandy()
|
||||||
|
if(d == null){
|
||||||
|
done()
|
||||||
|
}else
|
||||||
|
done('unexpected valid response '+(d) )
|
||||||
|
c.destroy()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user