@live-change/framework 0.5.5 → 0.5.9
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/runtime/ReaderModel.js +5 -5
- package/lib/utils/CommandQueue.js +1 -1
- package/lib/utils/validation.js +55 -0
- package/lib/utils.js +1 -1
- 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
|
|
@@ -30,7 +30,7 @@ class ReaderModel {
|
|
|
30
30
|
if(pathRange) {
|
|
31
31
|
return this.indexRangePath(index, utils.prefixRange(pathRange, prefix, prefix))
|
|
32
32
|
}
|
|
33
|
-
return this.indexRangePath(index,{ gte: prefix+'
|
|
33
|
+
return this.indexRangePath(index, { gte: prefix+':', lte: prefix+'_\xFF\xFF\xFF\xFF' })
|
|
34
34
|
}
|
|
35
35
|
return ['database', 'query', this.service.databaseName, `(${
|
|
36
36
|
async (input, output, { tableName, indexName, range }) => {
|
|
@@ -86,7 +86,7 @@ class ReaderModel {
|
|
|
86
86
|
if(pathRange) {
|
|
87
87
|
return this.sortedIndexRangePath(index, utils.prefixRange(pathRange, prefix, prefix))
|
|
88
88
|
}
|
|
89
|
-
return this.sortedIndexRangePath(index,{ gte:
|
|
89
|
+
return this.sortedIndexRangePath(index, { gte: prefix+':', lte: prefix+'_\xFF\xFF\xFF\xFF' })
|
|
90
90
|
}
|
|
91
91
|
return ['database', 'query', this.service.databaseName, `(${
|
|
92
92
|
async (input, output, { tableName, indexName, range }) => {
|
|
@@ -147,7 +147,7 @@ class ReaderModel {
|
|
|
147
147
|
if(pathRange) {
|
|
148
148
|
return this.indexObjectPath(index, utils.prefixRange(pathRange, prefix, prefix))
|
|
149
149
|
}
|
|
150
|
-
return this.indexObjectPath(index,{ gte: prefix+'
|
|
150
|
+
return this.indexObjectPath(index,{ gte: prefix+':', lte: prefix+'_\xFF\xFF\xFF\xFF' })
|
|
151
151
|
}
|
|
152
152
|
return ['database', 'queryObject', this.service.databaseName, `(${
|
|
153
153
|
async (input, output, { tableName, indexName, range }) => {
|
|
@@ -185,7 +185,7 @@ class ReaderModel {
|
|
|
185
185
|
if(pathRange) {
|
|
186
186
|
return this.indexRangeDelete(index, utils.prefixRange(pathRange, prefix, prefix))
|
|
187
187
|
}
|
|
188
|
-
return this.indexRangeDelete(index,{ gte: prefix+'
|
|
188
|
+
return this.indexRangeDelete(index,{ gte: prefix+':', lte: prefix+'_\xFF\xFF\xFF\xFF' })
|
|
189
189
|
}
|
|
190
190
|
this.service.dao.request(['database', 'query'], this.service.databaseName, `${
|
|
191
191
|
async (input, output, { tableName, indexName, range }) => {
|
|
@@ -203,7 +203,7 @@ class ReaderModel {
|
|
|
203
203
|
if(pathRange) {
|
|
204
204
|
return this.indexRangeUpdate(index, update, utils.prefixRange(pathRange, prefix, prefix))
|
|
205
205
|
}
|
|
206
|
-
return this.indexRangeUpdate(index, update,{ gte: prefix+'
|
|
206
|
+
return this.indexRangeUpdate(index, update,{ gte: prefix+':', lte: prefix+'_\xFF\xFF\xFF\xFF' })
|
|
207
207
|
}
|
|
208
208
|
const operations = Array.isArray(update) ? update : [{ op:'merge', property: null, value: update }]
|
|
209
209
|
this.service.dao.request(['database', 'query'], this.service.databaseName, `(${
|
|
@@ -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/lib/utils.js
CHANGED
|
@@ -204,7 +204,7 @@ function prefixRange({ gt, lt, gte, lte, limit, reverse }, prefix, from = "") {
|
|
|
204
204
|
gte: (typeof gte == 'string') ? getPrefix(gte) : (typeof gt == 'string' ? undefined : `${prefix}:`),
|
|
205
205
|
lte: (typeof lte == 'string')
|
|
206
206
|
? getPrefix(lte)+"\xFF\xFF\xFF\xFF"
|
|
207
|
-
: (typeof lt == 'string' ? undefined : `${prefix}
|
|
207
|
+
: (typeof lt == 'string' ? undefined : `${prefix}_\xFF\xFF\xFF\xFF`),
|
|
208
208
|
limit,
|
|
209
209
|
reverse
|
|
210
210
|
}
|
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
|