@live-change/user-service 0.2.16 → 0.2.19

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 CHANGED
@@ -5,6 +5,8 @@ const { User, AutheticatedUser } = require('./model.js')
5
5
  require('./authenticator.js')
6
6
  require('./userProperty.js')
7
7
  require('./userItem.js')
8
+ require('./sessionOrUserProperty.js')
9
+ require('./sessionOrUserItem.js')
8
10
 
9
11
  const Session = definition.foreignModel('session', 'Session')
10
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/user-service",
3
- "version": "0.2.16",
3
+ "version": "0.2.19",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -21,8 +21,8 @@
21
21
  "url": "https://www.viamage.com/"
22
22
  },
23
23
  "dependencies": {
24
- "@live-change/framework": "^0.5.7",
24
+ "@live-change/framework": "^0.5.10",
25
25
  "@live-change/relations-plugin": "^0.1.10"
26
26
  },
27
- "gitHead": "98a41ae61218a0ec58d4861b6409d8d9facde37f"
27
+ "gitHead": "c2833a9660374ee17dd3def99fd1cdf47f6b1531"
28
28
  }
@@ -0,0 +1,190 @@
1
+ const definition = require("./definition.js")
2
+ const App = require("@live-change/framework")
3
+ const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition } = App
4
+ const { User } = require("./model.js")
5
+
6
+ definition.processor(function(service, app) {
7
+
8
+ for(let modelName in service.models) {
9
+ const model = service.models[modelName]
10
+ if(model.sessionOrUserItem) {
11
+ if (model.properties.owner) throw new Error('user property already exists!!!')
12
+ const originalModelProperties = { ...model.properties }
13
+ const modelProperties = Object.keys(model.properties)
14
+ const defaults = App.utils.generateDefault(model.properties)
15
+ const modelPropertyName = modelName.slice(0, 1).toLowerCase() + modelName.slice(1)
16
+
17
+ function modelRuntime() {
18
+ return service._runtime.models[modelName]
19
+ }
20
+
21
+ const config = model.sessionOrUserItem
22
+ const writeableProperties = modelProperties || config.writableProperties
23
+
24
+ //console.log("USER ITEM", model)
25
+
26
+ model.itemOfAny = {
27
+ ...config
28
+ }
29
+
30
+ if(config.ownerReadAccess) {
31
+ const viewName = 'my' + modelName + 's'
32
+ service.views[viewName] = new ViewDefinition({
33
+ name: viewName,
34
+ access(params, context) {
35
+ return config.ownerReadAccess ? config.ownerReadAccess(params, context) : true
36
+ },
37
+ properties: App.rangeProperties,
38
+ daoPath(range, { client, context }) {
39
+ const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
40
+ const path = modelRuntime().indexRangePath('byOwner', owner, range )
41
+ return path
42
+ }
43
+ })
44
+ for(const sortField of config.sortBy || []) {
45
+ const sortFieldUc = sortField.slice(0, 1).toUpperCase() + sortField.slice(1)
46
+ const viewName = 'mySessionOrUser' + modelName + 'sBy' + sortFieldUc
47
+ service.views[viewName] = new ViewDefinition({
48
+ name: viewName,
49
+ access(params, context) {
50
+ if(!context.client.user) return false
51
+ return config.userReadAccess ? config.userReadAccess(params, context) : true
52
+ },
53
+ properties: App.rangeProperties,
54
+ daoPath(range, { client, context }) {
55
+ const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
56
+ return modelRuntime().sortedIndexRangePath('byOwner' + sortFieldUc, owner, range)
57
+ }
58
+ })
59
+ }
60
+ }
61
+
62
+ if(config.ownerCreateAccess || config.ownerWriteAccess) {
63
+ const eventName = 'ownerOwned' + modelName + 'Created'
64
+ const actionName = 'createMy' + modelName
65
+ service.actions[actionName] = new ActionDefinition({
66
+ name: actionName,
67
+ access: config.ownerCreateAccess || config.ownerWriteAccess,
68
+ properties: {
69
+ ...originalModelProperties,
70
+ [modelPropertyName]: {
71
+ type: model,
72
+ validation: ['localId']
73
+ }
74
+ },
75
+ queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
76
+ waitForEvents: true,
77
+ async execute(properties, { client, service }, emit) {
78
+ const id = properties[modelPropertyName] || app.generateUid()
79
+ const entity = await modelRuntime().get(id)
80
+ if(entity) throw 'exists'
81
+ const identifiers = client.user ? {
82
+ ownerType: 'user_User',
83
+ owner: client.user,
84
+ } : {
85
+ ownerType: 'session_Session',
86
+ owner: client.session,
87
+ }
88
+ emit({
89
+ type: eventName,
90
+ [modelPropertyName]: id,
91
+ identifiers,
92
+ data: properties
93
+ })
94
+ return id
95
+ }
96
+ })
97
+ }
98
+ if(config.ownerUpdateAccess || config.ownerWriteAccess) {
99
+ const eventName = 'ownerOwned' + modelName + 'Updated'
100
+ const actionName = 'updateMy' + modelName
101
+ service.actions[actionName] = new ActionDefinition({
102
+ name: actionName,
103
+ access: config.ownerUpdateAccess || config.ownerWriteAccess,
104
+ properties: {
105
+ ...originalModelProperties,
106
+ [modelPropertyName]: {
107
+ type: model,
108
+ validation: ['nonEmpty']
109
+ }
110
+ },
111
+ skipValidation: true,
112
+ queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
113
+ waitForEvents: true,
114
+ async execute(properties, { client, service }, emit) {
115
+ const entity = await modelRuntime().get(properties[modelPropertyName])
116
+ if(!entity) throw 'not_found'
117
+ if(entity.ownerType == 'user_User') {
118
+ if(entity.owner != client.user) throw 'not_authorized'
119
+ }
120
+ if(entity.ownerType == 'session_Session') {
121
+ if(entity.owner != client.session) throw 'not_authorized'
122
+ }
123
+ let updateObject = {}
124
+ for(const propertyName of writeableProperties) {
125
+ if(properties.hasOwnProperty(propertyName)) {
126
+ updateObject[propertyName] = properties[propertyName]
127
+ }
128
+ }
129
+ const merged = App.utils.mergeDeep({}, entity, updateObject)
130
+ await App.validation.validate(merged, validators, { source: action, action, service, app, client })
131
+ const identifiers = client.user ? {
132
+ ownerType: 'user_User',
133
+ owner: client.user,
134
+ } : {
135
+ ownerType: 'session_Session',
136
+ owner: client.session,
137
+ }
138
+ emit({
139
+ type: eventName,
140
+ [modelPropertyName]: entity.id,
141
+ identifiers,
142
+ data: properties
143
+ })
144
+ }
145
+ })
146
+ const action = service.actions[actionName]
147
+ const validators = App.validation.getValidators(action, service, action)
148
+ }
149
+ if(config.userDeleteAccess || config.userWriteAccess) {
150
+ const eventName = 'userOwned' + modelName + 'Deleted'
151
+ const actionName = 'deleteMyUser' + modelName
152
+ service.actions[actionName] = new ActionDefinition({
153
+ name: actionName,
154
+ access: config.userDeleteAccess || config.userWriteAccess,
155
+ properties: {
156
+ [modelPropertyName]: {
157
+ type: model,
158
+ validation: ['nonEmpty']
159
+ }
160
+ },
161
+ queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
162
+ waitForEvents: true,
163
+ async execute(properties, { client, service }, emit) {
164
+ const entity = await modelRuntime().get(properties[modelPropertyName])
165
+ if(!entity) throw 'not_found'
166
+ if(entity.ownerType == 'user_User') {
167
+ if(entity.owner != client.user) throw 'not_authorized'
168
+ }
169
+ if(entity.ownerType == 'session_Session') {
170
+ if(entity.owner != client.session) throw 'not_authorized'
171
+ }
172
+ const identifiers = client.user ? {
173
+ ownerType: 'user_User',
174
+ owner: client.user,
175
+ } : {
176
+ ownerType: 'session_Session',
177
+ owner: client.session,
178
+ }
179
+ emit({
180
+ type: eventName,
181
+ [modelPropertyName]: entity.id,
182
+ identifiers
183
+ })
184
+ }
185
+ })
186
+ }
187
+ }
188
+ }
189
+
190
+ })
@@ -0,0 +1,177 @@
1
+ const definition = require("./definition.js")
2
+ const App = require("@live-change/framework")
3
+ const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition } = App
4
+ const { User } = require("./model.js")
5
+
6
+ definition.processor(function(service, app) {
7
+
8
+ for(let modelName in service.models) {
9
+ const model = service.models[modelName]
10
+
11
+ if(model.sessionOrUserProperty) {
12
+ console.log("MODEL " + modelName + " IS SESSION OR USER PROPERTY, CONFIG:", model.userProperty)
13
+ if (model.properties.owner) throw new Error('owner property already exists!!!')
14
+
15
+ const originalModelProperties = { ...model.properties }
16
+ const modelProperties = Object.keys(model.properties)
17
+ const defaults = App.utils.generateDefault(model.properties)
18
+
19
+ function modelRuntime() {
20
+ return service._runtime.models[modelName]
21
+ }
22
+
23
+ const config = model.sessionOrUserProperty
24
+ const writeableProperties = modelProperties || config.writableProperties
25
+
26
+ model.propertyOfAny = {
27
+ ...config
28
+ }
29
+
30
+ if(config.ownerReadAccess) {
31
+ const viewName = 'my' + modelName
32
+ service.views[viewName] = new ViewDefinition({
33
+ name: viewName,
34
+ access(params, context) {
35
+ return config.ownerReadAccess ? config.ownerReadAccess(params, context) : true
36
+ },
37
+ daoPath(params, { client, context }) {
38
+ const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
39
+ const id = owner.map(p => JSON.stringify(p)).join(':')
40
+ return modelRuntime().path(id)
41
+ }
42
+ })
43
+ }
44
+
45
+ if(config.ownerViews) {
46
+ for(const view of config.userViews) {
47
+ const viewName = view.name || ('my' + (view.prefix || '') + modelName + (view.suffix || ''))
48
+ service.views[viewName] = new ViewDefinition({
49
+ name: viewName,
50
+ access(params, context) {
51
+ return view.access ? view.access(params, context) : true
52
+ },
53
+ daoPath(params, { client, context }) {
54
+ const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
55
+ const id = owner.map(p => JSON.stringify(p)).join(':')
56
+ return view.fields
57
+ ? modelRuntime().limitedPath(id, view.fields)
58
+ : modelRuntime().path(id)
59
+ }
60
+ })
61
+ }
62
+ }
63
+
64
+ if(config.ownerSetAccess || config.ownerWriteAccess) {
65
+ const eventName = 'ownerOwned' + modelName + 'Set'
66
+ const actionName = 'setMy' + modelName
67
+ service.actions[actionName] = new ActionDefinition({
68
+ name: actionName,
69
+ properties: {
70
+ ...originalModelProperties
71
+ },
72
+ access: config.ownerSetAccess || config.ownerWriteAccess,
73
+ skipValidation: true,
74
+ queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
75
+ waitForEvents: true,
76
+ async execute(properties, {client, service}, emit) {
77
+ let newObject = {}
78
+ for(const propertyName of writeableProperties) {
79
+ if(properties.hasOwnProperty(propertyName)) {
80
+ newObject[propertyName] = properties[propertyName]
81
+ }
82
+ }
83
+ const data = App.utils.mergeDeep({}, defaults, newObject)
84
+ await App.validation.validate(data, validators, { source: action, action, service, app, client })
85
+ const identifiers = client.user ? {
86
+ ownerType: 'user_User',
87
+ owner: client.user,
88
+ } : {
89
+ ownerType: 'session_Session',
90
+ owner: client.session,
91
+ }
92
+ emit({
93
+ type: eventName,
94
+ identifiers,
95
+ data
96
+ })
97
+ }
98
+ })
99
+ const action = service.actions[actionName]
100
+ const validators = App.validation.getValidators(action, service, action)
101
+ }
102
+
103
+ if(config.ownerUpdateAccess || config.ownerWriteAccess) {
104
+ const eventName = 'ownerOwned' + modelName + 'Updated'
105
+ const actionName = 'updateMy' + modelName
106
+ service.actions[actionName] = new ActionDefinition({
107
+ name: actionName,
108
+ properties: {
109
+ ...originalModelProperties
110
+ },
111
+ access: config.ownerUpdateAccess || config.ownerWriteAccess,
112
+ skipValidation: true,
113
+ queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
114
+ waitForEvents: true,
115
+ async execute(properties, { client, service }, emit) {
116
+ const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
117
+ const id = owner.map(p => JSON.stringify(p)).join(':')
118
+ const entity = await modelRuntime().get(id)
119
+ if(!entity) throw 'not_found'
120
+ let updateObject = {}
121
+ for(const propertyName of writeableProperties) {
122
+ if(properties.hasOwnProperty(propertyName)) {
123
+ updateObject[propertyName] = properties[propertyName]
124
+ }
125
+ }
126
+ const merged = App.utils.mergeDeep({}, entity, updateObject)
127
+ await App.validation.validate(merged, validators, { source: action, action, service, app, client })
128
+ const identifiers = client.user ? {
129
+ ownerType: 'user_User',
130
+ owner: client.user,
131
+ } : {
132
+ ownerType: 'session_Session',
133
+ owner: client.session,
134
+ }
135
+ emit({
136
+ type: eventName,
137
+ identifiers,
138
+ data: properties || {}
139
+ })
140
+ }
141
+ })
142
+ const action = service.actions[actionName]
143
+ const validators = App.validation.getValidators(action, service, action)
144
+ }
145
+
146
+ if(config.ownerResetAccess || config.ownerWriteAccess) {
147
+ const eventName = 'ownerOwned' + modelName + 'Reset'
148
+ const actionName = 'resetMy' + modelName
149
+ service.actions[actionName] = new ActionDefinition({
150
+ name: actionName,
151
+ access: config.ownerResetAccess || config.ownerWriteAccess,
152
+ queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
153
+ waitForEvents: true,
154
+ async execute(properties, {client, service}, emit) {
155
+ const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
156
+ const id = owner.map(p => JSON.stringify(p)).join(':')
157
+ const entity = await modelRuntime().get(id)
158
+ if (!entity) throw 'not_found'
159
+ const identifiers = client.user ? {
160
+ ownerType: 'user_User',
161
+ owner: client.user,
162
+ } : {
163
+ ownerType: 'session_Session',
164
+ owner: client.session,
165
+ }
166
+ emit({
167
+ type: eventName,
168
+ identifiers
169
+ })
170
+ }
171
+ })
172
+ }
173
+
174
+ }
175
+ }
176
+
177
+ })
package/userItem.js CHANGED
@@ -72,7 +72,7 @@ definition.processor(function(service, app) {
72
72
  validation: ['localId']
73
73
  }
74
74
  },
75
- //queuedBy: (command) => command.client.user,
75
+ queuedBy: (command) => command.client.user,
76
76
  waitForEvents: true,
77
77
  async execute(properties, { client, service }, emit) {
78
78
  const id = properties[modelPropertyName] || app.generateUid()
package/userProperty.js CHANGED
@@ -96,7 +96,7 @@ definition.processor(function(service, app) {
96
96
 
97
97
  if(config.userUpdateAccess || config.userWriteAccess) {
98
98
  const eventName = 'userOwned' + modelName + 'Updated'
99
- const actionName = 'updateMyuser' + modelName
99
+ const actionName = 'updateMyUser' + modelName
100
100
  service.actions[actionName] = new ActionDefinition({
101
101
  name: actionName,
102
102
  properties: {
@@ -132,14 +132,14 @@ definition.processor(function(service, app) {
132
132
 
133
133
  if(config.userResetAccess || config.userWriteAccess) {
134
134
  const eventName = 'userOwned' + modelName + 'Reset'
135
- const actionName = 'resetMyuser' + modelName
135
+ const actionName = 'resetMyUser' + modelName
136
136
  service.actions[actionName] = new ActionDefinition({
137
137
  name: actionName,
138
138
  access: config.userResetAccess || config.userWriteAccess,
139
139
  queuedBy: (command) => command.client.user,
140
140
  waitForEvents: true,
141
141
  async execute(properties, {client, service}, emit) {
142
- const entity = await modelRuntime().indexObjectGet('byuser', client.user)
142
+ const entity = await modelRuntime().indexObjectGet('byUser', client.user)
143
143
  if (!entity) throw 'not_found'
144
144
  emit({
145
145
  type: eventName,