@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 +3 -3
- package/src/changeTriggers.js +7 -6
- package/src/propertyOf.ts +1 -1
- package/src/propertyOfAny.ts +1 -1
- package/src/singularRelationAnyUtils.js +17 -7
- package/src/utils.ts +5 -1
- package/src/utilsAny.ts +6 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/relations-plugin",
|
|
3
|
-
"version": "0.9.
|
|
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.
|
|
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": "
|
|
33
|
+
"gitHead": "a509834e600a546297faa7d1534b6f52e66d2e66"
|
|
34
34
|
}
|
package/src/changeTriggers.js
CHANGED
|
@@ -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
|
|
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 =
|
|
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 = [
|
package/src/propertyOfAny.ts
CHANGED
|
@@ -64,7 +64,7 @@ export default function(service, app) {
|
|
|
64
64
|
context.reverseRelationWord = 'Owned'
|
|
65
65
|
context.partialReverseRelationWord = 'Owned'
|
|
66
66
|
|
|
67
|
-
context.sameIdAsParent =
|
|
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,
|
|
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,
|
|
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)
|