@live-change/framework 0.5.6 → 0.5.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +8 -2
- package/lib/App.js +24 -9
- package/lib/processors/autoValidation.js +3 -53
- package/lib/runtime/Action.js +1 -1
- package/lib/runtime/ApiServer.js +25 -11
- package/lib/runtime/LiveDao.js +103 -0
- package/lib/utils/CommandQueue.js +1 -1
- package/lib/utils/validation.js +55 -0
- package/package.json +1 -1
- package/lib/runtime/SessionApiServer.js +0 -54
package/index.js
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
const App = require('./lib/App.js')
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
module.exports = App
|
|
4
|
+
|
|
5
|
+
module.exports.app = () => {
|
|
3
6
|
if(!global.liveChangeFrameworkApp) {
|
|
4
7
|
global.liveChangeFrameworkApp = new App()
|
|
5
8
|
}
|
|
6
9
|
return global.liveChangeFrameworkApp
|
|
7
10
|
}
|
|
8
11
|
|
|
9
|
-
module.exports =
|
|
12
|
+
module.exports.utils = require('./lib/utils.js')
|
|
13
|
+
module.exports.validation = require('./lib/utils/validation.js')
|
|
14
|
+
module.exports.rangeProperties = module.exports.utils.rangeProperties
|
|
15
|
+
|
|
10
16
|
|
|
11
17
|
module.exports.ActionDefinition = require('./lib/definition/ActionDefinition.js')
|
|
12
18
|
module.exports.EventDefinition = require('./lib/definition/EventDefinition.js')
|
package/lib/App.js
CHANGED
|
@@ -9,8 +9,9 @@ const Service = require("./runtime/Service.js")
|
|
|
9
9
|
const profileLog = require("./utils/profileLog.js")
|
|
10
10
|
|
|
11
11
|
const Dao = require("./runtime/Dao.js")
|
|
12
|
+
const SessionDao = require("./runtime/SessionDao.js")
|
|
13
|
+
const LiveDao = require("./runtime/LiveDao.js")
|
|
12
14
|
const ApiServer = require("./runtime/ApiServer.js")
|
|
13
|
-
const SessionApiServer = require("./runtime/SessionApiServer.js")
|
|
14
15
|
|
|
15
16
|
const reverseRelationProcessor = require("./processors/reverseRelation.js")
|
|
16
17
|
const indexListProcessor = require("./processors/indexList.js")
|
|
@@ -73,20 +74,28 @@ class App {
|
|
|
73
74
|
|
|
74
75
|
this.instanceId = randomString(4)
|
|
75
76
|
this.uidGenerator = uidGenerator(this.instanceId)
|
|
77
|
+
|
|
78
|
+
this.activeTimeouts = new Set()
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
createServiceDefinition( definition ) {
|
|
79
|
-
const config = this.config && this.config.services && this.config.services
|
|
82
|
+
const config = this.config && this.config.services && this.config.services.find
|
|
83
|
+
&& this.config.services.find(c => c.name == definition.name)
|
|
80
84
|
return new ServiceDefinition({ ...definition, config })
|
|
81
85
|
}
|
|
82
86
|
|
|
83
87
|
processServiceDefinition( sourceService, processors ) {
|
|
84
88
|
if(!processors) processors = this.defaultProcessors
|
|
85
89
|
processors = processors.slice()
|
|
86
|
-
|
|
87
|
-
|
|
90
|
+
function processUse(service) {
|
|
91
|
+
if(service && service.use) {
|
|
92
|
+
for(const plugin of service.use) {
|
|
93
|
+
processUse(plugin)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
processors.unshift(...service.processors)
|
|
88
97
|
}
|
|
89
|
-
|
|
98
|
+
processUse(sourceService)
|
|
90
99
|
for(let processor of processors) processor(sourceService, this)
|
|
91
100
|
}
|
|
92
101
|
|
|
@@ -145,9 +154,11 @@ class App {
|
|
|
145
154
|
async createApiServer( config ) {
|
|
146
155
|
return new ApiServer({ ...config, app: this })
|
|
147
156
|
}
|
|
148
|
-
|
|
149
157
|
async createSessionApiServer( config ) {
|
|
150
|
-
return new
|
|
158
|
+
return new ApiServer({ ...config, app: this }, SessionDao)
|
|
159
|
+
}
|
|
160
|
+
async createLiveApiServer( config ) {
|
|
161
|
+
return new ApiServer({ ...config, app: this }, LiveDao)
|
|
151
162
|
}
|
|
152
163
|
|
|
153
164
|
generateUid() {
|
|
@@ -248,9 +259,11 @@ class App {
|
|
|
248
259
|
requestTimeout = this.requestTimeout
|
|
249
260
|
}
|
|
250
261
|
if(requestTimeout) {
|
|
251
|
-
setTimeout(() => {
|
|
262
|
+
const timeout = setTimeout(() => {
|
|
263
|
+
this.activeTimeouts.delete(timeout)
|
|
252
264
|
reject('timeout')
|
|
253
265
|
}, requestTimeout)
|
|
266
|
+
this.activeTimeouts.add(timeout)
|
|
254
267
|
}
|
|
255
268
|
}).finally(() => {
|
|
256
269
|
objectObservable.unobserve(observer)
|
|
@@ -374,6 +387,9 @@ class App {
|
|
|
374
387
|
}
|
|
375
388
|
|
|
376
389
|
async close() {
|
|
390
|
+
for(const timeout of this.activeTimeouts) {
|
|
391
|
+
clearTimeout(timeout)
|
|
392
|
+
}
|
|
377
393
|
this.dao.dispose()
|
|
378
394
|
}
|
|
379
395
|
|
|
@@ -381,4 +397,3 @@ class App {
|
|
|
381
397
|
|
|
382
398
|
|
|
383
399
|
module.exports = App
|
|
384
|
-
module.exports.rangeProperties = utils.rangeProperties
|
|
@@ -1,60 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
if(typeof validation == 'string') {
|
|
3
|
-
let validator = context.service.validators[validation]
|
|
4
|
-
if(!validator) throw new Error(`Validator ${validation} not found`)
|
|
5
|
-
return validator({}, context)
|
|
6
|
-
} else {
|
|
7
|
-
let validator = context.service.validators[validation.name]
|
|
8
|
-
if(!validator) throw new Error(`Validator ${validation.name} not found`)
|
|
9
|
-
return validator(validation, context)
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function getValidators(source, service) {
|
|
14
|
-
let validators = {}
|
|
15
|
-
const context = { source, service, getValidator: validation => getValidator(validation, context) }
|
|
16
|
-
for(let propName in source.properties) {
|
|
17
|
-
const prop = source.properties[propName]
|
|
18
|
-
if(prop.validation) {
|
|
19
|
-
const validations = Array.isArray(prop.validation) ? prop.validation : [prop.validation]
|
|
20
|
-
for(let validation of validations) {
|
|
21
|
-
const validator = getValidator(validation, context)
|
|
22
|
-
if(validators[propName]) validators[propName].push(validator)
|
|
23
|
-
else validators[propName] = [validator]
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return validators
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async function validate(props, validators, context) {
|
|
31
|
-
console.log("VALIDATE PROPS", props, "WITH", validators)
|
|
32
|
-
let propPromises = {}
|
|
33
|
-
for(let propName in validators) {
|
|
34
|
-
let propValidators = validators[propName]
|
|
35
|
-
let promises = []
|
|
36
|
-
for(let validator of propValidators) {
|
|
37
|
-
//console.log("PROPS",props, propName)
|
|
38
|
-
promises.push(validator(props[propName], { ...context, props, propName }))
|
|
39
|
-
}
|
|
40
|
-
propPromises[propName] = Promise.all(promises)
|
|
41
|
-
}
|
|
42
|
-
let propErrors = {}
|
|
43
|
-
for(let propName in validators) {
|
|
44
|
-
let errors = (await propPromises[propName]).filter(e=>!!e)
|
|
45
|
-
console.log("EERRS",propName, errors)
|
|
46
|
-
if(errors.length > 0) {
|
|
47
|
-
console.log("ERRS", propName)
|
|
48
|
-
propErrors[propName] = errors[0]
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
console.log("PROP ERRORS", propErrors)
|
|
52
|
-
if(Object.keys(propErrors).length > 0) throw { properties: propErrors }
|
|
53
|
-
}
|
|
1
|
+
const { getValidators, validate } = require('../utils/validation.js')
|
|
54
2
|
|
|
55
3
|
module.exports = function(service, app) {
|
|
56
4
|
for(let actionName in service.actions) {
|
|
57
5
|
const action = service.actions[actionName]
|
|
6
|
+
if(action.skipValidation) continue
|
|
58
7
|
const validators = getValidators(action, service, action)
|
|
59
8
|
if(Object.keys(validators).length > 0) {
|
|
60
9
|
const oldExec = action.execute
|
|
@@ -68,6 +17,7 @@ module.exports = function(service, app) {
|
|
|
68
17
|
}
|
|
69
18
|
for(let viewName in service.views) {
|
|
70
19
|
const view = service.views[viewName]
|
|
20
|
+
if(view.skipValidation) continue
|
|
71
21
|
const validators = getValidators(view, service, view)
|
|
72
22
|
if(Object.keys(validators).length > 0) {
|
|
73
23
|
if (view.read && !view.fetch) {
|
package/lib/runtime/Action.js
CHANGED
|
@@ -42,7 +42,7 @@ class Action {
|
|
|
42
42
|
parameters: await preFilterParameters(parameters, this.definition.properties)
|
|
43
43
|
}
|
|
44
44
|
if(parameters._commandId) command.id = parameters._commandId
|
|
45
|
-
console.log("CALL COMMAND", JSON.stringify(command, null, " "))
|
|
45
|
+
//console.log("CALL COMMAND", JSON.stringify(command, null, " "))
|
|
46
46
|
return this.service.app.command(command, this.definition.requestTimeout)
|
|
47
47
|
}
|
|
48
48
|
}
|
package/lib/runtime/ApiServer.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
const
|
|
1
|
+
const LcDao = require("@live-change/dao")
|
|
2
2
|
const Dao = require("./Dao.js")
|
|
3
3
|
const cookie = require('cookie')
|
|
4
4
|
|
|
5
5
|
const { getIp } = require("./utils.js")
|
|
6
6
|
|
|
7
7
|
class ApiServer {
|
|
8
|
-
constructor(config) {
|
|
8
|
+
constructor(config, DaoConstructor = Dao) {
|
|
9
9
|
this.config = config
|
|
10
|
-
this.
|
|
11
|
-
|
|
10
|
+
this.DaoConstructor = DaoConstructor
|
|
11
|
+
|
|
12
|
+
this.reactiveServer = new LcDao.ReactiveServer(
|
|
13
|
+
(credentials, connection) => {
|
|
12
14
|
const ip = getIp(connection)
|
|
13
15
|
if(this.config.fastAuth) {
|
|
14
16
|
if(typeof this.config.fastAuth == 'function') {
|
|
@@ -24,16 +26,28 @@ class ApiServer {
|
|
|
24
26
|
}, config)
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
async daoFactory(credentialsp, ip)
|
|
29
|
+
async daoFactory(credentialsp, ip) {
|
|
28
30
|
let credentials = { ...credentialsp, ip, roles: [] }
|
|
29
|
-
if(this.config.
|
|
30
|
-
|
|
31
|
-
? this.config.
|
|
32
|
-
for(
|
|
33
|
-
if(authenticator
|
|
31
|
+
if(this.config.authenticators) {
|
|
32
|
+
const auth = Array.isArray(this.config.authenticators)
|
|
33
|
+
? this.config.authenticators : [this.config.authenticators]
|
|
34
|
+
for(const authenticator of auth) {
|
|
35
|
+
if(authenticator && authenticator.prepareCredentials)
|
|
36
|
+
await authenticator.prepareCredentials(credentials, this.config)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
for(const service of this.config.services) {
|
|
40
|
+
console.log("SERIVCE AUTH", service.name, service.authenticators)
|
|
41
|
+
if(service.authenticators) {
|
|
42
|
+
for(const authenticator of service.authenticators) {
|
|
43
|
+
if(authenticator && authenticator.prepareCredentials)
|
|
44
|
+
await authenticator.prepareCredentials(credentials, this.config)
|
|
45
|
+
}
|
|
34
46
|
}
|
|
35
47
|
}
|
|
36
|
-
|
|
48
|
+
const dao = new this.DaoConstructor(this.config, { ...credentials })
|
|
49
|
+
await dao.start()
|
|
50
|
+
return dao
|
|
37
51
|
}
|
|
38
52
|
|
|
39
53
|
handleConnection(connection) {
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const LcDao = require("@live-change/dao")
|
|
2
|
+
const Dao = require("./Dao.js")
|
|
3
|
+
|
|
4
|
+
const { waitForSignal } = require('./utils.js')
|
|
5
|
+
|
|
6
|
+
class LiveDao extends LcDao.DaoProxy {
|
|
7
|
+
constructor(config, credentials) {
|
|
8
|
+
super(null)
|
|
9
|
+
this.config = config
|
|
10
|
+
this.initialCredentials = credentials
|
|
11
|
+
|
|
12
|
+
this.authenticators = []
|
|
13
|
+
if(this.config.authenticators) {
|
|
14
|
+
const auth = Array.isArray(this.config.authenticators)
|
|
15
|
+
? this.config.authenticators : [this.config.authenticators]
|
|
16
|
+
for(const authenticator of auth) {
|
|
17
|
+
if(authenticator && authenticator.authenticatorObservable)
|
|
18
|
+
this.authenticators.push(authenticator)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
for(const service of this.config.services) {
|
|
22
|
+
console.log("SERIVCE AUTH", service.name, service.authenticators)
|
|
23
|
+
if(service.authenticators) {
|
|
24
|
+
for(const authenticator of service.authenticators) {
|
|
25
|
+
if(authenticator && authenticator.authenticatorObservable)
|
|
26
|
+
this.authenticators.push(authenticator)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
this.currentDao = null
|
|
32
|
+
this.disposed = false
|
|
33
|
+
this.started = false
|
|
34
|
+
this.credentials = JSON.parse(JSON.stringify(this.initialCredentials))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async refreshCredentials() {
|
|
38
|
+
if(!this.started) return /// waiting for start
|
|
39
|
+
const newCredentials = this.computeCredentials()
|
|
40
|
+
if(JSON.stringify(newCredentials) != JSON.stringify(this.credentials)) {
|
|
41
|
+
this.credentials = newCredentials
|
|
42
|
+
this.buildDao()
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
computeCredentials() {
|
|
47
|
+
let credentials = JSON.parse(JSON.stringify(this.initialCredentials))
|
|
48
|
+
for(const credentialsObserver of this.credentialsObservations) {
|
|
49
|
+
credentials = {
|
|
50
|
+
...credentials,
|
|
51
|
+
...credentialsObservers.credentials,
|
|
52
|
+
roles: [...credentials.roles, ...credentialsObserver.credentials.roles]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return credentials
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async start() {
|
|
59
|
+
this.credentialsObservations = this.authenticators.map(authenticator => {
|
|
60
|
+
const observable = authenticator.authenticatorObservable(this.initialCredentials)
|
|
61
|
+
const observer = {
|
|
62
|
+
set: (newCredentials) => {
|
|
63
|
+
state.credentials = newCredentials
|
|
64
|
+
this.refreshCredentials()
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const promise = waitForSignal(observable)
|
|
68
|
+
const state = {
|
|
69
|
+
observable, observer, promise, credentials: {}
|
|
70
|
+
}
|
|
71
|
+
return state
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
await Promise.all(this.credentialsObservations.map(observation => observation.promise))
|
|
75
|
+
|
|
76
|
+
const newCredentials = this.computeCredentials()
|
|
77
|
+
if(JSON.stringify(newCredentials) != JSON.stringify(this.credentials)) {
|
|
78
|
+
this.credentials = newCredentials
|
|
79
|
+
}
|
|
80
|
+
this.buildDao()
|
|
81
|
+
this.started = true
|
|
82
|
+
|
|
83
|
+
if(!this.dao) throw new Error("dao not created?!")
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
buildDao() {
|
|
87
|
+
const oldDao = this.currentDao
|
|
88
|
+
this.currentDao = new Dao(this.config, { ...this.credentials })
|
|
89
|
+
this.setDao(this.currentDao)
|
|
90
|
+
if(oldDao) oldDao.dispose()
|
|
91
|
+
}
|
|
92
|
+
dispose() {
|
|
93
|
+
if(this.disposed) throw new Error("DAO dispose called twice!")
|
|
94
|
+
this.disposed = true
|
|
95
|
+
this.started = false
|
|
96
|
+
for(const observation of this.credentialsObservations) {
|
|
97
|
+
observation.observable.unobserver(observation.observer)
|
|
98
|
+
}
|
|
99
|
+
super.dispose()
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
module.exports = LiveDao
|
|
@@ -48,7 +48,7 @@ class CommandQueue {
|
|
|
48
48
|
})
|
|
49
49
|
}
|
|
50
50
|
async handleCommand(command) {
|
|
51
|
-
console.log("COMMNAD HANDLE!", command)
|
|
51
|
+
//console.log("COMMNAD HANDLE!", command)
|
|
52
52
|
if(command.state != 'new') return
|
|
53
53
|
if(this.commandsStarted.has(command.id)) return
|
|
54
54
|
this.commandsStarted.set(command.id, command)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
function getValidator(validation, context) {
|
|
2
|
+
if(typeof validation == 'string') {
|
|
3
|
+
let validator = context.service.validators[validation]
|
|
4
|
+
if(!validator) throw new Error(`Validator ${validation} not found`)
|
|
5
|
+
return validator({}, context)
|
|
6
|
+
} else {
|
|
7
|
+
let validator = context.service.validators[validation.name]
|
|
8
|
+
if(!validator) throw new Error(`Validator ${validation.name} not found`)
|
|
9
|
+
return validator(validation, context)
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getValidators(source, service) {
|
|
14
|
+
let validators = {}
|
|
15
|
+
const context = { source, service, getValidator: validation => getValidator(validation, context) }
|
|
16
|
+
for(let propName in source.properties) {
|
|
17
|
+
const prop = source.properties[propName]
|
|
18
|
+
if(prop.validation) {
|
|
19
|
+
const validations = Array.isArray(prop.validation) ? prop.validation : [prop.validation]
|
|
20
|
+
for(let validation of validations) {
|
|
21
|
+
const validator = getValidator(validation, context)
|
|
22
|
+
if(validators[propName]) validators[propName].push(validator)
|
|
23
|
+
else validators[propName] = [validator]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return validators
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function validate(props, validators, context) {
|
|
31
|
+
//console.log("VALIDATE PROPS", props, "WITH", validators)
|
|
32
|
+
let propPromises = {}
|
|
33
|
+
for(let propName in validators) {
|
|
34
|
+
let propValidators = validators[propName]
|
|
35
|
+
let promises = []
|
|
36
|
+
for(let validator of propValidators) {
|
|
37
|
+
//console.log("PROPS",props, propName)
|
|
38
|
+
promises.push(validator(props[propName], { ...context, props, propName }))
|
|
39
|
+
}
|
|
40
|
+
propPromises[propName] = Promise.all(promises)
|
|
41
|
+
}
|
|
42
|
+
let propErrors = {}
|
|
43
|
+
for(let propName in validators) {
|
|
44
|
+
let errors = (await propPromises[propName]).filter(e=>!!e)
|
|
45
|
+
console.log("EERRS",propName, errors)
|
|
46
|
+
if(errors.length > 0) {
|
|
47
|
+
console.log("ERRS", propName)
|
|
48
|
+
propErrors[propName] = errors[0]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
console.log("PROP ERRORS", propErrors)
|
|
52
|
+
if(Object.keys(propErrors).length > 0) throw { properties: propErrors }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = { getValidator, getValidators, validate }
|
package/package.json
CHANGED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
const LcDao = require("@live-change/dao")
|
|
2
|
-
const SessionDao = require("./SessionDao.js")
|
|
3
|
-
const cookie = require('cookie')
|
|
4
|
-
|
|
5
|
-
const { getIp } = require("./utils.js")
|
|
6
|
-
|
|
7
|
-
class SessionApiServer {
|
|
8
|
-
constructor(config) {
|
|
9
|
-
this.config = config
|
|
10
|
-
this.reactiveServer = new LcDao.ReactiveServer(
|
|
11
|
-
(credentials, connection) => {
|
|
12
|
-
const ip = getIp(connection)
|
|
13
|
-
if(this.config.fastAuth) {
|
|
14
|
-
if(typeof this.config.fastAuth == 'function') {
|
|
15
|
-
credentials = this.config.fastAuth(connection)
|
|
16
|
-
} else {
|
|
17
|
-
const cookies = cookie.parse(connection.headers.cookie || '')
|
|
18
|
-
const sessionKey = cookies.sessionKey
|
|
19
|
-
if(!sessionKey) throw new Error('session key undefined')
|
|
20
|
-
credentials = { sessionKey }
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return this.daoFactory(credentials, ip)
|
|
24
|
-
}, config)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async daoFactory(credentialsp, ip) {
|
|
28
|
-
let credentials = { ...credentialsp, ip, roles: [] }
|
|
29
|
-
if(this.config.authenticators) {
|
|
30
|
-
const auth = Array.isArray(this.config.authenticators)
|
|
31
|
-
? this.config.authenticators : [this.config.authenticators]
|
|
32
|
-
for(const authenticator of auth) {
|
|
33
|
-
if(authenticator) await authenticator(credentials, this.config)
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
for(const service of this.config.services) {
|
|
37
|
-
console.log("SERIVCE AUTH", service.name, service.authenticators)
|
|
38
|
-
if(service.authenticators) {
|
|
39
|
-
for(const authenticator of service.authenticators) {
|
|
40
|
-
if(authenticator) await authenticator(credentials, this.config)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
const dao = new SessionDao(this.config, { ...credentials })
|
|
45
|
-
await dao.start()
|
|
46
|
-
return dao
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
handleConnection(connection) {
|
|
50
|
-
this.reactiveServer.handleConnection(connection)
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
module.exports = SessionApiServer
|