@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,5 +1,7 @@
1
1
  import App from '@live-change/framework'
2
- import { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition } from '@live-change/framework'
2
+ import {
3
+ PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, TriggerDefinition
4
+ } from '@live-change/framework'
3
5
  import {
4
6
  extractTypeAndIdParts, extractIdentifiersWithTypes, generateAnyId, prepareAccessControl
5
7
  } from './utilsAny.js'
@@ -24,7 +26,7 @@ function createIdentifiersProperties(keys) {
24
26
  return identifiers
25
27
  }
26
28
 
27
- function defineObjectView(config, context) {
29
+ function defineObjectView(config, context, external = true) {
28
30
  const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
29
31
  modelName, others, model } = context
30
32
  const viewProperties = {}
@@ -38,7 +40,8 @@ function defineObjectView(config, context) {
38
40
  validation: ['nonEmpty']
39
41
  })
40
42
  }
41
- const accessControl = config.singleAccessControl || config.readAccessControl || config.writeAccessControl
43
+ const accessControl = external
44
+ && (config.singleAccessControl || config.readAccessControl || config.writeAccessControl)
42
45
  prepareAccessControl(accessControl, otherPropertyNames)
43
46
  const viewName = config.name || ((config.prefix ? (config.prefix + joinedOthersClassName) : joinedOthersPropertyName) +
44
47
  context.reverseRelationWord + modelName + (config.suffix || ''))
@@ -50,7 +53,8 @@ function defineObjectView(config, context) {
50
53
  returns: {
51
54
  type: model,
52
55
  },
53
- access: config.singleAccess || config.readAccess,
56
+ internal: !external,
57
+ access: external && (config.singleAccess || config.readAccess),
54
58
  accessControl,
55
59
  daoPath(properties, { client, context }) {
56
60
  const typeAndIdParts = extractTypeAndIdParts(otherPropertyNames, properties)
@@ -61,11 +65,11 @@ function defineObjectView(config, context) {
61
65
  })
62
66
  }
63
67
 
64
- function defineRangeViews(config, context) {
68
+ function defineRangeViews(config, context, external = true) {
65
69
  const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
66
70
  modelName, others, model } = context
67
71
  const identifierCombinations = allCombinations(otherPropertyNames).slice(0, -1)
68
- const accessControl = config.listAccessControl || config.readAccessControl || config.writeAccessControl
72
+ const accessControl = external && (config.listAccessControl || config.readAccessControl || config.writeAccessControl)
69
73
  prepareAccessControl(accessControl, otherPropertyNames)
70
74
  for(const combination of identifierCombinations) {
71
75
  const propsUpperCase = combination.map(prop => prop[0].toUpperCase() + prop.slice(1))
@@ -80,7 +84,8 @@ function defineRangeViews(config, context) {
80
84
  ...identifiers,
81
85
  ...App.rangeProperties,
82
86
  },
83
- access: config.listAccess || config.readAccess,
87
+ internal: !external,
88
+ access: external && (config.listAccess || config.readAccess),
84
89
  accessControl,
85
90
  daoPath(params, { client, context }) {
86
91
  const owner = []
@@ -93,53 +98,106 @@ function defineRangeViews(config, context) {
93
98
  }
94
99
  }
95
100
 
96
- function defineSetAction(config, context) {
101
+ function getSetFunction( validators, validationContext, config, context) {
97
102
  const {
98
103
  service, app, model, objectType,
99
104
  otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
100
105
  } = context
101
-
102
106
  const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Set'
107
+ return async function execute(properties, { client, service }, emit) {
108
+ const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
109
+ const data = extractObjectData(writeableProperties, properties,
110
+ App.computeDefaults(model, properties, { client, service } ))
111
+ await App.validation.validate({ ...identifiers, ...data }, validators,
112
+ validationContext)
113
+ await fireChangeTriggers(context, objectType, identifiers, id, null, data)
114
+ emit({
115
+ type: eventName,
116
+ identifiers, data
117
+ })
118
+ }
119
+ }
120
+
121
+ function defineSetAction(config, context) {
122
+ const {
123
+ service, app, model, objectType,
124
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
125
+ } = context
103
126
  const actionName = 'set' + joinedOthersClassName + context.reverseRelationWord + modelName
104
127
  const accessControl = config.setAccessControl || config.writeAccessControl
105
128
  prepareAccessControl(accessControl, otherPropertyNames)
106
- service.actions[actionName] = new ActionDefinition({
129
+ const action = new ActionDefinition({
107
130
  name: actionName,
108
- properties: {
109
- ...(model.properties)
110
- },
131
+ properties: { ...(model.properties) },
111
132
  access: config.setAccess || config.writeAccess,
112
133
  accessControl,
113
134
  skipValidation: true,
114
135
  queuedBy: otherPropertyNames,
115
136
  waitForEvents: true,
116
- async execute(properties, { client, service }, emit) {
117
- const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
118
- const data = extractObjectData(writeableProperties, properties,
119
- App.computeDefaults(model, properties, { client, service } ))
120
- await App.validation.validate({ ...identifiers, ...data }, validators,
121
- { source: action, action, service, app, client })
122
- await fireChangeTriggers(context, objectType, identifiers, id, null, data)
123
- emit({
124
- type: eventName,
125
- identifiers, data
126
- })
127
- }
137
+ execute: () => { throw new Error('not generated yet') }
128
138
  })
129
- const action = service.actions[actionName]
130
139
  const validators = App.validation.getValidators(action, service, action)
140
+ const validationContext = { source: action, action }
141
+ action.execute = getSetFunction( validators, validationContext, config, context)
142
+ service.actions[actionName] = action
131
143
  }
132
144
 
133
- function defineUpdateAction(config, context) {
145
+ function defineSetTrigger(config, context) {
146
+ const {
147
+ service, app, model, objectType,
148
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
149
+ } = context
150
+ const actionName = 'set' + joinedOthersClassName + context.reverseRelationWord + modelName
151
+ const triggerName = `${service.name}_${actionName}`
152
+ const trigger = new TriggerDefinition({
153
+ name: triggerName,
154
+ properties: { ...(model.properties) },
155
+ skipValidation: true,
156
+ queuedBy: otherPropertyNames,
157
+ waitForEvents: true,
158
+ execute: () => { throw new Error('not generated yet') }
159
+ })
160
+ const validators = App.validation.getValidators(trigger, service, trigger)
161
+ const validationContext = { source: trigger, trigger }
162
+ trigger.execute = getSetFunction( validators, validationContext, config, context)
163
+ service.triggers[triggerName] = [trigger]
164
+ }
165
+
166
+ function getUpdateFunction( validators, validationContext, config, context) {
134
167
  const {
135
168
  service, app, model, modelRuntime, objectType,
136
169
  otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
137
170
  } = context
138
171
  const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Updated'
172
+ return async function execute(properties, {client, service}, emit) {
173
+ const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
174
+ const id = generateAnyId(otherPropertyNames, properties)
175
+ const entity = await modelRuntime().get(id)
176
+ if (!entity) throw new Error('not_found')
177
+ const data = App.utils.mergeDeep({},
178
+ extractObjectData(writeableProperties, properties, entity),
179
+ App.computeUpdates(model, { ...entity, ...properties }, { client, service })
180
+ )
181
+ await App.validation.validate({ ...identifiers, ...data }, validators,
182
+ validationContext)
183
+ await fireChangeTriggers(context, objectType, identifiers, id,
184
+ entity ? extractObjectData(writeableProperties, entity, {}) : null, data)
185
+ emit({
186
+ type: eventName,
187
+ identifiers, data
188
+ })
189
+ }
190
+ }
191
+
192
+ function defineUpdateAction(config, context) {
193
+ const {
194
+ service, app, model, modelRuntime, objectType,
195
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
196
+ } = context
139
197
  const actionName = 'update' + joinedOthersClassName + context.reverseRelationWord + modelName
140
198
  const accessControl = config.updateAccessControl || config.writeAccessControl
141
199
  prepareAccessControl(accessControl, otherPropertyNames)
142
- service.actions[actionName] = new ActionDefinition({
200
+ const action = new ActionDefinition({
143
201
  name: actionName,
144
202
  properties: {
145
203
  ...(model.properties)
@@ -149,24 +207,61 @@ function defineUpdateAction(config, context) {
149
207
  skipValidation: true,
150
208
  queuedBy: otherPropertyNames,
151
209
  waitForEvents: true,
152
- async execute(properties, {client, service}, emit) {
153
- const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
154
- const id = generateAnyId(otherPropertyNames, properties)
155
- const entity = await modelRuntime().get(id)
156
- if (!entity) throw new Error('not_found')
157
- const data = extractObjectData(writeableProperties, properties, entity)
158
- await App.validation.validate({ ...identifiers, ...data }, validators,
159
- { source: action, action, service, app, client })
160
- await fireChangeTriggers(context, objectType, identifiers, id,
161
- entity ? extractObjectData(writeableProperties, entity, {}) : null, data)
162
- emit({
163
- type: eventName,
164
- identifiers, data
165
- })
166
- }
210
+ execute: () => { throw new Error('not generated yet') }
167
211
  })
168
- const action = service.actions[actionName]
169
212
  const validators = App.validation.getValidators(action, service, action)
213
+ const validationContext = { source: action, action }
214
+ action.execute = getUpdateFunction( validators, validationContext, config, context)
215
+ service.actions[actionName] = action
216
+ }
217
+
218
+ function defineUpdateTrigger(config, context) {
219
+ const {
220
+ service, app, model, modelRuntime, objectType,
221
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
222
+ } = context
223
+ const actionName = 'update' + joinedOthersClassName + context.reverseRelationWord + modelName
224
+ const triggerName = `${service.name}_${actionName}`
225
+ const trigger = new TriggerDefinition({
226
+ name: triggerName,
227
+ properties: {
228
+ ...(model.properties)
229
+ },
230
+ skipValidation: true,
231
+ queuedBy: otherPropertyNames,
232
+ waitForEvents: true,
233
+ execute: () => { throw new Error('not generated yet') }
234
+ })
235
+ const validators = App.validation.getValidators(trigger, service, trigger)
236
+ const validationContext = { source: trigger, trigger }
237
+ trigger.execute = getUpdateFunction( validators, validationContext, config, context)
238
+ service.triggers[triggerName] = [trigger]
239
+ }
240
+
241
+ function getSetOrUpdateFunction( validators, validationContext, config, context) {
242
+ const {
243
+ service, app, model, modelRuntime, objectType,
244
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
245
+ } = context
246
+ const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Updated'
247
+ return async function execute(properties, { client, service }, emit) {
248
+ const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
249
+ const id = generateAnyId(otherPropertyNames, properties)
250
+ const entity = await modelRuntime().get(id)
251
+ const data = App.utils.mergeDeep({},
252
+ App.computeDefaults(model, properties, { client, service } ),
253
+ extractObjectData(writeableProperties, properties, entity),
254
+ App.computeUpdates(model, { ...entity, ...properties }, { client, service })
255
+ )
256
+ await App.validation.validate({ ...identifiers, ...data }, validators,
257
+ validationContext)
258
+ await fireChangeTriggers(context, objectType, identifiers, id,
259
+ entity ? extractObjectData(writeableProperties, entity, {}) : null, data)
260
+ emit({
261
+ type: eventName,
262
+ identifiers, data
263
+ })
264
+ }
170
265
  }
171
266
 
172
267
  function defineSetOrUpdateAction(config, context) {
@@ -178,7 +273,7 @@ function defineSetOrUpdateAction(config, context) {
178
273
  const actionName = 'setOrUpdate' + joinedOthersClassName + context.reverseRelationWord + modelName
179
274
  const accessControl = config.setOrUpdateAccessControl || config.writeAccessControl
180
275
  prepareAccessControl(accessControl, otherPropertyNames)
181
- service.actions[actionName] = new ActionDefinition({
276
+ const action = new ActionDefinition({
182
277
  name: actionName,
183
278
  properties: {
184
279
  ...(model.properties)
@@ -188,26 +283,55 @@ function defineSetOrUpdateAction(config, context) {
188
283
  skipValidation: true,
189
284
  queuedBy: otherPropertyNames,
190
285
  waitForEvents: true,
191
- async execute(properties, { client, service }, emit) {
192
- const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
193
- const id = generateAnyId(otherPropertyNames, properties)
194
- const entity = await modelRuntime().get(id)
195
- const data = extractObjectData(writeableProperties, properties, {
196
- ...App.computeDefaults(model, properties, { client, service } ),
197
- ...entity
198
- })
199
- await App.validation.validate({ ...identifiers, ...data }, validators,
200
- { source: action, action, service, app, client })
201
- await fireChangeTriggers(context, objectType, identifiers, id,
202
- entity ? extractObjectData(writeableProperties, entity, {}) : null, data)
203
- emit({
204
- type: eventName,
205
- identifiers, data
206
- })
207
- }
286
+ execute: () => { throw new Error('not generated yet') }
208
287
  })
209
- const action = service.actions[actionName]
210
288
  const validators = App.validation.getValidators(action, service, action)
289
+ const validationContext = { source: action, action }
290
+ action.execute = getSetOrUpdateFunction( validators, validationContext, config, context)
291
+ service.actions[actionName] = action
292
+ }
293
+
294
+ function defineSetOrUpdateTrigger(config, context) {
295
+ const {
296
+ service, app, model, modelRuntime, objectType,
297
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
298
+ } = context
299
+ const actionName = 'setOrUpdate' + joinedOthersClassName + context.reverseRelationWord + modelName
300
+ const triggerName = `${service.name}_${actionName}`
301
+ const trigger = new TriggerDefinition({
302
+ name: triggerName,
303
+ properties: {
304
+ ...(model.properties)
305
+ },
306
+ skipValidation: true,
307
+ queuedBy: otherPropertyNames,
308
+ waitForEvents: true,
309
+ execute: () => { throw new Error('not generated yet') }
310
+ })
311
+ const validators = App.validation.getValidators(trigger, service, trigger)
312
+ const validationContext = { source: trigger, trigger }
313
+ trigger.execute = getSetOrUpdateFunction( validators, validationContext, config, context)
314
+ service.triggers[triggerName] = [trigger]
315
+ }
316
+
317
+ function getResetFunction(config, context) {
318
+ const {
319
+ service, app, model, modelRuntime, objectType,
320
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
321
+ } = context
322
+ const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Reset'
323
+ return async function execute(properties, {client, service}, emit) {
324
+ const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
325
+ const id = generateAnyId(otherPropertyNames, properties)
326
+ const entity = await modelRuntime().get(id)
327
+ if (!entity) throw new Error('not_found')
328
+ await fireChangeTriggers(context, objectType, identifiers, id,
329
+ entity ? extractObjectData(writeableProperties, entity, {}) : null, null)
330
+ emit({
331
+ type: eventName,
332
+ identifiers
333
+ })
334
+ }
211
335
  }
212
336
 
213
337
  function defineResetAction(config, context) {
@@ -215,39 +339,42 @@ function defineResetAction(config, context) {
215
339
  service, modelRuntime, modelPropertyName, identifiers, objectType,
216
340
  otherPropertyNames, joinedOthersPropertyName, modelName, joinedOthersClassName, model
217
341
  } = context
218
- const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Reset'
219
342
  const actionName = 'reset' + joinedOthersClassName + context.reverseRelationWord + modelName
220
343
  const accessControl = config.resetAccessControl || config.writeAccessControl
221
344
  prepareAccessControl(accessControl, otherPropertyNames)
222
345
  service.actions[actionName] = new ActionDefinition({
223
346
  name: actionName,
224
347
  properties: {
225
- /*[modelPropertyName]: {
226
- type: model,
227
- validation: ['nonEmpty']
228
- },*/
229
348
  ...identifiers
230
349
  },
231
350
  access: config.resetAccess || config.writeAccess,
232
351
  accessControl,
233
352
  queuedBy: otherPropertyNames,
234
353
  waitForEvents: true,
235
- async execute(properties, {client, service}, emit) {
236
- const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
237
- const id = generateAnyId(otherPropertyNames, properties)
238
- const entity = await modelRuntime().get(id)
239
- if (!entity) throw new Error('not_found')
240
- await fireChangeTriggers(context, objectType, identifiers, id,
241
- entity ? extractObjectData(writeableProperties, entity, {}) : null, null)
242
- emit({
243
- type: eventName,
244
- identifiers
245
- })
246
- }
354
+ execute: getResetFunction(config, context)
247
355
  })
248
356
  }
249
357
 
358
+ function defineResetTrigger(config, context) {
359
+ const {
360
+ service, modelRuntime, modelPropertyName, identifiers, objectType,
361
+ otherPropertyNames, joinedOthersPropertyName, modelName, joinedOthersClassName, model
362
+ } = context
363
+ const actionName = 'reset' + joinedOthersClassName + context.reverseRelationWord + modelName
364
+ const triggerName = `${service.name}_${actionName}`
365
+ service.triggers[triggerName] = [new TriggerDefinition({
366
+ name: triggerName,
367
+ properties: {
368
+ ...identifiers
369
+ },
370
+ queuedBy: otherPropertyNames,
371
+ waitForEvents: true,
372
+ execute: getResetFunction(config, context)
373
+ })]
374
+ }
375
+
250
376
  export {
251
377
  defineObjectView, defineRangeViews,
252
- defineSetAction, defineUpdateAction, defineSetOrUpdateAction, defineResetAction
378
+ defineSetAction, defineUpdateAction, defineSetOrUpdateAction, defineResetAction,
379
+ defineSetTrigger, defineUpdateTrigger, defineSetOrUpdateTrigger, defineResetTrigger
253
380
  }