@live-change/relations-plugin 0.5.21 → 0.5.24
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/boundTo.js +45 -0
- package/boundToAny.js +46 -0
- package/index.js +15 -6
- package/itemOf.js +8 -158
- package/itemOfAny.js +8 -167
- package/package.json +3 -3
- package/pluralRelationAnyUtils.js +163 -0
- package/pluralRelationUtils.js +158 -0
- package/propertyOf.js +7 -132
- package/propertyOfAny.js +12 -141
- package/relatedTo.js +51 -0
- package/relatedToAny.js +51 -0
- package/singularRelationAnyUtils.js +136 -0
- package/singularRelationUtils.js +129 -0
- package/utils.js +31 -19
- package/utilsAny.js +27 -17
package/boundTo.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const {
|
|
2
|
+
defineProperties, defineIndex,
|
|
3
|
+
processModelsAnnotation, generateId
|
|
4
|
+
} = require('./utils.js')
|
|
5
|
+
|
|
6
|
+
const { defineSetEvent, defineUpdatedEvent, defineTransferredEvent, defineResetEvent } = require('./propertyEvents.js')
|
|
7
|
+
|
|
8
|
+
const { defineView, defineSetAction, defineUpdateAction, defineResetAction } = require('./singularRelationUtils.js')
|
|
9
|
+
|
|
10
|
+
module.exports = function(service, app) {
|
|
11
|
+
processModelsAnnotation(service, app, 'boundTo', false, (config, context) => {
|
|
12
|
+
|
|
13
|
+
context.relationWord = 'Friend'
|
|
14
|
+
context.reverseRelationWord = 'Bound'
|
|
15
|
+
|
|
16
|
+
defineProperties(context.model, context.others, context.otherPropertyNames)
|
|
17
|
+
defineIndex(context.model, context.joinedOthersClassName, context.otherPropertyNames)
|
|
18
|
+
|
|
19
|
+
if(config.readAccess) {
|
|
20
|
+
defineView({ ...config, access: config.readAccess }, context)
|
|
21
|
+
}
|
|
22
|
+
if(config.views) {
|
|
23
|
+
for(const view of config.views) {
|
|
24
|
+
defineView({ ...config, ...view }, context)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
defineSetEvent(config, context, generateId)
|
|
29
|
+
defineUpdatedEvent(config, context, generateId)
|
|
30
|
+
defineTransferredEvent(config, context, generateId)
|
|
31
|
+
defineResetEvent(config, context, generateId)
|
|
32
|
+
|
|
33
|
+
if(config.setAccess || config.writeAccess) {
|
|
34
|
+
defineSetAction(config, context)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if(config.updateAccess || config.writeAccess) {
|
|
38
|
+
defineUpdateAction(config, context)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if(config.resetAccess || config.writeAccess) {
|
|
42
|
+
defineResetAction(config, context);
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
}
|
package/boundToAny.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const {
|
|
2
|
+
defineAnyProperties, defineAnyIndex,
|
|
3
|
+
processModelsAnyAnnotation, generateAnyId
|
|
4
|
+
} = require('./utilsAny.js')
|
|
5
|
+
|
|
6
|
+
const { defineSetEvent, defineUpdatedEvent, defineTransferredEvent, defineResetEvent } = require('./propertyEvents.js')
|
|
7
|
+
|
|
8
|
+
const { defineView, defineSetAction, defineUpdateAction, defineResetAction } = require('./singularRelationUtils.js')
|
|
9
|
+
|
|
10
|
+
module.exports = function(service, app) {
|
|
11
|
+
processModelsAnyAnnotation(service, app, 'boundToAny', false, (config, context) => {
|
|
12
|
+
|
|
13
|
+
context.relationWord = 'Friend'
|
|
14
|
+
context.reverseRelationWord = 'Bound'
|
|
15
|
+
|
|
16
|
+
defineAnyProperties(context.model, context.otherPropertyNames)
|
|
17
|
+
defineAnyIndex(context.model, context.joinedOthersClassName, context.otherPropertyNames)
|
|
18
|
+
|
|
19
|
+
if(config.readAccess) {
|
|
20
|
+
defineView({ ...config, access: config.readAccess }, context)
|
|
21
|
+
}
|
|
22
|
+
if(config.views) {
|
|
23
|
+
for(const view of config.views) {
|
|
24
|
+
defineView({ ...config, ...view }, context)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
defineSetEvent(config, context, generateAnyId)
|
|
29
|
+
defineUpdatedEvent(config, context, generateAnyId)
|
|
30
|
+
defineTransferredEvent(config, context, generateAnyId)
|
|
31
|
+
defineResetEvent(config, context, generateAnyId)
|
|
32
|
+
|
|
33
|
+
if(config.setAccess || config.writeAccess) {
|
|
34
|
+
defineSetAction(config, context)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if(config.updateAccess || config.writeAccess) {
|
|
38
|
+
defineUpdateAction(config, context)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if(config.resetAccess || config.writeAccess) {
|
|
42
|
+
defineResetAction(config, context);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
})
|
|
46
|
+
}
|
package/index.js
CHANGED
|
@@ -4,14 +4,23 @@ const itemOf = require('./itemOf.js')
|
|
|
4
4
|
const propertyOfAny = require('./propertyOfAny.js')
|
|
5
5
|
const itemOfAny = require('./itemOfAny.js')
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const relatedTo = require('./relatedTo.js')
|
|
8
|
+
const relatedToAny = require('./relatedToAny.js')
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
const boundTo = require('./boundTo.js')
|
|
11
|
+
const boundToAny = require('./boundToAny.js')
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
const processors = [
|
|
14
|
+
propertyOf, itemOf,
|
|
15
|
+
propertyOfAny, itemOfAny,
|
|
16
|
+
relatedTo, relatedToAny,
|
|
17
|
+
boundTo, boundToAny
|
|
18
|
+
]
|
|
14
19
|
|
|
20
|
+
module.exports = function(app, services) {
|
|
21
|
+
app.defaultProcessors.push(...processors)
|
|
15
22
|
}
|
|
16
23
|
|
|
17
|
-
module.exports.processors = [
|
|
24
|
+
module.exports.processors = [
|
|
25
|
+
...processors
|
|
26
|
+
]
|
package/itemOf.js
CHANGED
|
@@ -1,171 +1,21 @@
|
|
|
1
|
-
const App = require("@live-change/framework")
|
|
2
|
-
const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition } = App
|
|
3
|
-
|
|
4
1
|
const {
|
|
5
|
-
|
|
2
|
+
defineProperties, defineIndex,
|
|
6
3
|
processModelsAnnotation
|
|
7
4
|
} = require('./utils.js')
|
|
8
5
|
|
|
9
|
-
const pluralize = require('pluralize')
|
|
10
|
-
|
|
11
|
-
function defineView(config, context) {
|
|
12
|
-
const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
|
|
13
|
-
modelName, others, model } = context
|
|
14
|
-
const indexName = 'by'+context.joinedOthersClassName
|
|
15
|
-
const viewProperties = {}
|
|
16
|
-
for (let i = 0; i < others.length; i++) {
|
|
17
|
-
viewProperties[otherPropertyNames[i]] = new PropertyDefinition({
|
|
18
|
-
type: others[i],
|
|
19
|
-
validation: ['nonEmpty']
|
|
20
|
-
})
|
|
21
|
-
}
|
|
22
|
-
const viewName = joinedOthersPropertyName + 'Owned' + pluralize(modelName)
|
|
23
|
-
service.views[viewName] = new ViewDefinition({
|
|
24
|
-
name: viewName,
|
|
25
|
-
properties: {
|
|
26
|
-
...viewProperties,
|
|
27
|
-
...App.utils.rangeProperties
|
|
28
|
-
},
|
|
29
|
-
returns: {
|
|
30
|
-
type: Array,
|
|
31
|
-
of: {
|
|
32
|
-
type: model
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
access: config.readAccess,
|
|
36
|
-
daoPath(properties, { client, context }) {
|
|
37
|
-
const idParts = extractIdParts(otherPropertyNames, properties)
|
|
38
|
-
const range = extractRange(properties)
|
|
39
|
-
const path = modelRuntime().sortedIndexRangePath(indexName, idParts, range)
|
|
40
|
-
return path
|
|
41
|
-
}
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
|
|
45
6
|
const {
|
|
46
7
|
defineCreatedEvent, defineUpdatedEvent, defineDeletedEvent, defineTransferredEvent,
|
|
47
8
|
} = require('./itemEvents.js')
|
|
48
|
-
const { defineTransferEvent } = require("./itemEvents");
|
|
49
|
-
|
|
50
|
-
function defineCreateAction(config, context) {
|
|
51
|
-
const {
|
|
52
|
-
service, app, model, defaults, modelPropertyName, modelRuntime,
|
|
53
|
-
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
|
|
54
|
-
} = context
|
|
55
|
-
const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Created'
|
|
56
|
-
const actionName = 'set' + joinedOthersClassName + 'Owned' + modelName
|
|
57
|
-
service.actions[actionName] = new ActionDefinition({
|
|
58
|
-
name: actionName,
|
|
59
|
-
properties: {
|
|
60
|
-
...(model.properties)
|
|
61
|
-
},
|
|
62
|
-
access: config.createAccess || config.writeAccess,
|
|
63
|
-
skipValidation: true,
|
|
64
|
-
//queuedBy: otherPropertyNames,
|
|
65
|
-
waitForEvents: true,
|
|
66
|
-
async execute(properties, { client, service }, emit) {
|
|
67
|
-
const id = properties[modelPropertyName] || app.generateUid()
|
|
68
|
-
const entity = await modelRuntime().get(id)
|
|
69
|
-
if(entity) throw 'exists'
|
|
70
|
-
const identifiers = extractIdentifiers(otherPropertyNames, properties)
|
|
71
|
-
const data = extractObjectData(writeableProperties, properties, defaults)
|
|
72
|
-
await App.validation.validate(data, validators, { source: action, action, service, app, client })
|
|
73
|
-
emit({
|
|
74
|
-
type: eventName,
|
|
75
|
-
[modelPropertyName]: id,
|
|
76
|
-
identifiers, data
|
|
77
|
-
})
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
const action = service.actions[actionName]
|
|
81
|
-
const validators = App.validation.getValidators(action, service, action)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function defineUpdateAction(config, context) {
|
|
85
|
-
const {
|
|
86
|
-
service, app, model, modelRuntime, modelPropertyName,
|
|
87
|
-
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
|
|
88
|
-
} = context
|
|
89
|
-
const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Updated'
|
|
90
|
-
const actionName = 'update' + joinedOthersClassName + 'Owned' + modelName
|
|
91
|
-
service.actions[actionName] = new ActionDefinition({
|
|
92
|
-
name: actionName,
|
|
93
|
-
properties: {
|
|
94
|
-
...(model.properties)
|
|
95
|
-
},
|
|
96
|
-
access: config.updateAccess || config.writeAccess,
|
|
97
|
-
skipValidation: true,
|
|
98
|
-
//queuedBy: otherPropertyNames,
|
|
99
|
-
waitForEvents: true,
|
|
100
|
-
async execute(properties, {client, service}, emit) {
|
|
101
|
-
const id = properties[modelPropertyName]
|
|
102
|
-
const entity = await modelRuntime().get(id)
|
|
103
|
-
if(!entity) throw 'not_found'
|
|
104
|
-
const entityIdParts = extractIdParts(otherPropertyNames, entity)
|
|
105
|
-
const idParts = extractIdParts(otherPropertyNames, properties)
|
|
106
|
-
if(JSON.stringify(entityIdParts) != JSON.stringify(idParts)) {
|
|
107
|
-
throw 'not_authorized'
|
|
108
|
-
}
|
|
109
|
-
const identifiers = extractIdentifiers(otherPropertyNames, properties)
|
|
110
|
-
const data = extractObjectData(writeableProperties, properties, entity)
|
|
111
|
-
await App.validation.validate(data, validators, { source: action, action, service, app, client })
|
|
112
|
-
emit({
|
|
113
|
-
type: eventName,
|
|
114
|
-
[modelPropertyName]: id,
|
|
115
|
-
identifiers,
|
|
116
|
-
data
|
|
117
|
-
})
|
|
118
|
-
}
|
|
119
|
-
})
|
|
120
|
-
const action = service.actions[actionName]
|
|
121
|
-
const validators = App.validation.getValidators(action, service, action)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function defineDeleteAction(config, context) {
|
|
125
|
-
const {
|
|
126
|
-
service, app, model, modelRuntime, modelPropertyName,
|
|
127
|
-
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
|
|
128
|
-
} = context
|
|
129
|
-
const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Deleted'
|
|
130
|
-
const actionName = 'delete' + joinedOthersClassName + 'Owned' + modelName
|
|
131
|
-
service.actions[actionName] = new ActionDefinition({
|
|
132
|
-
name: actionName,
|
|
133
|
-
properties: {
|
|
134
|
-
...(model.properties)
|
|
135
|
-
},
|
|
136
|
-
access: config.deleteAccess || config.writeAccess,
|
|
137
|
-
skipValidation: true,
|
|
138
|
-
//queuedBy: otherPropertyNames,
|
|
139
|
-
waitForEvents: true,
|
|
140
|
-
async execute(properties, {client, service}, emit) {
|
|
141
|
-
const id = properties[modelPropertyName]
|
|
142
|
-
const entity = await modelRuntime().get(id)
|
|
143
|
-
if(!entity) throw new Error('not_found')
|
|
144
|
-
const entityIdParts = extractIdParts(otherPropertyNames, entity)
|
|
145
|
-
const idParts = extractIdParts(otherPropertyNames, properties)
|
|
146
|
-
if(JSON.stringify(entityIdParts) != JSON.stringify(idParts)) {
|
|
147
|
-
throw new Error('not_authorized')
|
|
148
|
-
}
|
|
149
|
-
emit({
|
|
150
|
-
type: eventName,
|
|
151
|
-
[modelPropertyName]: id
|
|
152
|
-
})
|
|
153
|
-
}
|
|
154
|
-
})
|
|
155
|
-
}
|
|
156
9
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const sortFieldsUc = sortFields.map(fd=>fd.slice(0, 1).toUpperCase() + fd.slice(1))
|
|
161
|
-
const indexName = 'by' + context.joinedOthersClassName + sortFieldsUc.join('')
|
|
162
|
-
context.model.indexes[indexName] = new IndexDefinition({
|
|
163
|
-
property: [...context.otherPropertyNames, ...sortFields]
|
|
164
|
-
})
|
|
165
|
-
}
|
|
10
|
+
const {
|
|
11
|
+
defineView, defineCreateAction, defineUpdateAction, defineDeleteAction, defineSortIndex
|
|
12
|
+
} = require('./pluralRelationUtils.js')
|
|
166
13
|
|
|
167
14
|
module.exports = function(service, app) {
|
|
168
|
-
processModelsAnnotation(service, app, 'itemOf', (config, context) => {
|
|
15
|
+
processModelsAnnotation(service, app, 'itemOf', false, (config, context) => {
|
|
16
|
+
|
|
17
|
+
context.relationWord = 'Item'
|
|
18
|
+
context.reverseRelationWord = 'Owned'
|
|
169
19
|
|
|
170
20
|
defineProperties(context.model, context.others, context.otherPropertyNames)
|
|
171
21
|
defineIndex(context.model, context.joinedOthersClassName, context.otherPropertyNames)
|
package/itemOfAny.js
CHANGED
|
@@ -1,180 +1,21 @@
|
|
|
1
|
-
const App = require("@live-change/framework")
|
|
2
|
-
const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition } = App
|
|
3
|
-
|
|
4
|
-
const {
|
|
5
|
-
extractRange, extractObjectData
|
|
6
|
-
} = require('./utils.js')
|
|
7
|
-
|
|
8
1
|
const {
|
|
9
|
-
|
|
2
|
+
defineAnyProperties, defineAnyIndex,
|
|
10
3
|
processModelsAnyAnnotation
|
|
11
4
|
} = require('./utilsAny.js')
|
|
12
5
|
|
|
13
|
-
const pluralize = require('pluralize')
|
|
14
|
-
|
|
15
|
-
function defineView(config, context) {
|
|
16
|
-
const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
|
|
17
|
-
modelName, others, model } = context
|
|
18
|
-
const indexName = 'by'+context.joinedOthersClassName
|
|
19
|
-
const viewProperties = {}
|
|
20
|
-
for (let i = 0; i < others.length; i++) {
|
|
21
|
-
viewProperties[otherPropertyNames[i]] = new PropertyDefinition({
|
|
22
|
-
type: 'String',
|
|
23
|
-
validation: ['nonEmpty']
|
|
24
|
-
})
|
|
25
|
-
viewProperties[otherPropertyNames[i] + 'Type'] = new PropertyDefinition({
|
|
26
|
-
type: 'String',
|
|
27
|
-
validation: ['nonEmpty']
|
|
28
|
-
})
|
|
29
|
-
}
|
|
30
|
-
const viewName = joinedOthersPropertyName + 'Owned' + pluralize(modelName)
|
|
31
|
-
service.views[viewName] = new ViewDefinition({
|
|
32
|
-
name: viewName,
|
|
33
|
-
properties: {
|
|
34
|
-
...viewProperties,
|
|
35
|
-
...App.utils.rangeProperties
|
|
36
|
-
},
|
|
37
|
-
returns: {
|
|
38
|
-
type: Array,
|
|
39
|
-
of: {
|
|
40
|
-
type: model
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
access: config.readAccess,
|
|
44
|
-
daoPath(properties, { client, context }) {
|
|
45
|
-
const typeAndIdParts = extractTypeAndIdParts(otherPropertyNames, properties)
|
|
46
|
-
const range = extractRange(properties)
|
|
47
|
-
const path = modelRuntime().sortedIndexRangePath(indexName, typeAndIdParts, range)
|
|
48
|
-
return path
|
|
49
|
-
}
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
|
|
53
6
|
const {
|
|
54
7
|
defineCreatedEvent, defineUpdatedEvent, defineDeletedEvent, defineTransferredEvent,
|
|
55
8
|
} = require('./itemEvents.js')
|
|
56
|
-
const { defineTransferEvent } = require("./itemEvents");
|
|
57
|
-
|
|
58
|
-
function defineCreateAction(config, context) {
|
|
59
|
-
const {
|
|
60
|
-
service, app, model, defaults, modelPropertyName, modelRuntime,
|
|
61
|
-
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
|
|
62
|
-
} = context
|
|
63
|
-
const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Created'
|
|
64
|
-
const actionName = 'set' + joinedOthersClassName + 'Owned' + modelName
|
|
65
|
-
service.actions[actionName] = new ActionDefinition({
|
|
66
|
-
name: actionName,
|
|
67
|
-
properties: {
|
|
68
|
-
...(model.properties)
|
|
69
|
-
},
|
|
70
|
-
access: config.createAccess || config.writeAccess,
|
|
71
|
-
skipValidation: true,
|
|
72
|
-
//queuedBy: otherPropertyNames,
|
|
73
|
-
waitForEvents: true,
|
|
74
|
-
async execute(properties, { client, service }, emit) {
|
|
75
|
-
const id = properties[modelPropertyName] || app.generateUid()
|
|
76
|
-
const entity = await modelRuntime().get(id)
|
|
77
|
-
if(entity) throw 'exists'
|
|
78
|
-
const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
|
|
79
|
-
const data = extractObjectData(writeableProperties, properties, defaults)
|
|
80
|
-
await App.validation.validate(data, validators, { source: action, action, service, app, client })
|
|
81
|
-
emit({
|
|
82
|
-
type: eventName,
|
|
83
|
-
[modelPropertyName]: id,
|
|
84
|
-
identifiers, data
|
|
85
|
-
})
|
|
86
|
-
}
|
|
87
|
-
})
|
|
88
|
-
const action = service.actions[actionName]
|
|
89
|
-
const validators = App.validation.getValidators(action, service, action)
|
|
90
|
-
}
|
|
91
9
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
|
|
96
|
-
} = context
|
|
97
|
-
const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Updated'
|
|
98
|
-
const actionName = 'update' + joinedOthersClassName + 'Owned' + modelName
|
|
99
|
-
service.actions[actionName] = new ActionDefinition({
|
|
100
|
-
name: actionName,
|
|
101
|
-
properties: {
|
|
102
|
-
...(model.properties)
|
|
103
|
-
},
|
|
104
|
-
access: config.updateAccess || config.writeAccess,
|
|
105
|
-
skipValidation: true,
|
|
106
|
-
//queuedBy: otherPropertyNames,
|
|
107
|
-
waitForEvents: true,
|
|
108
|
-
async execute(properties, { client, service }, emit) {
|
|
109
|
-
const id = properties[modelPropertyName]
|
|
110
|
-
const entity = await modelRuntime().get(id)
|
|
111
|
-
if(!entity) throw 'not_found'
|
|
112
|
-
const entityTypeAndIdParts = extractTypeAndIdParts(otherPropertyNames, entity)
|
|
113
|
-
const typeAndIdParts = extractTypeAndIdParts(otherPropertyNames, properties)
|
|
114
|
-
if(JSON.stringify(entityTypeAndIdParts) != JSON.stringify(typeAndIdParts)) {
|
|
115
|
-
throw 'not_authorized'
|
|
116
|
-
}
|
|
117
|
-
const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
|
|
118
|
-
const data = extractObjectData(writeableProperties, properties, entity)
|
|
119
|
-
await App.validation.validate(data, validators, { source: action, action, service, app, client })
|
|
120
|
-
emit({
|
|
121
|
-
type: eventName,
|
|
122
|
-
[modelPropertyName]: id,
|
|
123
|
-
identifiers,
|
|
124
|
-
data
|
|
125
|
-
})
|
|
126
|
-
}
|
|
127
|
-
})
|
|
128
|
-
const action = service.actions[actionName]
|
|
129
|
-
const validators = App.validation.getValidators(action, service, action)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function defineDeleteAction(config, context) {
|
|
133
|
-
const {
|
|
134
|
-
service, app, model, modelRuntime, modelPropertyName,
|
|
135
|
-
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
|
|
136
|
-
} = context
|
|
137
|
-
const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Deleted'
|
|
138
|
-
const actionName = 'delete' + joinedOthersClassName + 'Owned' + modelName
|
|
139
|
-
service.actions[actionName] = new ActionDefinition({
|
|
140
|
-
name: actionName,
|
|
141
|
-
properties: {
|
|
142
|
-
...(model.properties)
|
|
143
|
-
},
|
|
144
|
-
access: config.deleteAccess || config.writeAccess,
|
|
145
|
-
skipValidation: true,
|
|
146
|
-
//queuedBy: otherPropertyNames,
|
|
147
|
-
waitForEvents: true,
|
|
148
|
-
async execute(properties, { client, service }, emit) {
|
|
149
|
-
const id = properties[modelPropertyName]
|
|
150
|
-
const entity = await modelRuntime().get(id)
|
|
151
|
-
if(!entity) throw new Error('not_found')
|
|
152
|
-
const entityTypeAndIdParts = extractTypeAndIdParts(otherPropertyNames, entity)
|
|
153
|
-
const typeAndIdParts = extractTypeAndIdParts(otherPropertyNames, properties)
|
|
154
|
-
if(JSON.stringify(entityTypeAndIdParts) != JSON.stringify(typeAndIdParts)) {
|
|
155
|
-
throw new Error('not_authorized')
|
|
156
|
-
}
|
|
157
|
-
emit({
|
|
158
|
-
type: eventName,
|
|
159
|
-
[modelPropertyName]: id
|
|
160
|
-
})
|
|
161
|
-
}
|
|
162
|
-
})
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function defineSortIndex(context, sortFields) {
|
|
166
|
-
if(!Array.isArray(sortFields)) sortFields = [sortFields]
|
|
167
|
-
console.log("DEFINE SORT INDEX", sortFields)
|
|
168
|
-
const sortFieldsUc = sortFields.map(fd => fd.slice(0, 1).toUpperCase() + fd.slice(1))
|
|
169
|
-
const indexName = 'by' + context.joinedOthersClassName + sortFieldsUc.join('')
|
|
170
|
-
context.model.indexes[indexName] = new IndexDefinition({
|
|
171
|
-
property: [...(context.otherPropertyNames.map(prop => [prop + 'Type', prop])), ...sortFields]
|
|
172
|
-
})
|
|
173
|
-
}
|
|
10
|
+
const {
|
|
11
|
+
defineView, defineCreateAction, defineUpdateAction, defineDeleteAction, defineSortIndex
|
|
12
|
+
} = require('./pluralRelationAnyUtils.js')
|
|
174
13
|
|
|
175
14
|
module.exports = function(service, app) {
|
|
176
|
-
processModelsAnyAnnotation(service, app, 'itemOfAny', (config, context) => {
|
|
177
|
-
|
|
15
|
+
processModelsAnyAnnotation(service, app, 'itemOfAny',false, (config, context) => {
|
|
16
|
+
|
|
17
|
+
context.relationWord = 'Item'
|
|
18
|
+
context.reverseRelationWord = 'Owned'
|
|
178
19
|
|
|
179
20
|
defineAnyProperties(context.model, context.otherPropertyNames)
|
|
180
21
|
defineAnyIndex(context.model, context.joinedOthersClassName, context.otherPropertyNames)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/relations-plugin",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.24",
|
|
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.5.
|
|
24
|
+
"@live-change/framework": "^0.5.24",
|
|
25
25
|
"pluralize": "8.0.0"
|
|
26
26
|
},
|
|
27
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "2fb6050c59e88d0dd285d640e454819d30130b0b"
|
|
28
28
|
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
const App = require("@live-change/framework")
|
|
2
|
+
const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition } = App
|
|
3
|
+
const { extractTypeAndIdParts, extractIdentifiersWithTypes } = require("./utilsAny.js")
|
|
4
|
+
const { extractRange, extractObjectData } = require("./utils.js")
|
|
5
|
+
|
|
6
|
+
const pluralize = require('pluralize')
|
|
7
|
+
|
|
8
|
+
function defineView(config, context) {
|
|
9
|
+
const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
|
|
10
|
+
modelName, others, model } = context
|
|
11
|
+
const indexName = 'by'+context.joinedOthersClassName
|
|
12
|
+
const viewProperties = {}
|
|
13
|
+
for (let i = 0; i < others.length; i++) {
|
|
14
|
+
viewProperties[otherPropertyNames[i]] = new PropertyDefinition({
|
|
15
|
+
type: 'String',
|
|
16
|
+
validation: ['nonEmpty']
|
|
17
|
+
})
|
|
18
|
+
viewProperties[otherPropertyNames[i] + 'Type'] = new PropertyDefinition({
|
|
19
|
+
type: 'String',
|
|
20
|
+
validation: ['nonEmpty']
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
const viewName = joinedOthersPropertyName + context.reverseRelationWord + pluralize(modelName)
|
|
24
|
+
service.views[viewName] = new ViewDefinition({
|
|
25
|
+
name: viewName,
|
|
26
|
+
properties: {
|
|
27
|
+
...viewProperties,
|
|
28
|
+
...App.utils.rangeProperties
|
|
29
|
+
},
|
|
30
|
+
returns: {
|
|
31
|
+
type: Array,
|
|
32
|
+
of: {
|
|
33
|
+
type: model
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
access: config.readAccess,
|
|
37
|
+
daoPath(properties, { client, context }) {
|
|
38
|
+
const typeAndIdParts = extractTypeAndIdParts(otherPropertyNames, properties)
|
|
39
|
+
const range = extractRange(properties)
|
|
40
|
+
const path = modelRuntime().sortedIndexRangePath(indexName, typeAndIdParts, range)
|
|
41
|
+
return path
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function defineCreateAction(config, context) {
|
|
47
|
+
const {
|
|
48
|
+
service, app, model, defaults, modelPropertyName, modelRuntime,
|
|
49
|
+
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
|
|
50
|
+
} = context
|
|
51
|
+
const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Created'
|
|
52
|
+
const actionName = 'create' + joinedOthersClassName + context.reverseRelationWord + modelName
|
|
53
|
+
service.actions[actionName] = new ActionDefinition({
|
|
54
|
+
name: actionName,
|
|
55
|
+
properties: {
|
|
56
|
+
...(model.properties)
|
|
57
|
+
},
|
|
58
|
+
access: config.createAccess || config.writeAccess,
|
|
59
|
+
skipValidation: true,
|
|
60
|
+
//queuedBy: otherPropertyNames,
|
|
61
|
+
waitForEvents: true,
|
|
62
|
+
async execute(properties, { client, service }, emit) {
|
|
63
|
+
const id = properties[modelPropertyName] || app.generateUid()
|
|
64
|
+
const entity = await modelRuntime().get(id)
|
|
65
|
+
if(entity) throw 'exists'
|
|
66
|
+
const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
|
|
67
|
+
const data = extractObjectData(writeableProperties, properties, defaults)
|
|
68
|
+
await App.validation.validate(data, validators, { source: action, action, service, app, client })
|
|
69
|
+
emit({
|
|
70
|
+
type: eventName,
|
|
71
|
+
[modelPropertyName]: id,
|
|
72
|
+
identifiers, data
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
const action = service.actions[actionName]
|
|
77
|
+
const validators = App.validation.getValidators(action, service, action)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function defineUpdateAction(config, context) {
|
|
81
|
+
const {
|
|
82
|
+
service, app, model, modelRuntime, modelPropertyName,
|
|
83
|
+
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
|
|
84
|
+
} = context
|
|
85
|
+
const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Updated'
|
|
86
|
+
const actionName = 'update' + joinedOthersClassName + context.reverseRelationWord + modelName
|
|
87
|
+
service.actions[actionName] = new ActionDefinition({
|
|
88
|
+
name: actionName,
|
|
89
|
+
properties: {
|
|
90
|
+
...(model.properties)
|
|
91
|
+
},
|
|
92
|
+
access: config.updateAccess || config.writeAccess,
|
|
93
|
+
skipValidation: true,
|
|
94
|
+
//queuedBy: otherPropertyNames,
|
|
95
|
+
waitForEvents: true,
|
|
96
|
+
async execute(properties, { client, service }, emit) {
|
|
97
|
+
const id = properties[modelPropertyName]
|
|
98
|
+
const entity = await modelRuntime().get(id)
|
|
99
|
+
if(!entity) throw 'not_found'
|
|
100
|
+
const entityTypeAndIdParts = extractTypeAndIdParts(otherPropertyNames, entity)
|
|
101
|
+
const typeAndIdParts = extractTypeAndIdParts(otherPropertyNames, properties)
|
|
102
|
+
if(JSON.stringify(entityTypeAndIdParts) != JSON.stringify(typeAndIdParts)) {
|
|
103
|
+
throw 'not_authorized'
|
|
104
|
+
}
|
|
105
|
+
const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
|
|
106
|
+
const data = extractObjectData(writeableProperties, properties, entity)
|
|
107
|
+
await App.validation.validate(data, validators, { source: action, action, service, app, client })
|
|
108
|
+
emit({
|
|
109
|
+
type: eventName,
|
|
110
|
+
[modelPropertyName]: id,
|
|
111
|
+
identifiers,
|
|
112
|
+
data
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
const action = service.actions[actionName]
|
|
117
|
+
const validators = App.validation.getValidators(action, service, action)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function defineDeleteAction(config, context) {
|
|
121
|
+
const {
|
|
122
|
+
service, app, model, modelRuntime, modelPropertyName,
|
|
123
|
+
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
|
|
124
|
+
} = context
|
|
125
|
+
const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Deleted'
|
|
126
|
+
const actionName = 'delete' + joinedOthersClassName + context.reverseRelationWord + modelName
|
|
127
|
+
service.actions[actionName] = new ActionDefinition({
|
|
128
|
+
name: actionName,
|
|
129
|
+
properties: {
|
|
130
|
+
...(model.properties)
|
|
131
|
+
},
|
|
132
|
+
access: config.deleteAccess || config.writeAccess,
|
|
133
|
+
skipValidation: true,
|
|
134
|
+
//queuedBy: otherPropertyNames,
|
|
135
|
+
waitForEvents: true,
|
|
136
|
+
async execute(properties, { client, service }, emit) {
|
|
137
|
+
const id = properties[modelPropertyName]
|
|
138
|
+
const entity = await modelRuntime().get(id)
|
|
139
|
+
if(!entity) throw new Error('not_found')
|
|
140
|
+
const entityTypeAndIdParts = extractTypeAndIdParts(otherPropertyNames, entity)
|
|
141
|
+
const typeAndIdParts = extractTypeAndIdParts(otherPropertyNames, properties)
|
|
142
|
+
if(JSON.stringify(entityTypeAndIdParts) != JSON.stringify(typeAndIdParts)) {
|
|
143
|
+
throw new Error('not_authorized')
|
|
144
|
+
}
|
|
145
|
+
emit({
|
|
146
|
+
type: eventName,
|
|
147
|
+
[modelPropertyName]: id
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function defineSortIndex(context, sortFields) {
|
|
154
|
+
if(!Array.isArray(sortFields)) sortFields = [sortFields]
|
|
155
|
+
console.log("DEFINE SORT INDEX", sortFields)
|
|
156
|
+
const sortFieldsUc = sortFields.map(fd => fd.slice(0, 1).toUpperCase() + fd.slice(1))
|
|
157
|
+
const indexName = 'by' + context.joinedOthersClassName + sortFieldsUc.join('')
|
|
158
|
+
context.model.indexes[indexName] = new IndexDefinition({
|
|
159
|
+
property: [...(context.otherPropertyNames.map(prop => [prop + 'Type', prop])), ...sortFields]
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
module.exports = { defineView, defineCreateAction, defineUpdateAction, defineDeleteAction, defineSortIndex }
|