@symbo.ls/sdk 3.1.2 → 3.2.6

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 (187) hide show
  1. package/README.md +143 -2
  2. package/dist/cjs/config/environment.js +98 -30
  3. package/dist/cjs/index.js +144 -24
  4. package/dist/cjs/services/AdminService.js +351 -0
  5. package/dist/cjs/services/AuthService.js +738 -305
  6. package/dist/cjs/services/BaseService.js +158 -6
  7. package/dist/cjs/services/BranchService.js +484 -0
  8. package/dist/cjs/services/CollabService.js +743 -0
  9. package/dist/cjs/services/DnsService.js +340 -0
  10. package/dist/cjs/services/FeatureFlagService.js +175 -0
  11. package/dist/cjs/services/FileService.js +201 -0
  12. package/dist/cjs/services/IntegrationService.js +538 -0
  13. package/dist/cjs/services/MetricsService.js +62 -0
  14. package/dist/cjs/services/PaymentService.js +271 -0
  15. package/dist/cjs/services/PlanService.js +426 -0
  16. package/dist/cjs/services/ProjectService.js +1207 -0
  17. package/dist/cjs/services/PullRequestService.js +503 -0
  18. package/dist/cjs/services/ScreenshotService.js +304 -0
  19. package/dist/cjs/services/SubscriptionService.js +396 -0
  20. package/dist/cjs/services/TrackingService.js +661 -0
  21. package/dist/cjs/services/WaitlistService.js +148 -0
  22. package/dist/cjs/services/index.js +64 -16
  23. package/dist/cjs/state/RootStateManager.js +65 -0
  24. package/dist/cjs/state/rootEventBus.js +74 -0
  25. package/dist/cjs/utils/CollabClient.js +223 -0
  26. package/dist/cjs/utils/TokenManager.js +78 -30
  27. package/dist/cjs/utils/changePreprocessor.js +199 -0
  28. package/dist/cjs/utils/jsonDiff.js +145 -0
  29. package/dist/cjs/utils/ordering.js +309 -0
  30. package/dist/cjs/utils/services.js +301 -103
  31. package/dist/cjs/utils/validation.js +0 -3
  32. package/dist/esm/config/environment.js +98 -30
  33. package/dist/esm/index.js +49505 -8718
  34. package/dist/esm/services/AdminService.js +1132 -0
  35. package/dist/esm/services/AuthService.js +1493 -386
  36. package/dist/esm/services/BaseService.js +757 -6
  37. package/dist/esm/services/BranchService.js +1265 -0
  38. package/dist/esm/services/CollabService.js +26895 -0
  39. package/dist/esm/services/DnsService.js +1121 -0
  40. package/dist/esm/services/FeatureFlagService.js +956 -0
  41. package/dist/esm/services/FileService.js +982 -0
  42. package/dist/esm/services/IntegrationService.js +1319 -0
  43. package/dist/esm/services/MetricsService.js +843 -0
  44. package/dist/esm/services/PaymentService.js +1052 -0
  45. package/dist/esm/services/PlanService.js +1207 -0
  46. package/dist/esm/services/ProjectService.js +2526 -0
  47. package/dist/esm/services/PullRequestService.js +1284 -0
  48. package/dist/esm/services/ScreenshotService.js +1085 -0
  49. package/dist/esm/services/SubscriptionService.js +1177 -0
  50. package/dist/esm/services/TrackingService.js +18454 -0
  51. package/dist/esm/services/WaitlistService.js +929 -0
  52. package/dist/esm/services/index.js +49062 -8569
  53. package/dist/esm/state/RootStateManager.js +90 -0
  54. package/dist/esm/state/rootEventBus.js +56 -0
  55. package/dist/esm/utils/CollabClient.js +18889 -0
  56. package/dist/esm/utils/TokenManager.js +78 -30
  57. package/dist/esm/utils/changePreprocessor.js +542 -0
  58. package/dist/esm/utils/jsonDiff.js +7011 -0
  59. package/dist/esm/utils/ordering.js +291 -0
  60. package/dist/esm/utils/services.js +301 -103
  61. package/dist/esm/utils/validation.js +116 -50
  62. package/dist/node/config/environment.js +98 -30
  63. package/dist/node/index.js +175 -32
  64. package/dist/node/services/AdminService.js +332 -0
  65. package/dist/node/services/AuthService.js +742 -310
  66. package/dist/node/services/BaseService.js +148 -6
  67. package/dist/node/services/BranchService.js +465 -0
  68. package/dist/node/services/CollabService.js +724 -0
  69. package/dist/node/services/DnsService.js +321 -0
  70. package/dist/node/services/FeatureFlagService.js +156 -0
  71. package/dist/node/services/FileService.js +182 -0
  72. package/dist/node/services/IntegrationService.js +519 -0
  73. package/dist/node/services/MetricsService.js +43 -0
  74. package/dist/node/services/PaymentService.js +252 -0
  75. package/dist/node/services/PlanService.js +407 -0
  76. package/dist/node/services/ProjectService.js +1188 -0
  77. package/dist/node/services/PullRequestService.js +484 -0
  78. package/dist/node/services/ScreenshotService.js +285 -0
  79. package/dist/node/services/SubscriptionService.js +377 -0
  80. package/dist/node/services/TrackingService.js +632 -0
  81. package/dist/node/services/WaitlistService.js +129 -0
  82. package/dist/node/services/index.js +64 -16
  83. package/dist/node/state/RootStateManager.js +36 -0
  84. package/dist/node/state/rootEventBus.js +55 -0
  85. package/dist/node/utils/CollabClient.js +194 -0
  86. package/dist/node/utils/TokenManager.js +78 -30
  87. package/dist/node/utils/changePreprocessor.js +180 -0
  88. package/dist/node/utils/jsonDiff.js +116 -0
  89. package/dist/node/utils/ordering.js +290 -0
  90. package/dist/node/utils/services.js +301 -103
  91. package/dist/node/utils/validation.js +0 -3
  92. package/package.json +39 -21
  93. package/src/config/environment.js +99 -28
  94. package/src/index.js +181 -36
  95. package/src/services/AdminService.js +374 -0
  96. package/src/services/AuthService.js +874 -328
  97. package/src/services/BaseService.js +166 -6
  98. package/src/services/BranchService.js +536 -0
  99. package/src/services/CollabService.js +900 -0
  100. package/src/services/DnsService.js +366 -0
  101. package/src/services/FeatureFlagService.js +174 -0
  102. package/src/services/FileService.js +213 -0
  103. package/src/services/IntegrationService.js +548 -0
  104. package/src/services/MetricsService.js +40 -0
  105. package/src/services/PaymentService.js +287 -0
  106. package/src/services/PlanService.js +468 -0
  107. package/src/services/ProjectService.js +1366 -0
  108. package/src/services/PullRequestService.js +537 -0
  109. package/src/services/ScreenshotService.js +258 -0
  110. package/src/services/SubscriptionService.js +425 -0
  111. package/src/services/TrackingService.js +853 -0
  112. package/src/services/WaitlistService.js +130 -0
  113. package/src/services/index.js +80 -13
  114. package/src/services/tests/BranchService/createBranch.test.js +153 -0
  115. package/src/services/tests/BranchService/deleteBranch.test.js +173 -0
  116. package/src/services/tests/BranchService/getBranchChanges.test.js +146 -0
  117. package/src/services/tests/BranchService/listBranches.test.js +87 -0
  118. package/src/services/tests/BranchService/mergeBranch.test.js +210 -0
  119. package/src/services/tests/BranchService/publishVersion.test.js +183 -0
  120. package/src/services/tests/BranchService/renameBranch.test.js +240 -0
  121. package/src/services/tests/BranchService/resetBranch.test.js +152 -0
  122. package/src/services/tests/FeatureFlagService/adminFeatureFlags.test.js +67 -0
  123. package/src/services/tests/FeatureFlagService/getFeatureFlags.test.js +75 -0
  124. package/src/services/tests/FileService/createFileFormData.test.js +74 -0
  125. package/src/services/tests/FileService/getFileUrl.test.js +69 -0
  126. package/src/services/tests/FileService/updateProjectIcon.test.js +109 -0
  127. package/src/services/tests/FileService/uploadDocument.test.js +36 -0
  128. package/src/services/tests/FileService/uploadFile.test.js +78 -0
  129. package/src/services/tests/FileService/uploadFileWithValidation.test.js +114 -0
  130. package/src/services/tests/FileService/uploadImage.test.js +36 -0
  131. package/src/services/tests/FileService/uploadMultipleFiles.test.js +111 -0
  132. package/src/services/tests/FileService/validateFile.test.js +63 -0
  133. package/src/services/tests/PlanService/createPlan.test.js +104 -0
  134. package/src/services/tests/PlanService/createPlanWithValidation.test.js +523 -0
  135. package/src/services/tests/PlanService/deletePlan.test.js +92 -0
  136. package/src/services/tests/PlanService/getActivePlans.test.js +123 -0
  137. package/src/services/tests/PlanService/getAdminPlans.test.js +84 -0
  138. package/src/services/tests/PlanService/getPlan.test.js +50 -0
  139. package/src/services/tests/PlanService/getPlanByKey.test.js +109 -0
  140. package/src/services/tests/PlanService/getPlanWithValidation.test.js +85 -0
  141. package/src/services/tests/PlanService/getPlans.test.js +53 -0
  142. package/src/services/tests/PlanService/getPlansByPriceRange.test.js +109 -0
  143. package/src/services/tests/PlanService/getPlansWithValidation.test.js +48 -0
  144. package/src/services/tests/PlanService/initializePlans.test.js +75 -0
  145. package/src/services/tests/PlanService/updatePlan.test.js +111 -0
  146. package/src/services/tests/PlanService/updatePlanWithValidation.test.js +556 -0
  147. package/src/state/RootStateManager.js +76 -0
  148. package/src/state/rootEventBus.js +67 -0
  149. package/src/utils/CollabClient.js +248 -0
  150. package/src/utils/TokenManager.js +88 -33
  151. package/src/utils/changePreprocessor.js +239 -0
  152. package/src/utils/jsonDiff.js +144 -0
  153. package/src/utils/ordering.js +271 -0
  154. package/src/utils/services.js +326 -107
  155. package/src/utils/validation.js +0 -3
  156. package/dist/cjs/services/AIService.js +0 -155
  157. package/dist/cjs/services/BasedService.js +0 -1185
  158. package/dist/cjs/services/CoreService.js +0 -1751
  159. package/dist/cjs/services/SocketIOService.js +0 -307
  160. package/dist/cjs/services/SocketService.js +0 -161
  161. package/dist/cjs/services/SymstoryService.js +0 -571
  162. package/dist/cjs/utils/basedQuerys.js +0 -181
  163. package/dist/cjs/utils/symstoryClient.js +0 -259
  164. package/dist/esm/services/AIService.js +0 -185
  165. package/dist/esm/services/BasedService.js +0 -5278
  166. package/dist/esm/services/CoreService.js +0 -2264
  167. package/dist/esm/services/SocketIOService.js +0 -470
  168. package/dist/esm/services/SocketService.js +0 -191
  169. package/dist/esm/services/SymstoryService.js +0 -7041
  170. package/dist/esm/utils/basedQuerys.js +0 -163
  171. package/dist/esm/utils/symstoryClient.js +0 -370
  172. package/dist/node/services/AIService.js +0 -136
  173. package/dist/node/services/BasedService.js +0 -1156
  174. package/dist/node/services/CoreService.js +0 -1722
  175. package/dist/node/services/SocketIOService.js +0 -278
  176. package/dist/node/services/SocketService.js +0 -142
  177. package/dist/node/services/SymstoryService.js +0 -542
  178. package/dist/node/utils/basedQuerys.js +0 -162
  179. package/dist/node/utils/symstoryClient.js +0 -230
  180. package/src/services/AIService.js +0 -150
  181. package/src/services/BasedService.js +0 -1301
  182. package/src/services/CoreService.js +0 -1943
  183. package/src/services/SocketIOService.js +0 -334
  184. package/src/services/SocketService.js +0 -168
  185. package/src/services/SymstoryService.js +0 -649
  186. package/src/utils/basedQuerys.js +0 -164
  187. package/src/utils/symstoryClient.js +0 -252
@@ -1,18 +1,40 @@
1
1
  import {
2
- createSymstoryService,
3
2
  createAuthService,
4
- createAIService,
5
- createSocketService,
6
- createCoreService
3
+ createCollabService,
4
+ createProjectService,
5
+ createPlanService,
6
+ createFileService,
7
+ createPaymentService,
8
+ createDnsService,
9
+ createBranchService,
10
+ createPullRequestService,
11
+ createAdminService,
12
+ createSubscriptionService,
13
+ createScreenshotService,
14
+ createTrackingService,
15
+ createWaitlistService,
16
+ createMetricsService,
17
+ createIntegrationService,
18
+ createFeatureFlagService
7
19
  } from "./services/index.js";
8
20
  import { SERVICE_METHODS } from "./utils/services.js";
9
- import { SymstoryService } from "./services/SymstoryService.js";
10
21
  import environment from "./config/environment.js";
22
+ import { rootBus } from "./state/rootEventBus.js";
23
+ const isBrowserEnvironment = () => typeof window !== "undefined";
24
+ const isLocalhost = () => {
25
+ if (!isBrowserEnvironment()) {
26
+ return false;
27
+ }
28
+ const host = window.location && window.location.hostname;
29
+ return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "" || !host;
30
+ };
11
31
  class SDK {
12
32
  constructor(options = {}) {
13
33
  this._services = /* @__PURE__ */ new Map();
14
34
  this._context = {};
15
35
  this._options = this._validateOptions(options);
36
+ this.environment = environment;
37
+ this.rootBus = rootBus;
16
38
  this._createServiceProxies();
17
39
  }
18
40
  // Initialize SDK with context
@@ -30,29 +52,114 @@ class SDK {
30
52
  })
31
53
  ),
32
54
  this._initService(
33
- "socket",
34
- createSocketService({
55
+ "collab",
56
+ createCollabService({
57
+ context: this._context,
58
+ options: this._options
59
+ })
60
+ ),
61
+ // Initialize new modular services
62
+ this._initService(
63
+ "project",
64
+ createProjectService({
65
+ context: this._context,
66
+ options: this._options
67
+ })
68
+ ),
69
+ this._initService(
70
+ "plan",
71
+ createPlanService({
72
+ context: this._context,
73
+ options: this._options
74
+ })
75
+ ),
76
+ this._initService(
77
+ "subscription",
78
+ createSubscriptionService({
35
79
  context: this._context,
36
80
  options: this._options
37
81
  })
38
82
  ),
39
83
  this._initService(
40
- "symstory",
41
- createSymstoryService({
84
+ "file",
85
+ createFileService({
42
86
  context: this._context,
43
87
  options: this._options
44
88
  })
45
89
  ),
46
90
  this._initService(
47
- "ai",
48
- createAIService({
91
+ "payment",
92
+ createPaymentService({
49
93
  context: this._context,
50
94
  options: this._options
51
95
  })
52
96
  ),
53
97
  this._initService(
54
- "core",
55
- createCoreService({
98
+ "dns",
99
+ createDnsService({
100
+ context: this._context,
101
+ options: this._options
102
+ })
103
+ ),
104
+ this._initService(
105
+ "branch",
106
+ createBranchService({
107
+ context: this._context,
108
+ options: this._options
109
+ })
110
+ ),
111
+ this._initService(
112
+ "pullRequest",
113
+ createPullRequestService({
114
+ context: this._context,
115
+ options: this._options
116
+ })
117
+ ),
118
+ this._initService(
119
+ "admin",
120
+ createAdminService({
121
+ context: this._context,
122
+ options: this._options
123
+ })
124
+ ),
125
+ this._initService(
126
+ "screenshot",
127
+ createScreenshotService({
128
+ context: this._context,
129
+ options: this._options
130
+ })
131
+ ),
132
+ this._initService(
133
+ "tracking",
134
+ createTrackingService({
135
+ context: this._context,
136
+ options: this._options
137
+ })
138
+ ),
139
+ this._initService(
140
+ "waitlist",
141
+ createWaitlistService({
142
+ context: this._context,
143
+ options: this._options
144
+ })
145
+ ),
146
+ this._initService(
147
+ "metrics",
148
+ createMetricsService({
149
+ context: this._context,
150
+ options: this._options
151
+ })
152
+ ),
153
+ this._initService(
154
+ "integration",
155
+ createIntegrationService({
156
+ context: this._context,
157
+ options: this._options
158
+ })
159
+ ),
160
+ this._initService(
161
+ "featureFlag",
162
+ createFeatureFlagService({
56
163
  context: this._context,
57
164
  options: this._options
58
165
  })
@@ -73,16 +180,33 @@ class SDK {
73
180
  this._services.set(name, service);
74
181
  }
75
182
  _validateOptions(options) {
183
+ const onLocalhost = isLocalhost();
184
+ const hasGrafanaUrl = Boolean(environment.grafanaUrl);
76
185
  const defaults = {
77
186
  useNewServices: true,
78
187
  // Use new service implementations by default
79
- baseUrl: environment.baseUrl,
188
+ apiUrl: environment.apiUrl,
80
189
  socketUrl: environment.socketUrl,
81
190
  timeout: 3e4,
82
191
  retryAttempts: 3,
83
- debug: false
192
+ debug: false,
193
+ tracking: {
194
+ // Force-disabled on localhost or when no Grafana URL is configured
195
+ enabled: onLocalhost ? false : hasGrafanaUrl ? environment.features.trackingEnabled : false
196
+ }
84
197
  };
85
- return { ...defaults, ...options };
198
+ const merged = {
199
+ ...defaults,
200
+ ...options,
201
+ tracking: {
202
+ ...defaults.tracking,
203
+ ...options.tracking || {}
204
+ }
205
+ };
206
+ if (onLocalhost || !hasGrafanaUrl) {
207
+ merged.tracking.enabled = false;
208
+ }
209
+ return merged;
86
210
  }
87
211
  // Get service instance
88
212
  getService(name) {
@@ -93,23 +217,19 @@ class SDK {
93
217
  }
94
218
  // Update context
95
219
  updateContext(newContext) {
220
+ const { ...sanitized } = newContext || {};
96
221
  this._context = {
97
222
  ...this._context,
98
- ...newContext
223
+ ...sanitized
99
224
  };
100
225
  for (const service of this._services.values()) {
101
226
  service.updateContext(this._context);
102
- if (service instanceof SymstoryService) {
103
- service.init();
104
- }
105
227
  }
106
228
  }
107
229
  // Check if SDK is ready
108
230
  isReady() {
109
231
  const sdkServices = Array.from(this._services.values());
110
- return sdkServices.length > 0 && sdkServices.every(
111
- (service) => service.isReady()
112
- );
232
+ return sdkServices.length > 0 && sdkServices.every((service) => service.isReady());
113
233
  }
114
234
  // Get SDK status
115
235
  getStatus() {
@@ -160,20 +280,43 @@ class SDK {
160
280
  }
161
281
  var index_default = SDK;
162
282
  import {
163
- createSymstoryService as createSymstoryService2,
164
283
  createAuthService as createAuthService2,
165
- createAIService as createAIService2,
166
- createSocketService as createSocketService2,
167
- createCoreService as createCoreService2
284
+ createCollabService as createCollabService2,
285
+ createProjectService as createProjectService2,
286
+ createPlanService as createPlanService2,
287
+ createFileService as createFileService2,
288
+ createPaymentService as createPaymentService2,
289
+ createDnsService as createDnsService2,
290
+ createBranchService as createBranchService2,
291
+ createPullRequestService as createPullRequestService2,
292
+ createAdminService as createAdminService2,
293
+ createSubscriptionService as createSubscriptionService2,
294
+ createTrackingService as createTrackingService2,
295
+ createWaitlistService as createWaitlistService2,
296
+ createMetricsService as createMetricsService2,
297
+ createIntegrationService as createIntegrationService2,
298
+ createFeatureFlagService as createFeatureFlagService2
168
299
  } from "./services/index.js";
169
300
  import { default as default2 } from "./config/environment.js";
170
301
  export {
171
302
  SDK,
172
- createAIService2 as createAIService,
303
+ createAdminService2 as createAdminService,
173
304
  createAuthService2 as createAuthService,
174
- createCoreService2 as createCoreService,
175
- createSocketService2 as createSocketService,
176
- createSymstoryService2 as createSymstoryService,
305
+ createBranchService2 as createBranchService,
306
+ createCollabService2 as createCollabService,
307
+ createDnsService2 as createDnsService,
308
+ createFeatureFlagService2 as createFeatureFlagService,
309
+ createFileService2 as createFileService,
310
+ createIntegrationService2 as createIntegrationService,
311
+ createMetricsService2 as createMetricsService,
312
+ createPaymentService2 as createPaymentService,
313
+ createPlanService2 as createPlanService,
314
+ createProjectService2 as createProjectService,
315
+ createPullRequestService2 as createPullRequestService,
316
+ createSubscriptionService2 as createSubscriptionService,
317
+ createTrackingService2 as createTrackingService,
318
+ createWaitlistService2 as createWaitlistService,
177
319
  index_default as default,
178
- default2 as environment
320
+ default2 as environment,
321
+ isLocalhost
179
322
  };
@@ -0,0 +1,332 @@
1
+ import { BaseService } from "./BaseService.js";
2
+ class AdminService extends BaseService {
3
+ // ==================== ADMIN METHODS ====================
4
+ /**
5
+ * Get admin users list with comprehensive filtering and search capabilities
6
+ * Requires admin or super_admin global role
7
+ */
8
+ async getAdminUsers(params = {}) {
9
+ this._requireReady("getAdminUsers");
10
+ const {
11
+ emails,
12
+ ids,
13
+ query,
14
+ status,
15
+ page = 1,
16
+ limit = 50,
17
+ sort = { field: "createdAt", order: "desc" }
18
+ } = params;
19
+ const queryParams = new URLSearchParams();
20
+ if (emails) {
21
+ queryParams.append("emails", emails);
22
+ }
23
+ if (ids) {
24
+ queryParams.append("ids", ids);
25
+ }
26
+ if (query) {
27
+ queryParams.append("query", query);
28
+ }
29
+ if (status) {
30
+ queryParams.append("status", status);
31
+ }
32
+ if (page) {
33
+ queryParams.append("page", page.toString());
34
+ }
35
+ if (limit) {
36
+ queryParams.append("limit", limit.toString());
37
+ }
38
+ if (sort && sort.field) {
39
+ queryParams.append("sort[field]", sort.field);
40
+ queryParams.append("sort[order]", sort.order || "desc");
41
+ }
42
+ const queryString = queryParams.toString();
43
+ const url = `/users/admin/users${queryString ? `?${queryString}` : ""}`;
44
+ try {
45
+ const response = await this._request(url, {
46
+ method: "GET",
47
+ methodName: "getAdminUsers"
48
+ });
49
+ if (response.success) {
50
+ return response.data;
51
+ }
52
+ throw new Error(response.message);
53
+ } catch (error) {
54
+ throw new Error(`Failed to get admin users: ${error.message}`, { cause: error });
55
+ }
56
+ }
57
+ /**
58
+ * Assign projects to a specific user
59
+ * Requires admin or super_admin global role
60
+ */
61
+ async assignProjectsToUser(userId, options = {}) {
62
+ this._requireReady("assignProjectsToUser");
63
+ if (!userId) {
64
+ throw new Error("User ID is required");
65
+ }
66
+ const { projectIds, role = "guest" } = options;
67
+ const requestBody = {
68
+ userId,
69
+ role
70
+ };
71
+ if (projectIds && Array.isArray(projectIds)) {
72
+ requestBody.projectIds = projectIds;
73
+ }
74
+ try {
75
+ const response = await this._request("/assign-projects", {
76
+ method: "POST",
77
+ body: JSON.stringify(requestBody),
78
+ methodName: "assignProjectsToUser"
79
+ });
80
+ if (response.success) {
81
+ return response.data;
82
+ }
83
+ throw new Error(response.message);
84
+ } catch (error) {
85
+ throw new Error(`Failed to assign projects to user: ${error.message}`, { cause: error });
86
+ }
87
+ }
88
+ /**
89
+ * Update user information (admin only)
90
+ */
91
+ async updateUser(userId, userData) {
92
+ var _a;
93
+ this._requireReady("updateUser");
94
+ if (!userId) {
95
+ throw new Error("User ID is required");
96
+ }
97
+ if (!userData || typeof userData !== "object" || Object.keys(userData).length === 0) {
98
+ throw new Error("userData must be a non-empty object");
99
+ }
100
+ try {
101
+ const response = await this._request(`/users/${userId}`, {
102
+ method: "PATCH",
103
+ body: JSON.stringify(userData),
104
+ methodName: "updateUser"
105
+ });
106
+ if (response.success) {
107
+ return response.data;
108
+ }
109
+ throw new Error(response.message);
110
+ } catch (error) {
111
+ if ((_a = error.message) == null ? void 0 : _a.includes("Duplicate")) {
112
+ throw new Error("Username already exists");
113
+ }
114
+ throw new Error(`Failed to update user: ${error.message}`, { cause: error });
115
+ }
116
+ }
117
+ // ==================== ADMIN HELPER METHODS ====================
118
+ /**
119
+ * Helper method for admin users search
120
+ */
121
+ async searchAdminUsers(searchQuery, options = {}) {
122
+ return await this.getAdminUsers({
123
+ query: searchQuery,
124
+ ...options
125
+ });
126
+ }
127
+ /**
128
+ * Helper method to get admin users by email list
129
+ */
130
+ async getAdminUsersByEmails(emails, options = {}) {
131
+ const emailList = Array.isArray(emails) ? emails.join(",") : emails;
132
+ return await this.getAdminUsers({
133
+ emails: emailList,
134
+ ...options
135
+ });
136
+ }
137
+ /**
138
+ * Helper method to get admin users by ID list
139
+ */
140
+ async getAdminUsersByIds(ids, options = {}) {
141
+ const idList = Array.isArray(ids) ? ids.join(",") : ids;
142
+ return await this.getAdminUsers({
143
+ ids: idList,
144
+ ...options
145
+ });
146
+ }
147
+ /**
148
+ * Helper method to assign specific projects to a user with a specific role
149
+ */
150
+ async assignSpecificProjectsToUser(userId, projectIds, role = "guest") {
151
+ if (!Array.isArray(projectIds) || projectIds.length === 0) {
152
+ throw new Error("Project IDs must be a non-empty array");
153
+ }
154
+ return await this.assignProjectsToUser(userId, {
155
+ projectIds,
156
+ role
157
+ });
158
+ }
159
+ /**
160
+ * Helper method to assign all projects to a user with a specific role
161
+ */
162
+ async assignAllProjectsToUser(userId, role = "guest") {
163
+ return await this.assignProjectsToUser(userId, {
164
+ role
165
+ });
166
+ }
167
+ /**
168
+ * Helper method to validate user data for updates
169
+ */
170
+ validateUserData(userData) {
171
+ const errors = [];
172
+ if (!userData || typeof userData !== "object") {
173
+ errors.push("User data must be an object");
174
+ return { isValid: false, errors };
175
+ }
176
+ if (userData.email && typeof userData.email !== "string") {
177
+ errors.push("Email must be a string");
178
+ } else if (userData.email && !this._isValidEmail(userData.email)) {
179
+ errors.push("Email must be a valid email address");
180
+ }
181
+ if (userData.username && typeof userData.username !== "string") {
182
+ errors.push("Username must be a string");
183
+ } else if (userData.username && userData.username.length < 3) {
184
+ errors.push("Username must be at least 3 characters long");
185
+ }
186
+ if (userData.role && !["admin", "user", "guest"].includes(userData.role)) {
187
+ errors.push("Role must be one of: admin, user, guest");
188
+ }
189
+ if (userData.status && !["active", "inactive", "suspended"].includes(userData.status)) {
190
+ errors.push("Status must be one of: active, inactive, suspended");
191
+ }
192
+ return {
193
+ isValid: errors.length === 0,
194
+ errors
195
+ };
196
+ }
197
+ /**
198
+ * Helper method to update user with validation
199
+ */
200
+ async updateUserWithValidation(userId, userData) {
201
+ const validation = this.validateUserData(userData);
202
+ if (!validation.isValid) {
203
+ throw new Error(`Validation failed: ${validation.errors.join(", ")}`);
204
+ }
205
+ return await this.updateUser(userId, userData);
206
+ }
207
+ /**
208
+ * Helper method to get user statistics
209
+ */
210
+ async getUserStats() {
211
+ try {
212
+ const users = await this.getAdminUsers({ limit: 1e3 });
213
+ const stats = {
214
+ total: users.length,
215
+ active: 0,
216
+ inactive: 0,
217
+ suspended: 0,
218
+ admins: 0,
219
+ users: 0,
220
+ guests: 0
221
+ };
222
+ users.forEach((user) => {
223
+ if (user.status === "active") {
224
+ stats.active++;
225
+ }
226
+ if (user.status === "inactive") {
227
+ stats.inactive++;
228
+ }
229
+ if (user.status === "suspended") {
230
+ stats.suspended++;
231
+ }
232
+ if (user.role === "admin") {
233
+ stats.admins++;
234
+ }
235
+ if (user.role === "user") {
236
+ stats.users++;
237
+ }
238
+ if (user.role === "guest") {
239
+ stats.guests++;
240
+ }
241
+ });
242
+ return stats;
243
+ } catch (error) {
244
+ throw new Error(`Failed to get user stats: ${error.message}`, { cause: error });
245
+ }
246
+ }
247
+ /**
248
+ * Helper method to bulk update users
249
+ */
250
+ async bulkUpdateUsers(userUpdates) {
251
+ if (!Array.isArray(userUpdates) || userUpdates.length === 0) {
252
+ throw new Error("User updates must be a non-empty array");
253
+ }
254
+ const updatePromises = userUpdates.map(async (update) => {
255
+ try {
256
+ const result = await this.updateUser(update.userId, update.userData);
257
+ return {
258
+ userId: update.userId,
259
+ success: true,
260
+ data: result
261
+ };
262
+ } catch (error) {
263
+ return {
264
+ userId: update.userId,
265
+ success: false,
266
+ error: error.message
267
+ };
268
+ }
269
+ });
270
+ const results = await Promise.all(updatePromises);
271
+ return {
272
+ total: results.length,
273
+ successful: results.filter((r) => r.success).length,
274
+ failed: results.filter((r) => !r.success).length,
275
+ results
276
+ };
277
+ }
278
+ /**
279
+ * Helper method to get users by role
280
+ */
281
+ async getUsersByRole(role, options = {}) {
282
+ const users = await this.getAdminUsers(options);
283
+ return users.filter((user) => user.role === role);
284
+ }
285
+ /**
286
+ * Helper method to get users by status
287
+ */
288
+ async getUsersByStatus(status, options = {}) {
289
+ const users = await this.getAdminUsers(options);
290
+ return users.filter((user) => user.status === status);
291
+ }
292
+ /**
293
+ * Helper method to activate a user
294
+ */
295
+ async activateUser(userId) {
296
+ return await this.updateUser(userId, { status: "active" });
297
+ }
298
+ /**
299
+ * Helper method to deactivate a user
300
+ */
301
+ async deactivateUser(userId) {
302
+ return await this.updateUser(userId, { status: "inactive" });
303
+ }
304
+ /**
305
+ * Helper method to suspend a user
306
+ */
307
+ async suspendUser(userId) {
308
+ return await this.updateUser(userId, { status: "suspended" });
309
+ }
310
+ /**
311
+ * Helper method to promote user to admin
312
+ */
313
+ async promoteToAdmin(userId) {
314
+ return await this.updateUser(userId, { role: "admin" });
315
+ }
316
+ /**
317
+ * Helper method to demote user from admin
318
+ */
319
+ async demoteFromAdmin(userId) {
320
+ return await this.updateUser(userId, { role: "user" });
321
+ }
322
+ /**
323
+ * Private helper to validate email format
324
+ */
325
+ _isValidEmail(email) {
326
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/u;
327
+ return emailRegex.test(email);
328
+ }
329
+ }
330
+ export {
331
+ AdminService
332
+ };