@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 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
- module.exports = function(app, services) {
7
+ const relatedTo = require('./relatedTo.js')
8
+ const relatedToAny = require('./relatedToAny.js')
8
9
 
9
- app.defaultProcessors.push(propertyOf)
10
- app.defaultProcessors.push(itemOf)
10
+ const boundTo = require('./boundTo.js')
11
+ const boundToAny = require('./boundToAny.js')
11
12
 
12
- app.defaultProcessors.push(propertyOfAny)
13
- app.defaultProcessors.push(itemOfAny)
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 = [ propertyOf, itemOf, propertyOfAny, itemOfAny ]
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
- extractIdParts, extractRange, extractIdentifiers, extractObjectData, defineProperties, defineIndex,
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
- function defineSortIndex(context, sortFields) {
158
- if(!Array.isArray(sortFields)) sortFields = [sortFields]
159
- console.log("DEFINE SORT INDEX", sortFields)
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
- extractTypeAndIdParts, extractIdentifiersWithTypes, defineAnyProperties, defineAnyIndex,
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
- function defineUpdateAction(config, context) {
93
- const {
94
- service, app, model, modelRuntime, modelPropertyName,
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
- console.log("ITEM OF ANY", config)
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.21",
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.21",
24
+ "@live-change/framework": "^0.5.24",
25
25
  "pluralize": "8.0.0"
26
26
  },
27
- "gitHead": "00708b95082fc8c701e5ca32b9063c88a2c02a34"
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 }