@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,158 @@
1
+ const App = require("@live-change/framework")
2
+ const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition } = App
3
+ const { extractIdParts, extractRange, extractIdentifiers, extractObjectData } = require("./utils.js")
4
+
5
+ const pluralize = require('pluralize')
6
+
7
+ function defineView(config, context) {
8
+ const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
9
+ modelName, others, model } = context
10
+ const indexName = 'by'+context.joinedOthersClassName
11
+ const viewProperties = {}
12
+ for (let i = 0; i < others.length; i++) {
13
+ viewProperties[otherPropertyNames[i]] = new PropertyDefinition({
14
+ type: others[i],
15
+ validation: ['nonEmpty']
16
+ })
17
+ }
18
+ const viewName = joinedOthersPropertyName + context.reverseRelationWord + pluralize(modelName)
19
+ service.views[viewName] = new ViewDefinition({
20
+ name: viewName,
21
+ properties: {
22
+ ...viewProperties,
23
+ ...App.utils.rangeProperties
24
+ },
25
+ returns: {
26
+ type: Array,
27
+ of: {
28
+ type: model
29
+ }
30
+ },
31
+ access: config.readAccess,
32
+ daoPath(properties, { client, context }) {
33
+ const idParts = extractIdParts(otherPropertyNames, properties)
34
+ const range = extractRange(properties)
35
+ const path = modelRuntime().sortedIndexRangePath(indexName, idParts, range)
36
+ return path
37
+ }
38
+ })
39
+ }
40
+
41
+ function defineCreateAction(config, context) {
42
+ const {
43
+ service, app, model, defaults, modelPropertyName, modelRuntime,
44
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
45
+ } = context
46
+ const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Created'
47
+ const actionName = 'set' + joinedOthersClassName + context.reverseRelationWord + modelName
48
+ service.actions[actionName] = new ActionDefinition({
49
+ name: actionName,
50
+ properties: {
51
+ ...(model.properties)
52
+ },
53
+ access: config.createAccess || config.writeAccess,
54
+ skipValidation: true,
55
+ //queuedBy: otherPropertyNames,
56
+ waitForEvents: true,
57
+ async execute(properties, { client, service }, emit) {
58
+ const id = properties[modelPropertyName] || app.generateUid()
59
+ const entity = await modelRuntime().get(id)
60
+ if(entity) throw 'exists'
61
+ const identifiers = extractIdentifiers(otherPropertyNames, properties)
62
+ const data = extractObjectData(writeableProperties, properties, defaults)
63
+ await App.validation.validate(data, validators, { source: action, action, service, app, client })
64
+ emit({
65
+ type: eventName,
66
+ [modelPropertyName]: id,
67
+ identifiers, data
68
+ })
69
+ }
70
+ })
71
+ const action = service.actions[actionName]
72
+ const validators = App.validation.getValidators(action, service, action)
73
+ }
74
+
75
+ function defineUpdateAction(config, context) {
76
+ const {
77
+ service, app, model, modelRuntime, modelPropertyName,
78
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
79
+ } = context
80
+ const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Updated'
81
+ const actionName = 'update' + joinedOthersClassName + context.reverseRelationWord + modelName
82
+ service.actions[actionName] = new ActionDefinition({
83
+ name: actionName,
84
+ properties: {
85
+ ...(model.properties)
86
+ },
87
+ access: config.updateAccess || config.writeAccess,
88
+ skipValidation: true,
89
+ //queuedBy: otherPropertyNames,
90
+ waitForEvents: true,
91
+ async execute(properties, {client, service}, emit) {
92
+ const id = properties[modelPropertyName]
93
+ const entity = await modelRuntime().get(id)
94
+ if(!entity) throw 'not_found'
95
+ const entityIdParts = extractIdParts(otherPropertyNames, entity)
96
+ const idParts = extractIdParts(otherPropertyNames, properties)
97
+ if(JSON.stringify(entityIdParts) != JSON.stringify(idParts)) {
98
+ throw 'not_authorized'
99
+ }
100
+ const identifiers = extractIdentifiers(otherPropertyNames, properties)
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
+ [modelPropertyName]: id,
106
+ identifiers,
107
+ data
108
+ })
109
+ }
110
+ })
111
+ const action = service.actions[actionName]
112
+ const validators = App.validation.getValidators(action, service, action)
113
+ }
114
+
115
+ function defineDeleteAction(config, context) {
116
+ const {
117
+ service, app, model, modelRuntime, modelPropertyName,
118
+ otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
119
+ } = context
120
+ const eventName = joinedOthersPropertyName + context.reverseRelationWord + modelName + 'Deleted'
121
+ const actionName = 'delete' + joinedOthersClassName + context.reverseRelationWord + modelName
122
+ service.actions[actionName] = new ActionDefinition({
123
+ name: actionName,
124
+ properties: {
125
+ ...(model.properties)
126
+ },
127
+ access: config.deleteAccess || config.writeAccess,
128
+ skipValidation: true,
129
+ //queuedBy: otherPropertyNames,
130
+ waitForEvents: true,
131
+ async execute(properties, {client, service}, emit) {
132
+ const id = properties[modelPropertyName]
133
+ const entity = await modelRuntime().get(id)
134
+ if(!entity) throw new Error('not_found')
135
+ const entityIdParts = extractIdParts(otherPropertyNames, entity)
136
+ const idParts = extractIdParts(otherPropertyNames, properties)
137
+ if(JSON.stringify(entityIdParts) != JSON.stringify(idParts)) {
138
+ throw new Error('not_authorized')
139
+ }
140
+ emit({
141
+ type: eventName,
142
+ [modelPropertyName]: id
143
+ })
144
+ }
145
+ })
146
+ }
147
+
148
+ function defineSortIndex(context, sortFields) {
149
+ if(!Array.isArray(sortFields)) sortFields = [sortFields]
150
+ console.log("DEFINE SORT INDEX", sortFields)
151
+ const sortFieldsUc = sortFields.map(fd=>fd.slice(0, 1).toUpperCase() + fd.slice(1))
152
+ const indexName = 'by' + context.joinedOthersClassName + sortFieldsUc.join('')
153
+ context.model.indexes[indexName] = new IndexDefinition({
154
+ property: [...context.otherPropertyNames, ...sortFields]
155
+ })
156
+ }
157
+
158
+ module.exports = { defineView, defineCreateAction, defineUpdateAction, defineDeleteAction, defineSortIndex }
package/propertyOf.js CHANGED
@@ -1,142 +1,17 @@
1
- const App = require("@live-change/framework")
2
- const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition } = App
3
-
4
1
  const {
5
- extractIdParts, extractIdentifiers, extractObjectData, defineProperties, defineIndex,
2
+ defineProperties, defineIndex,
6
3
  processModelsAnnotation, generateId
7
4
  } = require('./utils.js')
8
5
 
6
+ const { defineSetEvent, defineUpdatedEvent, defineTransferredEvent, defineResetEvent } = require('./propertyEvents.js')
9
7
 
10
- function defineView(config, context) {
11
- const { service, modelRuntime, otherPropertyNames, joinedOthersPropertyName, joinedOthersClassName,
12
- modelName, others, model } = context
13
- const viewProperties = {}
14
- for (let i = 0; i < others.length; i++) {
15
- viewProperties[otherPropertyNames[i]] = new PropertyDefinition({
16
- type: others[i],
17
- validation: ['nonEmpty']
18
- })
19
- }
20
- const viewName = config.name || ((config.prefix ? (config.prefix + joinedOthersClassName) : joinedOthersPropertyName) +
21
- 'Owned' + modelName + (config.suffix || ''))
22
- service.views[viewName] = new ViewDefinition({
23
- name: viewName,
24
- properties: {
25
- ...viewProperties
26
- },
27
- returns: {
28
- type: model,
29
- },
30
- access: config.access,
31
- daoPath(properties, { client, context }) {
32
- const idParts = extractIdParts(otherPropertyNames, properties)
33
- const id = idParts.length > 1 ? idParts.map(p => JSON.stringify(p)).join(':') : idParts[0]
34
- const path = config.fields ? modelRuntime().limitedPath(id, config.fields) : modelRuntime().path(id)
35
- return path
36
- }
37
- })
38
- }
39
-
40
- const { defineSetEvent, defineUpdatedEvent, defineTransferredEvent, defineResetEvent } = require('./propertyEvents.js')
41
-
42
- function defineSetAction(config, context) {
43
- const {
44
- service, app, model, defaults,
45
- otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
46
- } = context
47
- const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Set'
48
- const actionName = 'set' + joinedOthersClassName + 'Owned' + 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 = extractIdentifiers(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 + 'Owned' + modelName + 'Updated'
78
- const actionName = 'update' + joinedOthersClassName + 'Owned' + 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 = extractIdentifiers(otherPropertyNames, properties)
90
- const id = generateId(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 + 'Owned' + modelName + 'Reset'
111
- const actionName = 'reset' + joinedOthersClassName + 'Owned' + 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 = extractIdentifiers(otherPropertyNames, properties)
125
- const id = generateId(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
-
8
+ const { defineView, defineSetAction, defineUpdateAction, defineResetAction } = require('./singularRelationUtils.js')
137
9
 
138
10
  module.exports = function(service, app) {
139
- processModelsAnnotation(service, app, 'propertyOf', (config, context) => {
11
+ processModelsAnnotation(service, app, 'propertyOf', false, (config, context) => {
12
+
13
+ context.relationWord = 'Property'
14
+ context.reverseRelationWord = 'Owned'
140
15
 
141
16
  defineProperties(context.model, context.others, context.otherPropertyNames)
142
17
  defineIndex(context.model, context.joinedOthersClassName, context.otherPropertyNames)
package/propertyOfAny.js CHANGED
@@ -1,151 +1,17 @@
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
1
  const {
9
- extractTypeAndIdParts, extractIdentifiersWithTypes, defineAnyProperties, defineAnyIndex,
2
+ defineAnyProperties, defineAnyIndex,
10
3
  processModelsAnyAnnotation, generateAnyId
11
4
  } = require('./utilsAny.js')
12
5
 
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
6
  const { defineSetEvent, defineUpdatedEvent, defineTransferredEvent, defineResetEvent } = require('./propertyEvents.js')
49
7
 
50
- function defineSetAction(config, context) {
51
- const {
52
- service, app, model, defaults,
53
- otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
54
- } = context
55
-
56
- const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Set'
57
- const actionName = 'set' + joinedOthersClassName + 'Owned' + modelName
58
- service.actions[actionName] = new ActionDefinition({
59
- name: actionName,
60
- properties: {
61
- ...(model.properties)
62
- },
63
- access: config.setAccess || config.writeAccess,
64
- skipValidation: true,
65
- queuedBy: otherPropertyNames,
66
- waitForEvents: true,
67
- async execute(properties, {client, service}, emit) {
68
- const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
69
- const data = extractObjectData(writeableProperties, properties, defaults)
70
- await App.validation.validate(data, validators, { source: action, action, service, app, client })
71
- emit({
72
- type: eventName,
73
- identifiers, data
74
- })
75
- }
76
- })
77
- const action = service.actions[actionName]
78
- const validators = App.validation.getValidators(action, service, action)
79
- }
80
-
81
- function defineUpdateAction(config, context) {
82
- const {
83
- service, app, model, modelRuntime,
84
- otherPropertyNames, joinedOthersPropertyName, modelName, writeableProperties, joinedOthersClassName
85
- } = context
86
- const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Updated'
87
- const actionName = 'update' + joinedOthersClassName + 'Owned' + modelName
88
- service.actions[actionName] = new ActionDefinition({
89
- name: actionName,
90
- properties: {
91
- ...(model.properties)
92
- },
93
- access: config.updateAccess || config.writeAccess,
94
- skipValidation: true,
95
- queuedBy: otherPropertyNames,
96
- waitForEvents: true,
97
- async execute(properties, {client, service}, emit) {
98
- const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
99
- const id = generateAnyId(otherPropertyNames, properties)
100
- const entity = await modelRuntime().get(id)
101
- if (!entity) throw new Error('not_found')
102
- const data = extractObjectData(writeableProperties, properties, entity)
103
- await App.validation.validate(data, validators, { source: action, action, service, app, client })
104
- emit({
105
- type: eventName,
106
- identifiers, data
107
- })
108
- }
109
- })
110
- const action = service.actions[actionName]
111
- const validators = App.validation.getValidators(action, service, action)
112
- }
113
-
114
- function defineResetAction(config, context) {
115
- const {
116
- service, modelRuntime, modelPropertyName,
117
- otherPropertyNames, joinedOthersPropertyName, modelName, joinedOthersClassName, model
118
- } = context
119
- const eventName = joinedOthersPropertyName + 'Owned' + modelName + 'Reset'
120
- const actionName = 'reset' + joinedOthersClassName + 'Owned' + modelName
121
- service.actions[actionName] = new ActionDefinition({
122
- name: actionName,
123
- properties: {
124
- [modelPropertyName]: {
125
- type: model,
126
- validation: ['nonEmpty']
127
- }
128
- },
129
- access: config.resetAccess || config.writeAccess,
130
- queuedBy: otherPropertyNames,
131
- waitForEvents: true,
132
- async execute(properties, {client, service}, emit) {
133
- const identifiers = extractIdentifiersWithTypes(otherPropertyNames, properties)
134
- const id = generateAnyId(otherPropertyNames, properties)
135
- const entity = await modelRuntime().get(id)
136
- if (!entity) throw new Error('not_found')
137
- emit({
138
- type: eventName,
139
- identifiers
140
- })
141
- }
142
- })
143
- }
144
-
145
-
8
+ const { defineView, defineSetAction, defineUpdateAction, defineResetAction } = require('./singularRelationUtils.js')
146
9
 
147
10
  module.exports = function(service, app) {
148
- processModelsAnyAnnotation(service, app, 'propertyOfAny', (config, context) => {
11
+ processModelsAnyAnnotation(service, app, 'propertyOfAny', false, (config, context) => {
12
+
13
+ context.relationWord = 'Property'
14
+ context.reverseRelationWord = 'Owned'
149
15
 
150
16
  defineAnyProperties(context.model, context.otherPropertyNames)
151
17
  defineAnyIndex(context.model, context.joinedOthersClassName, context.otherPropertyNames)
@@ -175,5 +41,6 @@ module.exports = function(service, app) {
175
41
  if(config.resetAccess || config.writeAccess) {
176
42
  defineResetAction(config, context);
177
43
  }
44
+
178
45
  })
179
46
  }
package/relatedTo.js ADDED
@@ -0,0 +1,51 @@
1
+ const {
2
+ defineProperties, defineIndex,
3
+ processModelsAnnotation
4
+ } = require('./utils.js')
5
+
6
+ const {
7
+ defineCreatedEvent, defineUpdatedEvent, defineDeletedEvent, defineTransferredEvent,
8
+ } = require('./itemEvents.js')
9
+
10
+ const {
11
+ defineView, defineCreateAction, defineUpdateAction, defineDeleteAction, defineSortIndex
12
+ } = require('./pluralRelationUtils.js')
13
+
14
+ module.exports = function(service, app) {
15
+ processModelsAnnotation(service, app, 'relatedTo', true, (config, context) => {
16
+
17
+ context.relationWord = 'Friend'
18
+ context.reverseRelationWord = 'Related'
19
+
20
+ defineProperties(context.model, context.others, context.otherPropertyNames)
21
+ defineIndex(context.model, context.joinedOthersClassName, context.otherPropertyNames)
22
+
23
+ if(config.sortBy) {
24
+ for(const sortFields of config.sortBy) {
25
+ defineSortIndex(context, sortFields)
26
+ }
27
+ }
28
+
29
+ if(config.readAccess) {
30
+ defineView(config, context)
31
+ }
32
+ /// TODO: multiple views with limited fields
33
+
34
+ defineCreatedEvent(config, context)
35
+ defineUpdatedEvent(config, context)
36
+ defineTransferredEvent(config, context)
37
+ defineDeletedEvent(config, context)
38
+
39
+ if(config.createAccess || config.writeAccess) {
40
+ defineCreateAction(config, context)
41
+ }
42
+
43
+ if(config.updateAccess || config.writeAccess) {
44
+ defineUpdateAction(config, context)
45
+ }
46
+
47
+ if(config.resetAccess || config.writeAccess) {
48
+ defineDeleteAction(config, context)
49
+ }
50
+ })
51
+ }
@@ -0,0 +1,51 @@
1
+ const {
2
+ defineAnyProperties, defineAnyIndex,
3
+ processModelsAnyAnnotation
4
+ } = require('./utilsAny.js')
5
+
6
+ const {
7
+ defineCreatedEvent, defineUpdatedEvent, defineDeletedEvent, defineTransferredEvent,
8
+ } = require('./itemEvents.js')
9
+
10
+ const {
11
+ defineView, defineCreateAction, defineUpdateAction, defineDeleteAction, defineSortIndex
12
+ } = require('./pluralRelationAnyUtils.js')
13
+
14
+ module.exports = function(service, app) {
15
+ processModelsAnyAnnotation(service, app, 'relatedToAny',true, (config, context) => {
16
+
17
+ context.relationWord = 'Friend'
18
+ context.reverseRelationWord = 'Related'
19
+
20
+ defineAnyProperties(context.model, context.otherPropertyNames)
21
+ defineAnyIndex(context.model, context.joinedOthersClassName, context.otherPropertyNames)
22
+
23
+ if(config.sortBy) {
24
+ for(const sortFields of config.sortBy) {
25
+ defineSortIndex(context, sortFields)
26
+ }
27
+ }
28
+
29
+ if(config.readAccess) {
30
+ defineView(config, context)
31
+ }
32
+ /// TODO: multiple views with limited fields
33
+
34
+ defineCreatedEvent(config, context)
35
+ defineUpdatedEvent(config, context)
36
+ defineTransferredEvent(config, context)
37
+ defineDeletedEvent(config, context)
38
+
39
+ if(config.createAccess || config.writeAccess) {
40
+ defineCreateAction(config, context)
41
+ }
42
+
43
+ if(config.updateAccess || config.writeAccess) {
44
+ defineUpdateAction(config, context)
45
+ }
46
+
47
+ if(config.resetAccess || config.writeAccess) {
48
+ defineDeleteAction(config, context)
49
+ }
50
+ })
51
+ }