@memberjunction/server 2.112.0 → 2.113.1

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 (250) hide show
  1. package/dist/agents/skip-agent.d.ts +4 -4
  2. package/dist/agents/skip-agent.d.ts.map +1 -1
  3. package/dist/agents/skip-agent.js +951 -808
  4. package/dist/agents/skip-agent.js.map +1 -1
  5. package/dist/agents/skip-sdk.d.ts +1 -1
  6. package/dist/agents/skip-sdk.d.ts.map +1 -1
  7. package/dist/agents/skip-sdk.js +43 -53
  8. package/dist/agents/skip-sdk.js.map +1 -1
  9. package/dist/apolloServer/index.js +1 -1
  10. package/dist/auth/AuthProviderFactory.d.ts +1 -1
  11. package/dist/auth/AuthProviderFactory.d.ts.map +1 -1
  12. package/dist/auth/AuthProviderFactory.js +3 -1
  13. package/dist/auth/AuthProviderFactory.js.map +1 -1
  14. package/dist/auth/BaseAuthProvider.d.ts +1 -1
  15. package/dist/auth/BaseAuthProvider.d.ts.map +1 -1
  16. package/dist/auth/BaseAuthProvider.js +2 -3
  17. package/dist/auth/BaseAuthProvider.js.map +1 -1
  18. package/dist/auth/IAuthProvider.d.ts +1 -1
  19. package/dist/auth/IAuthProvider.d.ts.map +1 -1
  20. package/dist/auth/exampleNewUserSubClass.d.ts.map +1 -1
  21. package/dist/auth/exampleNewUserSubClass.js +1 -1
  22. package/dist/auth/exampleNewUserSubClass.js.map +1 -1
  23. package/dist/auth/index.d.ts +1 -1
  24. package/dist/auth/index.d.ts.map +1 -1
  25. package/dist/auth/index.js +6 -6
  26. package/dist/auth/index.js.map +1 -1
  27. package/dist/auth/initializeProviders.js +1 -1
  28. package/dist/auth/initializeProviders.js.map +1 -1
  29. package/dist/auth/newUsers.d.ts +1 -1
  30. package/dist/auth/newUsers.d.ts.map +1 -1
  31. package/dist/auth/newUsers.js +7 -7
  32. package/dist/auth/newUsers.js.map +1 -1
  33. package/dist/auth/providers/Auth0Provider.d.ts +1 -1
  34. package/dist/auth/providers/Auth0Provider.d.ts.map +1 -1
  35. package/dist/auth/providers/Auth0Provider.js +1 -1
  36. package/dist/auth/providers/Auth0Provider.js.map +1 -1
  37. package/dist/auth/providers/CognitoProvider.d.ts +1 -1
  38. package/dist/auth/providers/CognitoProvider.d.ts.map +1 -1
  39. package/dist/auth/providers/CognitoProvider.js +6 -3
  40. package/dist/auth/providers/CognitoProvider.js.map +1 -1
  41. package/dist/auth/providers/GoogleProvider.d.ts +1 -1
  42. package/dist/auth/providers/GoogleProvider.d.ts.map +1 -1
  43. package/dist/auth/providers/GoogleProvider.js +1 -1
  44. package/dist/auth/providers/GoogleProvider.js.map +1 -1
  45. package/dist/auth/providers/MSALProvider.d.ts +1 -1
  46. package/dist/auth/providers/MSALProvider.d.ts.map +1 -1
  47. package/dist/auth/providers/MSALProvider.js +1 -1
  48. package/dist/auth/providers/MSALProvider.js.map +1 -1
  49. package/dist/auth/providers/OktaProvider.d.ts +1 -1
  50. package/dist/auth/providers/OktaProvider.d.ts.map +1 -1
  51. package/dist/auth/providers/OktaProvider.js +1 -1
  52. package/dist/auth/providers/OktaProvider.js.map +1 -1
  53. package/dist/config.d.ts.map +1 -1
  54. package/dist/config.js +10 -22
  55. package/dist/config.js.map +1 -1
  56. package/dist/context.d.ts +1 -1
  57. package/dist/context.d.ts.map +1 -1
  58. package/dist/context.js +7 -9
  59. package/dist/context.js.map +1 -1
  60. package/dist/entitySubclasses/entityPermissions.server.d.ts +1 -1
  61. package/dist/entitySubclasses/entityPermissions.server.d.ts.map +1 -1
  62. package/dist/entitySubclasses/entityPermissions.server.js +1 -1
  63. package/dist/entitySubclasses/entityPermissions.server.js.map +1 -1
  64. package/dist/generated/generated.d.ts +788 -658
  65. package/dist/generated/generated.d.ts.map +1 -1
  66. package/dist/generated/generated.js +2050 -3054
  67. package/dist/generated/generated.js.map +1 -1
  68. package/dist/generic/KeyInputOutputTypes.d.ts +1 -1
  69. package/dist/generic/KeyInputOutputTypes.d.ts.map +1 -1
  70. package/dist/generic/KeyInputOutputTypes.js +1 -1
  71. package/dist/generic/KeyInputOutputTypes.js.map +1 -1
  72. package/dist/generic/ResolverBase.d.ts +1 -1
  73. package/dist/generic/ResolverBase.d.ts.map +1 -1
  74. package/dist/generic/ResolverBase.js +10 -15
  75. package/dist/generic/ResolverBase.js.map +1 -1
  76. package/dist/generic/RunViewResolver.d.ts +1 -1
  77. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  78. package/dist/generic/RunViewResolver.js +15 -15
  79. package/dist/generic/RunViewResolver.js.map +1 -1
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +13 -18
  82. package/dist/index.js.map +1 -1
  83. package/dist/resolvers/ActionResolver.d.ts +2 -2
  84. package/dist/resolvers/ActionResolver.d.ts.map +1 -1
  85. package/dist/resolvers/ActionResolver.js +30 -28
  86. package/dist/resolvers/ActionResolver.js.map +1 -1
  87. package/dist/resolvers/AskSkipResolver.d.ts +2 -2
  88. package/dist/resolvers/AskSkipResolver.d.ts.map +1 -1
  89. package/dist/resolvers/AskSkipResolver.js +50 -60
  90. package/dist/resolvers/AskSkipResolver.js.map +1 -1
  91. package/dist/resolvers/ComponentRegistryResolver.d.ts.map +1 -1
  92. package/dist/resolvers/ComponentRegistryResolver.js +38 -36
  93. package/dist/resolvers/ComponentRegistryResolver.js.map +1 -1
  94. package/dist/resolvers/CreateQueryResolver.d.ts +1 -1
  95. package/dist/resolvers/CreateQueryResolver.d.ts.map +1 -1
  96. package/dist/resolvers/CreateQueryResolver.js +40 -43
  97. package/dist/resolvers/CreateQueryResolver.js.map +1 -1
  98. package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
  99. package/dist/resolvers/DatasetResolver.js +1 -1
  100. package/dist/resolvers/DatasetResolver.js.map +1 -1
  101. package/dist/resolvers/EntityRecordNameResolver.d.ts +1 -1
  102. package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
  103. package/dist/resolvers/EntityRecordNameResolver.js +1 -1
  104. package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
  105. package/dist/resolvers/EntityResolver.d.ts.map +1 -1
  106. package/dist/resolvers/EntityResolver.js +1 -1
  107. package/dist/resolvers/EntityResolver.js.map +1 -1
  108. package/dist/resolvers/FileCategoryResolver.js +1 -1
  109. package/dist/resolvers/FileCategoryResolver.js.map +1 -1
  110. package/dist/resolvers/FileResolver.js +1 -1
  111. package/dist/resolvers/FileResolver.js.map +1 -1
  112. package/dist/resolvers/GetDataContextDataResolver.d.ts +1 -1
  113. package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
  114. package/dist/resolvers/GetDataContextDataResolver.js +5 -5
  115. package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
  116. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  117. package/dist/resolvers/GetDataResolver.js +6 -8
  118. package/dist/resolvers/GetDataResolver.js.map +1 -1
  119. package/dist/resolvers/MergeRecordsResolver.d.ts +3 -3
  120. package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
  121. package/dist/resolvers/MergeRecordsResolver.js +3 -3
  122. package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
  123. package/dist/resolvers/PotentialDuplicateRecordResolver.d.ts +1 -1
  124. package/dist/resolvers/PotentialDuplicateRecordResolver.d.ts.map +1 -1
  125. package/dist/resolvers/PotentialDuplicateRecordResolver.js +1 -1
  126. package/dist/resolvers/PotentialDuplicateRecordResolver.js.map +1 -1
  127. package/dist/resolvers/QueryResolver.d.ts.map +1 -1
  128. package/dist/resolvers/QueryResolver.js +11 -11
  129. package/dist/resolvers/QueryResolver.js.map +1 -1
  130. package/dist/resolvers/ReportResolver.js +1 -1
  131. package/dist/resolvers/ReportResolver.js.map +1 -1
  132. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  133. package/dist/resolvers/RunAIAgentResolver.js +28 -27
  134. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  135. package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
  136. package/dist/resolvers/RunAIPromptResolver.js +31 -31
  137. package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
  138. package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
  139. package/dist/resolvers/RunTemplateResolver.js +9 -9
  140. package/dist/resolvers/RunTemplateResolver.js.map +1 -1
  141. package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
  142. package/dist/resolvers/SqlLoggingConfigResolver.js +10 -10
  143. package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
  144. package/dist/resolvers/SyncDataResolver.d.ts +1 -1
  145. package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
  146. package/dist/resolvers/SyncDataResolver.js +14 -15
  147. package/dist/resolvers/SyncDataResolver.js.map +1 -1
  148. package/dist/resolvers/SyncRolesUsersResolver.d.ts +1 -1
  149. package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
  150. package/dist/resolvers/SyncRolesUsersResolver.js +44 -48
  151. package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
  152. package/dist/resolvers/TaskResolver.d.ts.map +1 -1
  153. package/dist/resolvers/TaskResolver.js +7 -7
  154. package/dist/resolvers/TaskResolver.js.map +1 -1
  155. package/dist/resolvers/TransactionGroupResolver.d.ts +1 -1
  156. package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
  157. package/dist/resolvers/TransactionGroupResolver.js +12 -12
  158. package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
  159. package/dist/resolvers/UserFavoriteResolver.d.ts +1 -1
  160. package/dist/resolvers/UserFavoriteResolver.d.ts.map +1 -1
  161. package/dist/resolvers/UserFavoriteResolver.js +1 -1
  162. package/dist/resolvers/UserFavoriteResolver.js.map +1 -1
  163. package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
  164. package/dist/resolvers/UserViewResolver.js.map +1 -1
  165. package/dist/rest/EntityCRUDHandler.d.ts +1 -1
  166. package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
  167. package/dist/rest/EntityCRUDHandler.js +16 -14
  168. package/dist/rest/EntityCRUDHandler.js.map +1 -1
  169. package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
  170. package/dist/rest/RESTEndpointHandler.js +25 -23
  171. package/dist/rest/RESTEndpointHandler.js.map +1 -1
  172. package/dist/rest/ViewOperationsHandler.d.ts +1 -1
  173. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  174. package/dist/rest/ViewOperationsHandler.js +21 -17
  175. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  176. package/dist/scheduler/LearningCycleScheduler.d.ts.map +1 -1
  177. package/dist/scheduler/LearningCycleScheduler.js.map +1 -1
  178. package/dist/services/ScheduledJobsService.d.ts.map +1 -1
  179. package/dist/services/ScheduledJobsService.js +6 -4
  180. package/dist/services/ScheduledJobsService.js.map +1 -1
  181. package/dist/services/TaskOrchestrator.d.ts +1 -1
  182. package/dist/services/TaskOrchestrator.d.ts.map +1 -1
  183. package/dist/services/TaskOrchestrator.js +30 -30
  184. package/dist/services/TaskOrchestrator.js.map +1 -1
  185. package/dist/types.d.ts +3 -3
  186. package/dist/types.d.ts.map +1 -1
  187. package/dist/types.js +1 -0
  188. package/dist/types.js.map +1 -1
  189. package/dist/util.d.ts +1 -1
  190. package/dist/util.d.ts.map +1 -1
  191. package/dist/util.js +2 -2
  192. package/dist/util.js.map +1 -1
  193. package/package.json +39 -36
  194. package/src/agents/skip-agent.ts +1200 -1067
  195. package/src/agents/skip-sdk.ts +851 -877
  196. package/src/apolloServer/index.ts +2 -2
  197. package/src/auth/AuthProviderFactory.ts +14 -8
  198. package/src/auth/BaseAuthProvider.ts +4 -5
  199. package/src/auth/IAuthProvider.ts +2 -2
  200. package/src/auth/exampleNewUserSubClass.ts +2 -9
  201. package/src/auth/index.ts +26 -31
  202. package/src/auth/initializeProviders.ts +3 -3
  203. package/src/auth/newUsers.ts +134 -166
  204. package/src/auth/providers/Auth0Provider.ts +5 -5
  205. package/src/auth/providers/CognitoProvider.ts +10 -7
  206. package/src/auth/providers/GoogleProvider.ts +5 -4
  207. package/src/auth/providers/MSALProvider.ts +5 -5
  208. package/src/auth/providers/OktaProvider.ts +7 -6
  209. package/src/config.ts +54 -63
  210. package/src/context.ts +30 -42
  211. package/src/entitySubclasses/entityPermissions.server.ts +3 -3
  212. package/src/generated/generated.ts +40442 -48106
  213. package/src/generic/KeyInputOutputTypes.ts +6 -3
  214. package/src/generic/ResolverBase.ts +78 -119
  215. package/src/generic/RunViewResolver.ts +23 -27
  216. package/src/index.ts +48 -66
  217. package/src/resolvers/ActionResolver.ts +57 -46
  218. package/src/resolvers/AskSkipResolver.ts +533 -607
  219. package/src/resolvers/ComponentRegistryResolver.ts +562 -547
  220. package/src/resolvers/CreateQueryResolver.ts +655 -683
  221. package/src/resolvers/DatasetResolver.ts +6 -5
  222. package/src/resolvers/EntityCommunicationsResolver.ts +1 -1
  223. package/src/resolvers/EntityRecordNameResolver.ts +5 -9
  224. package/src/resolvers/EntityResolver.ts +7 -9
  225. package/src/resolvers/FileCategoryResolver.ts +2 -2
  226. package/src/resolvers/FileResolver.ts +4 -4
  227. package/src/resolvers/GetDataContextDataResolver.ts +118 -106
  228. package/src/resolvers/GetDataResolver.ts +205 -194
  229. package/src/resolvers/MergeRecordsResolver.ts +5 -5
  230. package/src/resolvers/PotentialDuplicateRecordResolver.ts +1 -1
  231. package/src/resolvers/QueryResolver.ts +78 -95
  232. package/src/resolvers/ReportResolver.ts +2 -2
  233. package/src/resolvers/RunAIAgentResolver.ts +828 -818
  234. package/src/resolvers/RunAIPromptResolver.ts +709 -693
  235. package/src/resolvers/RunTemplateResolver.ts +103 -105
  236. package/src/resolvers/SqlLoggingConfigResolver.ts +72 -69
  237. package/src/resolvers/SyncDataResolver.ts +352 -386
  238. package/src/resolvers/SyncRolesUsersResolver.ts +350 -387
  239. package/src/resolvers/TaskResolver.ts +115 -110
  240. package/src/resolvers/TransactionGroupResolver.ts +138 -143
  241. package/src/resolvers/UserFavoriteResolver.ts +8 -17
  242. package/src/resolvers/UserViewResolver.ts +12 -17
  243. package/src/rest/EntityCRUDHandler.ts +268 -291
  244. package/src/rest/RESTEndpointHandler.ts +776 -782
  245. package/src/rest/ViewOperationsHandler.ts +195 -191
  246. package/src/scheduler/LearningCycleScheduler.ts +52 -8
  247. package/src/services/ScheduledJobsService.ts +132 -129
  248. package/src/services/TaskOrchestrator.ts +776 -792
  249. package/src/types.ts +9 -15
  250. package/src/util.ts +109 -112
@@ -1,95 +1,90 @@
1
1
  import { Arg, Ctx, Field, InputType, Mutation, ObjectType, registerEnumType } from 'type-graphql';
2
2
  import { AppContext, UserPayload } from '../types.js';
3
- import {
4
- BaseEntity,
5
- CompositeKey,
6
- EntityDeleteOptions,
7
- EntitySaveOptions,
8
- LogError,
9
- Metadata,
10
- RunView,
11
- UserInfo,
12
- } from '@memberjunction/global';
3
+ import { BaseEntity, CompositeKey, EntityDeleteOptions, EntitySaveOptions, LogError, Metadata, RunView, UserInfo } from '@memberjunction/core';
13
4
  import { RequireSystemUser } from '../directives/RequireSystemUser.js';
14
5
  import { CompositeKeyInputType, CompositeKeyOutputType } from '../generic/KeyInputOutputTypes.js';
15
6
  import { DatasetItemEntity } from '@memberjunction/core-entities';
16
7
 
8
+
9
+
17
10
  /**
18
11
  * This type defines the possible list of actions that can be taken in syncing data: Create, Update, CreateOrUpdate, Delete, or DeleteWithFilter
19
12
  * DeleteWithFilter is where you specify a valid SQL expression that can be used in a where clause to get a list of records in a given entity to delete
20
13
  * this can be used to ensure cleaning out data from a subset of a given table.
21
14
  */
22
15
  export enum SyncDataActionType {
23
- Create = 'Create',
24
- Update = 'Update',
25
- CreateOrUpdate = 'CreateOrUpdate',
26
- Delete = 'Delete',
27
- DeleteWithFilter = 'DeleteWithFilter',
28
- }
29
-
30
- registerEnumType(SyncDataActionType, {
31
- name: 'SyncDataActionType', // GraphQL Enum Name
32
- description: 'Specifies the type of action to be taken in syncing, Create, Update, CreateOrUpdate, Delete', // Description,
33
- });
34
-
35
- @InputType()
36
- export class ActionItemInputType {
37
- @Field(() => String)
38
- EntityName!: string;
39
-
40
- @Field(() => CompositeKeyInputType, { nullable: true })
41
- PrimaryKey?: CompositeKeyInputType;
42
-
43
- @Field(() => CompositeKeyInputType, { nullable: true })
44
- AlternateKey?: CompositeKeyInputType;
45
-
46
- @Field(() => SyncDataActionType)
47
- Type!: SyncDataActionType;
48
-
49
- /**
50
- * This field is a JSON representation of the field values of the entity to be created or updated. It is used for all ActionTypes except for
51
- */
52
- @Field(() => String, { nullable: true })
53
- RecordJSON?: string;
54
-
55
- /**
56
- * This field is only provided when the Action Type is DeleteWithFilter. It is a valid SQL expression that can be used in a where clause to get a list of records in a given entity to delete
57
- */
58
- @Field(() => String, { nullable: true })
59
- DeleteFilter?: string;
60
- }
61
-
16
+ Create = "Create",
17
+ Update = "Update",
18
+ CreateOrUpdate = "CreateOrUpdate",
19
+ Delete = "Delete",
20
+ DeleteWithFilter = "DeleteWithFilter"
21
+ }
22
+
23
+ registerEnumType(SyncDataActionType, {
24
+ name: "SyncDataActionType", // GraphQL Enum Name
25
+ description: "Specifies the type of action to be taken in syncing, Create, Update, CreateOrUpdate, Delete" // Description,
26
+ });
27
+
28
+
29
+ @InputType()
30
+ export class ActionItemInputType {
31
+ @Field(() => String)
32
+ EntityName!: string;
33
+
34
+ @Field(() => CompositeKeyInputType, {nullable: true})
35
+ PrimaryKey?: CompositeKeyInputType;
36
+
37
+ @Field(() => CompositeKeyInputType, {nullable: true})
38
+ AlternateKey?: CompositeKeyInputType;
39
+
40
+ @Field(() => SyncDataActionType)
41
+ Type!: SyncDataActionType;
42
+
43
+ /**
44
+ * This field is a JSON representation of the field values of the entity to be created or updated. It is used for all ActionTypes except for
45
+ */
46
+ @Field(() => String, {nullable: true})
47
+ RecordJSON?: string;
48
+
49
+ /**
50
+ * This field is only provided when the Action Type is DeleteWithFilter. It is a valid SQL expression that can be used in a where clause to get a list of records in a given entity to delete
51
+ */
52
+ @Field(() => String, {nullable: true})
53
+ DeleteFilter?: string;
54
+ }
55
+
56
+
62
57
  @ObjectType()
63
58
  export class ActionItemOutputType {
64
- @Field(() => Boolean)
65
- Success: boolean;
59
+ @Field(() => Boolean)
60
+ Success: boolean;
66
61
 
67
- @Field(() => String)
68
- ErrorMessage: string;
62
+ @Field(() => String)
63
+ ErrorMessage: string;
69
64
 
70
- @Field(() => String)
71
- EntityName!: string;
65
+ @Field(() => String)
66
+ EntityName!: string;
72
67
 
73
- @Field(() => CompositeKeyOutputType, { nullable: true })
74
- PrimaryKey?: CompositeKeyOutputType;
68
+ @Field(() => CompositeKeyOutputType, {nullable: true})
69
+ PrimaryKey?: CompositeKeyOutputType;
75
70
 
76
- @Field(() => CompositeKeyOutputType, { nullable: true })
77
- AlternateKey?: CompositeKeyOutputType;
71
+ @Field(() => CompositeKeyOutputType, {nullable: true})
72
+ AlternateKey?: CompositeKeyOutputType;
78
73
 
79
- @Field(() => SyncDataActionType)
80
- Type!: SyncDataActionType;
74
+ @Field(() => SyncDataActionType)
75
+ Type!: SyncDataActionType;
81
76
 
82
- /**
83
- * This field is a JSON representation of the field values of the entity to be created or updated. It is used for all ActionTypes except for
84
- */
85
- @Field(() => String, { nullable: true })
86
- RecordJSON?: string;
77
+ /**
78
+ * This field is a JSON representation of the field values of the entity to be created or updated. It is used for all ActionTypes except for
79
+ */
80
+ @Field(() => String, {nullable: true})
81
+ RecordJSON?: string;
87
82
 
88
- /**
89
- * This field is only provided when the Action Type is DeleteWithFilter. It is a valid SQL expression that can be used in a where clause to get a list of records in a given entity to delete
90
- */
91
- @Field(() => String, { nullable: true })
92
- DeleteFilter?: string;
83
+ /**
84
+ * This field is only provided when the Action Type is DeleteWithFilter. It is a valid SQL expression that can be used in a where clause to get a list of records in a given entity to delete
85
+ */
86
+ @Field(() => String, {nullable: true})
87
+ DeleteFilter?: string;
93
88
  }
94
89
 
95
90
  @ObjectType()
@@ -101,347 +96,318 @@ export class SyncDataResultType {
101
96
  Results: ActionItemOutputType[] = [];
102
97
  }
103
98
 
99
+
104
100
  const __metadata_DatasetItems: string[] = [];
105
101
 
106
102
  export class SyncDataResolver {
107
- /**
108
- * This mutation will sync the specified items with the existing system. Items will be processed in order and the results of each operation will be returned in the Results array within the return value.
109
- * @param items - an array of ActionItemInputType objects that specify the action to be taken on the specified entity with the specified primary key and the JSON representation of the field values.
110
- */
111
- @RequireSystemUser()
112
- @Mutation(() => SyncDataResultType)
113
- async SyncData(@Arg('items', () => [ActionItemInputType]) items: ActionItemInputType[], @Ctx() context: AppContext) {
114
- try {
115
- // iterate through the items
116
- const md = new Metadata();
117
- const results: ActionItemOutputType[] = [];
118
- for (const item of items) {
119
- results.push(await this.SyncSingleItem(item, context, md, context.userPayload));
120
- }
121
-
122
- if (await this.DoSyncItemsAffectMetadata(context.userPayload.userRecord, items)) {
123
- await md.Refresh(); // force refesh the metadata which will cause a reload from the DB
124
- }
125
-
126
- const overallSuccess = !results.some((r) => !r.Success); // if any element in the array of results has a Success value of false, then the overall success is false
127
- return { Success: overallSuccess, Results: results };
128
- } catch (err) {
129
- LogError(err);
130
- throw new Error('SyncDataResolver::SyncData --- Error Syncing Data\n\n' + err);
103
+ /**
104
+ * This mutation will sync the specified items with the existing system. Items will be processed in order and the results of each operation will be returned in the Results array within the return value.
105
+ * @param items - an array of ActionItemInputType objects that specify the action to be taken on the specified entity with the specified primary key and the JSON representation of the field values.
106
+ */
107
+ @RequireSystemUser()
108
+ @Mutation(() => SyncDataResultType)
109
+ async SyncData(
110
+ @Arg('items', () => [ActionItemInputType] ) items: ActionItemInputType[],
111
+ @Ctx() context: AppContext
112
+ ) {
113
+ try {
114
+ // iterate through the items
115
+ const md = new Metadata();
116
+ const results: ActionItemOutputType[] = [];
117
+ for (const item of items) {
118
+ results.push(await this.SyncSingleItem(item, context, md, context.userPayload));
119
+ }
120
+
121
+ if (await this.DoSyncItemsAffectMetadata(context.userPayload.userRecord, items)) {
122
+ await md.Refresh(); // force refesh the metadata which will cause a reload from the DB
123
+ }
124
+
125
+ const overallSuccess = !results.some((r) => !r.Success); // if any element in the array of results has a Success value of false, then the overall success is false
126
+ return { Success: overallSuccess, Results: results };
127
+ }
128
+ catch (err) {
129
+ LogError(err);
130
+ throw new Error('SyncDataResolver::SyncData --- Error Syncing Data\n\n' + err);
131
+ }
131
132
  }
132
- }
133
133
 
134
- protected async GetLowercaseMetadataEntitiesList(user: UserInfo, forceRefresh: boolean = false): Promise<string[]> {
135
- if (forceRefresh || __metadata_DatasetItems.length === 0) {
136
- const rv = new RunView(); // cache this, veyr simple - should use an engine for this stuff later
137
- const result = await rv.RunView<DatasetItemEntity>(
138
- {
139
- EntityName: 'Dataset Items',
140
- ExtraFilter: "Dataset = 'MJ_Metadata'",
141
- },
142
- user
143
- );
144
- if (result && result.Success) {
145
- __metadata_DatasetItems.length = 0;
146
- __metadata_DatasetItems.push(
147
- ...result.Results.map((r) => {
148
- return r.Entity.trim().toLowerCase();
149
- })
150
- );
151
- }
134
+ protected async GetLowercaseMetadataEntitiesList(user: UserInfo, forceRefresh: boolean = false): Promise<string[]> {
135
+ if (forceRefresh || __metadata_DatasetItems.length === 0) {
136
+ const rv = new RunView(); // cache this, veyr simple - should use an engine for this stuff later
137
+ const result = await rv.RunView<DatasetItemEntity>({
138
+ EntityName: "Dataset Items",
139
+ ExtraFilter: "Dataset = 'MJ_Metadata'",
140
+ }, user)
141
+ if (result && result.Success) {
142
+ __metadata_DatasetItems.length = 0;
143
+ __metadata_DatasetItems.push(...result.Results.map((r) => {
144
+ return r.Entity.trim().toLowerCase();
145
+ }));
146
+ }
147
+ }
148
+ // now return the list of entities
149
+ return __metadata_DatasetItems;
152
150
  }
153
- // now return the list of entities
154
- return __metadata_DatasetItems;
155
- }
156
151
 
157
- protected async DoSyncItemsAffectMetadata(user: UserInfo, items: ActionItemInputType[]): Promise<boolean> {
158
- // check to see if any of the items affect any of these entities:
159
- const entitiesToCheck = await this.GetLowercaseMetadataEntitiesList(user, false);
160
- for (const item of items) {
161
- if (entitiesToCheck.find((e) => e === item.EntityName.trim().toLowerCase())) {
162
- return true;
163
- }
152
+ protected async DoSyncItemsAffectMetadata(user: UserInfo, items: ActionItemInputType[]): Promise<boolean> {
153
+ // check to see if any of the items affect any of these entities:
154
+ const entitiesToCheck = await this.GetLowercaseMetadataEntitiesList(user, false);
155
+ for (const item of items) {
156
+ if (entitiesToCheck.find(e => e === item.EntityName.trim().toLowerCase()) ) {
157
+ return true;
158
+ }
159
+ }
160
+ return false; // didn't find any
164
161
  }
165
- return false; // didn't find any
166
- }
167
162
 
168
- protected async SyncSingleItem(
169
- item: ActionItemInputType,
170
- context: AppContext,
171
- md: Metadata,
172
- userPayload: UserPayload
173
- ): Promise<ActionItemOutputType> {
174
- const result = new ActionItemOutputType();
175
- result.AlternateKey = item.AlternateKey;
176
- result.PrimaryKey = item.PrimaryKey;
177
- result.DeleteFilter = item.DeleteFilter;
178
- result.EntityName = item.EntityName;
179
- result.RecordJSON = item.RecordJSON;
180
- result.Type = item.Type;
181
- result.Success = false;
182
- result.ErrorMessage = '';
183
- try {
184
- const e = md.Entities.find((e) => e.Name === item.EntityName);
185
- if (e) {
186
- const pk = item.PrimaryKey ? new CompositeKey(item.PrimaryKey.KeyValuePairs) : null;
187
- const ak = item.AlternateKey ? new CompositeKey(item.AlternateKey.KeyValuePairs) : null;
188
- const entityObject =
189
- item.Type === SyncDataActionType.DeleteWithFilter ? null : await md.GetEntityObject(e.Name, context.userPayload.userRecord);
190
- const fieldValues = item.RecordJSON ? JSON.parse(item.RecordJSON) : {};
191
- switch (item.Type) {
192
- case SyncDataActionType.Create:
193
- await this.SyncSingleItemCreate(entityObject, fieldValues, result, userPayload);
194
- break;
195
- case SyncDataActionType.Update:
196
- await this.SyncSingleItemUpdate(entityObject, pk, ak, fieldValues, result, userPayload);
197
- break;
198
- case SyncDataActionType.CreateOrUpdate:
199
- // in this case we attempt to load the item first, if it is not possible to load the item, then we create it
200
- await this.SyncSingleItemCreateOrUpdate(entityObject, pk, ak, fieldValues, result, userPayload);
201
- break;
202
- case SyncDataActionType.Delete:
203
- await this.SyncSingleItemDelete(entityObject, pk, ak, result, userPayload);
204
- break;
205
- case SyncDataActionType.DeleteWithFilter:
206
- await this.SyncSingleItemDeleteWithFilter(
207
- item.EntityName,
208
- item.DeleteFilter,
209
- result,
210
- context.userPayload.userRecord,
211
- userPayload
212
- );
213
- break;
214
- default:
215
- throw new Error('Invalid SyncDataActionType');
163
+ protected async SyncSingleItem(item: ActionItemInputType, context: AppContext, md: Metadata, userPayload: UserPayload): Promise<ActionItemOutputType> {
164
+ const result = new ActionItemOutputType();
165
+ result.AlternateKey = item.AlternateKey;
166
+ result.PrimaryKey = item.PrimaryKey;
167
+ result.DeleteFilter = item.DeleteFilter;
168
+ result.EntityName = item.EntityName;
169
+ result.RecordJSON = item.RecordJSON;
170
+ result.Type = item.Type;
171
+ result.Success = false;
172
+ result.ErrorMessage = '';
173
+ try {
174
+ const e = md.Entities.find((e) => e.Name === item.EntityName);
175
+ if (e) {
176
+ const pk = item.PrimaryKey ? new CompositeKey(item.PrimaryKey.KeyValuePairs) : null;
177
+ const ak = item.AlternateKey ? new CompositeKey(item.AlternateKey.KeyValuePairs) : null;
178
+ const entityObject = item.Type === SyncDataActionType.DeleteWithFilter ? null : await md.GetEntityObject(e.Name, context.userPayload.userRecord);
179
+ const fieldValues = item.RecordJSON ? JSON.parse(item.RecordJSON) : {};
180
+ switch (item.Type) {
181
+ case SyncDataActionType.Create:
182
+ await this.SyncSingleItemCreate(entityObject, fieldValues, result, userPayload);
183
+ break;
184
+ case SyncDataActionType.Update:
185
+ await this.SyncSingleItemUpdate(entityObject, pk, ak, fieldValues, result, userPayload);
186
+ break;
187
+ case SyncDataActionType.CreateOrUpdate:
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, userPayload);
190
+ break;
191
+ case SyncDataActionType.Delete:
192
+ await this.SyncSingleItemDelete(entityObject, pk, ak, result, userPayload);
193
+ break;
194
+ case SyncDataActionType.DeleteWithFilter:
195
+ await this.SyncSingleItemDeleteWithFilter(item.EntityName, item.DeleteFilter, result, context.userPayload.userRecord, userPayload);
196
+ break;
197
+ default:
198
+ throw new Error('Invalid SyncDataActionType');
199
+ }
200
+ } else {
201
+ throw new Error('Entity not found');
202
+ }
203
+ }
204
+ catch (err) {
205
+ result.ErrorMessage = typeof err === 'string' ? err : (err as any).message;
206
+ LogError(err);
207
+ }
208
+ finally {
209
+ return result;
216
210
  }
217
- } else {
218
- throw new Error('Entity not found');
219
- }
220
- } catch (err) {
221
- result.ErrorMessage = typeof err === 'string' ? err : (err as any).message;
222
- LogError(err);
223
- } finally {
224
- return result;
225
211
  }
226
- }
227
212
 
228
- protected async SyncSingleItemDeleteWithFilter(
229
- entityName: string,
230
- filter: string,
231
- result: ActionItemOutputType,
232
- user: UserInfo,
233
- userPayload: UserPayload
234
- ) {
235
- try {
236
- // here we will iterate through the result of a RunView on the entityname/filter and delete each matching record
237
- let overallSuccess: boolean = true;
238
- let combinedErrorMessage: string = '';
239
- const rv = new RunView();
240
- const data = await rv.RunView<BaseEntity>(
241
- {
242
- EntityName: entityName,
243
- ExtraFilter: filter,
244
- ResultType: 'entity_object',
245
- },
246
- user
247
- );
248
- if (data && data.Success) {
249
- for (const entityObject of data.Results) {
250
- if (!(await entityObject.Delete())) {
251
- overallSuccess = false;
252
- combinedErrorMessage += 'Failed to delete the item :' + entityObject.LatestResult.Message + '\n';
253
- }
213
+
214
+ protected async SyncSingleItemDeleteWithFilter(entityName: string, filter: string, result: ActionItemOutputType, user: UserInfo, userPayload: UserPayload) {
215
+ try {
216
+ // here we will iterate through the result of a RunView on the entityname/filter and delete each matching record
217
+ let overallSuccess: boolean = true;
218
+ let combinedErrorMessage: string = "";
219
+ const rv = new RunView();
220
+ const data = await rv.RunView<BaseEntity>({
221
+ EntityName: entityName,
222
+ ExtraFilter: filter,
223
+ ResultType: 'entity_object'
224
+ }, user);
225
+ if (data && data.Success) {
226
+ for (const entityObject of data.Results) {
227
+ if (!await entityObject.Delete()) {
228
+ overallSuccess = false;
229
+ combinedErrorMessage += 'Failed to delete the item :' + entityObject.LatestResult.Message + '\n';
230
+ }
231
+ }
232
+ result.Success = overallSuccess
233
+ if (!overallSuccess) {
234
+ result.ErrorMessage = combinedErrorMessage
235
+ }
236
+ }
237
+ else {
238
+ result.Success = false;
239
+ result.ErrorMessage = 'Failed to run the view to get the list of items to delete for entity: ' + entityName + ' with filter: ' + filter + '\n';
240
+ }
254
241
  }
255
- result.Success = overallSuccess;
256
- if (!overallSuccess) {
257
- result.ErrorMessage = combinedErrorMessage;
242
+ catch (e) {
243
+ result.ErrorMessage = typeof e === 'string' ? e : (e as any).message;
258
244
  }
259
- } else {
260
- result.Success = false;
261
- result.ErrorMessage =
262
- 'Failed to run the view to get the list of items to delete for entity: ' + entityName + ' with filter: ' + filter + '\n';
263
- }
264
- } catch (e) {
265
- result.ErrorMessage = typeof e === 'string' ? e : (e as any).message;
266
245
  }
267
- }
268
246
 
269
- protected async LoadFromAlternateKey(entityName: string, alternateKey: CompositeKey, user: UserInfo): Promise<BaseEntity> {
270
- try {
271
- // no primary key provided, attempt to look up the primary key based on the
272
- const rv = new RunView();
273
- const md = new Metadata();
274
- const entity = md.EntityByName(entityName);
275
- const r = await rv.RunView<BaseEntity>(
276
- {
277
- EntityName: entityName,
278
- ExtraFilter: alternateKey.KeyValuePairs.map((kvp) => {
279
- const fieldInfo = entity.Fields.find((f) => f.Name === kvp.FieldName);
280
- const quotes = fieldInfo.NeedsQuotes ? "'" : '';
281
- return `${kvp.FieldName} = ${quotes}${kvp.Value}${quotes}`;
282
- }).join(' AND '),
283
- ResultType: 'entity_object',
284
- },
285
- user
286
- );
287
- if (r && r.Success && r.Results.length === 1) {
288
- return r.Results[0];
289
- } else {
290
- //LogError (`Failed to load the item with alternate key: ${alternateKey.KeyValuePairs.map((kvp) => `${kvp.FieldName} = ${kvp.Value}`).join(' AND ')}. Result: ${r.Success} and ${r.Results?.length} items returned`);
291
- return null;
292
- }
293
- } catch (e) {
294
- LogError(e);
295
- return null;
247
+ protected async LoadFromAlternateKey(entityName: string, alternateKey: CompositeKey, user: UserInfo): Promise<BaseEntity> {
248
+ try {
249
+ // no primary key provided, attempt to look up the primary key based on the
250
+ const rv = new RunView();
251
+ const md = new Metadata();
252
+ const entity = md.EntityByName(entityName);
253
+ const r = await rv.RunView<BaseEntity>({
254
+ EntityName: entityName,
255
+ ExtraFilter: alternateKey.KeyValuePairs.map((kvp) => {
256
+ const fieldInfo = entity.Fields.find((f) => f.Name === kvp.FieldName);
257
+ const quotes = fieldInfo.NeedsQuotes ? "'" : '';
258
+ return `${kvp.FieldName} = ${quotes}${kvp.Value}${quotes}`;
259
+ }).join(' AND '),
260
+ ResultType: 'entity_object'
261
+ }, user);
262
+ if (r && r.Success && r.Results.length === 1) {
263
+ return r.Results[0];
264
+ }
265
+ else {
266
+ //LogError (`Failed to load the item with alternate key: ${alternateKey.KeyValuePairs.map((kvp) => `${kvp.FieldName} = ${kvp.Value}`).join(' AND ')}. Result: ${r.Success} and ${r.Results?.length} items returned`);
267
+ return null;
268
+ }
269
+ }
270
+ catch (e) {
271
+ LogError(e);
272
+ return null;
273
+ }
296
274
  }
297
- }
298
275
 
299
- protected async SyncSingleItemCreateOrUpdate(
300
- entityObject: BaseEntity,
301
- pk: CompositeKey,
302
- ak: CompositeKey,
303
- fieldValues: any,
304
- result: ActionItemOutputType,
305
- userPayload: UserPayload
306
- ) {
307
- if (!pk || pk.KeyValuePairs.length === 0) {
308
- // no primary key try to load from alt key
309
- const altKeyResult = await this.LoadFromAlternateKey(entityObject.EntityInfo.Name, ak, entityObject.ContextCurrentUser);
310
- if (!altKeyResult) {
311
- // no record found, create a new one
312
- await this.SyncSingleItemCreate(entityObject, fieldValues, result, userPayload);
313
- } else {
314
- await this.InnerSyncSingleItemUpdate(altKeyResult, fieldValues, result, userPayload);
315
- }
316
- } else {
317
- // have a primary key do the usual load
318
- if (await entityObject.InnerLoad(pk)) {
319
- await this.InnerSyncSingleItemUpdate(entityObject, fieldValues, result, userPayload);
320
- } else {
321
- await this.SyncSingleItemCreate(entityObject, fieldValues, result, userPayload);
322
- }
276
+ protected async SyncSingleItemCreateOrUpdate(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, fieldValues: any, result: ActionItemOutputType, userPayload: UserPayload) {
277
+ if (!pk || pk.KeyValuePairs.length === 0) {
278
+ // no primary key try to load from alt key
279
+ const altKeyResult = await this.LoadFromAlternateKey(entityObject.EntityInfo.Name, ak, entityObject.ContextCurrentUser);
280
+ if (!altKeyResult) {
281
+ // no record found, create a new one
282
+ await this.SyncSingleItemCreate(entityObject, fieldValues, result, userPayload);
283
+ }
284
+ else {
285
+ await this.InnerSyncSingleItemUpdate(altKeyResult, fieldValues, result, userPayload);
286
+ }
287
+ }
288
+ else {
289
+ // have a primary key do the usual load
290
+ if (await entityObject.InnerLoad(pk)) {
291
+ await this.InnerSyncSingleItemUpdate(entityObject, fieldValues, result, userPayload);
292
+ }
293
+ else {
294
+ await this.SyncSingleItemCreate(entityObject, fieldValues, result, userPayload);
295
+ }
296
+ }
323
297
  }
324
- }
325
298
 
326
- protected async SyncSingleItemDelete(
327
- entityObject: BaseEntity,
328
- pk: CompositeKey,
329
- ak: CompositeKey,
330
- result: ActionItemOutputType,
331
- userPayload: UserPayload
332
- ) {
333
- if (!pk || pk.KeyValuePairs.length === 0) {
334
- const altKeyResult = await this.LoadFromAlternateKey(entityObject.EntityInfo.Name, ak, entityObject.ContextCurrentUser);
335
- if (!altKeyResult) {
336
- result.ErrorMessage = 'Failed to load the item, it is possible the record with the specified primary key does not exist';
337
- } else {
338
- // pass back the full record as it was JUST BEFORE the delete, often quite useful on the other end
339
- result.RecordJSON = await altKeyResult.GetDataObjectJSON({
340
- includeRelatedEntityData: false,
341
- excludeFields: [],
342
- omitEmptyStrings: false,
343
- relatedEntityList: [],
344
- omitNullValues: false,
345
- oldValues: false,
346
- });
347
- if (await altKeyResult.Delete()) {
348
- result.Success = true;
349
- } else {
350
- result.ErrorMessage = 'Failed to delete the item :' + entityObject.LatestResult.Message;
299
+ protected async SyncSingleItemDelete(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, result: ActionItemOutputType, userPayload: UserPayload) {
300
+ if (!pk || pk.KeyValuePairs.length === 0) {
301
+ const altKeyResult = await this.LoadFromAlternateKey(entityObject.EntityInfo.Name, ak, entityObject.ContextCurrentUser);
302
+ if (!altKeyResult) {
303
+ result.ErrorMessage = 'Failed to load the item, it is possible the record with the specified primary key does not exist';
304
+ }
305
+ else {
306
+ // pass back the full record as it was JUST BEFORE the delete, often quite useful on the other end
307
+ result.RecordJSON = await altKeyResult.GetDataObjectJSON({
308
+ includeRelatedEntityData: false,
309
+ excludeFields: [],
310
+ omitEmptyStrings: false,
311
+ relatedEntityList: [],
312
+ omitNullValues: false,
313
+ oldValues: false
314
+ });
315
+ if (await altKeyResult.Delete()) {
316
+ result.Success = true;
317
+ }
318
+ else {
319
+ result.ErrorMessage = 'Failed to delete the item :' + entityObject.LatestResult.Message;
320
+ }
321
+ }
322
+ }
323
+ else if (await entityObject.InnerLoad(pk)) {
324
+ // pass back the full record as it was JUST BEFORE the delete, often quite useful on the other end
325
+ result.RecordJSON = await entityObject.GetDataObjectJSON({
326
+ includeRelatedEntityData: false,
327
+ excludeFields: [],
328
+ omitEmptyStrings: false,
329
+ relatedEntityList: [],
330
+ omitNullValues: false,
331
+ oldValues: false
332
+ });
333
+ if (await entityObject.Delete()) {
334
+ result.Success = true;
335
+ }
336
+ else {
337
+ result.ErrorMessage = 'Failed to delete the item :' + entityObject.LatestResult.Message;
338
+ }
339
+ }
340
+ else {
341
+ result.ErrorMessage = 'Failed to load the item, it is possible the record with the specified primary key does not exist';
351
342
  }
352
- }
353
- } else if (await entityObject.InnerLoad(pk)) {
354
- // pass back the full record as it was JUST BEFORE the delete, often quite useful on the other end
355
- result.RecordJSON = await entityObject.GetDataObjectJSON({
356
- includeRelatedEntityData: false,
357
- excludeFields: [],
358
- omitEmptyStrings: false,
359
- relatedEntityList: [],
360
- omitNullValues: false,
361
- oldValues: false,
362
- });
363
- if (await entityObject.Delete()) {
364
- result.Success = true;
365
- } else {
366
- result.ErrorMessage = 'Failed to delete the item :' + entityObject.LatestResult.Message;
367
- }
368
- } else {
369
- result.ErrorMessage = 'Failed to load the item, it is possible the record with the specified primary key does not exist';
370
343
  }
371
- }
372
344
 
373
- protected async SyncSingleItemCreate(entityObject: BaseEntity, fieldValues: any, result: ActionItemOutputType, userPayload: UserPayload) {
374
- // 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
375
- const noPKValues = { ...fieldValues };
376
- entityObject.EntityInfo.PrimaryKeys.forEach((pk) => {
377
- delete noPKValues[pk.Name];
378
- });
379
- entityObject.SetMany(noPKValues);
380
- if (await entityObject.Save()) {
381
- result.Success = true;
382
- result.PrimaryKey = new CompositeKey(entityObject.PrimaryKeys.map((pk) => ({ FieldName: pk.Name, Value: pk.Value })));
383
- // pass back the full record AFTER the sync, that's often quite useful on the other end
384
- result.RecordJSON = await entityObject.GetDataObjectJSON({
385
- includeRelatedEntityData: false,
386
- excludeFields: [],
387
- omitEmptyStrings: false,
388
- relatedEntityList: [],
389
- omitNullValues: false,
390
- oldValues: false,
391
- });
392
- } else {
393
- result.ErrorMessage = 'Failed to create the item :' + entityObject.LatestResult.Message;
345
+ protected async SyncSingleItemCreate(entityObject: BaseEntity, fieldValues: any, result: ActionItemOutputType, userPayload: UserPayload) {
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
+ const noPKValues = {...fieldValues};
348
+ entityObject.EntityInfo.PrimaryKeys.forEach((pk) => {
349
+ delete noPKValues[pk.Name];
350
+ });
351
+ entityObject.SetMany(noPKValues);
352
+ if (await entityObject.Save()) {
353
+ result.Success = true;
354
+ result.PrimaryKey = new CompositeKey(entityObject.PrimaryKeys.map((pk) => ({FieldName: pk.Name, Value: pk.Value})));
355
+ // pass back the full record AFTER the sync, that's often quite useful on the other end
356
+ result.RecordJSON = await entityObject.GetDataObjectJSON({
357
+ includeRelatedEntityData: false,
358
+ excludeFields: [],
359
+ omitEmptyStrings: false,
360
+ relatedEntityList: [],
361
+ omitNullValues: false,
362
+ oldValues: false
363
+ });
364
+ }
365
+ else {
366
+ result.ErrorMessage = 'Failed to create the item :' + entityObject.LatestResult.Message;
367
+ }
394
368
  }
395
- }
396
369
 
397
- protected async SyncSingleItemUpdate(
398
- entityObject: BaseEntity,
399
- pk: CompositeKey,
400
- ak: CompositeKey,
401
- fieldValues: any,
402
- result: ActionItemOutputType,
403
- userPayload: UserPayload
404
- ) {
405
- if (!pk || pk.KeyValuePairs.length === 0) {
406
- // no pk, attempt to load by alt key
407
- const altKeyResult = await this.LoadFromAlternateKey(entityObject.EntityInfo.Name, ak, entityObject.ContextCurrentUser);
408
- if (!altKeyResult) {
409
- // no record found, create a new one
410
- result.ErrorMessage = 'Failed to load the item, it is possible the record with the specified alternate key does not exist';
411
- } else {
412
- await this.InnerSyncSingleItemUpdate(altKeyResult, fieldValues, result, userPayload);
413
- }
414
- } else if (await entityObject.InnerLoad(pk)) {
415
- await this.InnerSyncSingleItemUpdate(entityObject, fieldValues, result, userPayload);
416
- } else {
417
- // failed to load the item
418
- result.ErrorMessage = 'Failed to load the item, it is possible the record with the specified primary key does not exist';
370
+ protected async SyncSingleItemUpdate(entityObject: BaseEntity, pk: CompositeKey, ak: CompositeKey, fieldValues: any, result: ActionItemOutputType, userPayload: UserPayload) {
371
+ if (!pk || pk.KeyValuePairs.length === 0) {
372
+ // no pk, attempt to load by alt key
373
+ const altKeyResult = await this.LoadFromAlternateKey(entityObject.EntityInfo.Name, ak, entityObject.ContextCurrentUser);
374
+ if (!altKeyResult) {
375
+ // no record found, create a new one
376
+ result.ErrorMessage = 'Failed to load the item, it is possible the record with the specified alternate key does not exist';
377
+ }
378
+ else {
379
+ await this.InnerSyncSingleItemUpdate(altKeyResult, fieldValues, result, userPayload);
380
+ }
381
+ }
382
+ else if (await entityObject.InnerLoad(pk)) {
383
+ await this.InnerSyncSingleItemUpdate(entityObject, fieldValues, result, userPayload);
384
+ }
385
+ else {
386
+ // failed to load the item
387
+ result.ErrorMessage = 'Failed to load the item, it is possible the record with the specified primary key does not exist';
388
+ }
419
389
  }
420
- }
421
390
 
422
- protected async InnerSyncSingleItemUpdate(
423
- entityObject: BaseEntity,
424
- fieldValues: any,
425
- result: ActionItemOutputType,
426
- userPayload: UserPayload
427
- ) {
428
- entityObject.SetMany(fieldValues);
429
- if (await entityObject.Save()) {
430
- result.Success = true;
431
- if (!result.PrimaryKey || result.PrimaryKey.KeyValuePairs.length === 0) {
432
- result.PrimaryKey = new CompositeKey(entityObject.PrimaryKeys.map((pk) => ({ FieldName: pk.Name, Value: pk.Value })));
433
- }
434
- // pass back the full record AFTER the sync, that's often quite useful on the other end
435
- result.RecordJSON = await entityObject.GetDataObjectJSON({
436
- includeRelatedEntityData: false,
437
- excludeFields: [],
438
- omitEmptyStrings: false,
439
- relatedEntityList: [],
440
- omitNullValues: false,
441
- oldValues: false,
442
- });
443
- } else {
444
- result.ErrorMessage = 'Failed to update the item :' + entityObject.LatestResult.Message;
391
+ protected async InnerSyncSingleItemUpdate(entityObject: BaseEntity, fieldValues: any, result: ActionItemOutputType, userPayload: UserPayload) {
392
+ entityObject.SetMany(fieldValues);
393
+ if (await entityObject.Save()) {
394
+ result.Success = true;
395
+ if (!result.PrimaryKey || result.PrimaryKey.KeyValuePairs.length === 0) {
396
+ result.PrimaryKey = new CompositeKey(entityObject.PrimaryKeys.map((pk) => ({FieldName: pk.Name, Value: pk.Value})));
397
+ }
398
+ // pass back the full record AFTER the sync, that's often quite useful on the other end
399
+ result.RecordJSON = await entityObject.GetDataObjectJSON({
400
+ includeRelatedEntityData: false,
401
+ excludeFields: [],
402
+ omitEmptyStrings: false,
403
+ relatedEntityList: [],
404
+ omitNullValues: false,
405
+ oldValues: false
406
+ });
407
+ }
408
+ else {
409
+ result.ErrorMessage = 'Failed to update the item :' + entityObject.LatestResult.Message;
410
+ }
445
411
  }
446
- }
447
412
  }
413
+