@memberjunction/server 2.75.0 → 2.77.0

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.
Files changed (127) hide show
  1. package/README.md +61 -2
  2. package/dist/apolloServer/index.d.ts.map +1 -1
  3. package/dist/apolloServer/index.js +1 -3
  4. package/dist/apolloServer/index.js.map +1 -1
  5. package/dist/auth/exampleNewUserSubClass.d.ts +1 -1
  6. package/dist/auth/exampleNewUserSubClass.d.ts.map +1 -1
  7. package/dist/auth/exampleNewUserSubClass.js +1 -1
  8. package/dist/auth/exampleNewUserSubClass.js.map +1 -1
  9. package/dist/auth/newUsers.js.map +1 -1
  10. package/dist/context.d.ts +5 -0
  11. package/dist/context.d.ts.map +1 -1
  12. package/dist/context.js +34 -3
  13. package/dist/context.js.map +1 -1
  14. package/dist/entitySubclasses/entityPermissions.server.d.ts +2 -2
  15. package/dist/entitySubclasses/entityPermissions.server.d.ts.map +1 -1
  16. package/dist/entitySubclasses/entityPermissions.server.js +2 -2
  17. package/dist/entitySubclasses/entityPermissions.server.js.map +1 -1
  18. package/dist/generated/generated.d.ts +1787 -1628
  19. package/dist/generated/generated.d.ts.map +1 -1
  20. package/dist/generated/generated.js +5871 -4367
  21. package/dist/generated/generated.js.map +1 -1
  22. package/dist/generic/ResolverBase.d.ts +20 -21
  23. package/dist/generic/ResolverBase.d.ts.map +1 -1
  24. package/dist/generic/ResolverBase.js +75 -59
  25. package/dist/generic/ResolverBase.js.map +1 -1
  26. package/dist/generic/RunViewResolver.d.ts +8 -8
  27. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  28. package/dist/generic/RunViewResolver.js +50 -48
  29. package/dist/generic/RunViewResolver.js.map +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +1 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/resolvers/AskSkipResolver.d.ts +6 -6
  35. package/dist/resolvers/AskSkipResolver.d.ts.map +1 -1
  36. package/dist/resolvers/AskSkipResolver.js +33 -21
  37. package/dist/resolvers/AskSkipResolver.js.map +1 -1
  38. package/dist/resolvers/CreateQueryResolver.d.ts +12 -3
  39. package/dist/resolvers/CreateQueryResolver.d.ts.map +1 -1
  40. package/dist/resolvers/CreateQueryResolver.js +121 -65
  41. package/dist/resolvers/CreateQueryResolver.js.map +1 -1
  42. package/dist/resolvers/EntityResolver.d.ts +1 -2
  43. package/dist/resolvers/EntityResolver.d.ts.map +1 -1
  44. package/dist/resolvers/EntityResolver.js +17 -9
  45. package/dist/resolvers/EntityResolver.js.map +1 -1
  46. package/dist/resolvers/FileCategoryResolver.d.ts +1 -1
  47. package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
  48. package/dist/resolvers/FileCategoryResolver.js +9 -9
  49. package/dist/resolvers/FileCategoryResolver.js.map +1 -1
  50. package/dist/resolvers/FileResolver.d.ts.map +1 -1
  51. package/dist/resolvers/FileResolver.js +3 -1
  52. package/dist/resolvers/FileResolver.js.map +1 -1
  53. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  54. package/dist/resolvers/GetDataResolver.js +3 -0
  55. package/dist/resolvers/GetDataResolver.js.map +1 -1
  56. package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
  57. package/dist/resolvers/MergeRecordsResolver.js +2 -1
  58. package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
  59. package/dist/resolvers/QueryResolver.d.ts +4 -4
  60. package/dist/resolvers/QueryResolver.js +18 -18
  61. package/dist/resolvers/ReportResolver.js.map +1 -1
  62. package/dist/resolvers/SyncDataResolver.d.ts +8 -8
  63. package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
  64. package/dist/resolvers/SyncDataResolver.js +19 -19
  65. package/dist/resolvers/SyncDataResolver.js.map +1 -1
  66. package/dist/resolvers/SyncRolesUsersResolver.d.ts +10 -10
  67. package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
  68. package/dist/resolvers/SyncRolesUsersResolver.js +19 -19
  69. package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
  70. package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
  71. package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
  72. package/dist/resolvers/UserFavoriteResolver.d.ts +2 -2
  73. package/dist/resolvers/UserFavoriteResolver.d.ts.map +1 -1
  74. package/dist/resolvers/UserFavoriteResolver.js +7 -4
  75. package/dist/resolvers/UserFavoriteResolver.js.map +1 -1
  76. package/dist/resolvers/UserResolver.d.ts +3 -3
  77. package/dist/resolvers/UserResolver.d.ts.map +1 -1
  78. package/dist/resolvers/UserResolver.js +10 -6
  79. package/dist/resolvers/UserResolver.js.map +1 -1
  80. package/dist/resolvers/UserViewResolver.d.ts +2 -2
  81. package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
  82. package/dist/resolvers/UserViewResolver.js +11 -6
  83. package/dist/resolvers/UserViewResolver.js.map +1 -1
  84. package/dist/scheduler/LearningCycleScheduler.d.ts.map +1 -1
  85. package/dist/scheduler/LearningCycleScheduler.js +7 -1
  86. package/dist/scheduler/LearningCycleScheduler.js.map +1 -1
  87. package/dist/types.d.ts +7 -4
  88. package/dist/types.d.ts.map +1 -1
  89. package/dist/types.js +4 -0
  90. package/dist/types.js.map +1 -1
  91. package/dist/util.d.ts +8 -1
  92. package/dist/util.d.ts.map +1 -1
  93. package/dist/util.js +28 -0
  94. package/dist/util.js.map +1 -1
  95. package/package.json +34 -34
  96. package/src/apolloServer/index.ts +3 -3
  97. package/src/auth/exampleNewUserSubClass.ts +3 -2
  98. package/src/auth/newUsers.ts +1 -1
  99. package/src/context.ts +49 -9
  100. package/src/entitySubclasses/entityPermissions.server.ts +3 -3
  101. package/src/generated/generated.ts +5506 -4368
  102. package/src/generic/ResolverBase.ts +103 -86
  103. package/src/generic/RunViewResolver.ts +55 -54
  104. package/src/index.ts +1 -1
  105. package/src/resolvers/AskSkipResolver.ts +44 -23
  106. package/src/resolvers/CreateQueryResolver.ts +104 -62
  107. package/src/resolvers/EntityResolver.ts +18 -9
  108. package/src/resolvers/FileCategoryResolver.ts +12 -9
  109. package/src/resolvers/FileResolver.ts +4 -2
  110. package/src/resolvers/GetDataResolver.ts +3 -0
  111. package/src/resolvers/MergeRecordsResolver.ts +2 -1
  112. package/src/resolvers/QueryResolver.ts +14 -14
  113. package/src/resolvers/ReportResolver.ts +1 -1
  114. package/src/resolvers/SyncDataResolver.ts +21 -21
  115. package/src/resolvers/SyncRolesUsersResolver.ts +24 -21
  116. package/src/resolvers/TransactionGroupResolver.ts +1 -1
  117. package/src/resolvers/UserFavoriteResolver.ts +7 -5
  118. package/src/resolvers/UserResolver.ts +10 -6
  119. package/src/resolvers/UserViewResolver.ts +13 -7
  120. package/src/scheduler/LearningCycleScheduler.ts +10 -4
  121. package/src/types.ts +14 -4
  122. package/src/util.ts +45 -2
  123. package/dist/apolloServer/TransactionPlugin.d.ts +0 -4
  124. package/dist/apolloServer/TransactionPlugin.d.ts.map +0 -1
  125. package/dist/apolloServer/TransactionPlugin.js +0 -46
  126. package/dist/apolloServer/TransactionPlugin.js.map +0 -1
  127. package/src/apolloServer/TransactionPlugin.ts +0 -53
@@ -38,7 +38,7 @@ export class RunQueryResultType {
38
38
 
39
39
  @Resolver()
40
40
  export class RunQueryResolver {
41
- private async findQuery(QueryID: string, QueryName?: string, CategoryID?: string, CategoryName?: string, refreshMetadataIfNotFound: boolean = false): Promise<QueryInfo | null> {
41
+ private async findQuery(QueryID: string, QueryName?: string, CategoryID?: string, CategoryPath?: string, refreshMetadataIfNotFound: boolean = false): Promise<QueryInfo | null> {
42
42
  const md = new Metadata();
43
43
 
44
44
  // Filter queries based on provided criteria
@@ -50,8 +50,8 @@ export class RunQueryResolver {
50
50
  if (CategoryID) {
51
51
  matches = matches && q.CategoryID?.trim().toLowerCase() === CategoryID.trim().toLowerCase();
52
52
  }
53
- if (CategoryName) {
54
- matches = matches && q.Category?.trim().toLowerCase() === CategoryName.trim().toLowerCase();
53
+ if (CategoryPath) {
54
+ matches = matches && q.Category?.trim().toLowerCase() === CategoryPath.trim().toLowerCase();
55
55
  }
56
56
  return matches;
57
57
  }
@@ -62,7 +62,7 @@ export class RunQueryResolver {
62
62
  if (refreshMetadataIfNotFound) {
63
63
  // If we didn't find the query, refresh metadata and try again
64
64
  await md.Refresh();
65
- return this.findQuery(QueryID, QueryName, CategoryID, CategoryName, false); // change the refresh flag to false so we don't loop infinitely
65
+ return this.findQuery(QueryID, QueryName, CategoryID, CategoryPath, false); // change the refresh flag to false so we don't loop infinitely
66
66
  }
67
67
  else {
68
68
  return null; // No query found and not refreshing metadata
@@ -76,7 +76,7 @@ export class RunQueryResolver {
76
76
  async GetQueryData(@Arg('QueryID', () => String) QueryID: string,
77
77
  @Ctx() context: AppContext,
78
78
  @Arg('CategoryID', () => String, {nullable: true}) CategoryID?: string,
79
- @Arg('CategoryName', () => String, {nullable: true}) CategoryName?: string,
79
+ @Arg('CategoryPath', () => String, {nullable: true}) CategoryPath?: string,
80
80
  @Arg('Parameters', () => GraphQLJSONObject, {nullable: true}) Parameters?: Record<string, any>,
81
81
  @Arg('MaxRows', () => Int, {nullable: true}) MaxRows?: number,
82
82
  @Arg('StartRow', () => Int, {nullable: true}) StartRow?: number): Promise<RunQueryResultType> {
@@ -86,7 +86,7 @@ export class RunQueryResolver {
86
86
  {
87
87
  QueryID: QueryID,
88
88
  CategoryID: CategoryID,
89
- CategoryName: CategoryName,
89
+ CategoryPath: CategoryPath,
90
90
  Parameters: Parameters,
91
91
  MaxRows: MaxRows,
92
92
  StartRow: StartRow
@@ -102,7 +102,7 @@ export class RunQueryResolver {
102
102
  let queryName = result.QueryName;
103
103
  if (!queryName) {
104
104
  try {
105
- const queryInfo = await this.findQuery(QueryID, undefined, CategoryID, CategoryName, true);
105
+ const queryInfo = await this.findQuery(QueryID, undefined, CategoryID, CategoryPath, true);
106
106
  if (queryInfo) {
107
107
  queryName = queryInfo.Name;
108
108
  }
@@ -128,7 +128,7 @@ export class RunQueryResolver {
128
128
  async GetQueryDataByName(@Arg('QueryName', () => String) QueryName: string,
129
129
  @Ctx() context: AppContext,
130
130
  @Arg('CategoryID', () => String, {nullable: true}) CategoryID?: string,
131
- @Arg('CategoryName', () => String, {nullable: true}) CategoryName?: string,
131
+ @Arg('CategoryPath', () => String, {nullable: true}) CategoryPath?: string,
132
132
  @Arg('Parameters', () => GraphQLJSONObject, {nullable: true}) Parameters?: Record<string, any>,
133
133
  @Arg('MaxRows', () => Int, {nullable: true}) MaxRows?: number,
134
134
  @Arg('StartRow', () => Int, {nullable: true}) StartRow?: number): Promise<RunQueryResultType> {
@@ -137,7 +137,7 @@ export class RunQueryResolver {
137
137
  {
138
138
  QueryName: QueryName,
139
139
  CategoryID: CategoryID,
140
- CategoryName: CategoryName,
140
+ CategoryPath: CategoryPath,
141
141
  Parameters: Parameters,
142
142
  MaxRows: MaxRows,
143
143
  StartRow: StartRow
@@ -162,7 +162,7 @@ export class RunQueryResolver {
162
162
  async GetQueryDataSystemUser(@Arg('QueryID', () => String) QueryID: string,
163
163
  @Ctx() context: AppContext,
164
164
  @Arg('CategoryID', () => String, {nullable: true}) CategoryID?: string,
165
- @Arg('CategoryName', () => String, {nullable: true}) CategoryName?: string,
165
+ @Arg('CategoryPath', () => String, {nullable: true}) CategoryPath?: string,
166
166
  @Arg('Parameters', () => GraphQLJSONObject, {nullable: true}) Parameters?: Record<string, any>,
167
167
  @Arg('MaxRows', () => Int, {nullable: true}) MaxRows?: number,
168
168
  @Arg('StartRow', () => Int, {nullable: true}) StartRow?: number): Promise<RunQueryResultType> {
@@ -171,7 +171,7 @@ export class RunQueryResolver {
171
171
  {
172
172
  QueryID: QueryID,
173
173
  CategoryID: CategoryID,
174
- CategoryName: CategoryName,
174
+ CategoryPath: CategoryPath,
175
175
  Parameters: Parameters,
176
176
  MaxRows: MaxRows,
177
177
  StartRow: StartRow
@@ -182,7 +182,7 @@ export class RunQueryResolver {
182
182
  let queryName = result.QueryName;
183
183
  if (!queryName) {
184
184
  try {
185
- const queryInfo = await this.findQuery(QueryID, undefined, CategoryID, CategoryName, true);
185
+ const queryInfo = await this.findQuery(QueryID, undefined, CategoryID, CategoryPath, true);
186
186
  if (queryInfo) {
187
187
  queryName = queryInfo.Name;
188
188
  }
@@ -209,7 +209,7 @@ export class RunQueryResolver {
209
209
  async GetQueryDataByNameSystemUser(@Arg('QueryName', () => String) QueryName: string,
210
210
  @Ctx() context: AppContext,
211
211
  @Arg('CategoryID', () => String, {nullable: true}) CategoryID?: string,
212
- @Arg('CategoryName', () => String, {nullable: true}) CategoryName?: string,
212
+ @Arg('CategoryPath', () => String, {nullable: true}) CategoryPath?: string,
213
213
  @Arg('Parameters', () => GraphQLJSONObject, {nullable: true}) Parameters?: Record<string, any>,
214
214
  @Arg('MaxRows', () => Int, {nullable: true}) MaxRows?: number,
215
215
  @Arg('StartRow', () => Int, {nullable: true}) StartRow?: number): Promise<RunQueryResultType> {
@@ -218,7 +218,7 @@ export class RunQueryResolver {
218
218
  {
219
219
  QueryName: QueryName,
220
220
  CategoryID: CategoryID,
221
- CategoryName: CategoryName,
221
+ CategoryPath: CategoryPath,
222
222
  Parameters: Parameters,
223
223
  MaxRows: MaxRows,
224
224
  StartRow: StartRow
@@ -1,4 +1,4 @@
1
- import { Metadata, RunReport } from '@memberjunction/core';
1
+ import { EntitySaveOptions, Metadata, RunReport } from '@memberjunction/core';
2
2
  import { Arg, Ctx, Field, Int, Mutation, ObjectType, Query, Resolver } from 'type-graphql';
3
3
  import { AppContext } from '../types.js';
4
4
  import { ConversationDetailEntity, ReportEntity } from '@memberjunction/core-entities';
@@ -1,6 +1,6 @@
1
1
  import { Arg, Ctx, Field, InputType, Mutation, ObjectType, registerEnumType } from 'type-graphql';
2
- import { AppContext } from '../types.js';
3
- import { BaseEntity, CompositeKey, LogError, Metadata, RunView, UserInfo } from '@memberjunction/core';
2
+ import { AppContext, UserPayload } from '../types.js';
3
+ import { BaseEntity, CompositeKey, EntityDeleteOptions, EntitySaveOptions, LogError, Metadata, RunView, UserInfo } from '@memberjunction/core';
4
4
  import { RequireSystemUser } from '../directives/RequireSystemUser.js';
5
5
  import { CompositeKeyInputType, CompositeKeyOutputType } from '../generic/KeyInputOutputTypes.js';
6
6
  import { DatasetItemEntity } from '@memberjunction/core-entities';
@@ -115,7 +115,7 @@ export class SyncDataResolver {
115
115
  const md = new Metadata();
116
116
  const results: ActionItemOutputType[] = [];
117
117
  for (const item of items) {
118
- results.push(await this.SyncSingleItem(item, context, md));
118
+ results.push(await this.SyncSingleItem(item, context, md, context.userPayload));
119
119
  }
120
120
 
121
121
  if (await this.DoSyncItemsAffectMetadata(context.userPayload.userRecord, items)) {
@@ -160,7 +160,7 @@ export class SyncDataResolver {
160
160
  return false; // didn't find any
161
161
  }
162
162
 
163
- protected async SyncSingleItem(item: ActionItemInputType, context: AppContext, md: Metadata): Promise<ActionItemOutputType> {
163
+ protected async SyncSingleItem(item: ActionItemInputType, context: AppContext, md: Metadata, userPayload: UserPayload): Promise<ActionItemOutputType> {
164
164
  const result = new ActionItemOutputType();
165
165
  result.AlternateKey = item.AlternateKey;
166
166
  result.PrimaryKey = item.PrimaryKey;
@@ -179,20 +179,20 @@ export class SyncDataResolver {
179
179
  const fieldValues = item.RecordJSON ? JSON.parse(item.RecordJSON) : {};
180
180
  switch (item.Type) {
181
181
  case SyncDataActionType.Create:
182
- await this.SyncSingleItemCreate(entityObject, fieldValues, result);
182
+ await this.SyncSingleItemCreate(entityObject, fieldValues, result, userPayload);
183
183
  break;
184
184
  case SyncDataActionType.Update:
185
- await this.SyncSingleItemUpdate(entityObject, pk, ak, fieldValues, result);
185
+ await this.SyncSingleItemUpdate(entityObject, pk, ak, fieldValues, result, userPayload);
186
186
  break;
187
187
  case SyncDataActionType.CreateOrUpdate:
188
188
  // in this case we attempt to load the item first, if it is not possible to load the item, then we create it
189
- await this.SyncSingleItemCreateOrUpdate(entityObject, pk, ak, fieldValues, result);
189
+ await this.SyncSingleItemCreateOrUpdate(entityObject, pk, ak, fieldValues, result, userPayload);
190
190
  break;
191
191
  case SyncDataActionType.Delete:
192
- await this.SyncSingleItemDelete(entityObject, pk, ak, result);
192
+ await this.SyncSingleItemDelete(entityObject, pk, ak, result, userPayload);
193
193
  break;
194
194
  case SyncDataActionType.DeleteWithFilter:
195
- await this.SyncSingleItemDeleteWithFilter(item.EntityName, item.DeleteFilter, result, context.userPayload.userRecord);
195
+ await this.SyncSingleItemDeleteWithFilter(item.EntityName, item.DeleteFilter, result, context.userPayload.userRecord, userPayload);
196
196
  break;
197
197
  default:
198
198
  throw new Error('Invalid SyncDataActionType');
@@ -211,7 +211,7 @@ export class SyncDataResolver {
211
211
  }
212
212
 
213
213
 
214
- protected async SyncSingleItemDeleteWithFilter(entityName: string, filter: string, result: ActionItemOutputType, user: UserInfo) {
214
+ protected async SyncSingleItemDeleteWithFilter(entityName: string, filter: string, result: ActionItemOutputType, user: UserInfo, userPayload: UserPayload) {
215
215
  try {
216
216
  // here we will iterate through the result of a RunView on the entityname/filter and delete each matching record
217
217
  let overallSuccess: boolean = true;
@@ -273,30 +273,30 @@ export class SyncDataResolver {
273
273
  }
274
274
  }
275
275
 
276
- protected async SyncSingleItemCreateOrUpdate(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, fieldValues: any, result: ActionItemOutputType) {
276
+ protected async SyncSingleItemCreateOrUpdate(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, fieldValues: any, result: ActionItemOutputType, userPayload: UserPayload) {
277
277
  if (!pk || pk.KeyValuePairs.length === 0) {
278
278
  // no primary key try to load from alt key
279
279
  const altKeyResult = await this.LoadFromAlternateKey(entityObject.EntityInfo.Name, ak, entityObject.ContextCurrentUser);
280
280
  if (!altKeyResult) {
281
281
  // no record found, create a new one
282
- await this.SyncSingleItemCreate(entityObject, fieldValues, result);
282
+ await this.SyncSingleItemCreate(entityObject, fieldValues, result, userPayload);
283
283
  }
284
284
  else {
285
- await this.InnerSyncSingleItemUpdate(altKeyResult, fieldValues, result);
285
+ await this.InnerSyncSingleItemUpdate(altKeyResult, fieldValues, result, userPayload);
286
286
  }
287
287
  }
288
288
  else {
289
289
  // have a primary key do the usual load
290
290
  if (await entityObject.InnerLoad(pk)) {
291
- await this.InnerSyncSingleItemUpdate(entityObject, fieldValues, result);
291
+ await this.InnerSyncSingleItemUpdate(entityObject, fieldValues, result, userPayload);
292
292
  }
293
293
  else {
294
- await this.SyncSingleItemCreate(entityObject, fieldValues, result);
294
+ await this.SyncSingleItemCreate(entityObject, fieldValues, result, userPayload);
295
295
  }
296
296
  }
297
297
  }
298
298
 
299
- protected async SyncSingleItemDelete(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, result: ActionItemOutputType) {
299
+ protected async SyncSingleItemDelete(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, result: ActionItemOutputType, userPayload: UserPayload) {
300
300
  if (!pk || pk.KeyValuePairs.length === 0) {
301
301
  const altKeyResult = await this.LoadFromAlternateKey(entityObject.EntityInfo.Name, ak, entityObject.ContextCurrentUser);
302
302
  if (!altKeyResult) {
@@ -342,7 +342,7 @@ export class SyncDataResolver {
342
342
  }
343
343
  }
344
344
 
345
- protected async SyncSingleItemCreate(entityObject: BaseEntity, fieldValues: any, result: ActionItemOutputType) {
345
+ protected async SyncSingleItemCreate(entityObject: BaseEntity, fieldValues: any, result: ActionItemOutputType, userPayload: UserPayload) {
346
346
  // make sure we strip out the primary key from fieldValues before we pass it in because otherwise it will appear to be an existing record to the BaseEntity
347
347
  const noPKValues = {...fieldValues};
348
348
  entityObject.EntityInfo.PrimaryKeys.forEach((pk) => {
@@ -367,7 +367,7 @@ export class SyncDataResolver {
367
367
  }
368
368
  }
369
369
 
370
- protected async SyncSingleItemUpdate(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, fieldValues: any, result: ActionItemOutputType) {
370
+ protected async SyncSingleItemUpdate(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, fieldValues: any, result: ActionItemOutputType, userPayload: UserPayload) {
371
371
  if (!pk || pk.KeyValuePairs.length === 0) {
372
372
  // no pk, attempt to load by alt key
373
373
  const altKeyResult = await this.LoadFromAlternateKey(entityObject.EntityInfo.Name, ak, entityObject.ContextCurrentUser);
@@ -376,11 +376,11 @@ export class SyncDataResolver {
376
376
  result.ErrorMessage = 'Failed to load the item, it is possible the record with the specified alternate key does not exist';
377
377
  }
378
378
  else {
379
- await this.InnerSyncSingleItemUpdate(altKeyResult, fieldValues, result);
379
+ await this.InnerSyncSingleItemUpdate(altKeyResult, fieldValues, result, userPayload);
380
380
  }
381
381
  }
382
382
  else if (await entityObject.InnerLoad(pk)) {
383
- await this.InnerSyncSingleItemUpdate(entityObject, fieldValues, result);
383
+ await this.InnerSyncSingleItemUpdate(entityObject, fieldValues, result, userPayload);
384
384
  }
385
385
  else {
386
386
  // failed to load the item
@@ -388,7 +388,7 @@ export class SyncDataResolver {
388
388
  }
389
389
  }
390
390
 
391
- protected async InnerSyncSingleItemUpdate(entityObject: BaseEntity, fieldValues: any, result: ActionItemOutputType) {
391
+ protected async InnerSyncSingleItemUpdate(entityObject: BaseEntity, fieldValues: any, result: ActionItemOutputType, userPayload: UserPayload) {
392
392
  entityObject.SetMany(fieldValues);
393
393
  if (await entityObject.Save()) {
394
394
  result.Success = true;
@@ -1,6 +1,6 @@
1
1
  import { Arg, Ctx, Field, InputType, Mutation, ObjectType, registerEnumType } from 'type-graphql';
2
- import { AppContext } from '../types.js';
3
- import { LogError, Metadata, RunView, UserInfo } from '@memberjunction/core';
2
+ import { AppContext, UserPayload } from '../types.js';
3
+ import { EntityDeleteOptions, EntitySaveOptions, LogError, Metadata, RunView, UserInfo } from '@memberjunction/core';
4
4
  import { RequireSystemUser } from '../directives/RequireSystemUser.js';
5
5
  import { RoleEntity, UserEntity, UserRoleEntity } from '@memberjunction/core-entities';
6
6
  import { UserCache } from '@memberjunction/sqlserver-dataprovider';
@@ -131,9 +131,9 @@ export class SyncRolesAndUsersResolver {
131
131
 
132
132
  if (result && result.Success) {
133
133
  const currentRoles = result.Results;
134
- if (await this.DeleteRemovedRoles(currentRoles, roles, context.userPayload.userRecord)) {
135
- if ( await this.AddNewRoles(currentRoles, roles, context.userPayload.userRecord)) {
136
- return await this.UpdateExistingRoles(currentRoles, roles, context.userPayload.userRecord);
134
+ if (await this.DeleteRemovedRoles(currentRoles, roles, context.userPayload.userRecord, context.userPayload)) {
135
+ if ( await this.AddNewRoles(currentRoles, roles, context.userPayload.userRecord, context.userPayload)) {
136
+ return await this.UpdateExistingRoles(currentRoles, roles, context.userPayload);
137
137
  }
138
138
  }
139
139
  }
@@ -145,7 +145,7 @@ export class SyncRolesAndUsersResolver {
145
145
  }
146
146
  }
147
147
 
148
- protected async UpdateExistingRoles(currentRoles: RoleEntity[], futureRoles: RoleInputType[], user: UserInfo): Promise<SyncRolesAndUsersResultType> {
148
+ protected async UpdateExistingRoles(currentRoles: RoleEntity[], futureRoles: RoleInputType[], userPayload: UserPayload): Promise<SyncRolesAndUsersResultType> {
149
149
  // go through the future roles and update any that are in the current roles
150
150
  const md = new Metadata();
151
151
  let ok: boolean = true;
@@ -160,7 +160,7 @@ export class SyncRolesAndUsersResolver {
160
160
  return { Success: ok };
161
161
  }
162
162
 
163
- protected async AddNewRoles(currentRoles: RoleEntity[], futureRoles: RoleInputType[], user: UserInfo): Promise<boolean> {
163
+ protected async AddNewRoles(currentRoles: RoleEntity[], futureRoles: RoleInputType[], user: UserInfo, userPayload: UserPayload): Promise<boolean> {
164
164
  // go through the future roles and add any that are not in the current roles
165
165
  const md = new Metadata();
166
166
  let ok: boolean = true;
@@ -177,7 +177,7 @@ export class SyncRolesAndUsersResolver {
177
177
  }
178
178
 
179
179
 
180
- protected async DeleteRemovedRoles(currentRoles: RoleEntity[], futureRoles: RoleInputType[], user: UserInfo): Promise<boolean> {
180
+ protected async DeleteRemovedRoles(currentRoles: RoleEntity[], futureRoles: RoleInputType[], user: UserInfo, userPayload: UserPayload): Promise<boolean> {
181
181
  const rv = new RunView();
182
182
  let ok: boolean = true;
183
183
 
@@ -185,7 +185,7 @@ export class SyncRolesAndUsersResolver {
185
185
  for (const remove of currentRoles) {
186
186
  if (!this.IsStandardRole(remove.Name)) {
187
187
  if (!futureRoles.find(r => r.Name.trim().toLowerCase() === remove.Name.trim().toLowerCase())) {
188
- ok = ok && await this.DeleteSingleRole(remove, rv, user);
188
+ ok = ok && await this.DeleteSingleRole(remove, rv, user, userPayload);
189
189
  }
190
190
  }
191
191
  }
@@ -199,9 +199,10 @@ export class SyncRolesAndUsersResolver {
199
199
  return this.StandardRoles.find(r => r.toLowerCase() === roleName.toLowerCase()) !== undefined;
200
200
  }
201
201
 
202
- protected async DeleteSingleRole(role: RoleEntity, rv: RunView, user: UserInfo): Promise<boolean> {
202
+ protected async DeleteSingleRole(role: RoleEntity, rv: RunView, user: UserInfo, userPayload: UserPayload): Promise<boolean> {
203
203
  // first, remove all the UserRole records that match this role
204
204
  let ok: boolean = true;
205
+
205
206
  const r2 = await rv.RunView<UserRoleEntity>({
206
207
  EntityName: "User Roles",
207
208
  ExtraFilter: "RoleID = '" + role.ID + "'",
@@ -238,10 +239,10 @@ export class SyncRolesAndUsersResolver {
238
239
  if (result && result.Success) {
239
240
  // go through current users and remove those that are not in the input
240
241
  const currentUsers = result.Results;
241
- if (await this.DeleteRemovedUsers(currentUsers, users, context.userPayload.userRecord)) {
242
- if (await this.AddNewUsers(currentUsers, users, context.userPayload.userRecord)) {
243
- if (await this.UpdateExistingUsers(currentUsers, users, context.userPayload.userRecord)) {
244
- if (await this.SyncUserRoles(users, context.userPayload.userRecord)) {
242
+ if (await this.DeleteRemovedUsers(currentUsers, users, context.userPayload.userRecord, context.userPayload)) {
243
+ if (await this.AddNewUsers(currentUsers, users, context.userPayload)) {
244
+ if (await this.UpdateExistingUsers(currentUsers, users, context.userPayload)) {
245
+ if (await this.SyncUserRoles(users, context.userPayload.userRecord, context.userPayload)) {
245
246
  return { Success: true };
246
247
  }
247
248
  }
@@ -256,9 +257,10 @@ export class SyncRolesAndUsersResolver {
256
257
  }
257
258
  }
258
259
 
259
- protected async UpdateExistingUsers(currentUsers: UserEntity[], futureUsers: UserInputType[], u: UserInfo): Promise<boolean> {
260
+ protected async UpdateExistingUsers(currentUsers: UserEntity[], futureUsers: UserInputType[], userPayload: UserPayload): Promise<boolean> {
260
261
  // go through the future users and update any that are in the current users
261
262
  let ok: boolean = true;
263
+
262
264
  for (const update of futureUsers) {
263
265
  const current = currentUsers.find(c => c.Email?.trim().toLowerCase() === update.Email?.trim().toLowerCase());
264
266
  if (current) {
@@ -272,7 +274,7 @@ export class SyncRolesAndUsersResolver {
272
274
  }
273
275
  return ok;
274
276
  }
275
- protected async AddNewUsers(currentUsers: UserEntity[], futureUsers: UserInputType[], u: UserInfo): Promise<boolean> {
277
+ protected async AddNewUsers(currentUsers: UserEntity[], futureUsers: UserInputType[], userPayload: UserPayload): Promise<boolean> {
276
278
  // add users that are not in the current users
277
279
  const md = new Metadata();
278
280
  let ok: boolean = true;
@@ -285,7 +287,7 @@ export class SyncRolesAndUsersResolver {
285
287
  ok = ok && await match.Save();
286
288
  }
287
289
  else {
288
- const user = await md.GetEntityObject<UserEntity>("Users", u);
290
+ const user = await md.GetEntityObject<UserEntity>("Users", userPayload.userRecord);
289
291
  user.Name = add.Name;
290
292
  user.Type = add.Type;
291
293
  user.Email = add.Email;
@@ -300,7 +302,7 @@ export class SyncRolesAndUsersResolver {
300
302
  return ok;
301
303
  }
302
304
 
303
- protected async DeleteRemovedUsers(currentUsers: UserEntity[], futureUsers: UserInputType[], u: UserInfo): Promise<boolean> {
305
+ protected async DeleteRemovedUsers(currentUsers: UserEntity[], futureUsers: UserInputType[], u: UserInfo, userPayload: UserPayload): Promise<boolean> {
304
306
  // remove users that are not in the future users
305
307
  const rv = new RunView();
306
308
  const md = new Metadata();
@@ -310,16 +312,17 @@ export class SyncRolesAndUsersResolver {
310
312
  for (const remove of currentUsers) {
311
313
  if (remove.Type.trim().toLowerCase() !== 'owner') {
312
314
  if (!futureUsers.find(r => r.Email.trim().toLowerCase() === remove.Email.trim().toLowerCase())) {
313
- ok = ok && await this.DeleteSingleUser(remove, rv, u);
315
+ ok = ok && await this.DeleteSingleUser(remove, rv, u, userPayload);
314
316
  }
315
317
  }
316
318
  }
317
319
  return ok;
318
320
  }
319
321
 
320
- protected async DeleteSingleUser(user: UserEntity, rv: RunView, u: UserInfo): Promise<boolean> {
322
+ protected async DeleteSingleUser(user: UserEntity, rv: RunView, u: UserInfo, userPayload: UserPayload): Promise<boolean> {
321
323
  // first, remove all the UserRole records that match this user
322
324
  let ok: boolean = true;
325
+
323
326
  const r2 = await rv.RunView<UserRoleEntity>({
324
327
  EntityName: "User Roles",
325
328
  ExtraFilter: "UserID = '" + user.ID + "'",
@@ -341,7 +344,7 @@ export class SyncRolesAndUsersResolver {
341
344
  }
342
345
  }
343
346
 
344
- protected async SyncUserRoles(users: UserInputType[], u: UserInfo): Promise<boolean> {
347
+ protected async SyncUserRoles(users: UserInputType[], u: UserInfo, userPayload: UserPayload): Promise<boolean> {
345
348
  // for each user in the users array, make sure there is a User Role that matches. First, get a list of all DATABASE user and roels so we have that for fast lookup in memory
346
349
  const rv = new RunView();
347
350
  const md = new Metadata();
@@ -1,6 +1,6 @@
1
1
  import { Arg, Ctx, Field, InputType, Int, Mutation, ObjectType, registerEnumType } from 'type-graphql';
2
2
  import { AppContext } from '../types.js';
3
- import { CompositeKey, KeyValuePair, LogError, Metadata, TransactionVariable, BaseEntity } from '@memberjunction/core';
3
+ import { CompositeKey, KeyValuePair, LogError, Metadata, TransactionVariable, BaseEntity, EntityDeleteOptions, EntitySaveOptions } from '@memberjunction/core';
4
4
  import { SafeJSONParse } from '@memberjunction/global';
5
5
 
6
6
  export enum TransactionVariableType {
@@ -14,9 +14,9 @@ import {
14
14
  Resolver,
15
15
  } from '@memberjunction/server';
16
16
  import { UserCache } from '@memberjunction/sqlserver-dataprovider';
17
- import { UserFavoriteEntity } from '@memberjunction/core-entities';
18
17
 
19
18
  import { UserFavorite_, UserFavoriteResolverBase } from '../generated/generated.js';
19
+ import { GetReadOnlyProvider } from '../util.js';
20
20
 
21
21
  //****************************************************************************
22
22
  // INPUT TYPE for User Favorite Queries
@@ -69,13 +69,15 @@ export class UserFavoriteResult {
69
69
  @Resolver(UserFavorite_)
70
70
  export class UserFavoriteResolver extends UserFavoriteResolverBase {
71
71
  @Query(() => [UserFavorite_])
72
- async UserFavoritesByUserID(@Arg('UserID', () => Int) UserID: number, @Ctx() { dataSource, userPayload }: AppContext) {
73
- return await this.findBy(dataSource, 'User Favorites', { UserID }, userPayload.userRecord);
72
+ async UserFavoritesByUserID(@Arg('UserID', () => Int) UserID: number, @Ctx() { providers, userPayload }: AppContext) {
73
+ const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
74
+ return await this.findBy(provider, 'User Favorites', { UserID }, userPayload.userRecord);
74
75
  }
75
76
 
76
77
  @Query(() => [UserFavorite_])
77
- async UserFavoriteSearchByParams(@Arg('params', () => Int) params: UserFavoriteSearchParams, @Ctx() { dataSource, userPayload }: AppContext) {
78
- return await this.findBy(dataSource, 'User Favorites', params, userPayload.userRecord);
78
+ async UserFavoriteSearchByParams(@Arg('params', () => Int) params: UserFavoriteSearchParams, @Ctx() { providers, userPayload }: AppContext) {
79
+ const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
80
+ return await this.findBy(provider, 'User Favorites', params, userPayload.userRecord);
79
81
  }
80
82
 
81
83
  @Query(() => UserFavoriteResult)
@@ -1,5 +1,6 @@
1
1
  import { AppContext, Arg, Ctx, Int, Query, Resolver } from '@memberjunction/server';
2
2
  import { User_, UserResolverBase } from '../generated/generated.js';
3
+ import { GetReadOnlyProvider } from '../util.js';
3
4
 
4
5
  @Resolver(User_)
5
6
  export class UserResolver extends UserResolverBase {
@@ -11,22 +12,25 @@ export class UserResolver extends UserResolverBase {
11
12
  }
12
13
 
13
14
  @Query(() => User_)
14
- async UserByID(@Arg('ID', () => Int) ID: number, @Ctx() { dataSource, userPayload }: AppContext) {
15
- const retVal = super.safeFirstArrayElement(await this.findBy(dataSource, 'Users', { ID }, userPayload.userRecord));
15
+ async UserByID(@Arg('ID', () => Int) ID: number, @Ctx() { providers, userPayload }: AppContext) {
16
+ const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
17
+ const retVal = super.safeFirstArrayElement(await this.findBy(provider, 'Users', { ID }, userPayload.userRecord));
16
18
  return this.MapFieldNamesToCodeNames('Users', retVal);
17
19
  }
18
20
 
19
21
  @Query(() => User_)
20
- async UserByEmployeeID(@Arg('EmployeeID', () => Int) EmployeeID: number, @Ctx() { dataSource, userPayload }: AppContext) {
21
- const retVal = super.safeFirstArrayElement(await this.findBy(dataSource, 'Users', { EmployeeID }, userPayload.userRecord));
22
+ async UserByEmployeeID(@Arg('EmployeeID', () => Int) EmployeeID: number, @Ctx() { providers, userPayload }: AppContext) {
23
+ const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
24
+ const retVal = super.safeFirstArrayElement(await this.findBy(provider, 'Users', { EmployeeID }, userPayload.userRecord));
22
25
  return this.MapFieldNamesToCodeNames('Users', retVal);
23
26
  }
24
27
 
25
28
  @Query(() => User_)
26
- async UserByEmail(@Arg('Email', () => String) Email: string, @Ctx() { dataSource, userPayload }: AppContext) {
29
+ async UserByEmail(@Arg('Email', () => String) Email: string, @Ctx() { providers, userPayload }: AppContext) {
27
30
  // const searchEmail = userEmailMap[Email] ?? Email;
28
31
  const searchEmail = Email;
29
- const returnVal = super.safeFirstArrayElement(await this.findBy(dataSource, 'Users', { Email: searchEmail }, userPayload.userRecord));
32
+ const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
33
+ const returnVal = super.safeFirstArrayElement(await this.findBy(provider, 'Users', { Email: searchEmail }, userPayload.userRecord));
30
34
  return this.MapFieldNamesToCodeNames('Users', returnVal);
31
35
  }
32
36
  }
@@ -1,29 +1,33 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { Metadata } from '@memberjunction/core';
2
+ import { EntitySaveOptions, Metadata } from '@memberjunction/core';
3
3
  import { AppContext, Arg, Ctx, Int, Query, Resolver, UserPayload } from '@memberjunction/server';
4
4
  import { UserView_, UserViewResolverBase } from '../generated/generated.js';
5
5
  import { UserResolver } from './UserResolver.js';
6
6
  import { UserViewEntity, UserViewEntityExtended } from '@memberjunction/core-entities';
7
+ import { GetReadOnlyProvider } from '../util.js';
7
8
 
8
9
  @Resolver(UserView_)
9
10
  export class UserViewResolver extends UserViewResolverBase {
10
11
  @Query(() => [UserView_])
11
- async UserViewsByUserID(@Arg('UserID', () => Int) UserID: number, @Ctx() { dataSource, userPayload }: AppContext) {
12
- return await this.findBy(dataSource, 'User Views', { UserID }, userPayload.userRecord);
12
+ async UserViewsByUserID(@Arg('UserID', () => Int) UserID: number, @Ctx() { providers, userPayload }: AppContext) {
13
+ const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
14
+ return await this.findBy(provider, 'User Views', { UserID }, userPayload.userRecord);
13
15
  }
14
16
 
15
17
  @Query(() => [UserView_])
16
18
  async DefaultViewByUserAndEntity(
17
19
  @Arg('UserID', () => Int) UserID: number,
18
20
  @Arg('EntityID', () => Int) EntityID: number,
19
- @Ctx() { dataSource, userPayload }: AppContext
21
+ @Ctx() { providers, userPayload }: AppContext
20
22
  ) {
21
- return await this.findBy(dataSource, 'User Views', { UserID, EntityID, IsDefault: true }, userPayload.userRecord);
23
+ const provider = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true})
24
+ return await this.findBy(provider, 'User Views', { UserID, EntityID, IsDefault: true }, userPayload.userRecord);
22
25
  }
23
26
 
24
27
  @Query(() => [UserView_])
25
28
  async CurrentUserDefaultViewByEntityID(@Arg('EntityID', () => Int) EntityID: number, @Ctx() context: AppContext) {
26
- return await this.findBy(context.dataSource, 'User Views', {
29
+ const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true})
30
+ return await this.findBy(provider, 'User Views', {
27
31
  UserID: await this.getCurrentUserID(context),
28
32
  EntityID,
29
33
  IsDefault: true,
@@ -38,7 +42,8 @@ export class UserViewResolver extends UserViewResolverBase {
38
42
 
39
43
  @Query(() => [UserView_])
40
44
  async CurrentUserUserViewsByEntityID(@Arg('EntityID', () => Int) EntityID: number, @Ctx() context: AppContext) {
41
- return this.findBy(context.dataSource, 'User Views', { UserID: await this.getCurrentUserID(context), EntityID}, context.userPayload.userRecord);
45
+ const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true})
46
+ return this.findBy(provider, 'User Views', { UserID: await this.getCurrentUserID(context), EntityID}, context.userPayload.userRecord);
42
47
  }
43
48
 
44
49
  @Query(() => [UserView_])
@@ -52,6 +57,7 @@ export class UserViewResolver extends UserViewResolverBase {
52
57
  const viewEntity = <UserViewEntityExtended>await md.GetEntityObject('User Views', u);
53
58
  await viewEntity.Load(ID);
54
59
  viewEntity.UpdateWhereClause();
60
+
55
61
  if (await viewEntity.Save()) {
56
62
  return viewEntity.GetAll();
57
63
  } else {
@@ -1,10 +1,11 @@
1
1
  import { LogStatus, LogError } from '@memberjunction/core';
2
- import { UserCache } from '@memberjunction/sqlserver-dataprovider';
2
+ import { SQLServerDataProvider, SQLServerProviderConfigData, UserCache } from '@memberjunction/sqlserver-dataprovider';
3
3
  import { GetReadWriteDataSource } from '../util.js';
4
4
  import { AskSkipResolver } from '../resolvers/AskSkipResolver.js';
5
- import { DataSourceInfo } from '../types.js';
5
+ import { AppContext, DataSourceInfo } from '../types.js';
6
6
  import { getSystemUser } from '../auth/index.js';
7
7
  import { BaseSingleton } from '@memberjunction/global';
8
+ import { mj_core_schema } from '../config.js';
8
9
 
9
10
  /**
10
11
  * A simple scheduler for the Skip AI learning cycle
@@ -89,7 +90,11 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
89
90
  }
90
91
 
91
92
  // Create context for the resolver
92
- const context = {
93
+ const config = new SQLServerProviderConfigData(dataSource, mj_core_schema, 0, undefined, undefined, false);
94
+ const p = new SQLServerDataProvider();
95
+ await p.Config(config);
96
+
97
+ const context: AppContext = {
93
98
  dataSource: dataSource,
94
99
  dataSources: this.dataSources,
95
100
  userPayload: {
@@ -97,7 +102,8 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
97
102
  sessionId: `scheduler_${Date.now()}`,
98
103
  userRecord: systemUser,
99
104
  isSystemUser: true
100
- }
105
+ },
106
+ providers: [{provider: p, type: 'Read-Write'}]
101
107
  };
102
108
 
103
109
  // Execute the learning cycle
package/src/types.ts CHANGED
@@ -1,10 +1,11 @@
1
- import { UserInfo } from '@memberjunction/core';
1
+ import { DatabaseProviderBase, UserInfo } from '@memberjunction/core';
2
2
  import { UserViewEntity } from '@memberjunction/core-entities';
3
3
  import { GraphQLSchema } from 'graphql';
4
4
  import { PubSubEngine } from 'type-graphql';
5
5
  import sql from 'mssql';
6
6
  import { getSystemUser } from './auth/index.js';
7
7
  import { MJEvent, MJEventType, MJGlobal } from '@memberjunction/global';
8
+ import { SQLServerDataProvider } from '@memberjunction/sqlserver-dataprovider';
8
9
 
9
10
  export type UserPayload = {
10
11
  email: string;
@@ -28,8 +29,18 @@ export type AppContext = {
28
29
  * Array of connection pools that have additional information about their intended use e.g. Admin, Read-Write, Read-Only.
29
30
  */
30
31
  dataSources: DataSourceInfo[];
32
+
33
+ /**
34
+ * Per-request DatabaseProviderBase instances
35
+ */
36
+ providers: Array<ProviderInfo>;
31
37
  };
32
38
 
39
+ export class ProviderInfo {
40
+ provider: DatabaseProviderBase;
41
+ type: 'Admin' | 'Read-Write' | 'Read-Only' | 'Other';
42
+ }
43
+
33
44
  export class DataSourceInfo {
34
45
  dataSource: sql.ConnectionPool;
35
46
  host: string;
@@ -56,7 +67,7 @@ export type DirectiveBuilder = {
56
67
 
57
68
  export type RunViewGenericParams = {
58
69
  viewInfo: UserViewEntity;
59
- dataSource: sql.ConnectionPool;
70
+ provider: DatabaseProviderBase;
60
71
  extraFilter: string;
61
72
  orderBy: string;
62
73
  userSearchString: string;
@@ -69,8 +80,7 @@ export type RunViewGenericParams = {
69
80
  forceAuditLog?: boolean;
70
81
  auditLogDescription?: string;
71
82
  resultType?: string;
72
- userPayload?: UserPayload;
73
- pubSub: PubSubEngine;
83
+ userPayload?: UserPayload;
74
84
  };
75
85
 
76
86