@live-change/user-service 0.9.209 → 0.9.213

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/authenticator.js CHANGED
@@ -6,7 +6,13 @@ import definition from './definition.js'
6
6
  import { User, AuthenticatedUser } from './model.js'
7
7
 
8
8
  definition.authenticator({
9
+ name: 'user',
9
10
  async credentialsObservable(credentials) {
11
+ console.log('[auth] credentialsObservable start', {
12
+ name: 'user',
13
+ session: credentials.session,
14
+ ip: credentials.ip
15
+ })
10
16
  return app.dao.observable(
11
17
  ['database', 'queryObject', app.databaseName, `(${
12
18
  async (input, output, { session, authenticatedTableName, userTableName }) => {
@@ -17,10 +23,10 @@ definition.authenticator({
17
23
  let userObserver = null
18
24
  let oldCredentials = null
19
25
  await authenticatedTable.object(session).onChange(async (authData, oldAuthData) => {
20
- //output.debug("NEW USER AUTH", authData, "FROM", oldAuthData)
26
+ output.debug("NEW USER AUTH", authData, "FROM", oldAuthData)
21
27
  const newUser = authData ? authData.user : null
22
28
  if(newUser === user) return
23
- //output.debug("USER CHANGE", user, '=>', newUser)
29
+ output.debug("USER CHANGE", user, '=>', newUser)
24
30
  if(user) {
25
31
  if(userObject) {
26
32
  await userObject.unobserve(userObserver)
@@ -38,7 +44,7 @@ definition.authenticator({
38
44
  user,
39
45
  roles: userData.roles
40
46
  } : null
41
- //output.debug("NEW CREDENTIALS", newCredentials)
47
+ output.debug("NEW CREDENTIALS", newCredentials)
42
48
  output.change(newCredentials, oldCredentials)
43
49
  oldCredentials = newCredentials
44
50
  }).then(observer => {
@@ -49,6 +55,8 @@ definition.authenticator({
49
55
  }
50
56
  })
51
57
  } else {
58
+ output.debug("USER NULL", user)
59
+ output.debug("OLD CREDENTIALS", oldCredentials)
52
60
  user = null
53
61
  output.change(null, oldCredentials)
54
62
  oldCredentials = null
@@ -1,7 +1,12 @@
1
1
  import definition from './definition.js'
2
+ import App from '@live-change/framework'
2
3
  import {
3
4
  PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition
4
5
  } from '@live-change/framework'
6
+ import { fireChangeTriggers } from '@live-change/relations-plugin'
7
+ import {
8
+ fireItemOwnerTransferChange, fireItemUpdateChange, fireItemDeleteChange
9
+ } from './ownerChangeTriggers.js'
5
10
  import { User } from "./model.js"
6
11
 
7
12
  import pluralize from 'pluralize'
@@ -23,10 +28,14 @@ definition.processor(function(service, app) {
23
28
 
24
29
  const config = model.contactOrUserItem
25
30
  const writeableProperties = modelProperties || config.writableProperties
31
+ const objectType = service.name + '_' + modelName
26
32
 
27
33
  //console.log("USER ITEM", model)
28
34
 
29
35
  if(model.itemOfAny) throw new Error("model " + modelName + " already have owner")
36
+ const extendedWith = config.extendedWith
37
+ ? (Array.isArray(config.extendedWith) ? config.extendedWith : [config.extendedWith])
38
+ : []
30
39
  model.itemOfAny = {
31
40
  to: ['contactOrUser', ...extendedWith],
32
41
  ...(definition.config.contactTypes ? {
@@ -60,9 +69,13 @@ definition.processor(function(service, app) {
60
69
  validation: ['nonEmpty']
61
70
  }
62
71
  },
63
- async execute({ contactType, contact, user }, { service }, emit) {
72
+ async execute({ contactType, contact, user }, { service, trigger }, emit) {
64
73
  const contactPath = [contactType, contact]
65
74
  const contactItems = await modelRuntime().indexRangeGet('byOwner', contactPath, {} )
75
+ const toOwner = {
76
+ ownerType: 'user_User',
77
+ owner: user
78
+ }
66
79
  if(config.merge) {
67
80
  const userPath = ['user_User', user]
68
81
  const userItems = await modelRuntime().indexRangeGet('byOwner', userPath, {} )
@@ -70,6 +83,10 @@ definition.processor(function(service, app) {
70
83
  if(mergeResult) {
71
84
  const { transferred, updated, deleted } = mergeResult
72
85
  for(const entity of transferred) {
86
+ await fireItemOwnerTransferChange({
87
+ service, modelName, app, objectType, writeableProperties,
88
+ entity, to: toOwner, trigger
89
+ })
73
90
  emit({
74
91
  type: modelName + 'Transferred',
75
92
  [modelPropertyName]: entity.id,
@@ -81,6 +98,14 @@ definition.processor(function(service, app) {
81
98
  })
82
99
  }
83
100
  for(const entity of updated) {
101
+ const identifiers = {
102
+ ownerType: 'user_User',
103
+ owner: user
104
+ }
105
+ await fireItemUpdateChange({
106
+ service, modelName, app, objectType, writeableProperties,
107
+ entity, data: entity, identifiers, trigger
108
+ })
84
109
  emit({
85
110
  type: modelName + 'Updated',
86
111
  [modelPropertyName]: entity.id,
@@ -93,6 +118,13 @@ definition.processor(function(service, app) {
93
118
  })
94
119
  }
95
120
  for(const entity of deleted) {
121
+ const stored = await modelRuntime().get(entity.id)
122
+ if(stored) {
123
+ await fireItemDeleteChange({
124
+ service, modelName, app, objectType, writeableProperties,
125
+ entity: stored, trigger
126
+ })
127
+ }
96
128
  emit({
97
129
  type: modelName + 'Deleted',
98
130
  [modelPropertyName]: entity.id,
@@ -101,6 +133,10 @@ definition.processor(function(service, app) {
101
133
  }
102
134
  } else {
103
135
  for(const entity of contactItems) {
136
+ await fireItemOwnerTransferChange({
137
+ service, modelName, app, objectType, writeableProperties,
138
+ entity, to: toOwner, trigger
139
+ })
104
140
  emit({
105
141
  type: modelName + 'Transferred',
106
142
  [modelPropertyName]: entity.id,
@@ -167,7 +203,7 @@ definition.processor(function(service, app) {
167
203
  },
168
204
  queuedBy: (command) => 'u:'+command.client.user,
169
205
  waitForEvents: true,
170
- async execute(properties, { client, service }, emit) {
206
+ async execute(properties, { client, service, trigger }, emit) {
171
207
  const id = properties[modelPropertyName] || app.generateUid()
172
208
  const entity = await modelRuntime().get(id)
173
209
  if(entity) throw app.logicError("exists")
@@ -185,6 +221,10 @@ definition.processor(function(service, app) {
185
221
  App.computeDefaults(model, properties, { client, service }), newObject)
186
222
  await App.validation.validate({ ...identifiers, ...data }, validators,
187
223
  { source: action, action, service, app, client })
224
+ await fireChangeTriggers({
225
+ service, modelName, app, objectType, object: id,
226
+ identifiers, oldData: null, data, trigger
227
+ })
188
228
  emit({
189
229
  type: eventName,
190
230
  [modelPropertyName]: id,
@@ -215,7 +255,7 @@ definition.processor(function(service, app) {
215
255
  skipValidation: true,
216
256
  queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
217
257
  waitForEvents: true,
218
- async execute(properties, { client, service }, emit) {
258
+ async execute(properties, { client, service, trigger }, emit) {
219
259
  const entity = await modelRuntime().get(properties[modelPropertyName])
220
260
  if(!entity) throw app.logicError("not_found")
221
261
  if(entity.ownerType === 'user_User') {
@@ -227,18 +267,19 @@ definition.processor(function(service, app) {
227
267
  updateObject[propertyName] = properties[propertyName]
228
268
  }
229
269
  }
230
- const identifiers = client.user ? {
270
+ const identifiers = {
231
271
  ownerType: 'user_User',
232
272
  owner: client.user,
233
- } : {
234
- ownerType: 'session_Session',
235
- owner: client.session,
236
273
  }
237
274
  const computedUpdates = App.computeUpdates(model, { ...entity, ...properties }, { client, service })
238
275
  const data = App.utils.mergeDeep({}, updateObject, computedUpdates)
239
276
  const merged = App.utils.mergeDeep({}, entity, data)
240
277
  await App.validation.validate({ ...identifiers, ...merged, [modelPropertyName]: entity.id }, validators,
241
278
  { source: action, action, service, app, client })
279
+ await fireItemUpdateChange({
280
+ service, modelName, app, objectType, writeableProperties,
281
+ entity, data, identifiers, trigger
282
+ })
242
283
  emit({
243
284
  type: eventName,
244
285
  [modelPropertyName]: entity.id,
@@ -266,19 +307,20 @@ definition.processor(function(service, app) {
266
307
  },
267
308
  queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
268
309
  waitForEvents: true,
269
- async execute(properties, { client, service }, emit) {
310
+ async execute(properties, { client, service, trigger }, emit) {
270
311
  const entity = await modelRuntime().get(properties[modelPropertyName])
271
312
  if(!entity) throw app.logicError("not_found")
272
313
  if(entity.ownerType === 'user_User') {
273
314
  if(entity.owner !== client.user) throw app.logicError("not_authorized")
274
315
  } else throw app.logicError("not_authorized")
275
- const identifiers = client.user ? {
316
+ const identifiers = {
276
317
  ownerType: 'user_User',
277
318
  owner: client.user,
278
- } : {
279
- ownerType: 'session_Session',
280
- owner: client.session,
281
319
  }
320
+ await fireItemDeleteChange({
321
+ service, modelName, app, objectType, writeableProperties,
322
+ entity, identifiers, trigger
323
+ })
282
324
  emit({
283
325
  type: eventName,
284
326
  [modelPropertyName]: entity.id,
@@ -3,6 +3,13 @@ import App from '@live-change/framework'
3
3
  import {
4
4
  PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition
5
5
  } from '@live-change/framework'
6
+ import {
7
+ polymorphicPropertyId,
8
+ firePropertySetChange,
9
+ firePropertyUpdateChange,
10
+ firePropertyResetChange,
11
+ firePropertyTransferChange
12
+ } from './ownerChangeTriggers.js'
6
13
  import { User } from "./model.js"
7
14
  import { allCombinations } from "./combinations.js"
8
15
  import { createIdentifiersProperties } from './utils.js'
@@ -27,6 +34,7 @@ definition.processor(function(service, app) {
27
34
 
28
35
  const config = model.contactOrUserProperty
29
36
  const writeableProperties = modelProperties || config.writableProperties
37
+ const objectType = service.name + '_' + modelName
30
38
 
31
39
  if(model.propertyOf) throw new Error("model " + modelName + " already have owner")
32
40
  if(model.propertyOfAny) throw new Error("model " + modelName + " already have owner")
@@ -63,7 +71,7 @@ definition.processor(function(service, app) {
63
71
  validation: ['nonEmpty']
64
72
  }
65
73
  },
66
- async execute({ contactType, contact, user }, { service }, emit) {
74
+ async execute({ contactType, contact, user }, { service, trigger }, emit) {
67
75
  const contactPath = [contactType, contact]
68
76
  const contactPropertyId = contactPath.map(p => JSON.stringify(p)).join(':')
69
77
  const range = {
@@ -75,11 +83,27 @@ definition.processor(function(service, app) {
75
83
  for(const contactProperty of contactProperties) {
76
84
  console.log("CONTACT PROPERTY FOUND!", contactProperty, "MERGE =", config.merge)
77
85
  const userPath = ['user_User', user]
86
+ for(const key of extendedWith) {
87
+ userPath.push(contactProperty[key+'Type'], contactProperty[key])
88
+ }
78
89
  const userPropertyId = userPath.map(p => JSON.stringify(p)).join(':')
79
90
  const userProperty = await modelRuntime().get(userPropertyId)
80
91
  if(config.merge) {
81
92
  const mergeResult = await config.merge(contactProperty, userProperty)
93
+ const userIdentifiers = {
94
+ contactOrUserType: 'user_User',
95
+ contactOrUser: user
96
+ }
97
+ for(const key of extendedWith) {
98
+ userIdentifiers[key+'Type'] = contactProperty[key+'Type']
99
+ userIdentifiers[key] = contactProperty[key]
100
+ }
82
101
  if(mergeResult && userProperty) {
102
+ await firePropertyUpdateChange({
103
+ service, modelName, app, objectType, writeableProperties,
104
+ id: userPropertyId, identifiers: userIdentifiers,
105
+ entity: userProperty, data: mergeResult, trigger
106
+ })
83
107
  emit({
84
108
  type: modelName + 'Updated',
85
109
  identifiers: {
@@ -89,6 +113,11 @@ definition.processor(function(service, app) {
89
113
  data: mergeResult
90
114
  })
91
115
  } else {
116
+ await firePropertySetChange({
117
+ service, modelName, app, objectType,
118
+ id: userPropertyId, identifiers: userIdentifiers,
119
+ data: mergeResult, trigger
120
+ })
92
121
  emit({
93
122
  type: modelName + 'Set',
94
123
  identifiers: {
@@ -98,6 +127,20 @@ definition.processor(function(service, app) {
98
127
  data: mergeResult
99
128
  })
100
129
  }
130
+ const contactIdentifiers = {
131
+ contactOrUserType: contactType,
132
+ contactOrUser: contact
133
+ }
134
+ for(const key of extendedWith) {
135
+ contactIdentifiers[key+'Type'] = contactProperty[key+'Type']
136
+ contactIdentifiers[key] = contactProperty[key]
137
+ }
138
+ const contactId = polymorphicPropertyId(contactIdentifiers, 'contactOrUser', extendedWith)
139
+ await firePropertyResetChange({
140
+ service, modelName, app, objectType, writeableProperties,
141
+ id: contactId, identifiers: contactIdentifiers,
142
+ entity: contactProperty, trigger
143
+ })
101
144
  emit({
102
145
  type: modelName + 'Reset',
103
146
  identifiers: {
@@ -112,17 +155,25 @@ definition.processor(function(service, app) {
112
155
  extendedIdentifiers[key+'Type'] = contactProperty[key+'Type']
113
156
  extendedIdentifiers[key] = contactProperty[key]
114
157
  }
115
- await service.trigger({ type: modelName + 'Moved' }, {
116
- from: {
117
- contactOrUserType: contactType,
118
- contactOrUser: contact
119
- },
120
- to: {
121
- contactOrUserType: 'user_User',
122
- contactOrUser: user
123
- },
158
+ const from = {
159
+ contactOrUserType: contactType,
160
+ contactOrUser: contact,
124
161
  ...extendedIdentifiers
162
+ }
163
+ const to = {
164
+ contactOrUserType: 'user_User',
165
+ contactOrUser: user,
166
+ ...extendedIdentifiers
167
+ }
168
+ await firePropertyTransferChange({
169
+ service, modelName, app, objectType, writeableProperties,
170
+ fromIdentifiers: from, toIdentifiers: to,
171
+ sourceEntity: contactProperty,
172
+ ownerPrefix: 'contactOrUser',
173
+ extendedWith,
174
+ trigger
125
175
  })
176
+ await service.trigger({ type: modelName + 'Moved' }, { from, to, ...extendedIdentifiers })
126
177
  emit({
127
178
  type: transferEventName,
128
179
  from: {
@@ -230,7 +281,7 @@ definition.processor(function(service, app) {
230
281
  skipValidation: true,
231
282
  queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
232
283
  waitForEvents: true,
233
- async execute(properties, {client, service}, emit) {
284
+ async execute(properties, { client, service, trigger }, emit) {
234
285
  const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
235
286
  for(const extension of extendedWith) owner.push(properties[extension+'Type'], properties[extension])
236
287
  const id = owner.map(p => JSON.stringify(p)).join(':')
@@ -254,6 +305,9 @@ definition.processor(function(service, app) {
254
305
  }
255
306
  await App.validation.validate({ ...identifiers, ...data }, validators,
256
307
  { source: action, action, service, app, client })
308
+ await firePropertySetChange({
309
+ service, modelName, app, objectType, id, identifiers, data, trigger
310
+ })
257
311
  emit({
258
312
  type: eventName,
259
313
  identifiers,
@@ -281,7 +335,7 @@ definition.processor(function(service, app) {
281
335
  skipValidation: true,
282
336
  queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
283
337
  waitForEvents: true,
284
- async execute(properties, { client, service }, emit) {
338
+ async execute(properties, { client, service, trigger }, emit) {
285
339
  const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
286
340
  for(const extension of extendedWith) owner.push(properties[extension+'Type'], properties[extension])
287
341
  const id = owner.map(p => JSON.stringify(p)).join(':')
@@ -306,6 +360,10 @@ definition.processor(function(service, app) {
306
360
  const merged = App.utils.mergeDeep({}, entity, data)
307
361
  await App.validation.validate({ ...identifiers, ...merged }, validators,
308
362
  { source: action, action, service, app, client })
363
+ await firePropertyUpdateChange({
364
+ service, modelName, app, objectType, writeableProperties,
365
+ id, identifiers, entity, data, trigger
366
+ })
309
367
  emit({
310
368
  type: eventName,
311
369
  identifiers,
@@ -331,7 +389,7 @@ definition.processor(function(service, app) {
331
389
  && (config.ownerResetAccess || config.ownerWriteAccess)(params, context),
332
390
  queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
333
391
  waitForEvents: true,
334
- async execute(properties, {client, service}, emit) {
392
+ async execute(properties, { client, service, trigger }, emit) {
335
393
  const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
336
394
  for(const extension of extendedWith) owner.push(properties[extension+'Type'], properties[extension])
337
395
  const id = owner.map(p => JSON.stringify(p)).join(':')
@@ -345,6 +403,10 @@ definition.processor(function(service, app) {
345
403
  identifiers[key+'Type'] = properties[key+'Type']
346
404
  identifiers[key]=properties[key]
347
405
  }
406
+ await firePropertyResetChange({
407
+ service, modelName, app, objectType, writeableProperties,
408
+ id, identifiers, entity, trigger
409
+ })
348
410
  emit({
349
411
  type: eventName,
350
412
  identifiers
@@ -0,0 +1,121 @@
1
+ import App from '@live-change/framework'
2
+ import { fireChangeTriggers, extractObjectData } from '@live-change/relations-plugin'
3
+
4
+ export function propertyIdFromOwnerParts(ownerParts) {
5
+ return ownerParts.map(p => JSON.stringify(p)).join(':')
6
+ }
7
+
8
+ export function polymorphicPropertyId(identifiers, ownerPrefix, extendedWith = []) {
9
+ const parts = [
10
+ identifiers[ownerPrefix + 'Type'],
11
+ identifiers[ownerPrefix]
12
+ ]
13
+ for (const key of extendedWith) {
14
+ parts.push(identifiers[key + 'Type'], identifiers[key])
15
+ }
16
+ return propertyIdFromOwnerParts(parts)
17
+ }
18
+
19
+ export async function fireItemOwnerTransferChange({
20
+ service, modelName, app, objectType, writeableProperties,
21
+ entity, to, trigger
22
+ }) {
23
+ const oldData = extractObjectData(writeableProperties, entity, {})
24
+ const data = App.utils.mergeDeep({}, oldData, to)
25
+ await fireChangeTriggers({
26
+ service, modelName, app, objectType, object: entity.id,
27
+ identifiers: { ...to },
28
+ oldData,
29
+ data,
30
+ trigger
31
+ })
32
+ }
33
+
34
+ export async function fireItemUpdateChange({
35
+ service, modelName, app, objectType, writeableProperties,
36
+ entity, data, identifiers, trigger
37
+ }) {
38
+ await fireChangeTriggers({
39
+ service, modelName, app, objectType, object: entity.id,
40
+ identifiers,
41
+ oldData: extractObjectData(writeableProperties, entity, {}),
42
+ data,
43
+ trigger
44
+ })
45
+ }
46
+
47
+ export async function fireItemDeleteChange({
48
+ service, modelName, app, objectType, writeableProperties,
49
+ entity, identifiers, trigger
50
+ }) {
51
+ await fireChangeTriggers({
52
+ service, modelName, app, objectType, object: entity.id,
53
+ identifiers: identifiers || {
54
+ sessionOrUserType: entity.sessionOrUserType,
55
+ sessionOrUser: entity.sessionOrUser,
56
+ ownerType: entity.ownerType,
57
+ owner: entity.owner
58
+ },
59
+ oldData: extractObjectData(writeableProperties, entity, {}),
60
+ data: null,
61
+ trigger
62
+ })
63
+ }
64
+
65
+ export async function firePropertySetChange({
66
+ service, modelName, app, objectType, id, identifiers, data, trigger
67
+ }) {
68
+ await fireChangeTriggers({
69
+ service, modelName, app, objectType, object: id,
70
+ identifiers, oldData: null, data, trigger
71
+ })
72
+ }
73
+
74
+ export async function firePropertyUpdateChange({
75
+ service, modelName, app, objectType, writeableProperties,
76
+ id, identifiers, entity, data, trigger
77
+ }) {
78
+ await fireChangeTriggers({
79
+ service, modelName, app, objectType, object: id,
80
+ identifiers,
81
+ oldData: entity ? extractObjectData(writeableProperties, entity, {}) : null,
82
+ data,
83
+ trigger
84
+ })
85
+ }
86
+
87
+ export async function firePropertyResetChange({
88
+ service, modelName, app, objectType, writeableProperties,
89
+ id, identifiers, entity, trigger
90
+ }) {
91
+ await fireChangeTriggers({
92
+ service, modelName, app, objectType, object: id,
93
+ identifiers,
94
+ oldData: extractObjectData(writeableProperties, entity, {}),
95
+ data: null,
96
+ trigger
97
+ })
98
+ }
99
+
100
+ export async function firePropertyTransferChange({
101
+ service, modelName, app, objectType, writeableProperties,
102
+ fromIdentifiers, toIdentifiers, sourceEntity, ownerPrefix, extendedWith, trigger
103
+ }) {
104
+ const fromId = polymorphicPropertyId(fromIdentifiers, ownerPrefix, extendedWith)
105
+ const toId = polymorphicPropertyId(toIdentifiers, ownerPrefix, extendedWith)
106
+ const data = extractObjectData(writeableProperties, sourceEntity, {})
107
+ await fireChangeTriggers({
108
+ service, modelName, app, objectType, object: fromId,
109
+ identifiers: fromIdentifiers,
110
+ oldData: data,
111
+ data: null,
112
+ trigger
113
+ })
114
+ await fireChangeTriggers({
115
+ service, modelName, app, objectType, object: toId,
116
+ identifiers: toIdentifiers,
117
+ oldData: null,
118
+ data,
119
+ trigger
120
+ })
121
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/user-service",
3
- "version": "0.9.209",
3
+ "version": "0.9.213",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,9 +22,9 @@
22
22
  },
23
23
  "type": "module",
24
24
  "dependencies": {
25
- "@live-change/framework": "^0.9.209",
26
- "@live-change/relations-plugin": "^0.9.209",
25
+ "@live-change/framework": "^0.9.213",
26
+ "@live-change/relations-plugin": "^0.9.213",
27
27
  "pluralize": "^8.0.0"
28
28
  },
29
- "gitHead": "e1f934934d5d8a119f7ed27aa97bc6b9e9791719"
29
+ "gitHead": "1e22d761822df56c327242bccb3d7aed57631146"
30
30
  }
@@ -3,6 +3,10 @@ import App from '@live-change/framework'
3
3
  import {
4
4
  PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition, TriggerDefinition
5
5
  } from '@live-change/framework'
6
+ import { fireChangeTriggers, extractObjectData } from '@live-change/relations-plugin'
7
+ import {
8
+ fireItemOwnerTransferChange, fireItemUpdateChange, fireItemDeleteChange
9
+ } from './ownerChangeTriggers.js'
6
10
  import { User, Session } from "./model.js"
7
11
 
8
12
  import pluralize from 'pluralize'
@@ -23,6 +27,7 @@ definition.processor(function(service, app) {
23
27
 
24
28
  const config = model.sessionOrUserItem
25
29
  const writeableProperties = modelProperties || config.writableProperties
30
+ const objectType = service.name + '_' + modelName
26
31
 
27
32
  //console.log("USER ITEM", model)
28
33
 
@@ -51,9 +56,13 @@ definition.processor(function(service, app) {
51
56
  validation: ['nonEmpty']
52
57
  },
53
58
  },
54
- async execute({ user, session }, { service }, emit) {
59
+ async execute({ user, session }, { service, trigger }, emit) {
55
60
  const sessionPath = ['session_Session', session]
56
61
  const sessionItems = await modelRuntime().indexRangeGet('bySessionOrUser', sessionPath, {} )
62
+ const toOwner = {
63
+ sessionOrUserType: 'user_User',
64
+ sessionOrUser: user
65
+ }
57
66
  if(config.merge) {
58
67
  const userPath = ['user_User', user]
59
68
  const userItems = await modelRuntime().indexRangeGet('bySessionOrUser', userPath, {} )
@@ -61,6 +70,10 @@ definition.processor(function(service, app) {
61
70
  if(mergeResult) {
62
71
  const { transferred, updated, deleted } = mergeResult
63
72
  for(const entity of transferred) {
73
+ await fireItemOwnerTransferChange({
74
+ service, modelName, app, objectType, writeableProperties,
75
+ entity, to: toOwner, trigger
76
+ })
64
77
  emit({
65
78
  type: modelName + 'Transferred',
66
79
  [modelPropertyName]: entity.id,
@@ -71,6 +84,14 @@ definition.processor(function(service, app) {
71
84
  })
72
85
  }
73
86
  for(const entity of updated) {
87
+ const identifiers = {
88
+ sessionOrUserType: 'user_User',
89
+ sessionOrUser: user
90
+ }
91
+ await fireItemUpdateChange({
92
+ service, modelName, app, objectType, writeableProperties,
93
+ entity, data: entity, identifiers, trigger
94
+ })
74
95
  emit({
75
96
  type: modelName + 'Updated',
76
97
  [modelPropertyName]: entity.id,
@@ -83,6 +104,13 @@ definition.processor(function(service, app) {
83
104
  })
84
105
  }
85
106
  for(const entity of deleted) {
107
+ const stored = await modelRuntime().get(entity.id)
108
+ if(stored) {
109
+ await fireItemDeleteChange({
110
+ service, modelName, app, objectType, writeableProperties,
111
+ entity: stored, trigger
112
+ })
113
+ }
86
114
  emit({
87
115
  type: modelName + 'Deleted',
88
116
  [modelPropertyName]: entity.id,
@@ -91,6 +119,10 @@ definition.processor(function(service, app) {
91
119
  }
92
120
  } else {
93
121
  for(const entity of sessionItems) {
122
+ await fireItemOwnerTransferChange({
123
+ service, modelName, app, objectType, writeableProperties,
124
+ entity, to: toOwner, trigger
125
+ })
94
126
  emit({
95
127
  type: modelName + 'Transferred',
96
128
  [modelPropertyName]: entity.id,
@@ -225,7 +257,7 @@ definition.processor(function(service, app) {
225
257
  },
226
258
  queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
227
259
  waitForEvents: true,
228
- async execute(properties, { client, service }, emit) {
260
+ async execute(properties, { client, service, trigger }, emit) {
229
261
  const id = properties[modelPropertyName] || app.generateUid()
230
262
  const entity = await modelRuntime().get(id)
231
263
  if(entity) throw app.logicError("exists")
@@ -246,6 +278,10 @@ definition.processor(function(service, app) {
246
278
  App.computeDefaults(model, properties, { client, service }), newObject)
247
279
  await App.validation.validate({ ...identifiers, ...data }, validators,
248
280
  { source: action, action, service, app, client })
281
+ await fireChangeTriggers({
282
+ service, modelName, app, objectType, object: id,
283
+ identifiers, oldData: null, data, trigger
284
+ })
249
285
  emit({
250
286
  type: eventName,
251
287
  [modelPropertyName]: id,
@@ -275,7 +311,7 @@ definition.processor(function(service, app) {
275
311
  skipValidation: true,
276
312
  queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
277
313
  waitForEvents: true,
278
- async execute(properties, { client, service }, emit) {
314
+ async execute(properties, { client, service, trigger }, emit) {
279
315
  const entity = await modelRuntime().get(properties[modelPropertyName])
280
316
  if(!entity) throw app.logicError("not_found")
281
317
  if(entity.sessionOrUserType === 'user_User') {
@@ -303,6 +339,10 @@ definition.processor(function(service, app) {
303
339
  entity, data)
304
340
  await App.validation.validate({ ...identifiers, ...merged, [modelPropertyName]: entity.id }, validators,
305
341
  { source: action, action, service, app, client })
342
+ await fireItemUpdateChange({
343
+ service, modelName, app, objectType, writeableProperties,
344
+ entity, data, identifiers, trigger
345
+ })
306
346
  emit({
307
347
  type: eventName,
308
348
  [modelPropertyName]: entity.id,
@@ -329,7 +369,7 @@ definition.processor(function(service, app) {
329
369
  },
330
370
  queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
331
371
  waitForEvents: true,
332
- async execute(properties, { client, service }, emit) {
372
+ async execute(properties, { client, service, trigger }, emit) {
333
373
  const entity = await modelRuntime().get(properties[modelPropertyName])
334
374
  if(!entity) throw app.logicError("not_found")
335
375
  if(entity.sessionOrUserType === 'user_User') {
@@ -345,6 +385,10 @@ definition.processor(function(service, app) {
345
385
  sessionOrUserType: 'session_Session',
346
386
  sessionOrUser: client.session,
347
387
  }
388
+ await fireItemDeleteChange({
389
+ service, modelName, app, objectType, writeableProperties,
390
+ entity, identifiers, trigger
391
+ })
348
392
  emit({
349
393
  type: eventName,
350
394
  [modelPropertyName]: entity.id,
@@ -3,6 +3,14 @@ import App from '@live-change/framework'
3
3
  import {
4
4
  PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition
5
5
  } from '@live-change/framework'
6
+ import { fireChangeTriggers, extractObjectData } from '@live-change/relations-plugin'
7
+ import {
8
+ polymorphicPropertyId,
9
+ firePropertySetChange,
10
+ firePropertyUpdateChange,
11
+ firePropertyResetChange,
12
+ firePropertyTransferChange
13
+ } from './ownerChangeTriggers.js'
6
14
  import { User, Session } from "./model.js"
7
15
  import { allCombinations } from "./combinations.js"
8
16
  import { createIdentifiersProperties } from './utils.js'
@@ -27,6 +35,7 @@ definition.processor(function(service, app) {
27
35
 
28
36
  const config = model.sessionOrUserProperty
29
37
  const writeableProperties = modelProperties || config.writeableProperties
38
+ const objectType = service.name + '_' + modelName
30
39
 
31
40
  if(model.propertyOf) throw new Error("model " + modelName + " already have owner")
32
41
  if(model.propertyOfAny) throw new Error("model " + modelName + " already have owner")
@@ -56,7 +65,7 @@ definition.processor(function(service, app) {
56
65
  validation: ['nonEmpty']
57
66
  },
58
67
  },
59
- async execute({ user, session }, { service }, emit) {
68
+ async execute({ user, session }, { service, trigger }, emit) {
60
69
  const sessionPath = ['session_Session', session]
61
70
  const sessionPropertyId = sessionPath.map(p => JSON.stringify(p)).join(':')
62
71
  const range = {
@@ -81,7 +90,17 @@ definition.processor(function(service, app) {
81
90
 
82
91
  if(config.merge) {
83
92
  const mergeResult = await config.merge(sessionProperty, userProperty)
93
+ const userIdentifiers = {
94
+ sessionOrUserType: 'user_User',
95
+ sessionOrUser: user,
96
+ ...extendedIdentifiers
97
+ }
84
98
  if(mergeResult && userProperty) {
99
+ await firePropertyUpdateChange({
100
+ service, modelName, app, objectType, writeableProperties,
101
+ id: userPropertyId, identifiers: userIdentifiers,
102
+ entity: userProperty, data: mergeResult, trigger
103
+ })
85
104
  emit({
86
105
  type: modelName + 'Updated',
87
106
  identifiers: {
@@ -91,6 +110,11 @@ definition.processor(function(service, app) {
91
110
  data: mergeResult
92
111
  })
93
112
  } else {
113
+ await firePropertySetChange({
114
+ service, modelName, app, objectType,
115
+ id: userPropertyId, identifiers: userIdentifiers,
116
+ data: mergeResult, trigger
117
+ })
94
118
  emit({
95
119
  type: modelName + 'Set',
96
120
  identifiers: {
@@ -101,6 +125,17 @@ definition.processor(function(service, app) {
101
125
  })
102
126
  }
103
127
  if(!config.mergeWithoutDelete) {
128
+ const sessionIdentifiers = {
129
+ sessionOrUserType: 'session_Session',
130
+ sessionOrUser: session,
131
+ ...extendedIdentifiers
132
+ }
133
+ const sessionId = polymorphicPropertyId(sessionIdentifiers, 'sessionOrUser', extendedWith)
134
+ await firePropertyResetChange({
135
+ service, modelName, app, objectType, writeableProperties,
136
+ id: sessionId, identifiers: sessionIdentifiers,
137
+ entity: sessionProperty, trigger
138
+ })
104
139
  emit({
105
140
  type: modelName + 'Reset',
106
141
  identifiers: {
@@ -111,18 +146,25 @@ definition.processor(function(service, app) {
111
146
  }
112
147
  } else {
113
148
  if(!userProperty) {
114
- await service.trigger({ type: modelName + 'Moved' }, {
115
- from: {
116
- sessionOrUserType: 'session_Session',
117
- sessionOrUser: session,
118
- ...extendedIdentifiers
119
- },
120
- to: {
121
- sessionOrUserType: 'user_User',
122
- sessionOrUser: user,
123
- ...extendedIdentifiers
124
- },
149
+ const from = {
150
+ sessionOrUserType: 'session_Session',
151
+ sessionOrUser: session,
152
+ ...extendedIdentifiers
153
+ }
154
+ const to = {
155
+ sessionOrUserType: 'user_User',
156
+ sessionOrUser: user,
157
+ ...extendedIdentifiers
158
+ }
159
+ await firePropertyTransferChange({
160
+ service, modelName, app, objectType, writeableProperties,
161
+ fromIdentifiers: from, toIdentifiers: to,
162
+ sourceEntity: sessionProperty,
163
+ ownerPrefix: 'sessionOrUser',
164
+ extendedWith,
165
+ trigger
125
166
  })
167
+ await service.trigger({ type: modelName + 'Moved' }, { from, to })
126
168
  emit({
127
169
  type: transferEventName,
128
170
  from: {
@@ -246,7 +288,7 @@ definition.processor(function(service, app) {
246
288
  skipValidation: true,
247
289
  queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
248
290
  waitForEvents: true,
249
- async execute(properties, {client, service}, emit) {
291
+ async execute(properties, { client, service, trigger }, emit) {
250
292
  const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
251
293
  for(const extension of extendedWith) owner.push(properties[extension+'Type'], properties[extension])
252
294
  const id = owner.map(p => JSON.stringify(p)).join(':')
@@ -272,6 +314,9 @@ definition.processor(function(service, app) {
272
314
  identifiers[key+'Type'] = properties[key+'Type']
273
315
  identifiers[key]=properties[key]
274
316
  }
317
+ await firePropertySetChange({
318
+ service, modelName, app, objectType, id, identifiers, data, trigger
319
+ })
275
320
  emit({
276
321
  type: eventName,
277
322
  identifiers,
@@ -297,7 +342,7 @@ definition.processor(function(service, app) {
297
342
  skipValidation: true,
298
343
  queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
299
344
  waitForEvents: true,
300
- async execute(properties, { client, service }, emit) {
345
+ async execute(properties, { client, service, trigger }, emit) {
301
346
  const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
302
347
  for(const extension of extendedWith) owner.push(properties[extension+'Type'], properties[extension])
303
348
  const id = owner.map(p => JSON.stringify(p)).join(':')
@@ -325,6 +370,10 @@ definition.processor(function(service, app) {
325
370
  const merged = App.utils.mergeDeep({}, entity, data)
326
371
  await App.validation.validate({ ...identifiers, ...merged }, validators,
327
372
  { source: action, action, service, app, client })
373
+ await firePropertyUpdateChange({
374
+ service, modelName, app, objectType, writeableProperties,
375
+ id, identifiers, entity, data, trigger
376
+ })
328
377
  emit({
329
378
  type: eventName,
330
379
  identifiers,
@@ -351,7 +400,7 @@ definition.processor(function(service, app) {
351
400
  skipValidation: true,
352
401
  queuedBy: (command) => command.client.user ? 'u:'+command.client.user : 's:'+command.client.session,
353
402
  waitForEvents: true,
354
- async execute(properties, { client, service }, emit) {
403
+ async execute(properties, { client, service, trigger }, emit) {
355
404
  const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
356
405
  for(const extension of extendedWith) owner.push(properties[extension+'Type'], properties[extension])
357
406
  const id = owner.map(p => JSON.stringify(p)).join(':')
@@ -376,9 +425,11 @@ definition.processor(function(service, app) {
376
425
  if(!entity) {
377
426
  const data = App.utils.mergeDeep({},
378
427
  App.computeDefaults(model, properties, { client, service } ), updateObject)
379
- //console.log('V', { ...identifiers, ...data}, validators)
380
428
  await App.validation.validate({ ...identifiers, ...data}, validators,
381
429
  { source: action, action, service, app, client })
430
+ await firePropertySetChange({
431
+ service, modelName, app, objectType, id, identifiers, data, trigger
432
+ })
382
433
  emit({
383
434
  type: setEventName,
384
435
  identifiers,
@@ -388,9 +439,12 @@ definition.processor(function(service, app) {
388
439
  const computedUpdates = App.computeUpdates(model, { ...entity, ...properties }, { client, service })
389
440
  const data = App.utils.mergeDeep({}, updateObject, computedUpdates)
390
441
  const merged = App.utils.mergeDeep({}, entity, data)
391
- //console.log('V', { ...identifiers, ...merged}, validators)
392
442
  await App.validation.validate({ ...identifiers, ...merged}, validators,
393
443
  { source: action, action, service, app, client })
444
+ await firePropertyUpdateChange({
445
+ service, modelName, app, objectType, writeableProperties,
446
+ id, identifiers, entity, data, trigger
447
+ })
394
448
  emit({
395
449
  type: updatedEventName,
396
450
  identifiers,
@@ -415,7 +469,7 @@ definition.processor(function(service, app) {
415
469
  properties: {
416
470
  ...extendedIdentifiersProperties,
417
471
  },
418
- async execute(properties, {client, service}, emit) {
472
+ async execute(properties, { client, service, trigger }, emit) {
419
473
  const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
420
474
  for(const extension of extendedWith) owner.push(properties[extension+'Type'], properties[extension])
421
475
  const id = owner.map(p => JSON.stringify(p)).join(':')
@@ -432,6 +486,10 @@ definition.processor(function(service, app) {
432
486
  identifiers[key+'Type'] = properties[key+'Type']
433
487
  identifiers[key]=properties[key]
434
488
  }
489
+ await firePropertyResetChange({
490
+ service, modelName, app, objectType, writeableProperties,
491
+ id, identifiers, entity, trigger
492
+ })
435
493
  emit({
436
494
  type: eventName,
437
495
  identifiers
package/userItem.js CHANGED
@@ -3,6 +3,8 @@ import App from '@live-change/framework'
3
3
  import {
4
4
  PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition
5
5
  } from '@live-change/framework'
6
+ import { mcpFields } from '@live-change/relations-plugin'
7
+ import { fireChangeTriggers, extractObjectData } from '@live-change/relations-plugin'
6
8
  import { User } from "./model.js"
7
9
  import pluralize from 'pluralize'
8
10
 
@@ -22,6 +24,7 @@ definition.processor(function(service, app) {
22
24
 
23
25
  const config = model.userItem
24
26
  const writeableProperties = modelProperties || config.writableProperties
27
+ const objectType = service.name + '_' + modelName
25
28
 
26
29
  //console.log("USER ITEM", model)
27
30
  if(model.itemOf) throw new Error("model " + modelName + " already have owner")
@@ -44,6 +47,7 @@ definition.processor(function(service, app) {
44
47
  return config.userReadAccess ? config.userReadAccess(params, context) : true
45
48
  },
46
49
  properties: App.rangeProperties,
50
+ ...mcpFields(config, 'list'),
47
51
  daoPath(range, { client, context }) {
48
52
  const path = modelRuntime().indexRangePath('byUser', [client.user], range )
49
53
  return path
@@ -60,6 +64,7 @@ definition.processor(function(service, app) {
60
64
  return config.userReadAccess ? config.userReadAccess(params, context) : true
61
65
  },
62
66
  properties: App.rangeProperties,
67
+ ...mcpFields(config, 'list'),
63
68
  daoPath(range, { client, context }) {
64
69
  return modelRuntime().sortedIndexRangePath('byUser' + sortFieldUc, [client.user], range )
65
70
  }
@@ -80,6 +85,7 @@ definition.processor(function(service, app) {
80
85
  return config.userReadAccess ? config.userReadAccess(params, context) : true
81
86
  },
82
87
  properties: App.rangeProperties,
88
+ ...mcpFields(config, 'read'),
83
89
  daoPath(params, { client, context }) {
84
90
  const path = modelRuntime().path(params[modelPropertyName])
85
91
  return path
@@ -94,6 +100,7 @@ definition.processor(function(service, app) {
94
100
  name: actionName,
95
101
  skipValidation: true,
96
102
  access: config.userCreateAccess || config.userWriteAccess,
103
+ ...mcpFields(config, 'create'),
97
104
  properties: {
98
105
  ...originalModelProperties,
99
106
  [modelPropertyName]: {
@@ -103,7 +110,7 @@ definition.processor(function(service, app) {
103
110
  },
104
111
  queuedBy: (command) => command.client.user,
105
112
  waitForEvents: true,
106
- async execute(properties, { client, service }, emit) {
113
+ async execute(properties, { client, service, trigger }, emit) {
107
114
  const id = properties[modelPropertyName] || app.generateUid()
108
115
  const entity = await modelRuntime().get(id)
109
116
  if(entity) throw app.logicError("exists")
@@ -117,6 +124,11 @@ definition.processor(function(service, app) {
117
124
  App.computeDefaults(model, properties, { client, service }), newObject)
118
125
  await App.validation.validate(data, validators,
119
126
  { source: action, action, service, app, client })
127
+ const identifiers = { user: client.user }
128
+ await fireChangeTriggers({
129
+ service, modelName, app, objectType, object: id,
130
+ identifiers, oldData: null, data, trigger
131
+ })
120
132
  emit({
121
133
  type: eventName,
122
134
  [modelPropertyName]: id,
@@ -138,6 +150,7 @@ definition.processor(function(service, app) {
138
150
  service.actions[actionName] = new ActionDefinition({
139
151
  name: actionName,
140
152
  access: config.userUpdateAccess || config.userWriteAccess,
153
+ ...mcpFields(config, 'update'),
141
154
  properties: {
142
155
  ...originalModelProperties,
143
156
  [modelPropertyName]: {
@@ -148,7 +161,7 @@ definition.processor(function(service, app) {
148
161
  skipValidation: true,
149
162
  queuedBy: (command) => command.client.user,
150
163
  waitForEvents: true,
151
- async execute(properties, { client, service }, emit) {
164
+ async execute(properties, { client, service, trigger }, emit) {
152
165
  const entity = await modelRuntime().get(properties[modelPropertyName])
153
166
  if(!entity) throw app.logicError("not_found")
154
167
  if(entity.user !== client.user) throw app.logicError("not_authorized")
@@ -162,6 +175,14 @@ definition.processor(function(service, app) {
162
175
  const data = App.utils.mergeDeep({}, updateObject, computedUpdates)
163
176
  const merged = App.utils.mergeDeep({}, entity, data)
164
177
  await App.validation.validate({ ...merged, [modelPropertyName]: entity.id }, validators, { source: action, action, service, app, client })
178
+ const identifiers = { user: client.user }
179
+ await fireChangeTriggers({
180
+ service, modelName, app, objectType, object: entity.id,
181
+ identifiers,
182
+ oldData: extractObjectData(writeableProperties, entity, {}),
183
+ data,
184
+ trigger
185
+ })
165
186
  emit({
166
187
  type: eventName,
167
188
  [modelPropertyName]: entity.id,
@@ -182,6 +203,7 @@ definition.processor(function(service, app) {
182
203
  service.actions[actionName] = new ActionDefinition({
183
204
  name: actionName,
184
205
  access: config.userDeleteAccess || config.userWriteAccess,
206
+ ...mcpFields(config, 'delete'),
185
207
  properties: {
186
208
  [modelPropertyName]: {
187
209
  type: model,
@@ -190,10 +212,18 @@ definition.processor(function(service, app) {
190
212
  },
191
213
  queuedBy: (command) => command.client.user,
192
214
  waitForEvents: true,
193
- async execute(properties, { client, service }, emit) {
215
+ async execute(properties, { client, service, trigger }, emit) {
194
216
  const entity = await modelRuntime().get(properties[modelPropertyName])
195
217
  if(!entity) throw app.logicError("not_found")
196
218
  if(entity.user !== client.user) throw app.logicError("not_authorized")
219
+ const identifiers = { user: client.user }
220
+ await fireChangeTriggers({
221
+ service, modelName, app, objectType, object: entity.id,
222
+ identifiers,
223
+ oldData: extractObjectData(writeableProperties, entity, {}),
224
+ data: null,
225
+ trigger
226
+ })
197
227
  emit({
198
228
  type: eventName,
199
229
  [modelPropertyName]: entity.id,
package/userProperty.js CHANGED
@@ -3,6 +3,7 @@ import App from "@live-change/framework"
3
3
  import {
4
4
  PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition
5
5
  } from '@live-change/framework'
6
+ import { fireChangeTriggers, extractObjectData } from '@live-change/relations-plugin'
6
7
  import { User } from "./model.js"
7
8
 
8
9
  definition.processor(function(service, app) {
@@ -23,6 +24,7 @@ definition.processor(function(service, app) {
23
24
 
24
25
  const config = model.userProperty
25
26
  const writeableProperties = modelProperties || config.writableProperties
27
+ const objectType = service.name + '_' + modelName
26
28
 
27
29
  if(model.propertyOf) throw new Error("model " + modelName + " already have owner")
28
30
  model.propertyOf = {
@@ -79,7 +81,7 @@ definition.processor(function(service, app) {
79
81
  skipValidation: true,
80
82
  queuedBy: (command) => command.client.user,
81
83
  waitForEvents: true,
82
- async execute(properties, {client, service}, emit) {
84
+ async execute(properties, { client, service, trigger }, emit) {
83
85
  let newObject = {}
84
86
  for(const propertyName of writeableProperties) {
85
87
  if(properties.hasOwnProperty(propertyName)) {
@@ -89,6 +91,12 @@ definition.processor(function(service, app) {
89
91
  const data = App.utils.mergeDeep({},
90
92
  App.computeDefaults(model, properties, { client, service }), newObject)
91
93
  await App.validation.validate(data, validators, { source: action, action, service, app, client })
94
+ const id = client.user
95
+ const identifiers = { user: client.user }
96
+ await fireChangeTriggers({
97
+ service, modelName, app, objectType, object: id,
98
+ identifiers, oldData: null, data, trigger
99
+ })
92
100
  emit({
93
101
  type: eventName,
94
102
  identifiers: {
@@ -115,7 +123,7 @@ definition.processor(function(service, app) {
115
123
  skipValidation: true,
116
124
  queuedBy: (command) => command.client.user,
117
125
  waitForEvents: true,
118
- async execute(properties, { client, service }, emit) {
126
+ async execute(properties, { client, service, trigger }, emit) {
119
127
  const entity = await modelRuntime().get(client.user)
120
128
  if(!entity) throw app.logicError("not_found")
121
129
  let updateObject = {}
@@ -129,6 +137,15 @@ definition.processor(function(service, app) {
129
137
  const merged = App.utils.mergeDeep({}, entity, data)
130
138
  await App.validation.validate({ user: client.user, ...merged }, validators,
131
139
  { source: action, action, service, app, client })
140
+ const id = client.user
141
+ const identifiers = { user: client.user }
142
+ await fireChangeTriggers({
143
+ service, modelName, app, objectType, object: id,
144
+ identifiers,
145
+ oldData: extractObjectData(writeableProperties, entity, {}),
146
+ data,
147
+ trigger
148
+ })
132
149
  emit({
133
150
  type: eventName,
134
151
  identifiers: {
@@ -151,9 +168,18 @@ definition.processor(function(service, app) {
151
168
  access: config.userResetAccess || config.userWriteAccess,
152
169
  queuedBy: (command) => command.client.user,
153
170
  waitForEvents: true,
154
- async execute(properties, {client, service}, emit) {
171
+ async execute(properties, { client, service, trigger }, emit) {
155
172
  const entity = await modelRuntime().indexObjectGet('byUser', client.user)
156
173
  if (!entity) throw app.logicError("not_found")
174
+ const id = client.user
175
+ const identifiers = { user: client.user }
176
+ await fireChangeTriggers({
177
+ service, modelName, app, objectType, object: id,
178
+ identifiers,
179
+ oldData: extractObjectData(writeableProperties, entity, {}),
180
+ data: null,
181
+ trigger
182
+ })
157
183
  emit({
158
184
  type: eventName,
159
185
  identifiers: {