@live-change/user-service 0.3.19 → 0.3.21

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/model.js CHANGED
@@ -85,4 +85,4 @@ definition.event({
85
85
  }
86
86
  })
87
87
 
88
- module.exports = { User, AuthenticatedUser }
88
+ module.exports = { User, Session, AuthenticatedUser }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/user-service",
3
- "version": "0.3.19",
3
+ "version": "0.3.21",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -21,9 +21,9 @@
21
21
  "url": "https://www.viamage.com/"
22
22
  },
23
23
  "dependencies": {
24
- "@live-change/framework": "0.7.20",
25
- "@live-change/relations-plugin": "0.7.20",
24
+ "@live-change/framework": "0.7.22",
25
+ "@live-change/relations-plugin": "0.7.22",
26
26
  "pluralize": "8.0.0"
27
27
  },
28
- "gitHead": "5a7c43203f456ef7d9dcd9b34826991f803d5038"
28
+ "gitHead": "70c50fb3eaafe7d1cf5c07b9916ab5a6bfcc8e34"
29
29
  }
@@ -1,7 +1,7 @@
1
1
  const definition = require("./definition.js")
2
2
  const App = require("@live-change/framework")
3
- const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition } = App
4
- const { User } = require("./model.js")
3
+ const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition, TriggerDefinition } = App
4
+ const { User, Session } = require("./model.js")
5
5
 
6
6
  const pluralize = require('pluralize')
7
7
 
@@ -35,8 +35,113 @@ definition.processor(function(service, app) {
35
35
  to: ['sessionOrUser', ...extendedWith]
36
36
  }
37
37
 
38
- /// TODO: merge on signedIn trigger
39
- /// TODO: delete on userDeleted trigger
38
+ service.trigger({
39
+ name: 'signedIn',
40
+ properties: {
41
+ user: {
42
+ type: User,
43
+ validation: ['nonEmpty']
44
+ },
45
+ session: {
46
+ type: Session,
47
+ validation: ['nonEmpty']
48
+ },
49
+ },
50
+ async execute({ user, session }, { service }, emit) {
51
+ const sessionPath = ['session_Session', session]
52
+ const sessionItems = await modelRuntime().indexRangeGet('bySessionOrUser', sessionPath, {} )
53
+ if(config.merge) {
54
+ const userPath = ['user_User', user]
55
+ const userItems = await modelRuntime().indexRangeGet('bySessionOrUser', userPath, {} )
56
+ const mergeResult = await config.merge(sessionItems, userItems)
57
+ if(mergeResult) {
58
+ const { transferred, updated, deleted } = mergeResult
59
+ for(const entity of transferred) {
60
+ emit({
61
+ type: 'sessionOrUserOwned' + modelName + 'Transferred',
62
+ [modelPropertyName]: entity.id,
63
+ to: {
64
+ sessionOrUserType: 'user_User',
65
+ sessionOrUser: user
66
+ }
67
+ })
68
+ }
69
+ for(const entity of updated) {
70
+ emit({
71
+ type: 'sessionOrUserOwned' + modelName + 'Updated',
72
+ [modelPropertyName]: entity.id,
73
+ identifiers: {
74
+ id: entity.id,
75
+ sessionOrUserType: 'user_User',
76
+ sessionOrUser: user
77
+ },
78
+ data: entity
79
+ })
80
+ }
81
+ for(const entity of deleted) {
82
+ emit({
83
+ type: 'sessionOrUserOwned' + modelName + 'Deleted',
84
+ [modelPropertyName]: entity.id,
85
+ })
86
+ }
87
+ }
88
+ } else {
89
+ for(const entity of sessionItems) {
90
+ emit({
91
+ type: 'sessionOrUserOwned' + modelName + 'Transferred',
92
+ [modelPropertyName]: entity.id,
93
+ identifiers: {
94
+ id: entity.id
95
+ },
96
+ to: {
97
+ sessionOrUserType: 'user_User',
98
+ sessionOrUser: user
99
+ }
100
+ })
101
+ }
102
+ }
103
+ }
104
+ })
105
+
106
+ service.trigger({
107
+ name: 'userDeleted',
108
+ properties: {
109
+ user: {
110
+ type: User,
111
+ validation: ['nonEmpty']
112
+ }
113
+ },
114
+ async execute({ user, session }, { service }, emit) {
115
+ /// TODO: delete on userDeleted trigger
116
+ }
117
+ })
118
+
119
+ if(config.ownerReadAccess) {
120
+ const viewName = 'my' + modelName
121
+ const propertyName = modelName[0].toLowerCase() + modelName.slice(1)
122
+ service.views[viewName] = new ViewDefinition({
123
+ name: viewName,
124
+ access(params, context) {
125
+ return config.ownerReadAccess ? config.ownerReadAccess(params, context) : true
126
+ },
127
+ properties: {
128
+ [propertyName]: {
129
+ type: `${service.name}_${modelName}`,
130
+ validation: ['nonEmpty']
131
+ }
132
+ },
133
+ async daoPath(params, { client, context }) {
134
+ const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
135
+ const range = {
136
+ gte: '_'+ params[propertyName],
137
+ lte: '_'+ params[propertyName]
138
+ }
139
+ const path = modelRuntime().indexObjectPath('bySessionOrUser', owner, range )
140
+ console.log("DAO PATH", path, "range", range, 'params', params)
141
+ return path
142
+ }
143
+ })
144
+ }
40
145
 
41
146
  if(config.ownerReadAccess) {
42
147
  const viewName = 'my' + pluralize(modelName)
@@ -49,6 +154,7 @@ definition.processor(function(service, app) {
49
154
  daoPath(range, { client, context }) {
50
155
  const owner = client.user ? ['user_User', client.user] : ['session_Session', client.session]
51
156
  const path = modelRuntime().indexRangePath('bySessionOrUser', owner, range )
157
+ console.log("DAO PATH", path, "range", range)
52
158
  return path
53
159
  }
54
160
  })
@@ -157,7 +263,7 @@ definition.processor(function(service, app) {
157
263
  const validators = App.validation.getValidators(action, service, action)
158
264
  }
159
265
  if(config.userDeleteAccess || config.userWriteAccess) {
160
- const eventName = 'userOwned' + modelName + 'Deleted'
266
+ const eventName = 'sessionOrUser' + modelName + 'Deleted'
161
267
  const actionName = 'deleteMyUser' + modelName
162
268
  service.actions[actionName] = new ActionDefinition({
163
269
  name: actionName,
@@ -197,4 +303,4 @@ definition.processor(function(service, app) {
197
303
  }
198
304
  }
199
305
 
200
- })
306
+ })
@@ -1,7 +1,7 @@
1
1
  const definition = require("./definition.js")
2
2
  const App = require("@live-change/framework")
3
3
  const { PropertyDefinition, ViewDefinition, IndexDefinition, ActionDefinition, EventDefinition } = App
4
- const { User } = require("./model.js")
4
+ const { User, Session } = require("./model.js")
5
5
  const { allCombinations } = require("./combinations.js")
6
6
  const { createIdentifiersProperties } = require('./utils.js')
7
7
 
@@ -39,9 +39,120 @@ definition.processor(function(service, app) {
39
39
  to: ['sessionOrUser', ...extendedWith]
40
40
  }
41
41
 
42
- /// TODO: merge on signedIn trigger
43
- /// TODO: delete on userDeleted trigger
42
+ const transferEventName = ['sessionOrUser', ...(extendedWith.map(e => e[0].toUpperCase() + e.slice(1)))]
43
+ .join('And') + 'Owned' + modelName + 'Transferred'
44
44
 
45
+ service.trigger({
46
+ name: 'signedIn',
47
+ properties: {
48
+ user: {
49
+ type: User,
50
+ validation: ['nonEmpty']
51
+ },
52
+ session: {
53
+ type: Session,
54
+ validation: ['nonEmpty']
55
+ },
56
+ },
57
+ async execute({ user, session }, { service }, emit) {
58
+ const sessionPath = ['session_Session', session]
59
+ const sessionPropertyId = sessionPath.map(p => JSON.stringify(p)).join(':')
60
+ const range = {
61
+ gte: sessionPropertyId + '', // '' because it can be not-extended
62
+ lte: sessionPropertyId + ':\xFF'
63
+ }
64
+ const sessionProperties = await modelRuntime().rangeGet(range)
65
+ for(const sessionProperty of sessionProperties) {
66
+ console.log("SESSION PROPERTY FOUND!", sessionProperty, "MERGE =", config.merge)
67
+
68
+ const extendedIdentifiers = {}
69
+ for(const key of extendedWith) {
70
+ extendedIdentifiers[key+'Type'] = sessionProperty[key+'Type']
71
+ extendedIdentifiers[key] = sessionProperty[key]
72
+ }
73
+ const userPath = ['user_User', user]
74
+ for(const key of extendedWith) {
75
+ userPath.push(extendedIdentifiers[key+'Type'], extendedIdentifiers[key])
76
+ }
77
+ const userPropertyId = userPath.map(p => JSON.stringify(p)).join(':')
78
+ const userProperty = await modelRuntime().get(userPropertyId)
79
+
80
+ if(config.merge) {
81
+ const mergeResult = await config.merge(sessionProperty, userProperty)
82
+ if(mergeResult && userProperty) {
83
+ emit({
84
+ type: 'sessionOrUserOwned' + modelName + 'Updated',
85
+ identifiers: {
86
+ sessionOrUserType: 'user_User',
87
+ sessionOrUser: user
88
+ },
89
+ data: mergeResult
90
+ })
91
+ } else {
92
+ emit({
93
+ type: 'sessionOrUserOwned' + modelName + 'Set',
94
+ identifiers: {
95
+ sessionOrUserType: 'user_User',
96
+ sessionOrUser: user
97
+ },
98
+ data: mergeResult
99
+ })
100
+ }
101
+ if(!config.mergeWithoutDelete) {
102
+ emit({
103
+ type: 'sessionOrUserOwned' + modelName + 'Reset',
104
+ identifiers: {
105
+ sessionOrUserType: 'session_Session',
106
+ sessionOrUser: session
107
+ }
108
+ })
109
+ }
110
+ } else {
111
+ if(!userProperty) {
112
+ await service.trigger({
113
+ type: 'contactOrUserOwned' + modelName + 'Moved',
114
+ from: {
115
+ sessionOrUserType: 'session_Session',
116
+ sessionOrUser: session,
117
+ ...extendedIdentifiers
118
+ },
119
+ to: {
120
+ sessionOrUserType: 'user_User',
121
+ sessionOrUser: user,
122
+ ...extendedIdentifiers
123
+ },
124
+ })
125
+ emit({
126
+ type: transferEventName,
127
+ from: {
128
+ sessionOrUserType: 'session_Session',
129
+ sessionOrUser: session,
130
+ ...extendedIdentifiers
131
+ },
132
+ to: {
133
+ sessionOrUserType: 'user_User',
134
+ sessionOrUser: user,
135
+ ...extendedIdentifiers
136
+ }
137
+ })
138
+ } // else ignore - user property is more important by default
139
+ }
140
+ }
141
+ }
142
+ })
143
+
144
+ service.trigger({
145
+ name: 'userDeleted',
146
+ properties: {
147
+ user: {
148
+ type: User,
149
+ validation: ['nonEmpty']
150
+ }
151
+ },
152
+ async execute({ user, session }, { service }, emit) {
153
+ /// TODO: delete on userDeleted trigger
154
+ }
155
+ })
45
156
 
46
157
  if(config.ownerReadAccess) { // single item view
47
158
  const viewName = 'my' + modelName