@live-change/relations-plugin 0.5.20 → 0.5.23
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 +9 -157
- package/itemOfAny.js +9 -165
- package/package.json +4 -3
- package/pluralRelationAnyUtils.js +163 -0
- package/pluralRelationUtils.js +158 -0
- package/propertyOf.js +7 -132
- package/propertyOfAny.js +12 -140
- 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 +28 -18
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
const App = require("@live-change/framework")
|
|
2
|
+
const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition } = App
|
|
3
|
+
const { extractTypeAndIdParts, extractIdentifiersWithTypes, generateAnyId } = require("./utilsAny.js")
|
|
4
|
+
const { extractObjectData } = require("./utils.js")
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
function defineView(config, context) {
|
|
8
|
+
const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
|
|
9
|
+
modelName, others, model } = context
|
|
10
|
+
const viewProperties = {}
|
|
11
|
+
for (let i = 0; i < others.length; i++) {
|
|
12
|
+
viewProperties[otherPropertyNames[i]] = new PropertyDefinition({
|
|
13
|
+
type: others[i],
|
|
14
|
+
validation: ['nonEmpty']
|
|
15
|
+
})
|
|
16
|
+
viewProperties[otherPropertyNames[i] + 'Type'] = new PropertyDefinition({
|
|
17
|
+
type: 'String',
|
|
18
|
+
validation: ['nonEmpty']
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
const viewName = config.name || ((config.prefix ? (config.prefix + joinedOthersClassName) : joinedOthersPropertyName) +
|
|
22
|
+
context.reverseRelationWord + modelName + (config.suffix || ''))
|
|
23
|
+
service.views[viewName] = new ViewDefinition({
|
|
24
|
+
name: viewName,
|
|
25
|
+
properties: {
|
|
26
|
+
...viewProperties
|
|
27
|
+
},
|
|
28
|
+
returns: {
|
|
29
|
+
type: model,
|
|
30
|
+
},
|
|
31
|
+
access: config.access,
|
|
32
|
+
daoPath(properties, { client, context }) {
|
|
33
|
+
const typeAndIdParts = extractTypeAndIdParts(otherPropertyNames, properties)
|
|
34
|
+
const id = typeAndIdParts.length > 1 ? typeAndIdParts.map(p => JSON.stringify(p)).join(':') : idParts[0]
|
|
35
|
+
const path = config.fields ? modelRuntime().limitedPath(id, config.fields) : modelRuntime().path(id)
|
|
36
|
+
return path
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function defineSetAction(config, context) {
|
|
42
|
+
const {
|
|
43
|
+
service, app, model, defaults,
|
|
44
|
+
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
|
|
45
|
+
} = context
|
|
46
|
+
|
|
47
|
+
const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Set'
|
|
48
|
+
const actionName = 'set' + joinedOthersClassName + context.reverseRelationWord + modelName
|
|
49
|
+
service.actions[actionName] = new ActionDefinition({
|
|
50
|
+
name: actionName,
|
|
51
|
+
properties: {
|
|
52
|
+
...(model.properties)
|
|
53
|
+
},
|
|
54
|
+
access: config.setAccess || config.writeAccess,
|
|
55
|
+
skipValidation: true,
|
|
56
|
+
queuedBy: otherPropertyNames,
|
|
57
|
+
waitForEvents: true,
|
|
58
|
+
async execute(properties, {client, service}, emit) {
|
|
59
|
+
const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
|
|
60
|
+
const data = extractObjectData(writeableProperties, properties, defaults)
|
|
61
|
+
await App.validation.validate(data, validators, { source: action, action, service, app, client })
|
|
62
|
+
emit({
|
|
63
|
+
type: eventName,
|
|
64
|
+
identifiers, data
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
const action = service.actions[actionName]
|
|
69
|
+
const validators = App.validation.getValidators(action, service, action)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function defineUpdateAction(config, context) {
|
|
73
|
+
const {
|
|
74
|
+
service, app, model, modelRuntime,
|
|
75
|
+
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
|
|
76
|
+
} = context
|
|
77
|
+
const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Updated'
|
|
78
|
+
const actionName = 'update' + joinedOthersClassName + context.reverseRelationWord + modelName
|
|
79
|
+
service.actions[actionName] = new ActionDefinition({
|
|
80
|
+
name: actionName,
|
|
81
|
+
properties: {
|
|
82
|
+
...(model.properties)
|
|
83
|
+
},
|
|
84
|
+
access: config.updateAccess || config.writeAccess,
|
|
85
|
+
skipValidation: true,
|
|
86
|
+
queuedBy: otherPropertyNames,
|
|
87
|
+
waitForEvents: true,
|
|
88
|
+
async execute(properties, {client, service}, emit) {
|
|
89
|
+
const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
|
|
90
|
+
const id = generateAnyId(otherPropertyNames, properties)
|
|
91
|
+
const entity = await modelRuntime().get(id)
|
|
92
|
+
if (!entity) throw new Error('not_found')
|
|
93
|
+
const data = extractObjectData(writeableProperties, properties, entity)
|
|
94
|
+
await App.validation.validate(data, validators, { source: action, action, service, app, client })
|
|
95
|
+
emit({
|
|
96
|
+
type: eventName,
|
|
97
|
+
identifiers, data
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
const action = service.actions[actionName]
|
|
102
|
+
const validators = App.validation.getValidators(action, service, action)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function defineResetAction(config, context) {
|
|
106
|
+
const {
|
|
107
|
+
service, modelRuntime, modelPropertyName,
|
|
108
|
+
otherPropertyNames, joinedOthersPropertyName, modelName, joinedOthersClassName, model
|
|
109
|
+
} = context
|
|
110
|
+
const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Reset'
|
|
111
|
+
const actionName = 'reset' + joinedOthersClassName + context.reverseRelationWord + modelName
|
|
112
|
+
service.actions[actionName] = new ActionDefinition({
|
|
113
|
+
name: actionName,
|
|
114
|
+
properties: {
|
|
115
|
+
[modelPropertyName]: {
|
|
116
|
+
type: model,
|
|
117
|
+
validation: ['nonEmpty']
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
access: config.resetAccess || config.writeAccess,
|
|
121
|
+
queuedBy: otherPropertyNames,
|
|
122
|
+
waitForEvents: true,
|
|
123
|
+
async execute(properties, {client, service}, emit) {
|
|
124
|
+
const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
|
|
125
|
+
const id = generateAnyId(otherPropertyNames, properties)
|
|
126
|
+
const entity = await modelRuntime().get(id)
|
|
127
|
+
if (!entity) throw new Error('not_found')
|
|
128
|
+
emit({
|
|
129
|
+
type: eventName,
|
|
130
|
+
identifiers
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
module.exports = { defineView, defineSetAction, defineUpdateAction, defineResetAction }
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
const App = require("@live-change/framework")
|
|
2
|
+
const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition } = App
|
|
3
|
+
const { extractIdentifiers, extractObjectData, generateId, extractIdParts} = require("./utils.js")
|
|
4
|
+
|
|
5
|
+
function defineView(config, context) {
|
|
6
|
+
const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
|
|
7
|
+
modelName, others, model } = context
|
|
8
|
+
const viewProperties = {}
|
|
9
|
+
for (let i = 0; i < others.length; i++) {
|
|
10
|
+
viewProperties[otherPropertyNames[i]] = new PropertyDefinition({
|
|
11
|
+
type: others[i],
|
|
12
|
+
validation: ['nonEmpty']
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
const viewName = config.name || ((config.prefix ? (config.prefix + joinedOthersClassName) : joinedOthersPropertyName) +
|
|
16
|
+
'Owned' + modelName + (config.suffix || ''))
|
|
17
|
+
service.views[viewName] = new ViewDefinition({
|
|
18
|
+
name: viewName,
|
|
19
|
+
properties: {
|
|
20
|
+
...viewProperties
|
|
21
|
+
},
|
|
22
|
+
returns: {
|
|
23
|
+
type: model,
|
|
24
|
+
},
|
|
25
|
+
access: config.access,
|
|
26
|
+
daoPath(properties, { client, context }) {
|
|
27
|
+
const idParts = extractIdParts(otherPropertyNames, properties)
|
|
28
|
+
const id = idParts.length > 1 ? idParts.map(p => JSON.stringify(p)).join(':') : idParts[0]
|
|
29
|
+
const path = config.fields ? modelRuntime().limitedPath(id, config.fields) : modelRuntime().path(id)
|
|
30
|
+
return path
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function defineSetAction(config, context) {
|
|
36
|
+
const {
|
|
37
|
+
service, app, model, defaults,
|
|
38
|
+
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
|
|
39
|
+
} = context
|
|
40
|
+
const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Set'
|
|
41
|
+
const actionName = 'set' + joinedOthersClassName + 'Owned' + modelName
|
|
42
|
+
service.actions[actionName] = new ActionDefinition({
|
|
43
|
+
name: actionName,
|
|
44
|
+
properties: {
|
|
45
|
+
...(model.properties)
|
|
46
|
+
},
|
|
47
|
+
access: config.setAccess || config.writeAccess,
|
|
48
|
+
skipValidation: true,
|
|
49
|
+
queuedBy: otherPropertyNames,
|
|
50
|
+
waitForEvents: true,
|
|
51
|
+
async execute(properties, {client, service}, emit) {
|
|
52
|
+
const identifiers = extractIdentifiers(otherPropertyNames, properties)
|
|
53
|
+
const data = extractObjectData(writeableProperties, properties, defaults)
|
|
54
|
+
await App.validation.validate(data, validators, { source: action, action, service, app, client })
|
|
55
|
+
emit({
|
|
56
|
+
type: eventName,
|
|
57
|
+
identifiers, data
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
const action = service.actions[actionName]
|
|
62
|
+
const validators = App.validation.getValidators(action, service, action)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function defineUpdateAction(config, context) {
|
|
66
|
+
const {
|
|
67
|
+
service, app, model, modelRuntime,
|
|
68
|
+
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
|
|
69
|
+
} = context
|
|
70
|
+
const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Updated'
|
|
71
|
+
const actionName = 'update' + joinedOthersClassName + 'Owned' + modelName
|
|
72
|
+
service.actions[actionName] = new ActionDefinition({
|
|
73
|
+
name: actionName,
|
|
74
|
+
properties: {
|
|
75
|
+
...(model.properties)
|
|
76
|
+
},
|
|
77
|
+
access: config.updateAccess || config.writeAccess,
|
|
78
|
+
skipValidation: true,
|
|
79
|
+
queuedBy: otherPropertyNames,
|
|
80
|
+
waitForEvents: true,
|
|
81
|
+
async execute(properties, {client, service}, emit) {
|
|
82
|
+
const identifiers = extractIdentifiers(otherPropertyNames, properties)
|
|
83
|
+
const id = generateId(otherPropertyNames, properties)
|
|
84
|
+
const entity = await modelRuntime().get(id)
|
|
85
|
+
if (!entity) throw new Error('not_found')
|
|
86
|
+
const data = extractObjectData(writeableProperties, properties, entity)
|
|
87
|
+
await App.validation.validate(data, validators, { source: action, action, service, app, client })
|
|
88
|
+
emit({
|
|
89
|
+
type: eventName,
|
|
90
|
+
identifiers, data
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
const action = service.actions[actionName]
|
|
95
|
+
const validators = App.validation.getValidators(action, service, action)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function defineResetAction(config, context) {
|
|
99
|
+
const {
|
|
100
|
+
service, modelRuntime, modelPropertyName,
|
|
101
|
+
otherPropertyNames, joinedOthersPropertyName, modelName, joinedOthersClassName, model
|
|
102
|
+
} = context
|
|
103
|
+
const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Reset'
|
|
104
|
+
const actionName = 'reset' + joinedOthersClassName + 'Owned' + modelName
|
|
105
|
+
service.actions[actionName] = new ActionDefinition({
|
|
106
|
+
name: actionName,
|
|
107
|
+
properties: {
|
|
108
|
+
[modelPropertyName]: {
|
|
109
|
+
type: model,
|
|
110
|
+
validation: ['nonEmpty']
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
access: config.resetAccess || config.writeAccess,
|
|
114
|
+
queuedBy: otherPropertyNames,
|
|
115
|
+
waitForEvents: true,
|
|
116
|
+
async execute(properties, {client, service}, emit) {
|
|
117
|
+
const identifiers = extractIdentifiers(otherPropertyNames, properties)
|
|
118
|
+
const id = generateId(otherPropertyNames, properties)
|
|
119
|
+
const entity = await modelRuntime().get(id)
|
|
120
|
+
if (!entity) throw new Error('not_found')
|
|
121
|
+
emit({
|
|
122
|
+
type: eventName,
|
|
123
|
+
identifiers
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
module.exports = { defineView, defineSetAction, defineUpdateAction, defineResetAction }
|
package/utils.js
CHANGED
|
@@ -59,7 +59,7 @@ function defineIndex(model, what, props) {
|
|
|
59
59
|
})
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
function processModelsAnnotation(service, app, annotation, cb) {
|
|
62
|
+
function processModelsAnnotation(service, app, annotation, multiple, cb) {
|
|
63
63
|
if (!service) throw new Error("no service")
|
|
64
64
|
if (!app) throw new Error("no app")
|
|
65
65
|
|
|
@@ -81,30 +81,42 @@ function processModelsAnnotation(service, app, annotation, cb) {
|
|
|
81
81
|
return service._runtime.models[modelName]
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
if (!model.indexes)
|
|
84
|
+
if (!model.indexes) {
|
|
85
|
+
model.indexes = {}
|
|
86
|
+
}
|
|
85
87
|
|
|
86
|
-
let
|
|
87
|
-
if
|
|
88
|
+
let configs
|
|
89
|
+
if(multiple) {
|
|
90
|
+
configs = Array.isArray(model[annotation]) ? model[annotation] : [ model[annotation] ]
|
|
91
|
+
} else { // only single ownership is possible, but may be owned by objects set
|
|
92
|
+
configs = [ model[annotation] ]
|
|
93
|
+
}
|
|
88
94
|
|
|
89
|
-
|
|
95
|
+
for(let config of configs) {
|
|
96
|
+
if (typeof config == 'string' || Array.isArray(config)) {
|
|
97
|
+
config = { what: config }
|
|
98
|
+
}
|
|
90
99
|
|
|
91
|
-
|
|
92
|
-
.map(other => other.name ? other.name : other)
|
|
100
|
+
console.log("MODEL " + modelName + " IS " + annotation + " " + config.what)
|
|
93
101
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const otherPropertyNames = others.map(other => other.slice(0, 1).toLowerCase() + other.slice(1))
|
|
97
|
-
const joinedOthersPropertyName = otherPropertyNames[0] +
|
|
98
|
-
(others.length > 1 ? ('And' + others.slice(1).join('And')) : '')
|
|
99
|
-
const joinedOthersClassName = others.join('And')
|
|
102
|
+
const others = (Array.isArray(config.what) ? config.what : [config.what])
|
|
103
|
+
.map(other => other.name ? other.name : other)
|
|
100
104
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
otherPropertyNames
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
const writeableProperties = modelProperties || config.writeableProperties
|
|
106
|
+
//console.log("PPP", others)
|
|
107
|
+
const otherPropertyNames = others.map(other => other.slice(0, 1).toLowerCase() + other.slice(1))
|
|
108
|
+
const joinedOthersPropertyName = otherPropertyNames[0] +
|
|
109
|
+
(others.length > 1 ? ('And' + others.slice(1).join('And')) : '')
|
|
110
|
+
const joinedOthersClassName = others.join('And')
|
|
106
111
|
|
|
107
|
-
|
|
112
|
+
const context = {
|
|
113
|
+
service, app, model, originalModelProperties, modelProperties, modelPropertyName, defaults, modelRuntime,
|
|
114
|
+
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName,
|
|
115
|
+
others, annotation
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
cb(config, context)
|
|
119
|
+
}
|
|
108
120
|
}
|
|
109
121
|
}
|
|
110
122
|
}
|
package/utilsAny.js
CHANGED
|
@@ -27,7 +27,7 @@ function generateAnyId(otherPropertyNames, properties) {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
function defineAnyProperties(model, names) {
|
|
30
|
-
for (let i = 0; i <
|
|
30
|
+
for (let i = 0; i < names.length; i++) {
|
|
31
31
|
model.properties[names[i]] = new PropertyDefinition({
|
|
32
32
|
type: String,
|
|
33
33
|
validation: ['nonEmpty']
|
|
@@ -45,7 +45,7 @@ function defineAnyIndex(model, what, props) {
|
|
|
45
45
|
})
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
function processModelsAnyAnnotation(service, app, annotation, cb) {
|
|
48
|
+
function processModelsAnyAnnotation(service, app, annotation, multiple, cb) {
|
|
49
49
|
if (!service) throw new Error("no service")
|
|
50
50
|
if (!app) throw new Error("no app")
|
|
51
51
|
|
|
@@ -67,28 +67,38 @@ function processModelsAnyAnnotation(service, app, annotation, cb) {
|
|
|
67
67
|
return service._runtime.models[modelName]
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
if (!model.indexes)
|
|
70
|
+
if (!model.indexes) {
|
|
71
|
+
model.indexes = {}
|
|
72
|
+
}
|
|
71
73
|
|
|
72
|
-
let
|
|
73
|
-
if
|
|
74
|
+
let configs
|
|
75
|
+
if(multiple) {
|
|
76
|
+
configs = Array.isArray(model[annotation]) ? model[annotation] : [ model[annotation] ]
|
|
77
|
+
} else { // only single ownership is possible, but may be owned by objects set
|
|
78
|
+
configs = [ model[annotation] ]
|
|
79
|
+
}
|
|
74
80
|
|
|
75
|
-
|
|
81
|
+
for(let config of configs) {
|
|
82
|
+
if (typeof config == 'string' || Array.isArray(config)) config = {what: config}
|
|
76
83
|
|
|
77
|
-
|
|
78
|
-
.map(other => other.name ? other.name : other)
|
|
84
|
+
console.log("MODEL " + modelName + " IS " + annotation + " " + config.what)
|
|
79
85
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const joinedOthersPropertyName = otherPropertyNames[0] +
|
|
83
|
-
(others.length > 1 ? ('And' + others.slice(1).join('And')) : '')
|
|
84
|
-
const joinedOthersClassName = others.join('And')
|
|
86
|
+
const otherPropertyNames = (Array.isArray(config.to) ? config.to : [config.to ?? 'owner'])
|
|
87
|
+
.map(other => other.name ? other.name : other)
|
|
85
88
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
const writeableProperties = modelProperties || config.writeableProperties
|
|
90
|
+
const others = otherPropertyNames.map(other => other.slice(0, 1).toUpperCase() + other.slice(1))
|
|
91
|
+
const joinedOthersPropertyName = otherPropertyNames[0] +
|
|
92
|
+
(others.length > 1 ? ('And' + others.slice(1).join('And')) : '')
|
|
93
|
+
const joinedOthersClassName = others.join('And')
|
|
90
94
|
|
|
91
|
-
|
|
95
|
+
const context = {
|
|
96
|
+
service, app, model, originalModelProperties, modelProperties, modelPropertyName, defaults, modelRuntime,
|
|
97
|
+
otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
cb(config, context)
|
|
101
|
+
}
|
|
92
102
|
}
|
|
93
103
|
}
|
|
94
104
|
}
|