@live-change/relations-plugin 0.9.199 → 0.9.200

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/relations-plugin",
3
- "version": "0.9.199",
3
+ "version": "0.9.200",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "type": "module",
24
24
  "dependencies": {
25
- "@live-change/framework": "^0.9.199",
25
+ "@live-change/framework": "^0.9.200",
26
26
  "pluralize": "^8.0.0"
27
27
  },
28
28
  "devDependencies": {
@@ -30,5 +30,5 @@
30
30
  "typedoc-plugin-markdown": "^4.6.3",
31
31
  "typedoc-plugin-rename-defaults": "^0.7.3"
32
32
  },
33
- "gitHead": "1900043a10cf9ad49b9cc33a539fb973706de962"
33
+ "gitHead": "a509834e600a546297faa7d1534b6f52e66d2e66"
34
34
  }
@@ -9,10 +9,10 @@ async function fireChangeTriggers(context, objectType, identifiers, object, oldD
9
9
  const { service, modelName, app } = context
10
10
  //if(!trigger) trigger = (...args) => app.trigger(...args)
11
11
  assert(trigger, "trigger is required")
12
- const changeType = data ? (oldData ? 'update' : 'create') : 'delete'
13
- //console.log("FIRE CHANGE TRIGGERS", { context, objectType, identifiers, object, oldData, data })
14
- //console.trace()
12
+ const changeType = data ? (oldData ? 'update' : 'create') : 'delete'
15
13
  const triggerParameters = { objectType, object, identifiers, data, oldData, changeType }
14
+ //console.log("FIRE CHANGE TRIGGERS", triggerParameters)
15
+ //console.trace()
16
16
  await Promise.all([
17
17
  trigger({
18
18
  type: changeType + service.name[0].toUpperCase() + service.name.slice(1) + '_' + modelName,
@@ -32,7 +32,7 @@ async function fireChangeTriggers(context, objectType, identifiers, object, oldD
32
32
  async function iterateChildren(context, propertyName, path, cb) {
33
33
  const {
34
34
  service, modelRuntime, objectType: myType, writeableProperties, modelName,
35
- reverseRelationWord, app, otherPropertyNames, sameIdAsParent
35
+ reverseRelationWord, app, otherPropertyNames, sameIdAsParent, isAny
36
36
  } = context
37
37
  assert(modelRuntime, "modelRuntime is required")
38
38
  assert(modelRuntime().sortedIndexRangeGet, "sortedIndexRangeGet is required")
@@ -41,7 +41,8 @@ async function iterateChildren(context, propertyName, path, cb) {
41
41
  assert(path, "path is required")
42
42
  assert(cb, "cb is required")
43
43
  if(sameIdAsParent) {
44
- const entity = await modelRuntime().get(path)
44
+ const id = Array.isArray(path) ? (path.length > 1 ? path.map(p => JSON.stringify(p)).join(':') : path[0]) : path
45
+ const entity = await modelRuntime().get(id)
45
46
  if(entity) await cb(entity)
46
47
  } else {
47
48
  const indexName = 'by' + propertyName[0].toUpperCase() + propertyName.slice(1)
@@ -72,7 +73,7 @@ async function triggerDeleteOnParentDeleteTriggers(
72
73
  } = context
73
74
 
74
75
  let found = false
75
- await iterateChildren(context, propertyName, path, async entity => {
76
+ await iterateChildren(context, propertyName, path, async entity => {
76
77
  found = true
77
78
  const identifiers = extractIdentifiers(otherPropertyNames, entity)
78
79
  await fireChangeTriggers(context, myType, identifiers, entity.id,
package/src/propertyOf.ts CHANGED
@@ -60,7 +60,7 @@ export default function(service, app) {
60
60
  context.reverseRelationWord = 'Owned'
61
61
  context.partialReverseRelationWord = 'Owned'
62
62
 
63
- context.sameIdAsParent = true
63
+ context.sameIdAsParent = context.otherPropertyNames.length === 1
64
64
 
65
65
  context.identifiers = defineProperties(context.model, context.others, context.otherPropertyNames)
66
66
  context.model.identifiers = [
@@ -64,7 +64,7 @@ export default function(service, app) {
64
64
  context.reverseRelationWord = 'Owned'
65
65
  context.partialReverseRelationWord = 'Owned'
66
66
 
67
- context.sameIdAsParent = true
67
+ context.sameIdAsParent = context.otherPropertyNames.length === 1
68
68
 
69
69
  context.identifiers = defineAnyProperties(context.model, context.otherPropertyNames, config)
70
70
  context.model.identifiers = [
@@ -16,28 +16,34 @@ import { fireChangeTriggers } from "./changeTriggers.js"
16
16
 
17
17
  import pluralize from 'pluralize'
18
18
 
19
- export function createIdentifiersProperties(keys) {
19
+ export function createIdentifiersProperties(keys, idField) {
20
20
  const identifiers = {}
21
21
  if(keys) for(const key of keys) {
22
22
  identifiers[key + 'Type'] = {
23
23
  type: String,
24
- validation: ['nonEmpty']
24
+ validation: idField ? [{ name: 'ifEmpty', prop: idField, then: ['nonEmpty'] }] : ['nonEmpty']
25
25
  }
26
26
  identifiers[key] = {
27
27
  type: String,
28
- validation: ['nonEmpty']
28
+ validation: idField ? [{ name: 'ifEmpty', prop: idField, then: ['nonEmpty'] }] : ['nonEmpty']
29
29
  }
30
30
  }
31
+ if(idField) identifiers[idField] = {
32
+ type: String,
33
+ validation: keys.map(key => ({ name: 'ifEmpty', prop: key+'Type', then: ['nonEmpty'] }))
34
+ }
31
35
  return identifiers
32
36
  }
33
37
 
34
38
  function defineObjectView(config, context, external = true) {
35
39
  const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
36
- modelName, others, model } = context
37
- const viewProperties = createIdentifiersProperties(otherPropertyNames)
40
+ modelName, others, model, modelPropertyName } = context
41
+ const viewProperties = createIdentifiersProperties(otherPropertyNames, modelPropertyName)
38
42
  const sourceAccessControl = external
39
43
  && (config.singleAccessControl || config.readAccessControl || config.writeAccessControl)
40
- const accessControl = cloneAndPrepareAccessControl(sourceAccessControl, otherPropertyNames)
44
+ const accessControl = cloneAndPrepareAccessControl(sourceAccessControl,
45
+ otherPropertyNames.concat(modelPropertyName),
46
+ new Array(otherPropertyNames.length).fill(undefined).concat(model))
41
47
  const viewName = config.name
42
48
  || ((config.prefix ? config.prefix + modelName : modelName[0].toLowerCase() + modelName.slice(1)) + (config.suffix || ''))
43
49
  model.crud.read ??= viewName
@@ -54,6 +60,11 @@ function defineObjectView(config, context, external = true) {
54
60
  global: config.globalView,
55
61
  accessControl,
56
62
  daoPath(properties, { client, context }) {
63
+ const idProp = modelPropertyName ? properties[modelPropertyName] : null
64
+ if(idProp) {
65
+ const path = config.fields ? modelRuntime().limitedPath(idProp, config.fields) : modelRuntime().path(idProp)
66
+ return path
67
+ }
57
68
  const typeAndIdParts = extractTypeAndIdParts(otherPropertyNames, properties)
58
69
  const id = typeAndIdParts.length > 1 ? typeAndIdParts.map(p => JSON.stringify(p)).join(':') : typeAndIdParts[0]
59
70
  const path = config.fields ? modelRuntime().limitedPath(id, config.fields) : modelRuntime().path(id)
@@ -106,7 +117,6 @@ function getSetFunction( validators, validationContext, config, context) {
106
117
  return async function execute(properties, { client, service, trigger }, emit) {
107
118
  const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
108
119
  const id = generateAnyId(otherPropertyNames, properties)
109
- const entity = await modelRuntime().get(id)
110
120
  const data = extractObjectData(writeableProperties, properties,
111
121
  App.computeDefaults(model, properties, { client, service } ))
112
122
  await App.validation.validate({ ...identifiers, ...data }, validators,
package/src/utils.ts CHANGED
@@ -256,7 +256,7 @@ export function prepareAccessControl(accessControl: AccessControlSettings, names
256
256
  ac.objects = ac.objects ?? ((params) => names.map((name, index) => ({
257
257
  objectType: types[index],
258
258
  object: params[name]
259
- })).filter(obj => obj.object))
259
+ })).filter(obj => obj.object && obj.objectType))
260
260
  ac.objParams = { names, types }
261
261
  }
262
262
  }
@@ -274,6 +274,7 @@ export function cloneAndPrepareAccessControl(accessControl: AccessControlSetting
274
274
  export function defineDeleteByOwnerEvents(config: RelationConfig, context: RelationContext) {
275
275
  const {
276
276
  service, modelRuntime, joinedOthersPropertyName, modelName, modelPropertyName, otherPropertyNames,
277
+ sameIdAsParent
277
278
  } = context
278
279
  for(const propertyName of otherPropertyNames) {
279
280
  const eventName = modelName + 'DeleteByOwner'
@@ -287,6 +288,9 @@ export function defineDeleteByOwnerEvents(config: RelationConfig, context: Relat
287
288
  },
288
289
  async execute({owner}) {
289
290
  const runtime = modelRuntime()
291
+ if(sameIdAsParent) {
292
+ return await runtime.delete(owner)
293
+ }
290
294
  const tableName = runtime.tableName
291
295
  const prefix = JSON.stringify(owner)
292
296
  const indexName = tableName + '_by' + propertyName[0].toUpperCase() + propertyName.slice(1)
package/src/utilsAny.ts CHANGED
@@ -225,7 +225,7 @@ export function prepareAccessControl(accessControl, names, types = undefined) {
225
225
  accessControl.objects = accessControl.objects ?? ((params) => names.map((name, index) => ({
226
226
  objectType: types?.[index] ?? params[name + 'Type'],
227
227
  object: params[name]
228
- })))
228
+ })).filter(obj => obj.object && obj.objectType))
229
229
  }
230
230
  }
231
231
 
@@ -241,7 +241,8 @@ export function cloneAndPrepareAccessControl(accessControl, names, types = undef
241
241
 
242
242
  export function defineDeleteByOwnerEvents(config, context) {
243
243
  const {
244
- service, modelRuntime, joinedOthersPropertyName, modelName, modelPropertyName, otherPropertyNames, reverseRelationWord
244
+ service, modelRuntime, joinedOthersPropertyName, modelName, modelPropertyName, otherPropertyNames,
245
+ reverseRelationWord, sameIdAsParent
245
246
  } = context
246
247
  for(const propertyName of otherPropertyNames) {
247
248
  const eventName = modelName + 'DeleteByOwner'
@@ -259,6 +260,9 @@ export function defineDeleteByOwnerEvents(config, context) {
259
260
  },
260
261
  async execute({ ownerType, owner }) {
261
262
  const runtime = modelRuntime()
263
+ if(sameIdAsParent) {
264
+ return await runtime.delete(JSON.stringify(ownerType) + ':' + JSON.stringify(owner))
265
+ }
262
266
  const tableName = runtime.tableName
263
267
  const prefix = JSON.stringify(ownerType) + ':' + JSON.stringify(owner)
264
268
  const indexName = tableName + '_by' + propertyName[0].toUpperCase() + propertyName.slice(1)