@live-change/relations-plugin 0.7.34 → 0.7.36
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/changeTriggers.js +172 -27
- package/dataUtils.js +24 -0
- package/itemEvents.js +19 -1
- package/itemOf.js +18 -3
- package/package.json +3 -3
- package/pluralRelationUtils.js +158 -3
- package/propertyOf.js +2 -0
- package/propertyOfAny.js +2 -0
- package/utils.js +14 -20
- package/utilsAny.js +2 -2
package/changeTriggers.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
const {extractObjectData} = require("./
|
|
2
|
-
const App = require("@live-change/framework")
|
|
1
|
+
const { extractObjectData, extractIdentifiers } = require("./dataUtils.js")
|
|
2
|
+
const App = require("@live-change/framework")
|
|
3
3
|
const {
|
|
4
4
|
TriggerDefinition
|
|
5
5
|
} = App
|
|
6
6
|
|
|
7
7
|
async function fireChangeTriggers(context, objectType, identifiers, object, oldData, data) {
|
|
8
|
-
const { service, modelName } = context
|
|
8
|
+
const { service, modelName, app } = context
|
|
9
9
|
const changeType = data ? (oldData ? 'update' : 'create') : 'delete'
|
|
10
10
|
await Promise.all([
|
|
11
|
-
|
|
11
|
+
app.trigger({
|
|
12
12
|
type: changeType+service.name[0].toUpperCase()+service.name.slice(1)+'_'+modelName,
|
|
13
13
|
objectType,
|
|
14
14
|
object,
|
|
@@ -16,7 +16,7 @@ async function fireChangeTriggers(context, objectType, identifiers, object, oldD
|
|
|
16
16
|
data,
|
|
17
17
|
oldData
|
|
18
18
|
}),
|
|
19
|
-
|
|
19
|
+
app.trigger({
|
|
20
20
|
type: changeType+'Object',
|
|
21
21
|
objectType,
|
|
22
22
|
object,
|
|
@@ -27,32 +27,48 @@ async function fireChangeTriggers(context, objectType, identifiers, object, oldD
|
|
|
27
27
|
])
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
async function iterateChildren(context, propertyName, path, cb) {
|
|
31
|
+
const {
|
|
32
|
+
service, modelRuntime, objectType: myType, writeableProperties, modelName,
|
|
33
|
+
reverseRelationWord, app, otherPropertyNames, sameIdAsParent
|
|
34
|
+
} = context
|
|
35
|
+
if(sameIdAsParent) {
|
|
36
|
+
const entity = await modelRuntime().get(path)
|
|
37
|
+
if(entity) await cb(entity)
|
|
38
|
+
} else {
|
|
39
|
+
const indexName = 'by' + propertyName[0].toUpperCase() + propertyName.slice(1)
|
|
40
|
+
const bucketSize = 32
|
|
41
|
+
let bucket
|
|
42
|
+
let gt = ''
|
|
43
|
+
do {
|
|
44
|
+
bucket = await modelRuntime().sortedIndexRangeGet(indexName, path, {
|
|
45
|
+
gt,
|
|
46
|
+
limit: bucketSize
|
|
47
|
+
})
|
|
48
|
+
//console.log("BUCKET", bucket)
|
|
49
|
+
if(bucket.length == 0) break
|
|
50
|
+
gt = bucket[bucket.length - 1].id
|
|
51
|
+
const copyTriggerPromises = bucket.map(entity => cb({ ...entity, id: entity.to }))
|
|
52
|
+
await Promise.all(copyTriggerPromises)
|
|
53
|
+
} while (bucket.length == bucketSize)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
30
58
|
async function triggerDeleteOnParentDeleteTriggers(
|
|
31
59
|
context, propertyName, path, objectType, object, emit) {
|
|
32
60
|
const {
|
|
33
|
-
service, modelRuntime,
|
|
34
|
-
reverseRelationWord
|
|
61
|
+
service, modelRuntime, objectType: myType, writeableProperties, modelName,
|
|
62
|
+
reverseRelationWord, otherPropertyNames
|
|
35
63
|
} = context
|
|
36
|
-
|
|
37
|
-
const bucketSize = 32
|
|
64
|
+
|
|
38
65
|
let found = false
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
})
|
|
46
|
-
if (bucket.length > 0) found = true
|
|
47
|
-
gt = bucket[bucket.length - 1].id
|
|
48
|
-
const deleteTriggerPromises = bucket.map(entity => {
|
|
49
|
-
return (async () => {
|
|
50
|
-
await fireChangeTriggers(context, myType, identifiers, entity.to,
|
|
51
|
-
extractObjectData(writeableProperties, entity, {}), null)
|
|
52
|
-
})()
|
|
53
|
-
})
|
|
54
|
-
await Promise.all(deleteTriggerPromises)
|
|
55
|
-
} while (bucket.length == bucketSize)
|
|
66
|
+
await iterateChildren(context, propertyName, path, async entity => {
|
|
67
|
+
found = true
|
|
68
|
+
const identifiers = extractIdentifiers(otherPropertyNames, entity)
|
|
69
|
+
await fireChangeTriggers(context, myType, identifiers, entity.id,
|
|
70
|
+
extractObjectData(writeableProperties, entity, {}), null)
|
|
71
|
+
})
|
|
56
72
|
if (found) {
|
|
57
73
|
const eventName = propertyName + reverseRelationWord + modelName + 'DeleteByOwner'
|
|
58
74
|
emit({
|
|
@@ -109,7 +125,136 @@ function registerParentDeleteTriggers(context, config) {
|
|
|
109
125
|
}
|
|
110
126
|
}
|
|
111
127
|
|
|
128
|
+
async function copyObject(context, objectType, object, parentType, parent, identifiers, data, emit) {
|
|
129
|
+
const {
|
|
130
|
+
app, service, modelPropertyName, modelName, otherPropertyNames, joinedOthersPropertyName, others
|
|
131
|
+
} = context
|
|
132
|
+
const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Copied'
|
|
133
|
+
const newIdentifiers = {
|
|
134
|
+
...identifiers
|
|
135
|
+
}
|
|
136
|
+
for(let i = 0; i < others.length; i++) {
|
|
137
|
+
const other = others[i]
|
|
138
|
+
if(other == parentType) {
|
|
139
|
+
newIdentifiers[otherPropertyNames[i]] = parent
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
console.log("COPY OBJECT", objectType, object, "TO", parentType, parent)
|
|
143
|
+
console.log("IDENTIFIERS", newIdentifiers)
|
|
144
|
+
console.log("DATA", data)
|
|
145
|
+
|
|
146
|
+
const newId = app.generateUid()
|
|
147
|
+
app.trigger({
|
|
148
|
+
type: 'copy'+service.name[0].toUpperCase()+service.name.slice(1)+'_'+modelName,
|
|
149
|
+
objectType,
|
|
150
|
+
object: newId,
|
|
151
|
+
from: object,
|
|
152
|
+
identifiers: newIdentifiers,
|
|
153
|
+
data
|
|
154
|
+
})
|
|
155
|
+
app.trigger({
|
|
156
|
+
type: 'copyObject',
|
|
157
|
+
objectType,
|
|
158
|
+
object: newId,
|
|
159
|
+
from: object,
|
|
160
|
+
identifiers: newIdentifiers,
|
|
161
|
+
data
|
|
162
|
+
})
|
|
163
|
+
await fireChangeTriggers(context, objectType, newIdentifiers, newId, null, data)
|
|
164
|
+
emit({
|
|
165
|
+
type: eventName,
|
|
166
|
+
[modelPropertyName]: newId,
|
|
167
|
+
['from'+modelPropertyName[0].toUpperCase() + modelPropertyName.slice(1)]: object,
|
|
168
|
+
identifiers: newIdentifiers,
|
|
169
|
+
data
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async function triggerCopyOnParentCopyTriggers(
|
|
174
|
+
context, propertyName, path, objectType, object, from, emit) {
|
|
175
|
+
const {
|
|
176
|
+
service, modelRuntime, objectType: myType, writeableProperties, modelName,
|
|
177
|
+
reverseRelationWord, app, otherPropertyNames
|
|
178
|
+
} = context
|
|
179
|
+
await iterateChildren(context, propertyName, path, async entity => {
|
|
180
|
+
const data = extractObjectData(writeableProperties, entity, {})
|
|
181
|
+
const identifiers = extractIdentifiers(otherPropertyNames, entity)
|
|
182
|
+
const fromId = entity.id
|
|
183
|
+
|
|
184
|
+
console.log("TRIGGERED COPY", myType, fromId, "FROM", objectType, from, "TO", object)
|
|
185
|
+
|
|
186
|
+
//console.log("COPY TRIGGER", myType, fromId, objectType, object, from, identifiers, data)
|
|
187
|
+
const copyTriggerResults = await app.trigger({
|
|
188
|
+
type: 'copyOnParentCopy'+service.name[0].toUpperCase()+service.name.slice(1)+'_'+modelName,
|
|
189
|
+
objectType: myType,
|
|
190
|
+
object: fromId,
|
|
191
|
+
parentType: objectType,
|
|
192
|
+
parent: object,
|
|
193
|
+
fromParent: from,
|
|
194
|
+
identifiers,
|
|
195
|
+
data
|
|
196
|
+
})
|
|
197
|
+
//console.log("COPY TRIGGER RESULTS", copyTriggerResults)
|
|
198
|
+
if(copyTriggerResults.length == 0) { // normal copy, without special logic
|
|
199
|
+
await copyObject(context, myType, fromId, objectType, object, identifiers, data, emit)
|
|
200
|
+
}
|
|
201
|
+
})
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function registerParentCopyTriggers(context, config) {
|
|
205
|
+
const {
|
|
206
|
+
service, parentsTypes, otherPropertyNames, modelName
|
|
207
|
+
} = context
|
|
208
|
+
if(parentsTypes) {
|
|
209
|
+
for (const index in parentsTypes) {
|
|
210
|
+
const otherType = parentsTypes[index]
|
|
211
|
+
const propertyName = otherPropertyNames[index]
|
|
212
|
+
const triggerName = 'copy' + otherType[0].toUpperCase() + otherType.slice(1)
|
|
213
|
+
if (!service.triggers[triggerName]) service.triggers[triggerName] = []
|
|
214
|
+
service.triggers[triggerName].push(new TriggerDefinition({
|
|
215
|
+
name: triggerName,
|
|
216
|
+
properties: {
|
|
217
|
+
object: {
|
|
218
|
+
type: String
|
|
219
|
+
},
|
|
220
|
+
from: {
|
|
221
|
+
type: String
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
async execute({ object , from }, {client, service}, emit) {
|
|
225
|
+
await triggerCopyOnParentCopyTriggers(context, propertyName, [from],
|
|
226
|
+
otherType, object, from, emit)
|
|
227
|
+
}
|
|
228
|
+
}))
|
|
229
|
+
}
|
|
230
|
+
} else {
|
|
231
|
+
const triggerName = 'copyObject'
|
|
232
|
+
if(!service.triggers[triggerName]) service.triggers[triggerName] = []
|
|
233
|
+
service.triggers[triggerName].push(new TriggerDefinition({
|
|
234
|
+
name: triggerName,
|
|
235
|
+
properties: {
|
|
236
|
+
objectType: {
|
|
237
|
+
type: String,
|
|
238
|
+
},
|
|
239
|
+
object: {
|
|
240
|
+
type: String
|
|
241
|
+
},
|
|
242
|
+
from: {
|
|
243
|
+
type: String
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
async execute({ objectType, object, from }, {client, service}, emit) {
|
|
247
|
+
for(const propertyName of otherPropertyNames) {
|
|
248
|
+
await triggerCopyOnParentCopyTriggers(context, propertyName, [objectType, from],
|
|
249
|
+
objectType, object, from, emit)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}))
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
112
256
|
module.exports = {
|
|
113
257
|
fireChangeTriggers,
|
|
114
|
-
registerParentDeleteTriggers
|
|
258
|
+
registerParentDeleteTriggers,
|
|
259
|
+
registerParentCopyTriggers,
|
|
115
260
|
}
|
package/dataUtils.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const App = require("@live-change/framework");
|
|
2
|
+
|
|
3
|
+
function extractIdentifiers(otherPropertyNames, properties) {
|
|
4
|
+
const identifiers = {}
|
|
5
|
+
for (const propertyName of otherPropertyNames) {
|
|
6
|
+
identifiers[propertyName] = properties[propertyName]
|
|
7
|
+
}
|
|
8
|
+
return identifiers
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function extractObjectData(writeableProperties, properties, defaults) {
|
|
12
|
+
let objectData = {}
|
|
13
|
+
for (const propertyName of writeableProperties) {
|
|
14
|
+
if (properties.hasOwnProperty(propertyName)) {
|
|
15
|
+
objectData[propertyName] = properties[propertyName]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return App.utils.mergeDeep({}, defaults, JSON.parse(JSON.stringify(objectData)))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = {
|
|
22
|
+
extractIdentifiers,
|
|
23
|
+
extractObjectData
|
|
24
|
+
}
|
package/itemEvents.js
CHANGED
|
@@ -57,4 +57,22 @@ function defineDeletedEvent(config, context) {
|
|
|
57
57
|
})
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
function defineCopyEvent(config, context) {
|
|
61
|
+
const {
|
|
62
|
+
service, modelRuntime, joinedOthersPropertyName, modelName, modelPropertyName, reverseRelationWord
|
|
63
|
+
} = context
|
|
64
|
+
const eventName = joinedOthersPropertyName + reverseRelationWord + modelName + 'Copied'
|
|
65
|
+
service.events[eventName] = new EventDefinition({
|
|
66
|
+
name: eventName,
|
|
67
|
+
execute(properties) {
|
|
68
|
+
const id = properties[modelPropertyName]
|
|
69
|
+
console.log("COPY CREATE", { ...properties.data, ...properties.identifiers, id })
|
|
70
|
+
return modelRuntime().create({ ...properties.data, ...properties.identifiers, id })
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
module.exports = {
|
|
76
|
+
defineCreatedEvent, defineUpdatedEvent, defineTransferredEvent, defineDeletedEvent,
|
|
77
|
+
defineCopyEvent,
|
|
78
|
+
}
|
package/itemOf.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
const {
|
|
2
2
|
defineProperties, defineIndexes,
|
|
3
3
|
processModelsAnnotation, addAccessControlParents,
|
|
4
|
-
defineDeleteByOwnerEvents, defineParentDeleteTriggers
|
|
4
|
+
defineDeleteByOwnerEvents, defineParentDeleteTriggers, defineParentCopyTriggers
|
|
5
5
|
} = require('./utils.js')
|
|
6
6
|
|
|
7
7
|
const {
|
|
8
8
|
defineCreatedEvent, defineUpdatedEvent, defineDeletedEvent, defineTransferredEvent,
|
|
9
|
+
defineCopyEvent
|
|
9
10
|
} = require('./itemEvents.js')
|
|
10
11
|
|
|
11
12
|
const {
|
|
12
|
-
defineView, defineCreateAction, defineUpdateAction, defineDeleteAction, defineSortIndex
|
|
13
|
+
defineView, defineCreateAction, defineUpdateAction, defineDeleteAction, defineSortIndex,
|
|
14
|
+
defineCopyAction, defineCopyOnParentCopyTrigger
|
|
13
15
|
} = require('./pluralRelationUtils.js')
|
|
14
16
|
|
|
15
17
|
module.exports = function(service, app) {
|
|
@@ -38,6 +40,7 @@ module.exports = function(service, app) {
|
|
|
38
40
|
defineTransferredEvent(config, context)
|
|
39
41
|
defineDeletedEvent(config, context)
|
|
40
42
|
defineDeleteByOwnerEvents(config, context)
|
|
43
|
+
defineCopyEvent(config, context)
|
|
41
44
|
|
|
42
45
|
if(config.createAccess || config.writeAccess || config.createAccessControl || config.writeAccessControl) {
|
|
43
46
|
defineCreateAction(config, context)
|
|
@@ -51,6 +54,18 @@ module.exports = function(service, app) {
|
|
|
51
54
|
defineDeleteAction(config, context)
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
if(
|
|
57
|
+
if(config.copyAccess || config.copyAccessControl) {
|
|
58
|
+
defineCopyAction(config, context)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if(!config.customDeleteTrigger) {
|
|
62
|
+
defineParentDeleteTriggers(config, context)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if(!config.customParentCopyTrigger) {
|
|
66
|
+
defineParentCopyTriggers(config, context)
|
|
67
|
+
//defineCopyOnParentCopyTrigger(config, context)
|
|
68
|
+
}
|
|
69
|
+
|
|
55
70
|
})
|
|
56
71
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/relations-plugin",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.36",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"url": "https://www.viamage.com/"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@live-change/framework": "^0.7.
|
|
24
|
+
"@live-change/framework": "^0.7.36",
|
|
25
25
|
"pluralize": "^8.0.0"
|
|
26
26
|
},
|
|
27
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "23f7ed337f9bb45ed698b0e72959720076b6222c"
|
|
28
28
|
}
|
package/pluralRelationUtils.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const App = require("@live-change/framework")
|
|
2
|
-
const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition } = App
|
|
2
|
+
const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, TriggerDefinition } = App
|
|
3
3
|
const { extractIdParts, extractIdentifiers, extractObjectData, prepareAccessControl } = require("./utils.js")
|
|
4
4
|
|
|
5
5
|
const pluralize = require('pluralize')
|
|
6
|
-
const {fireChangeTriggers} = require("./changeTriggers.js")
|
|
6
|
+
const { fireChangeTriggers } = require("./changeTriggers.js")
|
|
7
7
|
|
|
8
8
|
function defineView(config, context) {
|
|
9
9
|
const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
|
|
@@ -177,6 +177,156 @@ function defineDeleteAction(config, context) {
|
|
|
177
177
|
})
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
function defineCopyAction(config, context) {
|
|
181
|
+
const {
|
|
182
|
+
service, app, model, modelRuntime, modelPropertyName, objectType,
|
|
183
|
+
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others,
|
|
184
|
+
identifiers
|
|
185
|
+
} = context
|
|
186
|
+
const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Copied'
|
|
187
|
+
const actionName = 'copy' + joinedOthersClassName + context.reverseRelationWord + modelName
|
|
188
|
+
const accessControl = config.copyAccessControl
|
|
189
|
+
prepareAccessControl(accessControl, otherPropertyNames, others)
|
|
190
|
+
service.actions[actionName] = new ActionDefinition({
|
|
191
|
+
name: actionName,
|
|
192
|
+
properties: {
|
|
193
|
+
[modelPropertyName]: {
|
|
194
|
+
type: model,
|
|
195
|
+
validation: ['nonEmpty']
|
|
196
|
+
},
|
|
197
|
+
...(identifiers),
|
|
198
|
+
updates: {
|
|
199
|
+
type: 'object',
|
|
200
|
+
properties: {
|
|
201
|
+
...(model.properties)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
access: config.copyAccess,
|
|
206
|
+
skipValidation: true,
|
|
207
|
+
//queuedBy: otherPropertyNames,
|
|
208
|
+
waitForEvents: true,
|
|
209
|
+
async execute(properties, { client, service }, emit) {
|
|
210
|
+
const id = properties[modelPropertyName]
|
|
211
|
+
const entity = await modelRuntime().get(id)
|
|
212
|
+
if(!entity) throw new Error('not_found')
|
|
213
|
+
const entityIdParts = extractIdParts(otherPropertyNames, entity)
|
|
214
|
+
const idParts = extractIdParts(otherPropertyNames, properties)
|
|
215
|
+
const identifiers = extractIdentifiers(otherPropertyNames, entity)
|
|
216
|
+
if(JSON.stringify(entityIdParts) != JSON.stringify(idParts)) {
|
|
217
|
+
throw new Error('not_authorized')
|
|
218
|
+
}
|
|
219
|
+
const srcData = extractObjectData(writeableProperties, properties, entity)
|
|
220
|
+
const updatedData = App.utils.mergeDeep(srcData, properties.updates)
|
|
221
|
+
const newId = app.generateUid()
|
|
222
|
+
const dataWithIdentifiers = { [modelPropertyName]: newId, ...identifiers, ...updatedData }
|
|
223
|
+
await App.validation.validate(dataWithIdentifiers, validators,
|
|
224
|
+
{ source: action, action, service, app, client })
|
|
225
|
+
app.trigger({
|
|
226
|
+
type: 'copy'+service.name[0].toUpperCase()+service.name.slice(1)+'_'+modelName,
|
|
227
|
+
objectType,
|
|
228
|
+
object: newId,
|
|
229
|
+
from: id,
|
|
230
|
+
identifiers,
|
|
231
|
+
data: updatedData
|
|
232
|
+
}),
|
|
233
|
+
app.trigger({
|
|
234
|
+
type: 'copyObject',
|
|
235
|
+
objectType,
|
|
236
|
+
object: newId,
|
|
237
|
+
from: id,
|
|
238
|
+
identifiers,
|
|
239
|
+
data: updatedData
|
|
240
|
+
})
|
|
241
|
+
await fireChangeTriggers(context, objectType, identifiers, newId, null, updatedData)
|
|
242
|
+
emit({
|
|
243
|
+
type: eventName,
|
|
244
|
+
[modelPropertyName]: newId,
|
|
245
|
+
['from'+modelPropertyName[0].toUpperCase() + modelPropertyName.slice(1)]: id,
|
|
246
|
+
identifiers,
|
|
247
|
+
data: updatedData
|
|
248
|
+
})
|
|
249
|
+
return {
|
|
250
|
+
newId,
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
})
|
|
254
|
+
const action = service.actions[actionName]
|
|
255
|
+
const validators = App.validation.getValidators(action, service, action)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function defineCopyOnParentCopyTrigger(config, context) {
|
|
259
|
+
const {
|
|
260
|
+
service, app, model, modelRuntime, modelPropertyName, objectType,
|
|
261
|
+
otherPropertyNames, others, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName,
|
|
262
|
+
} = context
|
|
263
|
+
const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Copied'
|
|
264
|
+
const triggerName = 'copyOnParentCopy_' + service.name + '_' + modelName
|
|
265
|
+
if(!service.triggers[triggerName]) service.triggers[triggerName] = []
|
|
266
|
+
service.triggers[triggerName].push(new TriggerDefinition({
|
|
267
|
+
name: triggerName,
|
|
268
|
+
properties: {
|
|
269
|
+
objectType: {
|
|
270
|
+
type: String,
|
|
271
|
+
},
|
|
272
|
+
object: {
|
|
273
|
+
type: String,
|
|
274
|
+
},
|
|
275
|
+
parentType: {
|
|
276
|
+
type: String,
|
|
277
|
+
},
|
|
278
|
+
parent: {
|
|
279
|
+
type: String,
|
|
280
|
+
},
|
|
281
|
+
fromParent: {
|
|
282
|
+
type: String,
|
|
283
|
+
},
|
|
284
|
+
identifiers: {
|
|
285
|
+
type: Object,
|
|
286
|
+
},
|
|
287
|
+
data: {
|
|
288
|
+
type: Object,
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
async execute({ objectType, object, parentType, parent, fromParent, identifiers, data }, {client, service}, emit) {
|
|
292
|
+
const newIdentifiers = {
|
|
293
|
+
...identifiers
|
|
294
|
+
}
|
|
295
|
+
for(let i = 0; i < others.length; i++) {
|
|
296
|
+
const other = others[i]
|
|
297
|
+
if(other == parentType) {
|
|
298
|
+
newIdentifiers[otherPropertyNames[i]] = parent
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const newId = app.generateUid()
|
|
302
|
+
app.trigger({
|
|
303
|
+
type: 'copy'+service.name[0].toUpperCase()+service.name.slice(1)+'_'+modelName,
|
|
304
|
+
objectType,
|
|
305
|
+
object: newId,
|
|
306
|
+
from: object,
|
|
307
|
+
identifiers: newIdentifiers,
|
|
308
|
+
data
|
|
309
|
+
})
|
|
310
|
+
app.trigger({
|
|
311
|
+
type: 'copyObject',
|
|
312
|
+
objectType,
|
|
313
|
+
object: newId,
|
|
314
|
+
from: object,
|
|
315
|
+
identifiers: newIdentifiers,
|
|
316
|
+
data
|
|
317
|
+
})
|
|
318
|
+
await fireChangeTriggers(context, objectType, newIdentifiers, newId, null, data)
|
|
319
|
+
emit({
|
|
320
|
+
type: eventName,
|
|
321
|
+
[modelPropertyName]: newId,
|
|
322
|
+
['from'+modelPropertyName[0].toUpperCase() + modelPropertyName.slice(1)]: object,
|
|
323
|
+
identifiers,
|
|
324
|
+
data
|
|
325
|
+
})
|
|
326
|
+
}
|
|
327
|
+
}))
|
|
328
|
+
}
|
|
329
|
+
|
|
180
330
|
function defineSortIndex(context, sortFields) {
|
|
181
331
|
if(!Array.isArray(sortFields)) sortFields = [sortFields]
|
|
182
332
|
console.log("DEFINE SORT INDEX", sortFields)
|
|
@@ -187,4 +337,9 @@ function defineSortIndex(context, sortFields) {
|
|
|
187
337
|
})
|
|
188
338
|
}
|
|
189
339
|
|
|
190
|
-
module.exports = {
|
|
340
|
+
module.exports = {
|
|
341
|
+
defineView,
|
|
342
|
+
defineCreateAction, defineUpdateAction, defineDeleteAction, defineCopyAction,
|
|
343
|
+
defineCopyOnParentCopyTrigger,
|
|
344
|
+
defineSortIndex,
|
|
345
|
+
}
|
package/propertyOf.js
CHANGED
|
@@ -16,6 +16,8 @@ module.exports = function(service, app) {
|
|
|
16
16
|
context.relationWord = 'Property'
|
|
17
17
|
context.reverseRelationWord = 'Owned'
|
|
18
18
|
|
|
19
|
+
context.sameIdAsParent = true
|
|
20
|
+
|
|
19
21
|
context.identifiers = defineProperties(context.model, context.others, context.otherPropertyNames)
|
|
20
22
|
addAccessControlParents(context)
|
|
21
23
|
defineIndexes(context.model, context.otherPropertyNames, context.others)
|
package/propertyOfAny.js
CHANGED
|
@@ -20,6 +20,8 @@ module.exports = function(service, app) {
|
|
|
20
20
|
context.reverseRelationWord = 'Owned'
|
|
21
21
|
context.partialReverseRelationWord = 'Owned'
|
|
22
22
|
|
|
23
|
+
context.sameIdAsParent = true
|
|
24
|
+
|
|
23
25
|
context.identifiers = defineAnyProperties(context.model, context.otherPropertyNames)
|
|
24
26
|
addAccessControlAnyParents(context)
|
|
25
27
|
defineAnyIndexes(context.model, context.otherPropertyNames, false)
|
package/utils.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
const App = require("@live-change/framework")
|
|
2
2
|
const app = App.app()
|
|
3
3
|
const { allCombinations } = require("./combinations.js")
|
|
4
|
-
const {
|
|
4
|
+
const {
|
|
5
|
+
fireChangeTriggers, registerParentDeleteTriggers, registerParentCopyTriggers
|
|
6
|
+
} = require("./changeTriggers.js")
|
|
5
7
|
const {
|
|
6
8
|
PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition, TriggerDefinition
|
|
7
9
|
} = App
|
|
8
10
|
|
|
11
|
+
const {
|
|
12
|
+
extractObjectData, extractIdentifiers
|
|
13
|
+
} = require('./dataUtils.js')
|
|
14
|
+
|
|
9
15
|
function extractIdParts(otherPropertyNames, properties) {
|
|
10
16
|
const idParts = []
|
|
11
17
|
for (const propertyName of otherPropertyNames) {
|
|
@@ -14,13 +20,6 @@ function extractIdParts(otherPropertyNames, properties) {
|
|
|
14
20
|
return idParts
|
|
15
21
|
}
|
|
16
22
|
|
|
17
|
-
function extractIdentifiers(otherPropertyNames, properties) {
|
|
18
|
-
const identifiers = {}
|
|
19
|
-
for (const propertyName of otherPropertyNames) {
|
|
20
|
-
identifiers[propertyName] = properties[propertyName]
|
|
21
|
-
}
|
|
22
|
-
return identifiers
|
|
23
|
-
}
|
|
24
23
|
|
|
25
24
|
function generateId(otherPropertyNames, properties) {
|
|
26
25
|
return otherPropertyNames.length > 1
|
|
@@ -28,16 +27,6 @@ function generateId(otherPropertyNames, properties) {
|
|
|
28
27
|
: properties[otherPropertyNames[0]]
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
function extractObjectData(writeableProperties, properties, defaults) {
|
|
32
|
-
let objectData = {}
|
|
33
|
-
for (const propertyName of writeableProperties) {
|
|
34
|
-
if (properties.hasOwnProperty(propertyName)) {
|
|
35
|
-
objectData[propertyName] = properties[propertyName]
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return App.utils.mergeDeep({}, defaults, JSON.parse(JSON.stringify(objectData)))
|
|
39
|
-
}
|
|
40
|
-
|
|
41
30
|
function defineProperties(model, types, names) {
|
|
42
31
|
const identifiers = {}
|
|
43
32
|
for (let i = 0; i < types.length; i++) {
|
|
@@ -125,7 +114,7 @@ function processModelsAnnotation(service, app, annotation, multiple, cb) {
|
|
|
125
114
|
const context = {
|
|
126
115
|
service, app, model, originalModelProperties, modelProperties, modelPropertyName, defaults, modelRuntime,
|
|
127
116
|
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName,
|
|
128
|
-
others, annotation, objectType,
|
|
117
|
+
others, annotation, objectType, parentsTypes: others
|
|
129
118
|
}
|
|
130
119
|
|
|
131
120
|
cb(config, context)
|
|
@@ -194,8 +183,13 @@ function defineParentDeleteTriggers(config, context) {
|
|
|
194
183
|
registerParentDeleteTriggers(context, config)
|
|
195
184
|
}
|
|
196
185
|
|
|
186
|
+
function defineParentCopyTriggers(config, context) {
|
|
187
|
+
registerParentCopyTriggers(context, config)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
197
191
|
module.exports = {
|
|
198
192
|
extractIdParts, extractIdentifiers, extractObjectData, defineProperties, defineIndex, defineIndexes,
|
|
199
193
|
processModelsAnnotation, generateId, addAccessControlParents, prepareAccessControl,
|
|
200
|
-
defineDeleteByOwnerEvents, defineParentDeleteTriggers
|
|
194
|
+
defineDeleteByOwnerEvents, defineParentDeleteTriggers, defineParentCopyTriggers,
|
|
201
195
|
}
|
package/utilsAny.js
CHANGED
|
@@ -4,8 +4,8 @@ const {
|
|
|
4
4
|
PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition, TriggerDefinition
|
|
5
5
|
} = App
|
|
6
6
|
const { allCombinations } = require("./combinations.js")
|
|
7
|
-
const {fireChangeTriggers, registerParentDeleteTriggers} = require("./changeTriggers")
|
|
8
|
-
const {extractObjectData} = require("./
|
|
7
|
+
const { fireChangeTriggers, registerParentDeleteTriggers } = require("./changeTriggers")
|
|
8
|
+
const { extractObjectData } = require("./dataUtils.js")
|
|
9
9
|
|
|
10
10
|
function extractTypeAndIdParts(otherPropertyNames, properties) {
|
|
11
11
|
const typeAndIdParts = []
|