@live-change/relations-plugin 0.8.23 → 0.8.25

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.
@@ -1,10 +1,13 @@
1
- import { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition } from "@live-change/framework"
1
+ import App from '@live-change/framework'
2
+ import {
3
+ PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, TriggerDefinition
4
+ } from "@live-change/framework"
2
5
  import {
3
6
  extractIdentifiers, extractObjectData, generateId, extractIdParts, prepareAccessControl
4
7
  } from "./utils.js"
5
8
  import { fireChangeTriggers } from "./changeTriggers.js"
6
9
 
7
- function defineView(config, context) {
10
+ function defineView(config, context, external = true) {
8
11
  const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
9
12
  modelName, others, model } = context
10
13
  const viewProperties = {}
@@ -16,7 +19,7 @@ function defineView(config, context) {
16
19
  }
17
20
  const viewName = config.name || ((config.prefix ? (config.prefix + joinedOthersClassName) : joinedOthersPropertyName) +
18
21
  'Owned' + modelName + (config.suffix || ''))
19
- const accessControl = config.readAccessControl || config.writeAccessControl
22
+ const accessControl = external && (config.readAccessControl || config.writeAccessControl)
20
23
  prepareAccessControl(accessControl, otherPropertyNames, others)
21
24
  service.views[viewName] = new ViewDefinition({
22
25
  name: viewName,
@@ -26,7 +29,8 @@ function defineView(config, context) {
26
29
  returns: {
27
30
  type: model,
28
31
  },
29
- access: config.readAccess || config.writeAccess,
32
+ internal: !external,
33
+ access: external && (config.readAccess || config.writeAccess),
30
34
  accessControl,
31
35
  daoPath(properties, { client, context }) {
32
36
  const idParts = extractIdParts(otherPropertyNames, properties)
@@ -37,54 +41,110 @@ function defineView(config, context) {
37
41
  })
38
42
  }
39
43
 
40
- function defineSetAction(config, context) {
44
+ function getSetFunction( validators, validationContext, config, context) {
41
45
  const {
42
46
  service, app, model, objectType,
43
47
  otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others
44
48
  } = context
45
49
  const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Set'
50
+ async function execute(properties, { client, service }, emit) {
51
+ const idParts = extractIdParts(otherPropertyNames, properties)
52
+ const id = idParts.length > 1 ? idParts.map(p => JSON.stringify(p)).join(':') : idParts[0]
53
+ const identifiers = extractIdentifiers(otherPropertyNames, properties)
54
+ const data = extractObjectData(writeableProperties, properties,
55
+ App.computeDefaults(model, properties, { client, service } ))
56
+ await App.validation.validate({ ...identifiers, ...data }, validators,
57
+ validationContext)
58
+ await fireChangeTriggers(context, objectType, identifiers, id, null, data)
59
+ emit({
60
+ type: eventName,
61
+ identifiers, data
62
+ })
63
+ }
64
+ return execute
65
+ }
66
+
67
+ function defineSetAction(config, context) {
68
+ const {
69
+ service, app, model, objectType,
70
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others
71
+ } = context
46
72
  const actionName = 'set' + joinedOthersClassName + 'Owned' + modelName
47
73
  const accessControl = config.setAccessControl || config.writeAccessControl
48
74
  prepareAccessControl(accessControl, otherPropertyNames, others)
49
- service.actions[actionName] = new ActionDefinition({
75
+ const action = new ActionDefinition({
50
76
  name: actionName,
51
- properties: {
52
- ...(model.properties)
53
- },
77
+ properties: { ...(model.properties) },
54
78
  access: config.setAccess || config.writeAccess,
55
79
  accessControl,
56
80
  skipValidation: true,
57
81
  queuedBy: otherPropertyNames,
58
82
  waitForEvents: true,
59
- async execute(properties, { client, service }, emit) {
60
- const idParts = extractIdParts(otherPropertyNames, properties)
61
- const id = idParts.length > 1 ? idParts.map(p => JSON.stringify(p)).join(':') : idParts[0]
62
- const identifiers = extractIdentifiers(otherPropertyNames, properties)
63
- const data = extractObjectData(writeableProperties, properties,
64
- App.computeDefaults(model, properties, { client, service } ))
65
- await App.validation.validate({ ...identifiers, ...data }, validators,
66
- { source: action, action, service, app, client })
67
- await fireChangeTriggers(context, objectType, identifiers, id, null, data)
68
- emit({
69
- type: eventName,
70
- identifiers, data
71
- })
72
- }
83
+ execute: () => { throw new Error('not generated yet') }
73
84
  })
74
- const action = service.actions[actionName]
75
85
  const validators = App.validation.getValidators(action, service, action)
86
+ const validationContext = { source: action, action }
87
+ action.execute = getSetFunction( validators, validationContext, config, context)
88
+ service.actions[actionName] = action
76
89
  }
77
90
 
78
- function defineUpdateAction(config, context) {
91
+ function defineSetTrigger(config, context) {
92
+ const {
93
+ service, app, model, objectType,
94
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others
95
+ } = context
96
+ const actionName = 'set' + joinedOthersClassName + 'Owned' + modelName
97
+ const triggerName = `${service.name}_${actionName}`
98
+ const trigger = new TriggerDefinition({
99
+ name: triggerName,
100
+ properties: { ...(model.properties) },
101
+ skipValidation: true,
102
+ queuedBy: otherPropertyNames,
103
+ waitForEvents: true,
104
+ execute: () => { throw new Error('not generated yet') }
105
+ })
106
+ const validators = App.validation.getValidators(trigger, service, trigger)
107
+ const validationContext = { source: trigger, trigger }
108
+ trigger.execute = getSetFunction( validators, validationContext, config, context)
109
+ service.triggers[triggerName] = [trigger]
110
+ }
111
+
112
+ function getUpdateFunction( validators, validationContext, config, context) {
79
113
  const {
80
114
  service, app, model, modelRuntime, objectType,
81
115
  otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others
82
116
  } = context
83
117
  const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Updated'
118
+ return async function execute(properties, { client, service }, emit) {
119
+ const identifiers = extractIdentifiers(otherPropertyNames, properties)
120
+ const id = generateId(otherPropertyNames, properties)
121
+ const entity = await modelRuntime().get(id)
122
+ if (!entity) throw new Error('not_found')
123
+ const data = App.utils.mergeDeep({},
124
+ extractObjectData(writeableProperties, properties, entity),
125
+ App.computeUpdates(model, { ...entity, ...properties }, { client, service })
126
+ )
127
+ await App.validation.validate({ ...identifiers, ...data }, validators,
128
+ validationContext)
129
+ const oldData = extractObjectData(writeableProperties, entity, {})
130
+ await fireChangeTriggers(context, objectType, identifiers, id,
131
+ entity ? extractObjectData(writeableProperties, entity, {}) : null, data)
132
+ emit({
133
+ type: eventName,
134
+ identifiers, data
135
+ })
136
+ }
137
+ }
138
+
139
+ function defineUpdateAction(config, context) {
140
+ const {
141
+ service, app, model, modelRuntime, objectType,
142
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others
143
+ } = context
84
144
  const actionName = 'update' + joinedOthersClassName + 'Owned' + modelName
85
145
  const accessControl = config.updateAccessControl || config.writeAccessControl
86
146
  prepareAccessControl(accessControl, otherPropertyNames, others)
87
- service.actions[actionName] = new ActionDefinition({
147
+ const action = new ActionDefinition({
88
148
  name: actionName,
89
149
  properties: {
90
150
  ...(model.properties)
@@ -94,25 +154,60 @@ function defineUpdateAction(config, context) {
94
154
  skipValidation: true,
95
155
  queuedBy: otherPropertyNames,
96
156
  waitForEvents: true,
97
- async execute(properties, { client, service }, emit) {
98
- const identifiers = extractIdentifiers(otherPropertyNames, properties)
99
- const id = generateId(otherPropertyNames, properties)
100
- const entity = await modelRuntime().get(id)
101
- if (!entity) throw new Error('not_found')
102
- const data = extractObjectData(writeableProperties, properties, entity)
103
- await App.validation.validate({ ...identifiers, ...data }, validators,
104
- { source: action, action, service, app, client })
105
- const oldData = extractObjectData(writeableProperties, entity, {})
106
- await fireChangeTriggers(context, objectType, identifiers, id,
107
- entity ? extractObjectData(writeableProperties, entity, {}) : null, data)
108
- emit({
109
- type: eventName,
110
- identifiers, data
111
- })
112
- }
157
+ execute: () => { throw new Error('not generated yet') }
113
158
  })
114
- const action = service.actions[actionName]
115
159
  const validators = App.validation.getValidators(action, service, action)
160
+ const validationContext = { source: action, action }
161
+ action.execute = getUpdateFunction( validators, validationContext, config, context)
162
+ service.actions[actionName] = action
163
+ }
164
+
165
+ function defineUpdateTrigger(config, context) {
166
+ const {
167
+ service, app, model, modelRuntime, objectType,
168
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others
169
+ } = context
170
+ const actionName = 'update' + joinedOthersClassName + 'Owned' + modelName
171
+ const triggerName = `${service.name}_${actionName}`
172
+ const trigger = new TriggerDefinition({
173
+ name: triggerName,
174
+ properties: {
175
+ ...(model.properties)
176
+ },
177
+ skipValidation: true,
178
+ queuedBy: otherPropertyNames,
179
+ waitForEvents: true,
180
+ execute: () => { throw new Error('not generated yet') }
181
+ })
182
+ const validators = App.validation.getValidators(trigger, service, trigger)
183
+ const validationContext = { source: trigger, trigger }
184
+ trigger.execute = getUpdateFunction( validators, validationContext, config, context)
185
+ service.triggers[triggerName] = [trigger]
186
+ }
187
+
188
+ function getSetOrUpdateFunction( validators, validationContext, config, context) {
189
+ const {
190
+ service, app, model, modelRuntime, objectType,
191
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others
192
+ } = context
193
+ const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Updated'
194
+ return async function execute(properties, { client, service }, emit) {
195
+ const identifiers = extractIdentifiers(otherPropertyNames, properties)
196
+ const id = generateId(otherPropertyNames, properties)
197
+ const entity = await modelRuntime().get(id)
198
+ const data = App.utils.mergeDeep({},
199
+ App.computeDefaults(model, properties, { client, service } ),
200
+ extractObjectData(writeableProperties, properties, entity),
201
+ App.computeUpdates(model, { ...entity, ...properties }, { client, service })
202
+ )
203
+ await App.validation.validate({ ...identifiers, ...data }, validators, { ...validationContext, service, app, client })
204
+ await fireChangeTriggers(context, objectType, identifiers, id,
205
+ entity ? extractObjectData(writeableProperties, entity, {}) : null, data)
206
+ emit({
207
+ type: eventName,
208
+ identifiers, data
209
+ })
210
+ }
116
211
  }
117
212
 
118
213
  function defineSetOrUpdateAction(config, context) {
@@ -124,7 +219,7 @@ function defineSetOrUpdateAction(config, context) {
124
219
  const actionName = 'update' + joinedOthersClassName + 'Owned' + modelName
125
220
  const accessControl = config.updateAccessControl || config.writeAccessControl
126
221
  prepareAccessControl(accessControl, otherPropertyNames, others)
127
- service.actions[actionName] = new ActionDefinition({
222
+ const action = new ActionDefinition({
128
223
  name: actionName,
129
224
  properties: {
130
225
  ...(model.properties)
@@ -134,38 +229,66 @@ function defineSetOrUpdateAction(config, context) {
134
229
  skipValidation: true,
135
230
  queuedBy: otherPropertyNames,
136
231
  waitForEvents: true,
137
- async execute(properties, { client, service }, emit) {
138
- const identifiers = extractIdentifiers(otherPropertyNames, properties)
139
- const id = generateId(otherPropertyNames, properties)
140
- const entity = await modelRuntime().get(id)
141
- const data = extractObjectData(writeableProperties, properties, {
142
- ...App.computeDefaults(model, properties, { client, service } ),
143
- ...entity
144
- })
145
- await App.validation.validate({ ...identifiers, ...data }, validators,
146
- { source: action, action, service, app, client })
147
- await fireChangeTriggers(context, objectType, identifiers, id,
148
- entity ? extractObjectData(writeableProperties, entity, {}) : null, data)
149
- emit({
150
- type: eventName,
151
- identifiers, data
152
- })
153
- }
232
+ execute: () => { throw new Error('not generated yet') }
154
233
  })
155
- const action = service.actions[actionName]
156
234
  const validators = App.validation.getValidators(action, service, action)
235
+ const validationContext = { source: action, action }
236
+ action.execute = getSetOrUpdateFunction( validators, validationContext, config, context)
237
+ service.actions[actionName] = action
157
238
  }
158
239
 
159
- function defineResetAction(config, context) {
240
+ function defineSetOrUpdateTrigger(config, context) {
241
+ const {
242
+ service, app, model, modelRuntime, objectType,
243
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others
244
+ } = context
245
+ const actionName = 'update' + joinedOthersClassName + 'Owned' + modelName
246
+ const triggerName = `${service.name}_${actionName}`
247
+ const trigger = new TriggerDefinition({
248
+ name: triggerName,
249
+ properties: {
250
+ ...(model.properties)
251
+ },
252
+ skipValidation: true,
253
+ queuedBy: otherPropertyNames,
254
+ waitForEvents: true,
255
+ execute: () => { throw new Error('not generated yet') }
256
+ })
257
+ const validators = App.validation.getValidators(trigger, service, trigger)
258
+ const validationContext = { source: trigger, trigger }
259
+ trigger.execute = getSetOrUpdateFunction( validators, validationContext, config, context)
260
+ service.triggers[triggerName] = [trigger]
261
+ }
262
+
263
+ function getResetFunction( validators, validationContext, config, context) {
160
264
  const {
161
265
  service, modelRuntime, modelPropertyName, objectType,
162
266
  otherPropertyNames, joinedOthersPropertyName, modelName, joinedOthersClassName, model, others, writeableProperties
163
267
  } = context
164
268
  const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Reset'
269
+ return async function execute(properties, { client, service }, emit) {
270
+ const identifiers = extractIdentifiers(otherPropertyNames, properties)
271
+ const id = generateId(otherPropertyNames, properties)
272
+ const entity = await modelRuntime().get(id)
273
+ if (!entity) throw new Error('not_found')
274
+ await fireChangeTriggers(context, objectType, identifiers, id,
275
+ entity ? extractObjectData(writeableProperties, entity, {}) : null, null)
276
+ emit({
277
+ type: eventName,
278
+ identifiers
279
+ })
280
+ }
281
+ }
282
+
283
+ function defineResetAction(config, context) {
284
+ const {
285
+ service, modelRuntime, modelPropertyName, objectType,
286
+ otherPropertyNames, joinedOthersPropertyName, modelName, joinedOthersClassName, model, others, writeableProperties
287
+ } = context
165
288
  const actionName = 'reset' + joinedOthersClassName + 'Owned' + modelName
166
289
  const accessControl = config.resetAccessControl || config.writeAccessControl
167
290
  prepareAccessControl(accessControl, otherPropertyNames, others)
168
- service.actions[actionName] = new ActionDefinition({
291
+ const action = new ActionDefinition({
169
292
  name: actionName,
170
293
  properties: {
171
294
  [modelPropertyName]: {
@@ -177,19 +300,41 @@ function defineResetAction(config, context) {
177
300
  accessControl,
178
301
  queuedBy: otherPropertyNames,
179
302
  waitForEvents: true,
180
- async execute(properties, { client, service }, emit) {
181
- const identifiers = extractIdentifiers(otherPropertyNames, properties)
182
- const id = generateId(otherPropertyNames, properties)
183
- const entity = await modelRuntime().get(id)
184
- if (!entity) throw new Error('not_found')
185
- await fireChangeTriggers(context, objectType, identifiers, id,
186
- entity ? extractObjectData(writeableProperties, entity, {}) : null, null)
187
- emit({
188
- type: eventName,
189
- identifiers
190
- })
191
- }
303
+ execute: () => { throw new Error('not generated yet') }
304
+ })
305
+ const validators = App.validation.getValidators(action, service, action)
306
+ const validationContext = { source: action, action }
307
+ action.execute = getResetFunction( validators, validationContext, config, context)
308
+ service.actions[actionName] = action
309
+ }
310
+
311
+ function defineResetTrigger(config, context) {
312
+ const {
313
+ service, modelRuntime, modelPropertyName, objectType,
314
+ otherPropertyNames, joinedOthersPropertyName, modelName, joinedOthersClassName, model, others, writeableProperties
315
+ } = context
316
+ const actionName = 'reset' + joinedOthersClassName + 'Owned' + modelName
317
+ const triggerName = `${service.name}_${actionName}`
318
+ const trigger = new TriggerDefinition({
319
+ name: triggerName,
320
+ properties: {
321
+ [modelPropertyName]: {
322
+ type: model,
323
+ validation: ['nonEmpty']
324
+ }
325
+ },
326
+ queuedBy: otherPropertyNames,
327
+ waitForEvents: true,
328
+ execute: () => { throw new Error('not generated yet') }
192
329
  })
330
+ const validators = App.validation.getValidators(trigger, service, trigger)
331
+ const validationContext = { source: trigger, trigger }
332
+ trigger.execute = getResetFunction( validators, validationContext, config, context)
333
+ service.triggers[triggerName] = [trigger]
193
334
  }
194
335
 
195
- export { defineView, defineSetAction, defineUpdateAction, defineSetOrUpdateAction, defineResetAction }
336
+ export {
337
+ defineView,
338
+ defineSetAction, defineUpdateAction, defineSetOrUpdateAction, defineResetAction,
339
+ defineSetTrigger, defineUpdateTrigger, defineSetOrUpdateTrigger, defineResetTrigger
340
+ }