@live-change/relations-plugin 0.6.3 → 0.6.6

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