@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,203 +1,207 @@
1
- import { LogError, Metadata, RunView, RunViewParams, RunViewResult, UserInfo } from '@memberjunction/global';
1
+ import {
2
+ LogError, Metadata, RunView, RunViewParams,
3
+ RunViewResult, UserInfo
4
+ } from '@memberjunction/core';
2
5
 
3
6
  /**
4
7
  * View Operations Implementation for REST endpoints
5
8
  * These functions handle running views through the REST API
6
9
  */
7
10
  export class ViewOperationsHandler {
8
- /**
9
- * Run a view and return results
10
- */
11
- static async runView(params: RunViewParams, user: UserInfo): Promise<{ success: boolean; result?: RunViewResult; error?: string }> {
12
- try {
13
- // Validate entity exists
14
- const md = new Metadata();
15
- const entity = md.Entities.find((e) => e.Name === params.EntityName);
16
- if (!entity) {
17
- return {
18
- success: false,
19
- error: `Entity '${params.EntityName}' not found`,
20
- };
21
- }
22
-
23
- // Check read permission
24
- const permissions = entity.GetUserPermisions(user);
25
- if (!permissions.CanRead) {
26
- return {
27
- success: false,
28
- error: `User ${user.Name} does not have permission to read ${params.EntityName} records`,
29
- };
30
- }
31
-
32
- // Sanitize and validate parameters
33
- this.sanitizeRunViewParams(params);
34
-
35
- // Execute the view
36
- const runView = new RunView();
37
- const result = await runView.RunView(params, user);
38
-
39
- return { success: true, result };
40
- } catch (error) {
41
- LogError(error);
42
- return { success: false, error: (error as Error)?.message || 'Unknown error' };
43
- }
44
- }
45
-
46
- /**
47
- * Run multiple views in batch
48
- */
49
- static async runViews(
50
- paramsArray: RunViewParams[],
51
- user: UserInfo
52
- ): Promise<{ success: boolean; results?: RunViewResult[]; error?: string }> {
53
- try {
54
- // Validate and sanitize each set of parameters
55
- const md = new Metadata();
56
- for (const params of paramsArray) {
57
- // Validate entity exists
58
- const entity = md.Entities.find((e) => e.Name === params.EntityName);
59
- if (!entity) {
60
- return {
61
- success: false,
62
- error: `Entity '${params.EntityName}' not found`,
63
- };
64
- }
65
-
66
- // Check read permission
67
- const permissions = entity.GetUserPermisions(user);
68
- if (!permissions.CanRead) {
69
- return {
70
- success: false,
71
- error: `User ${user.Name} does not have permission to read ${params.EntityName} records`,
72
- };
11
+ /**
12
+ * Run a view and return results
13
+ */
14
+ static async runView(params: RunViewParams, user: UserInfo): Promise<{ success: boolean, result?: RunViewResult, error?: string }> {
15
+ try {
16
+ // Validate entity exists
17
+ const md = new Metadata();
18
+ const entity = md.Entities.find(e => e.Name === params.EntityName);
19
+ if (!entity) {
20
+ return {
21
+ success: false,
22
+ error: `Entity '${params.EntityName}' not found`
23
+ };
24
+ }
25
+
26
+ // Check read permission
27
+ const permissions = entity.GetUserPermisions(user);
28
+ if (!permissions.CanRead) {
29
+ return {
30
+ success: false,
31
+ error: `User ${user.Name} does not have permission to read ${params.EntityName} records`
32
+ };
33
+ }
34
+
35
+ // Sanitize and validate parameters
36
+ this.sanitizeRunViewParams(params);
37
+
38
+ // Execute the view
39
+ const runView = new RunView();
40
+ const result = await runView.RunView(params, user);
41
+
42
+ return { success: true, result };
43
+ } catch (error) {
44
+ LogError(error);
45
+ return { success: false, error: (error as Error)?.message || 'Unknown error' };
73
46
  }
74
-
75
- // Sanitize parameters
76
- this.sanitizeRunViewParams(params);
77
- }
78
-
79
- // Execute the views
80
- const runView = new RunView();
81
- const results = await runView.RunViews(paramsArray, user);
82
-
83
- return { success: true, results };
84
- } catch (error) {
85
- LogError(error);
86
- return { success: false, error: (error as Error)?.message || 'Unknown error' };
87
- }
88
- }
89
-
90
- /**
91
- * List entities with optional filtering
92
- */
93
- static async listEntities(params: RunViewParams, user: UserInfo): Promise<RunViewResult> {
94
- try {
95
- // Check entity exists and user has permission
96
- const md = new Metadata();
97
- const entity = md.Entities.find((e) => e.Name === params.EntityName);
98
- if (!entity) {
99
- throw new Error(`Entity '${params.EntityName}' not found`);
100
- }
101
-
102
- const permissions = entity.GetUserPermisions(user);
103
- if (!permissions.CanRead) {
104
- throw new Error(`User ${user.Name} does not have permission to read ${params.EntityName} records`);
105
- }
106
-
107
- // Sanitize and validate parameters
108
- this.sanitizeRunViewParams(params);
109
-
110
- // Execute the view
111
- const runView = new RunView();
112
- return await runView.RunView(params, user);
113
- } catch (error) {
114
- LogError(error);
115
- throw error;
116
- }
117
- }
118
-
119
- /**
120
- * Get available views for an entity
121
- */
122
- static async getEntityViews(entityName: string, user: UserInfo): Promise<{ success: boolean; views?: any[]; error?: string }> {
123
- try {
124
- // Validate entity exists
125
- const md = new Metadata();
126
- const entity = md.Entities.find((e) => e.Name === entityName);
127
- if (!entity) {
128
- return {
129
- success: false,
130
- error: `Entity '${entityName}' not found`,
131
- };
132
- }
133
-
134
- // Check read permission
135
- const permissions = entity.GetUserPermisions(user);
136
- if (!permissions.CanRead) {
137
- return {
138
- success: false,
139
- error: `User ${user.Name} does not have permission to read ${entityName} records`,
140
- };
141
- }
142
-
143
- // Run a view to get the available views
144
- const params: RunViewParams = {
145
- EntityName: 'User Views',
146
- ExtraFilter: `Entity = '${entityName}'`,
147
- };
148
-
149
- const runView = new RunView();
150
- const result = await runView.RunView(params, user);
151
-
152
- if (!result.Success) {
153
- return {
154
- success: false,
155
- error: result.ErrorMessage || 'Failed to retrieve views',
156
- };
157
- }
158
-
159
- // Format the view data
160
- const views = result.Results.map((view) => ({
161
- ID: view.ID,
162
- Name: view.Name,
163
- Description: view.Description,
164
- IsShared: view.IsShared,
165
- CreatedAt: view.CreatedAt,
166
- }));
167
-
168
- return { success: true, views };
169
- } catch (error) {
170
- LogError(error);
171
- return { success: false, error: (error as Error)?.message || 'Unknown error' };
172
47
  }
173
- }
174
-
175
- /**
176
- * Sanitize and validate RunViewParams
177
- */
178
- private static sanitizeRunViewParams(params: RunViewParams): void {
179
- // Ensure EntityName is provided
180
- if (!params.EntityName) {
181
- throw new Error('EntityName is required');
182
- }
183
-
184
- // Convert string arrays if they came in as comma-separated strings
185
- if (params.Fields && typeof params.Fields === 'string') {
186
- params.Fields = (params.Fields as string).split(',');
48
+
49
+ /**
50
+ * Run multiple views in batch
51
+ */
52
+ static async runViews(paramsArray: RunViewParams[], user: UserInfo): Promise<{ success: boolean, results?: RunViewResult[], error?: string }> {
53
+ try {
54
+ // Validate and sanitize each set of parameters
55
+ const md = new Metadata();
56
+ for (const params of paramsArray) {
57
+ // Validate entity exists
58
+ const entity = md.Entities.find(e => e.Name === params.EntityName);
59
+ if (!entity) {
60
+ return {
61
+ success: false,
62
+ error: `Entity '${params.EntityName}' not found`
63
+ };
64
+ }
65
+
66
+ // Check read permission
67
+ const permissions = entity.GetUserPermisions(user);
68
+ if (!permissions.CanRead) {
69
+ return {
70
+ success: false,
71
+ error: `User ${user.Name} does not have permission to read ${params.EntityName} records`
72
+ };
73
+ }
74
+
75
+ // Sanitize parameters
76
+ this.sanitizeRunViewParams(params);
77
+ }
78
+
79
+ // Execute the views
80
+ const runView = new RunView();
81
+ const results = await runView.RunViews(paramsArray, user);
82
+
83
+ return { success: true, results };
84
+ } catch (error) {
85
+ LogError(error);
86
+ return { success: false, error: (error as Error)?.message || 'Unknown error' };
87
+ }
187
88
  }
188
-
189
- // Sanitize numeric values
190
- if (params.MaxRows !== undefined) {
191
- params.MaxRows = typeof params.MaxRows === 'string' ? parseInt(params.MaxRows as string) : params.MaxRows;
89
+
90
+ /**
91
+ * List entities with optional filtering
92
+ */
93
+ static async listEntities(params: RunViewParams, user: UserInfo): Promise<RunViewResult> {
94
+ try {
95
+ // Check entity exists and user has permission
96
+ const md = new Metadata();
97
+ const entity = md.Entities.find(e => e.Name === params.EntityName);
98
+ if (!entity) {
99
+ throw new Error(`Entity '${params.EntityName}' not found`);
100
+ }
101
+
102
+ const permissions = entity.GetUserPermisions(user);
103
+ if (!permissions.CanRead) {
104
+ throw new Error(`User ${user.Name} does not have permission to read ${params.EntityName} records`);
105
+ }
106
+
107
+ // Sanitize and validate parameters
108
+ this.sanitizeRunViewParams(params);
109
+
110
+ // Execute the view
111
+ const runView = new RunView();
112
+ return await runView.RunView(params, user);
113
+ } catch (error) {
114
+ LogError(error);
115
+ throw error;
116
+ }
192
117
  }
193
-
194
- if (params.StartRow !== undefined) {
195
- params.StartRow = typeof params.StartRow === 'string' ? parseInt(params.StartRow as string) : params.StartRow;
118
+
119
+ /**
120
+ * Get available views for an entity
121
+ */
122
+ static async getEntityViews(entityName: string, user: UserInfo): Promise<{ success: boolean, views?: any[], error?: string }> {
123
+ try {
124
+ // Validate entity exists
125
+ const md = new Metadata();
126
+ const entity = md.Entities.find(e => e.Name === entityName);
127
+ if (!entity) {
128
+ return {
129
+ success: false,
130
+ error: `Entity '${entityName}' not found`
131
+ };
132
+ }
133
+
134
+ // Check read permission
135
+ const permissions = entity.GetUserPermisions(user);
136
+ if (!permissions.CanRead) {
137
+ return {
138
+ success: false,
139
+ error: `User ${user.Name} does not have permission to read ${entityName} records`
140
+ };
141
+ }
142
+
143
+ // Run a view to get the available views
144
+ const params: RunViewParams = {
145
+ EntityName: 'User Views',
146
+ ExtraFilter: `Entity = '${entityName}'`
147
+ };
148
+
149
+ const runView = new RunView();
150
+ const result = await runView.RunView(params, user);
151
+
152
+ if (!result.Success) {
153
+ return {
154
+ success: false,
155
+ error: result.ErrorMessage || 'Failed to retrieve views'
156
+ };
157
+ }
158
+
159
+ // Format the view data
160
+ const views = result.Results.map(view => ({
161
+ ID: view.ID,
162
+ Name: view.Name,
163
+ Description: view.Description,
164
+ IsShared: view.IsShared,
165
+ CreatedAt: view.CreatedAt
166
+ }));
167
+
168
+ return { success: true, views };
169
+ } catch (error) {
170
+ LogError(error);
171
+ return { success: false, error: (error as Error)?.message || 'Unknown error' };
172
+ }
196
173
  }
197
-
198
- // Default ResultType if not provided
199
- if (!params.ResultType) {
200
- params.ResultType = 'simple';
174
+
175
+ /**
176
+ * Sanitize and validate RunViewParams
177
+ */
178
+ private static sanitizeRunViewParams(params: RunViewParams): void {
179
+ // Ensure EntityName is provided
180
+ if (!params.EntityName) {
181
+ throw new Error('EntityName is required');
182
+ }
183
+
184
+ // Convert string arrays if they came in as comma-separated strings
185
+ if (params.Fields && typeof params.Fields === 'string') {
186
+ params.Fields = (params.Fields as string).split(',');
187
+ }
188
+
189
+ // Sanitize numeric values
190
+ if (params.MaxRows !== undefined) {
191
+ params.MaxRows = typeof params.MaxRows === 'string'
192
+ ? parseInt(params.MaxRows as string)
193
+ : params.MaxRows;
194
+ }
195
+
196
+ if (params.StartRow !== undefined) {
197
+ params.StartRow = typeof params.StartRow === 'string'
198
+ ? parseInt(params.StartRow as string)
199
+ : params.StartRow;
200
+ }
201
+
202
+ // Default ResultType if not provided
203
+ if (!params.ResultType) {
204
+ params.ResultType = 'simple';
205
+ }
201
206
  }
202
- }
203
- }
207
+ }
@@ -1,4 +1,4 @@
1
- import { LogStatus, LogError } from '@memberjunction/global';
1
+ import { LogStatus, LogError } from '@memberjunction/core';
2
2
  import { SQLServerDataProvider, SQLServerProviderConfigData, UserCache } from '@memberjunction/sqlserver-dataprovider';
3
3
  import { GetReadWriteDataSource } from '../util.js';
4
4
  import { AskSkipResolver } from '../resolvers/AskSkipResolver.js';
@@ -13,17 +13,22 @@ import { mj_core_schema } from '../config.js';
13
13
  */
14
14
  export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler> {
15
15
  // private intervalId: NodeJS.Timeout | null = null;
16
+
16
17
  // // Track executions by organization ID instead of a global flag
17
18
  // private runningOrganizations: Map<string, { startTime: Date, learningCycleId: string }> = new Map();
19
+
18
20
  // private lastRunTime: Date | null = null;
19
21
  // private dataSources: DataSourceInfo[] = [];
22
+
20
23
  // // Protected constructor to enforce singleton pattern via BaseSingleton
21
24
  // protected constructor() {
22
25
  // super();
23
26
  // }
27
+
24
28
  // public static get Instance(): LearningCycleScheduler {
25
29
  // return super.getInstance<LearningCycleScheduler>();
26
30
  // }
31
+
27
32
  // /**
28
33
  // * Set the data sources for the scheduler
29
34
  // * @param dataSources Array of data sources
@@ -31,6 +36,7 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
31
36
  // public setDataSources(dataSources: DataSourceInfo[]): void {
32
37
  // this.dataSources = dataSources;
33
38
  // }
39
+
34
40
  // /**
35
41
  // * Start the scheduler with the specified interval in minutes
36
42
  // * @param intervalMinutes The interval in minutes between runs
@@ -38,16 +44,19 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
38
44
  // */
39
45
  // public start(intervalMinutes: number = 60): void {
40
46
  // LogStatus(`Starting learning cycle scheduler with interval of ${intervalMinutes} minutes`);
47
+
41
48
  // // Set up the interval for recurring calls
42
49
  // const intervalMs = intervalMinutes * 60 * 1000;
43
50
  // this.intervalId = setInterval(() => {
44
51
  // this.runLearningCycle()
45
52
  // .catch(error => LogError(`Error in scheduled learning cycle: ${error}`));
46
53
  // }, intervalMs);
54
+
47
55
  // // Start learning cycle immediately upon the server start
48
56
  // this.runLearningCycle()
49
57
  // .catch(error => LogError(`Error in initial learning cycle: ${error}`));
50
58
  // }
59
+
51
60
  // /**
52
61
  // * Stop the scheduler
53
62
  // */
@@ -58,27 +67,33 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
58
67
  // LogStatus('Learning cycle scheduler stopped');
59
68
  // }
60
69
  // }
70
+
61
71
  // /**
62
72
  // * Run the learning cycle if it's not already running
63
73
  // * @returns A promise that resolves when the learning cycle completes
64
74
  // */
65
75
  // public async runLearningCycle(): Promise<boolean> {
66
76
  // const startTime = new Date();
77
+
67
78
  // try {
68
79
  // // Make sure we have data sources
69
80
  // if (!this.dataSources || this.dataSources.length === 0) {
70
81
  // throw new Error('No data sources available for the learning cycle');
71
82
  // }
83
+
72
84
  // const dataSource = GetReadWriteDataSource(this.dataSources);
85
+
73
86
  // // Get system user for operation
74
87
  // const systemUser = await getSystemUser(dataSource);
75
88
  // if (!systemUser) {
76
89
  // throw new Error('System user not found');
77
90
  // }
91
+
78
92
  // // Create context for the resolver
79
93
  // const config = new SQLServerProviderConfigData(dataSource, mj_core_schema, 0, undefined, undefined, false);
80
94
  // const p = new SQLServerDataProvider();
81
95
  // await p.Config(config);
96
+
82
97
  // const context: AppContext = {
83
98
  // dataSource: dataSource,
84
99
  // dataSources: this.dataSources,
@@ -90,15 +105,19 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
90
105
  // },
91
106
  // providers: [{provider: p, type: 'Read-Write'}]
92
107
  // };
108
+
93
109
  // // Execute the learning cycle
94
110
  // const skipResolver = new AskSkipResolver();
95
111
  // const result = await skipResolver.ExecuteAskSkipLearningCycle(
96
112
  // context,
97
113
  // false // forceEntityRefresh
98
114
  // );
115
+
99
116
  // const endTime = new Date();
100
117
  // const elapsedMs = endTime.getTime() - startTime.getTime();
118
+
101
119
  // this.lastRunTime = startTime;
120
+
102
121
  // if (result.learningCycleSkipped) {
103
122
  // // skipped the learning cycle - no messages to process, already logged..
104
123
  // return true;
@@ -106,7 +125,7 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
106
125
  // else if (result.success) {
107
126
  // LogStatus(`Learning cycle completed successfully in ${elapsedMs}ms`);
108
127
  // return true;
109
- // }
128
+ // }
110
129
  // else {
111
130
  // LogError(`Learning cycle failed after ${elapsedMs}ms: ${result.error}`);
112
131
  // return false;
@@ -114,8 +133,9 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
114
133
  // } catch (error) {
115
134
  // LogError(`Error executing learning cycle: ${error}`);
116
135
  // return false;
117
- // }
136
+ // }
118
137
  // }
138
+
119
139
  // /**
120
140
  // * Get the current status of the scheduler
121
141
  // */
@@ -131,6 +151,7 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
131
151
  // }))
132
152
  // };
133
153
  // }
154
+
134
155
  // /**
135
156
  // * Checks if an organization is currently running a learning cycle
136
157
  // * @param organizationId The organization ID to check
@@ -140,19 +161,23 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
140
161
  // organizationId: string
141
162
  // ): { isRunning: boolean, startTime?: Date, learningCycleId?: string, runningForMinutes?: number } {
142
163
  // const runningInfo = this.runningOrganizations.get(organizationId);
164
+
143
165
  // if (runningInfo) {
144
166
  // // Check if it's been running too long and should be considered stalled
145
167
  // const now = new Date();
146
168
  // const elapsedMinutes = (now.getTime() - runningInfo.startTime.getTime()) / (1000 * 60);
147
- // return {
148
- // isRunning: true,
169
+
170
+ // return {
171
+ // isRunning: true,
149
172
  // startTime: runningInfo.startTime,
150
173
  // learningCycleId: runningInfo.learningCycleId,
151
174
  // runningForMinutes: elapsedMinutes
152
175
  // };
153
176
  // }
177
+
154
178
  // return { isRunning: false };
155
179
  // }
180
+
156
181
  // /**
157
182
  // * Registers an organization as running a learning cycle
158
183
  // * @param organizationId The organization ID to register
@@ -162,16 +187,20 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
162
187
  // public registerRunningCycle(organizationId: string, learningCycleId: string): boolean {
163
188
  // // First check if already running
164
189
  // const { isRunning } = this.isOrganizationRunningCycle(organizationId);
190
+
165
191
  // if (isRunning) {
166
192
  // return false;
167
193
  // }
194
+
168
195
  // // Register the organization as running a cycle
169
196
  // this.runningOrganizations.set(organizationId, {
170
197
  // startTime: new Date(),
171
198
  // learningCycleId
172
199
  // });
200
+
173
201
  // return true;
174
202
  // }
203
+
175
204
  // /**
176
205
  // * Unregisters an organization after its learning cycle completes
177
206
  // * @param organizationId The organization ID to unregister
@@ -182,8 +211,10 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
182
211
  // this.runningOrganizations.delete(organizationId);
183
212
  // return true;
184
213
  // }
214
+
185
215
  // return false;
186
216
  // }
217
+
187
218
  // /**
188
219
  // * Manually execute a learning cycle run for testing purposes
189
220
  // * This is intended for debugging/testing only and will force a run
@@ -194,16 +225,20 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
194
225
  // public async manuallyExecuteLearningCycle(organizationId?: string): Promise<boolean> {
195
226
  // try {
196
227
  // LogStatus('🧪 Manually executing learning cycle for testing...');
228
+
197
229
  // // If an organization ID is provided, register it as running
198
230
  // const learningCycleId = `manual_${Date.now()}`;
199
231
  // let orgRegistered = false;
232
+
200
233
  // if (organizationId) {
201
234
  // // Check if already running
202
235
  // const runningStatus = this.isOrganizationRunningCycle(organizationId);
236
+
203
237
  // if (runningStatus.isRunning) {
204
238
  // LogError(`Organization ${organizationId} is already running a learning cycle. Cannot start a new one.`);
205
239
  // return false;
206
240
  // }
241
+
207
242
  // // Register this organization
208
243
  // orgRegistered = this.registerRunningCycle(organizationId, learningCycleId);
209
244
  // if (!orgRegistered) {
@@ -211,36 +246,42 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
211
246
  // return false;
212
247
  // }
213
248
  // }
249
+
214
250
  // // Run the learning cycle
215
251
  // const result = await this.runLearningCycle();
216
252
  // LogStatus(`🧪 Manual learning cycle execution completed with result: ${result ? 'Success' : 'Failed'}`);
253
+
217
254
  // // Unregister the organization if it was registered
218
255
  // if (organizationId && orgRegistered) {
219
256
  // this.unregisterRunningCycle(organizationId);
220
257
  // }
258
+
221
259
  // return result;
222
260
  // } catch (error) {
223
261
  // // Make sure to unregister on error
224
262
  // if (organizationId && this.runningOrganizations.has(organizationId)) {
225
263
  // this.unregisterRunningCycle(organizationId);
226
264
  // }
265
+
227
266
  // LogError(`Error in manual learning cycle execution: ${error}`);
228
267
  // return false;
229
268
  // }
230
269
  // }
270
+
231
271
  // /**
232
272
  // * Force stop a running learning cycle for an organization
233
273
  // * @param organizationId The organization ID to stop the cycle for
234
274
  // * @returns Information about the stopped cycle
235
275
  // */
236
- // public stopLearningCycleForOrganization(organizationId: string): {
237
- // success: boolean,
276
+ // public stopLearningCycleForOrganization(organizationId: string): {
277
+ // success: boolean,
238
278
  // message: string,
239
279
  // wasRunning: boolean,
240
280
  // cycleDetails?: { learningCycleId: string, startTime: Date, runningForMinutes: number }
241
281
  // } {
242
282
  // // Check if this organization has a running cycle
243
283
  // const runningStatus = this.isOrganizationRunningCycle(organizationId);
284
+
244
285
  // if (!runningStatus.isRunning) {
245
286
  // return {
246
287
  // success: false,
@@ -248,12 +289,15 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
248
289
  // wasRunning: false
249
290
  // };
250
291
  // }
292
+
251
293
  // // Capture details before unregistering
252
294
  // const startTime = runningStatus.startTime!;
253
295
  // const learningCycleId = runningStatus.learningCycleId!;
254
296
  // const runningForMinutes = runningStatus.runningForMinutes!;
297
+
255
298
  // // Unregister the organization
256
299
  // const unregistered = this.unregisterRunningCycle(organizationId);
300
+
257
301
  // if (unregistered) {
258
302
  // return {
259
303
  // success: true,
@@ -273,4 +317,4 @@ export class LearningCycleScheduler extends BaseSingleton<LearningCycleScheduler
273
317
  // };
274
318
  // }
275
319
  // }
276
- }
320
+ }