@live-change/relations-plugin 0.5.21 → 0.5.22

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.
@@ -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) model.indexes = {}
84
+ if (!model.indexes) {
85
+ model.indexes = {}
86
+ }
85
87
 
86
- let config = model[annotation] // only single ownership is possible, but may be owned by objects set
87
- if (typeof config == 'string' || Array.isArray(config)) config = {what: config}
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
- console.log("MODEL " + modelName + " IS "+ annotation +" " + config.what)
95
+ for(let config of configs) {
96
+ if (typeof config == 'string' || Array.isArray(config)) {
97
+ config = { what: config }
98
+ }
90
99
 
91
- const others = (Array.isArray(config.what) ? config.what : [config.what])
92
- .map(other => other.name ? other.name : other)
100
+ console.log("MODEL " + modelName + " IS " + annotation + " " + config.what)
93
101
 
94
- const writeableProperties = modelProperties || config.writeableProperties
95
- //console.log("PPP", others)
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
- const context = {
102
- service, app, model, originalModelProperties, modelProperties, modelPropertyName, defaults, modelRuntime,
103
- otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName,
104
- others
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
- cb(config, context)
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
@@ -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
 
@@ -69,26 +69,38 @@ function processModelsAnyAnnotation(service, app, annotation, cb) {
69
69
 
70
70
  if (!model.indexes) model.indexes = {}
71
71
 
72
- let config = model[annotation] // only single ownership is possible, but may be owned by objects set
73
- if (typeof config == 'string' || Array.isArray(config)) config = { what: config }
72
+ if (!model.indexes) {
73
+ model.indexes = {}
74
+ }
74
75
 
75
- console.log("MODEL " + modelName + " IS "+ annotation +" " + config.what)
76
+ let configs
77
+ if(multiple) {
78
+ configs = Array.isArray(model[annotation]) ? model[annotation] : [ model[annotation] ]
79
+ } else { // only single ownership is possible, but may be owned by objects set
80
+ configs = [ model[annotation] ]
81
+ }
76
82
 
77
- const otherPropertyNames = (Array.isArray(config.to) ? config.to : [ config.to ?? 'owner' ])
78
- .map(other => other.name ? other.name : other)
83
+ for(let config of configs) {
84
+ if (typeof config == 'string' || Array.isArray(config)) config = {what: config}
79
85
 
80
- const writeableProperties = modelProperties || config.writeableProperties
81
- const others = otherPropertyNames.map(other => other.slice(0, 1).toUpperCase() + other.slice(1))
82
- const joinedOthersPropertyName = otherPropertyNames[0] +
83
- (others.length > 1 ? ('And' + others.slice(1).join('And')) : '')
84
- const joinedOthersClassName = others.join('And')
86
+ console.log("MODEL " + modelName + " IS " + annotation + " " + config.what)
85
87
 
86
- const context = {
87
- service, app, model, originalModelProperties, modelProperties, modelPropertyName, defaults, modelRuntime,
88
- otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others
89
- }
88
+ const otherPropertyNames = (Array.isArray(config.to) ? config.to : [config.to ?? 'owner'])
89
+ .map(other => other.name ? other.name : other)
90
90
 
91
- cb(config, context)
91
+ const writeableProperties = modelProperties || config.writeableProperties
92
+ const others = otherPropertyNames.map(other => other.slice(0, 1).toUpperCase() + other.slice(1))
93
+ const joinedOthersPropertyName = otherPropertyNames[0] +
94
+ (others.length > 1 ? ('And' + others.slice(1).join('And')) : '')
95
+ const joinedOthersClassName = others.join('And')
96
+
97
+ const context = {
98
+ service, app, model, originalModelProperties, modelProperties, modelPropertyName, defaults, modelRuntime,
99
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others
100
+ }
101
+
102
+ cb(config, context)
103
+ }
92
104
  }
93
105
  }
94
106
  }