@live-change/relations-plugin 0.1.12 → 0.1.13

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/itemEvents.js ADDED
@@ -0,0 +1,45 @@
1
+
2
+ function defineCreatedEvent(config, context) {
3
+ const {
4
+ service, modelRuntime, joinedOthersPropertyName, modelName, modelPropertyName
5
+ } = context
6
+ const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Created'
7
+ service.events[eventName] = new EventDefinition({
8
+ name: eventName,
9
+ execute(properties) {
10
+ const id = properties[modelPropertyName]
11
+ return modelRuntime().create({ ...properties.data, ...properties.identifiers, id })
12
+ }
13
+ })
14
+ }
15
+
16
+ function defineUpdatedEvent(config, context) {
17
+ const {
18
+ service, modelRuntime, joinedOthersPropertyName, modelName, modelPropertyName
19
+ } = context
20
+ const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Updated'
21
+ service.events[eventName] = new EventDefinition({
22
+ name: eventName,
23
+ execute(properties) {
24
+ const id = properties[modelPropertyName]
25
+ return modelRuntime().update(id, { ...properties.data, ...properties.identifiers, id })
26
+ }
27
+ })
28
+ }
29
+
30
+
31
+ function defineDeletedEvent(config, context) {
32
+ const {
33
+ service, modelRuntime, joinedOthersPropertyName, modelName, modelPropertyName
34
+ } = context
35
+ const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Deleted'
36
+ service.events[eventName] = new EventDefinition({
37
+ name: eventName,
38
+ execute(properties) {
39
+ const id = properties[modelPropertyName]
40
+ return modelRuntime().delete(id)
41
+ }
42
+ })
43
+ }
44
+
45
+ module.exports = { defineCreatedEvent, defineUpdatedEvent, defineDeletedEvent }
package/itemOf.js CHANGED
@@ -40,19 +40,9 @@ function defineView(config, context) {
40
40
  })
41
41
  }
42
42
 
43
- async function defineCreatedEvent(config, context) {
44
- const {
45
- service, modelRuntime, joinedOthersPropertyName, modelName, modelPropertyName
46
- } = context
47
- const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Created'
48
- service.events[eventName] = new EventDefinition({
49
- name: eventName,
50
- execute(properties) {
51
- const id = properties[modelPropertyName]
52
- return modelRuntime().create({ ...properties.data, ...properties.identifiers, id })
53
- }
54
- })
55
- }
43
+ const {
44
+ defineCreatedEvent, defineUpdatedEvent, defineDeletedEvent
45
+ } = require('itemEvents.js')
56
46
 
57
47
  function defineCreateAction(config, context) {
58
48
  const {
@@ -88,21 +78,7 @@ function defineCreateAction(config, context) {
88
78
  const validators = App.validation.getValidators(action, service, action)
89
79
  }
90
80
 
91
- async function defineUpdatedEvent(config, context) {
92
- const {
93
- service, modelRuntime, joinedOthersPropertyName, modelName, modelPropertyName
94
- } = context
95
- const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Updated'
96
- service.events[eventName] = new EventDefinition({
97
- name: eventName,
98
- execute(properties) {
99
- const id = properties[modelPropertyName]
100
- return modelRuntime().update(id, { ...properties.data, ...properties.identifiers, id })
101
- }
102
- })
103
- }
104
-
105
- async function defineUpdateAction(config, context) {
81
+ function defineUpdateAction(config, context) {
106
82
  const {
107
83
  service, app, model, modelRuntime, modelPropertyName,
108
84
  otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
@@ -142,21 +118,7 @@ async function defineUpdateAction(config, context) {
142
118
  const validators = App.validation.getValidators(action, service, action)
143
119
  }
144
120
 
145
- async function defineDeletedEvent(config, context) {
146
- const {
147
- service, modelRuntime, joinedOthersPropertyName, modelName, modelPropertyName
148
- } = context
149
- const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Deleted'
150
- service.events[eventName] = new EventDefinition({
151
- name: eventName,
152
- execute(properties) {
153
- const id = properties[modelPropertyName]
154
- return modelRuntime().delete(id)
155
- }
156
- })
157
- }
158
-
159
- async function defineDeleteAction(config, context) {
121
+ function defineDeleteAction(config, context) {
160
122
  const {
161
123
  service, app, model, modelRuntime, modelPropertyName,
162
124
  otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
package/itemOfAny.js ADDED
@@ -0,0 +1,205 @@
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
+ const {
9
+ extractTypeAndIdParts, extractIdentifiersWithTypes, defineAnyProperties, defineAnyIndex,
10
+ processModelsAnyAnnotation
11
+ } = require('./utilsAny.js')
12
+
13
+ function defineView(config, context) {
14
+ const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
15
+ modelName, others, model } = context
16
+ const indexName = 'by'+context.joinedOthersClassName
17
+ const viewProperties = {}
18
+ for (let i = 0; i < others.length; i++) {
19
+ viewProperties[otherPropertyNames[i]] = new PropertyDefinition({
20
+ type: 'String',
21
+ validation: ['nonEmpty']
22
+ })
23
+ viewProperties[otherPropertyNames[i] + 'Type'] = new PropertyDefinition({
24
+ type: 'String',
25
+ validation: ['nonEmpty']
26
+ })
27
+ }
28
+ const viewName = joinedOthersPropertyName + 'Owned' + modelName + 's'
29
+ service.views[viewName] = new ViewDefinition({
30
+ name: viewName,
31
+ properties: {
32
+ ...viewProperties,
33
+ ...App.utils.rangeProperties
34
+ },
35
+ returns: {
36
+ type: Array,
37
+ of: {
38
+ type: model
39
+ }
40
+ },
41
+ access: config.readAccess,
42
+ daoPath(properties, { client, context }) {
43
+ const typeAndIdParts = extractTypeAndIdParts(otherPropertyNames, properties)
44
+ const range = extractRange(properties)
45
+ const path = modelRuntime().sortedIndexRangePath(indexName, typeAndIdParts, range)
46
+ return path
47
+ }
48
+ })
49
+ }
50
+
51
+ const {
52
+ defineCreatedEvent, defineUpdatedEvent, defineDeletedEvent
53
+ } = require('itemEvents.js')
54
+
55
+ function defineCreateAction(config, context) {
56
+ const {
57
+ service, app, model, defaults, modelPropertyName, modelRuntime,
58
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
59
+ } = context
60
+ const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Created'
61
+ const actionName = 'set' + joinedOthersClassName + 'Owned' + modelName
62
+ service.actions[actionName] = new ActionDefinition({
63
+ name: actionName,
64
+ properties: {
65
+ ...(model.properties)
66
+ },
67
+ access: config.createAccess || config.writeAccess,
68
+ skipValidation: true,
69
+ //queuedBy: otherPropertyNames,
70
+ waitForEvents: true,
71
+ async execute(properties, { client, service }, emit) {
72
+ const id = properties[modelPropertyName] || app.generateUid()
73
+ const entity = await modelRuntime().get(id)
74
+ if(entity) throw 'exists'
75
+ const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
76
+ const data = extractObjectData(writeableProperties, properties, defaults)
77
+ await App.validation.validate(data, validators, { source: action, action, service, app, client })
78
+ emit({
79
+ type: eventName,
80
+ [modelPropertyName]: id,
81
+ identifiers, data
82
+ })
83
+ }
84
+ })
85
+ const action = service.actions[actionName]
86
+ const validators = App.validation.getValidators(action, service, action)
87
+ }
88
+
89
+ function defineUpdateAction(config, context) {
90
+ const {
91
+ service, app, model, modelRuntime, modelPropertyName,
92
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
93
+ } = context
94
+ const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Updated'
95
+ const actionName = 'update' + joinedOthersClassName + 'Owned' + modelName
96
+ service.actions[actionName] = new ActionDefinition({
97
+ name: actionName,
98
+ properties: {
99
+ ...(model.properties)
100
+ },
101
+ access: config.updateAccess || config.writeAccess,
102
+ skipValidation: true,
103
+ //queuedBy: otherPropertyNames,
104
+ waitForEvents: true,
105
+ async execute(properties, {client, service}, emit) {
106
+ const id = properties[modelPropertyName]
107
+ const entity = await modelRuntime().get(id)
108
+ if(!entity) throw 'not_found'
109
+ const entityTypeAndIdParts = extractTypeAndIdParts(otherPropertyNames, entity)
110
+ const typeAndIdParts = extractTypeAndIdParts(otherPropertyNames, properties)
111
+ if(JSON.stringify(entityTypeAndIdParts) != JSON.stringify(typeAndIdParts)) {
112
+ throw 'not_authorized'
113
+ }
114
+ const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
115
+ const data = extractObjectData(writeableProperties, properties, entity)
116
+ await App.validation.validate(data, validators, { source: action, action, service, app, client })
117
+ emit({
118
+ type: eventName,
119
+ [modelPropertyName]: id,
120
+ identifiers,
121
+ data
122
+ })
123
+ }
124
+ })
125
+ const action = service.actions[actionName]
126
+ const validators = App.validation.getValidators(action, service, action)
127
+ }
128
+
129
+ function defineDeleteAction(config, context) {
130
+ const {
131
+ service, app, model, modelRuntime, modelPropertyName,
132
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
133
+ } = context
134
+ const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Deleted'
135
+ const actionName = 'delete' + joinedOthersClassName + 'Owned' + modelName
136
+ service.actions[actionName] = new ActionDefinition({
137
+ name: actionName,
138
+ properties: {
139
+ ...(model.properties)
140
+ },
141
+ access: config.deleteAccess || config.writeAccess,
142
+ skipValidation: true,
143
+ //queuedBy: otherPropertyNames,
144
+ waitForEvents: true,
145
+ async execute(properties, {client, service}, emit) {
146
+ const id = properties[modelPropertyName]
147
+ const entity = await modelRuntime().get(id)
148
+ if(!entity) throw new Error('not_found')
149
+ const entityTypeAndIdParts = extractTypeAndIdParts(otherPropertyNames, entity)
150
+ const typeAndIdParts = extractTypeAndIdParts(otherPropertyNames, properties)
151
+ if(JSON.stringify(entityTypeAndIdParts) != JSON.stringify(typeAndIdParts)) {
152
+ throw new Error('not_authorized')
153
+ }
154
+ emit({
155
+ type: eventName,
156
+ [modelPropertyName]: id
157
+ })
158
+ }
159
+ })
160
+ }
161
+
162
+ function defineSortIndex(context, sortFields) {
163
+ if(!Array.isArray(sortFields)) sortFields = [sortFields]
164
+ console.log("DEFINE SORT INDEX", sortFields)
165
+ const sortFieldsUc = sortFields.map(fd=>fd.slice(0, 1).toUpperCase() + fd.slice(1))
166
+ const indexName = 'by' + context.joinedOthersClassName + sortFieldsUc.join('')
167
+ context.model.indexes[indexName] = new IndexDefinition({
168
+ property: [...(context.otherPropertyNames.map(prop => [prop + 'Type', prop])), ...sortFields]
169
+ })
170
+ }
171
+
172
+ module.exports = function(service, app) {
173
+ processModelsAnyAnnotation(service, app, 'itemOfAny', (config, context) => {
174
+
175
+ defineAnyProperties(context.model, context.otherPropertyNames)
176
+ defineAnyIndex(context.model, context.joinedOthersClassName, context.otherPropertyNames)
177
+
178
+ if(config.sortBy) {
179
+ for(const sortFields of config.sortBy) {
180
+ defineSortIndex(context, sortFields)
181
+ }
182
+ }
183
+
184
+ if(config.readAccess) {
185
+ defineView(config, context)
186
+ }
187
+ /// TODO: multiple views with limited fields
188
+
189
+ defineCreatedEvent(config, context)
190
+ defineUpdatedEvent(config, context)
191
+ defineDeletedEvent(config, context)
192
+
193
+ if(config.setAccess || config.writeAccess) {
194
+ defineCreateAction(config, context)
195
+ }
196
+
197
+ if(config.updateAccess || config.writeAccess) {
198
+ defineUpdateAction(config, context)
199
+ }
200
+
201
+ if(config.resetAccess || config.writeAccess) {
202
+ defineDeleteAction(config, context)
203
+ }
204
+ })
205
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/relations-plugin",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,45 @@
1
+ const { generateAnyId } = require("./utilsAny.js");
2
+
3
+ function defineSetEvent(config, context) {
4
+ const {
5
+ service, modelRuntime, joinedOthersPropertyName, modelName, otherPropertyNames
6
+ } = context
7
+ const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Set'
8
+ service.events[eventName] = new EventDefinition({
9
+ name: eventName,
10
+ execute(properties) {
11
+ const id = generateId(otherPropertyNames, properties.identifiers)
12
+ return modelRuntime().create({ ...properties.data, ...properties.identifiers, id })
13
+ }
14
+ })
15
+ }
16
+
17
+ function defineUpdateEvent(config, context) {
18
+ const {
19
+ service, modelRuntime, joinedOthersPropertyName, modelName, otherPropertyNames
20
+ } = context
21
+ const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Updated'
22
+ service.events[eventName] = new EventDefinition({
23
+ name: eventName,
24
+ execute(properties) {
25
+ const id = generateId(otherPropertyNames, properties.identifiers)
26
+ return modelRuntime().update(id, { ...properties.data, ...properties.identifiers })
27
+ }
28
+ })
29
+ }
30
+
31
+ function defineResetEvent(config, context) {
32
+ const {
33
+ service, modelRuntime, joinedOthersPropertyName, modelName, otherPropertyNames
34
+ } = context
35
+ const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Reset'
36
+ service.events[eventName] = new EventDefinition({
37
+ name: eventName,
38
+ execute({ identifiers }) {
39
+ const id = generateId(otherPropertyNames, identifiers)
40
+ return modelRuntime().delete(id)
41
+ }
42
+ })
43
+ }
44
+
45
+ module.exports = { defineSetEvent, defineUpdateEvent, defineResetEvent }
package/propertyOf.js CHANGED
@@ -17,7 +17,7 @@ function defineView(config, context) {
17
17
  validation: ['nonEmpty']
18
18
  })
19
19
  }
20
- const viewName = config.name || ((config.prefix ? (prefix + joinedOthersClassName) : joinedOthersPropertyName) +
20
+ const viewName = config.name || ((config.prefix ? (config.prefix + joinedOthersClassName) : joinedOthersPropertyName) +
21
21
  'Owned' + modelName + (config.suffix || ''))
22
22
  service.views[viewName] = new ViewDefinition({
23
23
  name: viewName,
@@ -37,21 +37,9 @@ function defineView(config, context) {
37
37
  })
38
38
  }
39
39
 
40
- async function defineSetEvent(config, context) {
41
- const {
42
- service, modelRuntime, joinedOthersPropertyName, modelName, otherPropertyNames
43
- } = context
44
- const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Set'
45
- service.events[eventName] = new EventDefinition({
46
- name: eventName,
47
- execute(properties) {
48
- const id = generateId(otherPropertyNames, properties.identifiers)
49
- return modelRuntime().create({ ...properties.data, ...properties.identifiers, id })
50
- }
51
- })
52
- }
40
+ const { defineSetEvent, defineUpdateEvent, defineResetEvent } = require('./propertyEvents.js')
53
41
 
54
- async function defineSetAction(config, context) {
42
+ function defineSetAction(config, context) {
55
43
  const {
56
44
  service, app, model, defaults,
57
45
  otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
@@ -81,21 +69,7 @@ async function defineSetAction(config, context) {
81
69
  const validators = App.validation.getValidators(action, service, action)
82
70
  }
83
71
 
84
- async function defineUpdateEvent(config, context) {
85
- const {
86
- service, modelRuntime, joinedOthersPropertyName, modelName, otherPropertyNames
87
- } = context
88
- const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Updated'
89
- service.events[eventName] = new EventDefinition({
90
- name: eventName,
91
- execute(properties) {
92
- const id = generateId(otherPropertyNames, properties.identifiers)
93
- return modelRuntime().update(id, { ...properties.data, ...properties.identifiers })
94
- }
95
- })
96
- }
97
-
98
- async function defineUpdateAction(config, context) {
72
+ function defineUpdateAction(config, context) {
99
73
  const {
100
74
  service, app, model, modelRuntime,
101
75
  otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
@@ -128,21 +102,7 @@ async function defineUpdateAction(config, context) {
128
102
  const validators = App.validation.getValidators(action, service, action)
129
103
  }
130
104
 
131
- async function defineResetEvent(config, context) {
132
- const {
133
- service, modelRuntime, joinedOthersPropertyName, modelName, otherPropertyNames
134
- } = context
135
- const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Reset'
136
- service.events[eventName] = new EventDefinition({
137
- name: eventName,
138
- execute({ identifiers }) {
139
- const id = generateId(otherPropertyNames, identifiers)
140
- return modelRuntime().delete(id)
141
- }
142
- })
143
- }
144
-
145
- async function defineResetAction(config, context) {
105
+ function defineResetAction(config, context) {
146
106
  const {
147
107
  service, modelRuntime, modelPropertyName,
148
108
  otherPropertyNames, joinedOthersPropertyName, modelName, joinedOthersClassName, model
@@ -0,0 +1,177 @@
1
+ const App = require("@live-change/framework")
2
+ const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition } = App
3
+
4
+ const {
5
+ extractObjectData
6
+ } = require('./utils.js')
7
+
8
+ const {
9
+ extractTypeAndIdParts, extractIdentifiersWithTypes, defineAnyProperties, defineAnyIndex,
10
+ processModelsAnyAnnotation, generateAnyId
11
+ } = require('./utilsAny.js')
12
+
13
+
14
+ function defineView(config, context) {
15
+ const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
16
+ modelName, others, model } = context
17
+ const viewProperties = {}
18
+ for (let i = 0; i < others.length; i++) {
19
+ viewProperties[otherPropertyNames[i]] = new PropertyDefinition({
20
+ type: others[i],
21
+ validation: ['nonEmpty']
22
+ })
23
+ viewProperties[otherPropertyNames[i] + 'Type'] = new PropertyDefinition({
24
+ type: 'String',
25
+ validation: ['nonEmpty']
26
+ })
27
+ }
28
+ const viewName = config.name || ((config.prefix ? (config.prefix + joinedOthersClassName) : joinedOthersPropertyName) +
29
+ 'Owned' + modelName + (config.suffix || ''))
30
+ service.views[viewName] = new ViewDefinition({
31
+ name: viewName,
32
+ properties: {
33
+ ...viewProperties
34
+ },
35
+ returns: {
36
+ type: model,
37
+ },
38
+ access: config.access,
39
+ daoPath(properties, { client, context }) {
40
+ const typeAndIdParts = extractTypeAndIdParts(otherPropertyNames, properties)
41
+ const id = typeAndIdParts.length > 1 ? typeAndIdParts.map(p => JSON.stringify(p)).join(':') : idParts[0]
42
+ const path = config.fields ? modelRuntime().limitedPath(id, config.fields) : modelRuntime().path(id)
43
+ return path
44
+ }
45
+ })
46
+ }
47
+
48
+ const { defineSetEvent, defineUpdateEvent, defineResetEvent } = require('./propertyEvents.js')
49
+
50
+ function defineSetAction(config, context) {
51
+ const {
52
+ service, app, model, defaults,
53
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
54
+ } = context
55
+ const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Set'
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.setAccess || config.writeAccess,
63
+ skipValidation: true,
64
+ queuedBy: otherPropertyNames,
65
+ waitForEvents: true,
66
+ async execute(properties, {client, service}, emit) {
67
+ const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
68
+ const data = extractObjectData(writeableProperties, properties, defaults)
69
+ await App.validation.validate(data, validators, { source: action, action, service, app, client })
70
+ emit({
71
+ type: eventName,
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,
83
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
84
+ } = context
85
+ const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Updated'
86
+ const actionName = 'update' + joinedOthersClassName + 'Owned' + 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 identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
98
+ const id = generateAnyId(otherPropertyNames, properties)
99
+ const entity = await modelRuntime().get(id)
100
+ if (!entity) throw new Error('not_found')
101
+ const data = extractObjectData(writeableProperties, properties, entity)
102
+ await App.validation.validate(data, validators, { source: action, action, service, app, client })
103
+ emit({
104
+ type: eventName,
105
+ identifiers, data
106
+ })
107
+ }
108
+ })
109
+ const action = service.actions[actionName]
110
+ const validators = App.validation.getValidators(action, service, action)
111
+ }
112
+
113
+ function defineResetAction(config, context) {
114
+ const {
115
+ service, modelRuntime, modelPropertyName,
116
+ otherPropertyNames, joinedOthersPropertyName, modelName, joinedOthersClassName, model
117
+ } = context
118
+ const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Reset'
119
+ const actionName = 'reset' + joinedOthersClassName + 'Owned' + modelName
120
+ service.actions[actionName] = new ActionDefinition({
121
+ name: actionName,
122
+ properties: {
123
+ [modelPropertyName]: {
124
+ type: model,
125
+ validation: ['nonEmpty']
126
+ }
127
+ },
128
+ access: config.resetAccess || config.writeAccess,
129
+ queuedBy: otherPropertyNames,
130
+ waitForEvents: true,
131
+ async execute(properties, {client, service}, emit) {
132
+ const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
133
+ const id = generateAnyId(otherPropertyNames, properties)
134
+ const entity = await modelRuntime().get(id)
135
+ if (!entity) throw new Error('not_found')
136
+ emit({
137
+ type: eventName,
138
+ identifiers
139
+ })
140
+ }
141
+ })
142
+ }
143
+
144
+
145
+
146
+ module.exports = function(service, app) {
147
+ processModelsAnyAnnotation(service, app, 'propertyOf', (config, context) => {
148
+
149
+ defineAnyProperties(context.model, context.otherPropertyNames)
150
+ defineAnyIndex(context.model, context.joinedOthersClassName, context.otherPropertyNames)
151
+
152
+ if(config.readAccess) {
153
+ defineView({ ...config, access: config.readAccess }, context)
154
+ }
155
+ if(config.views) {
156
+ for(const view of config.views) {
157
+ defineView({ ...config, ...view }, context)
158
+ }
159
+ }
160
+
161
+ defineSetEvent(config, context)
162
+ defineUpdateEvent(config, context)
163
+ defineResetEvent(config, context)
164
+
165
+ if(config.setAccess || config.writeAccess) {
166
+ defineSetAction(config, context)
167
+ }
168
+
169
+ if(config.updateAccess || config.writeAccess) {
170
+ defineUpdateAction(config, context)
171
+ }
172
+
173
+ if(config.resetAccess || config.writeAccess) {
174
+ defineResetAction(config, context);
175
+ }
176
+ })
177
+ }
package/utils.js CHANGED
@@ -71,6 +71,7 @@ function processModelsAnnotation(service, app, annotation, cb) {
71
71
  if (model[annotation]) {
72
72
  if (model[annotation + 'Processed']) throw new Error("duplicated processing of " + annotation + " processor")
73
73
  model[annotation + 'Processed'] = true
74
+
74
75
  const originalModelProperties = { ...model.properties }
75
76
  const modelProperties = Object.keys(model.properties)
76
77
  const modelPropertyName = modelName.slice(0, 1).toLowerCase() + modelName.slice(1)
@@ -91,7 +92,7 @@ function processModelsAnnotation(service, app, annotation, cb) {
91
92
  .map(other => other.name ? other.name : other)
92
93
 
93
94
  const writeableProperties = modelProperties || config.writeableProperties
94
- console.log("PPP", others)
95
+ //console.log("PPP", others)
95
96
  const otherPropertyNames = others.map(other => other.slice(0, 1).toLowerCase() + other.slice(1))
96
97
  const joinedOthersPropertyName = otherPropertyNames[0] +
97
98
  (others.length > 1 ? ('And' + others.slice(1).join('And')) : '')
package/utilsAny.js ADDED
@@ -0,0 +1,99 @@
1
+ const App = require("@live-change/framework")
2
+ const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition } = App
3
+
4
+ function extractTypeAndIdParts(otherPropertyNames, properties) {
5
+ const typeAndIdParts = []
6
+ for (const propertyName of otherPropertyNames) {
7
+ typeAndIdParts.push(properties[propertyName+'Type'])
8
+ typeAndIdParts.push(properties[propertyName])
9
+ }
10
+ return typeAndIdParts
11
+ }
12
+
13
+ function extractIdentifiersWithTypes(otherPropertyNames, properties) {
14
+ const identifiers = {}
15
+ for (const propertyName of otherPropertyNames) {
16
+ identifiers[propertyName] = properties[propertyName]
17
+ identifiers[propertyName + 'Type'] = properties[propertyName + 'Type']
18
+ }
19
+ return identifiers
20
+ }
21
+
22
+ function generateAnyId(otherPropertyNames, properties) {
23
+ return otherPropertyNames
24
+ .map(p => [p+'Type', p])
25
+ .flat()
26
+ .map(p => JSON.stringify(properties[p])).join(':')
27
+ }
28
+
29
+ function defineAnyProperties(model, names) {
30
+ for (let i = 0; i < types.length; i++) {
31
+ model.properties[names[i]] = new PropertyDefinition({
32
+ type: String,
33
+ validation: ['nonEmpty']
34
+ })
35
+ model.properties[names[i]+'Type'] = new PropertyDefinition({
36
+ type: String,
37
+ validation: ['nonEmpty']
38
+ })
39
+ }
40
+ }
41
+
42
+ function defineAnyIndex(model, what, props) {
43
+ model.indexes['by' + what] = new IndexDefinition({
44
+ property: props.map(prop => [prop+'Type', prop]).flat()
45
+ })
46
+ }
47
+
48
+ function processModelsAnyAnnotation(service, app, annotation, cb) {
49
+ if (!service) throw new Error("no service")
50
+ if (!app) throw new Error("no app")
51
+
52
+ for(let modelName in service.models) {
53
+ const model = service.models[modelName]
54
+
55
+ //console.log("PO", modelName, model[annotation])
56
+
57
+ if (model[annotation]) {
58
+ if (model[annotation + 'Processed']) throw new Error("duplicated processing of " + annotation + " processor")
59
+ model[annotation + 'Processed'] = true
60
+
61
+ const originalModelProperties = { ...model.properties }
62
+ const modelProperties = Object.keys(model.properties)
63
+ const modelPropertyName = modelName.slice(0, 1).toLowerCase() + modelName.slice(1)
64
+ const defaults = App.utils.generateDefault(originalModelProperties)
65
+
66
+ function modelRuntime() {
67
+ return service._runtime.models[modelName]
68
+ }
69
+
70
+ if (!model.indexes) model.indexes = {}
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}
74
+
75
+ console.log("MODEL " + modelName + " IS "+ annotation +" " + config.what)
76
+
77
+ const otherPropertyNames = (Array.isArray(config.to) ? config.to : [config.to ?? 'owner'])
78
+ .map(other => other.name ? other.name : other)
79
+
80
+ const writeableProperties = modelProperties || config.writeableProperties
81
+ const others = otherPropertyNames.map(other => other.slice(0, 1).toLowerCase() + other.slice(1))
82
+ const joinedOthersPropertyName = otherPropertyNames[0] +
83
+ (others.length > 1 ? ('And' + others.slice(1).join('And')) : '')
84
+ const joinedOthersClassName = others.join('And')
85
+
86
+ const context = {
87
+ service, app, model, originalModelProperties, modelProperties, modelPropertyName, defaults, modelRuntime,
88
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName, others
89
+ }
90
+
91
+ cb(config, context)
92
+ }
93
+ }
94
+ }
95
+
96
+ module.exports = {
97
+ extractTypeAndIdParts, extractIdentifiersWithTypes, defineAnyProperties, defineAnyIndex,
98
+ processModelsAnyAnnotation, generateAnyId
99
+ }