@symbo.ls/sdk 3.1.2 → 3.2.3

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 (65) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/config/environment.js +5 -21
  3. package/dist/cjs/index.js +6 -26
  4. package/dist/cjs/services/AIService.js +3 -3
  5. package/dist/cjs/services/CollabService.js +420 -0
  6. package/dist/cjs/services/CoreService.js +651 -107
  7. package/dist/cjs/services/SocketService.js +207 -59
  8. package/dist/cjs/services/index.js +5 -13
  9. package/dist/cjs/state/RootStateManager.js +86 -0
  10. package/dist/cjs/state/rootEventBus.js +65 -0
  11. package/dist/cjs/utils/CollabClient.js +157 -0
  12. package/dist/cjs/utils/TokenManager.js +62 -27
  13. package/dist/cjs/utils/jsonDiff.js +103 -0
  14. package/dist/cjs/utils/services.js +129 -88
  15. package/dist/cjs/utils/symstoryClient.js +5 -5
  16. package/dist/esm/config/environment.js +5 -21
  17. package/dist/esm/index.js +20459 -9286
  18. package/dist/esm/services/AIService.js +3 -3
  19. package/dist/esm/services/BasedService.js +5 -21
  20. package/dist/esm/services/CollabService.js +18028 -0
  21. package/dist/esm/services/CoreService.js +718 -155
  22. package/dist/esm/services/SocketService.js +323 -58
  23. package/dist/esm/services/SymstoryService.js +10 -26
  24. package/dist/esm/services/index.js +20305 -9158
  25. package/dist/esm/state/RootStateManager.js +102 -0
  26. package/dist/esm/state/rootEventBus.js +47 -0
  27. package/dist/esm/utils/CollabClient.js +17483 -0
  28. package/dist/esm/utils/TokenManager.js +62 -27
  29. package/dist/esm/utils/jsonDiff.js +6096 -0
  30. package/dist/esm/utils/services.js +129 -88
  31. package/dist/esm/utils/symstoryClient.js +10 -26
  32. package/dist/node/config/environment.js +5 -21
  33. package/dist/node/index.js +10 -34
  34. package/dist/node/services/AIService.js +3 -3
  35. package/dist/node/services/CollabService.js +401 -0
  36. package/dist/node/services/CoreService.js +651 -107
  37. package/dist/node/services/SocketService.js +197 -59
  38. package/dist/node/services/index.js +5 -13
  39. package/dist/node/state/RootStateManager.js +57 -0
  40. package/dist/node/state/rootEventBus.js +46 -0
  41. package/dist/node/utils/CollabClient.js +128 -0
  42. package/dist/node/utils/TokenManager.js +62 -27
  43. package/dist/node/utils/jsonDiff.js +74 -0
  44. package/dist/node/utils/services.js +129 -88
  45. package/dist/node/utils/symstoryClient.js +5 -5
  46. package/package.json +12 -6
  47. package/src/config/environment.js +5 -19
  48. package/src/index.js +9 -31
  49. package/src/services/AIService.js +3 -3
  50. package/src/services/BasedService.js +1 -0
  51. package/src/services/CollabService.js +491 -0
  52. package/src/services/CoreService.js +715 -110
  53. package/src/services/SocketService.js +227 -59
  54. package/src/services/index.js +6 -13
  55. package/src/state/RootStateManager.js +71 -0
  56. package/src/state/rootEventBus.js +48 -0
  57. package/src/utils/CollabClient.js +161 -0
  58. package/src/utils/TokenManager.js +68 -30
  59. package/src/utils/jsonDiff.js +109 -0
  60. package/src/utils/services.js +140 -88
  61. package/src/utils/symstoryClient.js +5 -5
  62. package/dist/cjs/services/SocketIOService.js +0 -307
  63. package/dist/esm/services/SocketIOService.js +0 -470
  64. package/dist/node/services/SocketIOService.js +0 -278
  65. package/src/services/SocketIOService.js +0 -334
@@ -38,18 +38,18 @@ class CoreService extends import_BaseService.BaseService {
38
38
  super(config);
39
39
  this._client = null;
40
40
  this._initialized = false;
41
- this._baseUrl = null;
41
+ this._apiUrl = null;
42
42
  this._tokenManager = null;
43
43
  }
44
44
  init({ context }) {
45
45
  try {
46
46
  const { appKey, authToken } = context || this._context;
47
- this._baseUrl = import_environment.default.apiUrl || import_environment.default.baseUrl;
48
- if (!this._baseUrl) {
47
+ this._apiUrl = import_environment.default.apiUrl;
48
+ if (!this._apiUrl) {
49
49
  throw new Error("Core service base URL not configured");
50
50
  }
51
51
  this._tokenManager = (0, import_TokenManager.getTokenManager)({
52
- apiUrl: this._baseUrl,
52
+ apiUrl: this._apiUrl,
53
53
  onTokenRefresh: (tokens) => {
54
54
  this.updateContext({ authToken: tokens.accessToken });
55
55
  },
@@ -60,12 +60,12 @@ class CoreService extends import_BaseService.BaseService {
60
60
  console.error("Token management error:", error);
61
61
  }
62
62
  });
63
- if (authToken) {
63
+ if (authToken && !this._tokenManager.hasTokens()) {
64
64
  this._tokenManager.setTokens({ access_token: authToken });
65
65
  }
66
66
  this._info = {
67
67
  config: {
68
- baseUrl: this._baseUrl,
68
+ apiUrl: this._apiUrl,
69
69
  appKey: appKey ? `${appKey.substr(0, 4)}...${appKey.substr(-4)}` : null,
70
70
  hasToken: Boolean(authToken)
71
71
  }
@@ -83,11 +83,15 @@ class CoreService extends import_BaseService.BaseService {
83
83
  "register",
84
84
  "login",
85
85
  "googleAuth",
86
+ "googleAuthCallback",
86
87
  "githubAuth",
87
88
  "requestPasswordReset",
88
89
  "confirmPasswordReset",
89
90
  "confirmRegistration",
90
- "verifyEmail"
91
+ "verifyEmail",
92
+ "listPublicProjects",
93
+ "getPublicProject",
94
+ "getHealthStatus"
91
95
  ]);
92
96
  return !noInitMethods.has(methodName);
93
97
  }
@@ -118,24 +122,34 @@ class CoreService extends import_BaseService.BaseService {
118
122
  authHeader: this._tokenManager.getAuthHeader()
119
123
  };
120
124
  }
125
+ // Helper method to check if user is authenticated
126
+ isAuthenticated() {
127
+ if (!this._tokenManager) {
128
+ return false;
129
+ }
130
+ return this._tokenManager.hasTokens();
131
+ }
132
+ // Helper method to check if user has valid tokens
133
+ hasValidTokens() {
134
+ if (!this._tokenManager) {
135
+ return false;
136
+ }
137
+ return this._tokenManager.hasTokens() && this._tokenManager.isAccessTokenValid();
138
+ }
121
139
  // Helper method to make HTTP requests
122
140
  async _request(endpoint, options = {}) {
123
- const url = `${this._baseUrl}/core${endpoint}`;
124
- const defaultHeaders = {
125
- "Content-Type": "application/json"
126
- };
141
+ const url = `${this._apiUrl}/core${endpoint}`;
142
+ const defaultHeaders = {};
143
+ if (!(options.body instanceof FormData)) {
144
+ defaultHeaders["Content-Type"] = "application/json";
145
+ }
127
146
  if (this._requiresInit(options.methodName) && this._tokenManager) {
128
147
  try {
129
148
  const validToken = await this._tokenManager.ensureValidToken();
130
- console.log(`[CoreService] Token check for ${options.methodName}:`, {
131
- hasValidToken: Boolean(validToken),
132
- tokenPreview: validToken ? `${validToken.substring(0, 20)}...` : null
133
- });
134
149
  if (validToken) {
135
150
  const authHeader = this._tokenManager.getAuthHeader();
136
151
  if (authHeader) {
137
152
  defaultHeaders.Authorization = authHeader;
138
- console.log(`[CoreService] Added auth header for ${options.methodName}`);
139
153
  }
140
154
  }
141
155
  } catch (error) {
@@ -145,7 +159,6 @@ class CoreService extends import_BaseService.BaseService {
145
159
  const { authToken } = this._context;
146
160
  if (authToken) {
147
161
  defaultHeaders.Authorization = `Bearer ${authToken}`;
148
- console.log(`[CoreService] Using context token for ${options.methodName}`);
149
162
  }
150
163
  }
151
164
  try {
@@ -172,11 +185,15 @@ class CoreService extends import_BaseService.BaseService {
172
185
  // ==================== AUTH METHODS ====================
173
186
  async register(userData) {
174
187
  try {
175
- return await this._request("/auth/register", {
188
+ const response = await this._request("/auth/register", {
176
189
  method: "POST",
177
190
  body: JSON.stringify(userData),
178
191
  methodName: "register"
179
192
  });
193
+ if (response.success) {
194
+ return response.data;
195
+ }
196
+ throw new Error(response.message);
180
197
  } catch (error) {
181
198
  throw new Error(`Registration failed: ${error.message}`);
182
199
  }
@@ -202,7 +219,10 @@ class CoreService extends import_BaseService.BaseService {
202
219
  }
203
220
  this.updateContext({ authToken: tokens.accessToken });
204
221
  }
205
- return response;
222
+ if (response.success) {
223
+ return response.data;
224
+ }
225
+ throw new Error(response.message);
206
226
  } catch (error) {
207
227
  throw new Error(`Login failed: ${error.message}`);
208
228
  }
@@ -228,11 +248,15 @@ class CoreService extends import_BaseService.BaseService {
228
248
  }
229
249
  async refreshToken(refreshToken) {
230
250
  try {
231
- return await this._request("/auth/refresh", {
251
+ const response = await this._request("/auth/refresh", {
232
252
  method: "POST",
233
253
  body: JSON.stringify({ refreshToken }),
234
254
  methodName: "refreshToken"
235
255
  });
256
+ if (response.success) {
257
+ return response.data;
258
+ }
259
+ throw new Error(response.message);
236
260
  } catch (error) {
237
261
  throw new Error(`Token refresh failed: ${error.message}`);
238
262
  }
@@ -258,7 +282,10 @@ class CoreService extends import_BaseService.BaseService {
258
282
  }
259
283
  this.updateContext({ authToken: tokens.accessToken });
260
284
  }
261
- return response;
285
+ if (response.success) {
286
+ return response.data;
287
+ }
288
+ throw new Error(response.message);
262
289
  } catch (error) {
263
290
  throw new Error(`Google auth failed: ${error.message}`);
264
291
  }
@@ -284,40 +311,84 @@ class CoreService extends import_BaseService.BaseService {
284
311
  }
285
312
  this.updateContext({ authToken: tokens.accessToken });
286
313
  }
287
- return response;
314
+ if (response.success) {
315
+ return response.data;
316
+ }
317
+ throw new Error(response.message);
288
318
  } catch (error) {
289
319
  throw new Error(`GitHub auth failed: ${error.message}`);
290
320
  }
291
321
  }
322
+ async googleAuthCallback(code, redirectUri) {
323
+ var _a;
324
+ try {
325
+ const response = await this._request("/auth/google/callback", {
326
+ method: "POST",
327
+ body: JSON.stringify({ code, redirectUri }),
328
+ methodName: "googleAuthCallback"
329
+ });
330
+ if (response.success && response.data && response.data.tokens) {
331
+ const { tokens } = response.data;
332
+ const tokenData = {
333
+ access_token: tokens.accessToken,
334
+ refresh_token: tokens.refreshToken,
335
+ expires_in: (_a = tokens.accessTokenExp) == null ? void 0 : _a.expiresIn,
336
+ token_type: "Bearer"
337
+ };
338
+ if (this._tokenManager) {
339
+ this._tokenManager.setTokens(tokenData);
340
+ }
341
+ this.updateContext({ authToken: tokens.accessToken });
342
+ }
343
+ if (response.success) {
344
+ return response.data;
345
+ }
346
+ throw new Error(response.message);
347
+ } catch (error) {
348
+ throw new Error(`Google auth callback failed: ${error.message}`);
349
+ }
350
+ }
292
351
  async requestPasswordReset(email) {
293
352
  try {
294
- return await this._request("/auth/request-password-reset", {
353
+ const response = await this._request("/auth/request-password-reset", {
295
354
  method: "POST",
296
355
  body: JSON.stringify({ email }),
297
356
  methodName: "requestPasswordReset"
298
357
  });
358
+ if (response.success) {
359
+ return response.data;
360
+ }
361
+ throw new Error(response.message);
299
362
  } catch (error) {
300
363
  throw new Error(`Password reset request failed: ${error.message}`);
301
364
  }
302
365
  }
303
366
  async confirmPasswordReset(token, password) {
304
367
  try {
305
- return await this._request("/auth/reset-password-confirm", {
368
+ const response = await this._request("/auth/reset-password-confirm", {
306
369
  method: "POST",
307
370
  body: JSON.stringify({ token, password }),
308
371
  methodName: "confirmPasswordReset"
309
372
  });
373
+ if (response.success) {
374
+ return response.data;
375
+ }
376
+ throw new Error(response.message);
310
377
  } catch (error) {
311
378
  throw new Error(`Password reset confirmation failed: ${error.message}`);
312
379
  }
313
380
  }
314
381
  async confirmRegistration(token) {
315
382
  try {
316
- return await this._request("/auth/register-confirmation", {
383
+ const response = await this._request("/auth/register-confirmation", {
317
384
  method: "POST",
318
385
  body: JSON.stringify({ token }),
319
386
  methodName: "confirmRegistration"
320
387
  });
388
+ if (response.success) {
389
+ return response.data;
390
+ }
391
+ throw new Error(response.message);
321
392
  } catch (error) {
322
393
  throw new Error(`Registration confirmation failed: ${error.message}`);
323
394
  }
@@ -325,10 +396,14 @@ class CoreService extends import_BaseService.BaseService {
325
396
  async requestPasswordChange() {
326
397
  this._requireReady("requestPasswordChange");
327
398
  try {
328
- return await this._request("/auth/request-password-change", {
399
+ const response = await this._request("/auth/request-password-change", {
329
400
  method: "POST",
330
401
  methodName: "requestPasswordChange"
331
402
  });
403
+ if (response.success) {
404
+ return response.data;
405
+ }
406
+ throw new Error(response.message);
332
407
  } catch (error) {
333
408
  throw new Error(`Password change request failed: ${error.message}`);
334
409
  }
@@ -336,11 +411,15 @@ class CoreService extends import_BaseService.BaseService {
336
411
  async confirmPasswordChange(currentPassword, newPassword, code) {
337
412
  this._requireReady("confirmPasswordChange");
338
413
  try {
339
- return await this._request("/auth/confirm-password-change", {
414
+ const response = await this._request("/auth/confirm-password-change", {
340
415
  method: "POST",
341
416
  body: JSON.stringify({ currentPassword, newPassword, code }),
342
417
  methodName: "confirmPasswordChange"
343
418
  });
419
+ if (response.success) {
420
+ return response.data;
421
+ }
422
+ throw new Error(response.message);
344
423
  } catch (error) {
345
424
  throw new Error(`Password change confirmation failed: ${error.message}`);
346
425
  }
@@ -348,10 +427,14 @@ class CoreService extends import_BaseService.BaseService {
348
427
  async getMe() {
349
428
  this._requireReady("getMe");
350
429
  try {
351
- return await this._request("/auth/me", {
430
+ const response = await this._request("/auth/me", {
352
431
  method: "GET",
353
432
  methodName: "getMe"
354
433
  });
434
+ if (response.success) {
435
+ return response.data;
436
+ }
437
+ throw new Error(response.message);
355
438
  } catch (error) {
356
439
  throw new Error(`Failed to get user profile: ${error.message}`);
357
440
  }
@@ -379,35 +462,57 @@ class CoreService extends import_BaseService.BaseService {
379
462
  try {
380
463
  await this._tokenManager.ensureValidToken();
381
464
  } catch (error) {
382
- this._tokenManager.clearTokens();
465
+ console.warn("[CoreService] Token refresh failed:", error.message);
466
+ if (error.message.includes("401") || error.message.includes("403") || error.message.includes("invalid") || error.message.includes("expired")) {
467
+ this._tokenManager.clearTokens();
468
+ return {
469
+ userId: false,
470
+ authToken: false,
471
+ error: `Authentication failed: ${error.message}`
472
+ };
473
+ }
383
474
  return {
384
475
  userId: false,
385
- authToken: false,
386
- error: `Token refresh failed: ${error.message}`
476
+ authToken: this._tokenManager.getAccessToken(),
477
+ error: `Network error during token refresh: ${error.message}`,
478
+ hasTokens: true
387
479
  };
388
480
  }
389
481
  }
482
+ const currentAccessToken = this._tokenManager.getAccessToken();
483
+ if (!currentAccessToken) {
484
+ return {
485
+ userId: false,
486
+ authToken: false
487
+ };
488
+ }
390
489
  try {
391
490
  const currentUser = await this.getMe();
392
- const userProjects = await this.getUserProjects();
393
491
  return {
394
- userId: currentUser.data.id,
395
- authToken: this._tokenManager.getAccessToken(),
396
- user: {
397
- ...currentUser.data,
398
- projects: (userProjects == null ? void 0 : userProjects.data) || []
399
- },
492
+ userId: currentUser.user.id,
493
+ authToken: currentAccessToken,
494
+ ...currentUser,
400
495
  error: null
401
496
  };
402
497
  } catch (error) {
403
- this._tokenManager.clearTokens();
498
+ console.warn("[CoreService] Failed to get user data:", error.message);
499
+ if (error.message.includes("401") || error.message.includes("403")) {
500
+ this._tokenManager.clearTokens();
501
+ return {
502
+ userId: false,
503
+ authToken: false,
504
+ error: `Authentication failed: ${error.message}`
505
+ };
506
+ }
404
507
  return {
405
508
  userId: false,
406
- authToken: false,
407
- error: `Failed to get user data: ${error.message}`
509
+ authToken: currentAccessToken,
510
+ error: `Failed to get user data: ${error.message}`,
511
+ hasTokens: true
408
512
  };
409
513
  }
410
514
  } catch (error) {
515
+ console.error("[CoreService] Unexpected error in getStoredAuthState:", error);
411
516
  return {
412
517
  userId: false,
413
518
  authToken: false,
@@ -419,10 +524,14 @@ class CoreService extends import_BaseService.BaseService {
419
524
  async getUserProfile() {
420
525
  this._requireReady("getUserProfile");
421
526
  try {
422
- return await this._request("/users/profile", {
527
+ const response = await this._request("/users/profile", {
423
528
  method: "GET",
424
529
  methodName: "getUserProfile"
425
530
  });
531
+ if (response.success) {
532
+ return response.data;
533
+ }
534
+ throw new Error(response.message);
426
535
  } catch (error) {
427
536
  throw new Error(`Failed to get user profile: ${error.message}`);
428
537
  }
@@ -430,11 +539,15 @@ class CoreService extends import_BaseService.BaseService {
430
539
  async updateUserProfile(profileData) {
431
540
  this._requireReady("updateUserProfile");
432
541
  try {
433
- return await this._request("/users/profile", {
542
+ const response = await this._request("/users/profile", {
434
543
  method: "PATCH",
435
544
  body: JSON.stringify(profileData),
436
545
  methodName: "updateUserProfile"
437
546
  });
547
+ if (response.success) {
548
+ return response.data;
549
+ }
550
+ throw new Error(response.message);
438
551
  } catch (error) {
439
552
  throw new Error(`Failed to update user profile: ${error.message}`);
440
553
  }
@@ -442,10 +555,17 @@ class CoreService extends import_BaseService.BaseService {
442
555
  async getUserProjects() {
443
556
  this._requireReady("getUserProjects");
444
557
  try {
445
- return await this._request("/users/projects", {
558
+ const response = await this._request("/users/projects", {
446
559
  method: "GET",
447
560
  methodName: "getUserProjects"
448
561
  });
562
+ if (response.success) {
563
+ return response.data.map((project) => ({
564
+ ...project,
565
+ ...project.icon && { icon: { src: `${this._apiUrl}/core/files/public/${project.icon.id}/download`, ...project.icon } }
566
+ }));
567
+ }
568
+ throw new Error(response.message);
449
569
  } catch (error) {
450
570
  throw new Error(`Failed to get user projects: ${error.message}`);
451
571
  }
@@ -456,10 +576,14 @@ class CoreService extends import_BaseService.BaseService {
456
576
  throw new Error("User ID is required");
457
577
  }
458
578
  try {
459
- return await this._request(`/users/${userId}`, {
579
+ const response = await this._request(`/users/${userId}`, {
460
580
  method: "GET",
461
581
  methodName: "getUser"
462
582
  });
583
+ if (response.success) {
584
+ return response.data;
585
+ }
586
+ throw new Error(response.message);
463
587
  } catch (error) {
464
588
  throw new Error(`Failed to get user: ${error.message}`);
465
589
  }
@@ -470,13 +594,17 @@ class CoreService extends import_BaseService.BaseService {
470
594
  throw new Error("Email is required");
471
595
  }
472
596
  try {
473
- return await this._request("/auth/user", {
597
+ const response = await this._request("/auth/user", {
474
598
  method: "GET",
475
599
  headers: {
476
600
  "X-User-Email": email
477
601
  },
478
602
  methodName: "getUserByEmail"
479
603
  });
604
+ if (response.success) {
605
+ return response.data;
606
+ }
607
+ throw new Error(response.message);
480
608
  } catch (error) {
481
609
  throw new Error(`Failed to get user by email: ${error.message}`);
482
610
  }
@@ -485,50 +613,134 @@ class CoreService extends import_BaseService.BaseService {
485
613
  async createProject(projectData) {
486
614
  this._requireReady("createProject");
487
615
  try {
488
- return await this._request("/projects", {
616
+ const response = await this._request("/projects", {
489
617
  method: "POST",
490
618
  body: JSON.stringify(projectData),
491
619
  methodName: "createProject"
492
620
  });
621
+ if (response.success) {
622
+ return response.data;
623
+ }
624
+ throw new Error(response.message);
493
625
  } catch (error) {
494
626
  throw new Error(`Failed to create project: ${error.message}`);
495
627
  }
496
628
  }
497
- async getProjects() {
629
+ async getProjects(params = {}) {
498
630
  this._requireReady("getProjects");
499
631
  try {
500
- return await this._request("/projects", {
632
+ const queryParams = new URLSearchParams();
633
+ Object.keys(params).forEach((key) => {
634
+ if (params[key] != null) {
635
+ queryParams.append(key, params[key]);
636
+ }
637
+ });
638
+ const queryString = queryParams.toString();
639
+ const url = `/projects${queryString ? `?${queryString}` : ""}`;
640
+ const response = await this._request(url, {
501
641
  method: "GET",
502
642
  methodName: "getProjects"
503
643
  });
644
+ if (response.success) {
645
+ return response;
646
+ }
647
+ throw new Error(response.message);
504
648
  } catch (error) {
505
649
  throw new Error(`Failed to get projects: ${error.message}`);
506
650
  }
507
651
  }
652
+ /**
653
+ * Alias for getProjects for consistency with API naming
654
+ */
655
+ async listProjects(params = {}) {
656
+ return await this.getProjects(params);
657
+ }
658
+ /**
659
+ * List only public projects (no authentication required)
660
+ */
661
+ async listPublicProjects(params = {}) {
662
+ try {
663
+ const queryParams = new URLSearchParams();
664
+ Object.keys(params).forEach((key) => {
665
+ if (params[key] != null) {
666
+ queryParams.append(key, params[key]);
667
+ }
668
+ });
669
+ const queryString = queryParams.toString();
670
+ const url = `/projects/public${queryString ? `?${queryString}` : ""}`;
671
+ const response = await this._request(url, {
672
+ method: "GET",
673
+ methodName: "listPublicProjects"
674
+ });
675
+ if (response.success) {
676
+ return response.data;
677
+ }
678
+ throw new Error(response.message);
679
+ } catch (error) {
680
+ throw new Error(`Failed to list public projects: ${error.message}`);
681
+ }
682
+ }
508
683
  async getProject(projectId) {
509
684
  this._requireReady("getProject");
510
685
  if (!projectId) {
511
686
  throw new Error("Project ID is required");
512
687
  }
513
688
  try {
514
- return await this._request(`/projects/${projectId}`, {
689
+ const response = await this._request(`/projects/${projectId}`, {
515
690
  method: "GET",
516
691
  methodName: "getProject"
517
692
  });
693
+ if (response.success) {
694
+ const iconSrc = response.data.icon ? `${this._apiUrl}/core/files/public/${response.data.icon.id}/download` : null;
695
+ return {
696
+ ...response.data,
697
+ icon: { src: iconSrc, ...response.data.icon }
698
+ };
699
+ }
700
+ throw new Error(response.message);
518
701
  } catch (error) {
519
702
  throw new Error(`Failed to get project: ${error.message}`);
520
703
  }
521
704
  }
705
+ /**
706
+ * Get a public project by ID (no authentication required)
707
+ * Corresponds to router.get('/public/:projectId', ProjectController.getPublicProject)
708
+ */
709
+ async getPublicProject(projectId) {
710
+ if (!projectId) {
711
+ throw new Error("Project ID is required");
712
+ }
713
+ try {
714
+ const response = await this._request(`/projects/public/${projectId}`, {
715
+ method: "GET",
716
+ methodName: "getPublicProject"
717
+ });
718
+ if (response.success) {
719
+ const iconSrc = response.data.icon ? `${this._apiUrl}/core/files/public/${response.data.icon.id}/download` : null;
720
+ return {
721
+ ...response.data,
722
+ icon: { src: iconSrc, ...response.data.icon }
723
+ };
724
+ }
725
+ throw new Error(response.message);
726
+ } catch (error) {
727
+ throw new Error(`Failed to get public project: ${error.message}`);
728
+ }
729
+ }
522
730
  async getProjectByKey(key) {
523
731
  this._requireReady("getProjectByKey");
524
732
  if (!key) {
525
733
  throw new Error("Project key is required");
526
734
  }
527
735
  try {
528
- return await this._request(`/projects/check-key/${key}`, {
736
+ const response = await this._request(`/projects/check-key/${key}`, {
529
737
  method: "GET",
530
738
  methodName: "getProjectByKey"
531
739
  });
740
+ if (response.success) {
741
+ return response.data;
742
+ }
743
+ throw new Error(response.message);
532
744
  } catch (error) {
533
745
  throw new Error(`Failed to get project by key: ${error.message}`);
534
746
  }
@@ -539,11 +751,15 @@ class CoreService extends import_BaseService.BaseService {
539
751
  throw new Error("Project ID is required");
540
752
  }
541
753
  try {
542
- return await this._request(`/projects/${projectId}`, {
754
+ const response = await this._request(`/projects/${projectId}`, {
543
755
  method: "PATCH",
544
756
  body: JSON.stringify(data),
545
757
  methodName: "updateProject"
546
758
  });
759
+ if (response.success) {
760
+ return response.data;
761
+ }
762
+ throw new Error(response.message);
547
763
  } catch (error) {
548
764
  throw new Error(`Failed to update project: ${error.message}`);
549
765
  }
@@ -554,11 +770,15 @@ class CoreService extends import_BaseService.BaseService {
554
770
  throw new Error("Project ID is required");
555
771
  }
556
772
  try {
557
- return await this._request(`/projects/${projectId}/components`, {
773
+ const response = await this._request(`/projects/${projectId}/components`, {
558
774
  method: "PATCH",
559
775
  body: JSON.stringify({ components }),
560
776
  methodName: "updateProjectComponents"
561
777
  });
778
+ if (response.success) {
779
+ return response.data;
780
+ }
781
+ throw new Error(response.message);
562
782
  } catch (error) {
563
783
  throw new Error(`Failed to update project components: ${error.message}`);
564
784
  }
@@ -569,11 +789,15 @@ class CoreService extends import_BaseService.BaseService {
569
789
  throw new Error("Project ID is required");
570
790
  }
571
791
  try {
572
- return await this._request(`/projects/${projectId}/settings`, {
792
+ const response = await this._request(`/projects/${projectId}/settings`, {
573
793
  method: "PATCH",
574
794
  body: JSON.stringify({ settings }),
575
795
  methodName: "updateProjectSettings"
576
796
  });
797
+ if (response.success) {
798
+ return response.data;
799
+ }
800
+ throw new Error(response.message);
577
801
  } catch (error) {
578
802
  throw new Error(`Failed to update project settings: ${error.message}`);
579
803
  }
@@ -584,11 +808,15 @@ class CoreService extends import_BaseService.BaseService {
584
808
  throw new Error("Project ID is required");
585
809
  }
586
810
  try {
587
- return await this._request(`/projects/${projectId}`, {
811
+ const response = await this._request(`/projects/${projectId}`, {
588
812
  method: "PATCH",
589
813
  body: JSON.stringify({ name }),
590
814
  methodName: "updateProjectName"
591
815
  });
816
+ if (response.success) {
817
+ return response.data;
818
+ }
819
+ throw new Error(response.message);
592
820
  } catch (error) {
593
821
  throw new Error(`Failed to update project name: ${error.message}`);
594
822
  }
@@ -599,26 +827,34 @@ class CoreService extends import_BaseService.BaseService {
599
827
  throw new Error("Project ID is required");
600
828
  }
601
829
  try {
602
- return await this._request(`/projects/${projectId}/tier`, {
830
+ const response = await this._request(`/projects/${projectId}/tier`, {
603
831
  method: "PATCH",
604
832
  body: JSON.stringify({ tier: pkg }),
605
833
  methodName: "updateProjectPackage"
606
834
  });
835
+ if (response.success) {
836
+ return response.data;
837
+ }
838
+ throw new Error(response.message);
607
839
  } catch (error) {
608
840
  throw new Error(`Failed to update project package: ${error.message}`);
609
841
  }
610
842
  }
611
- async duplicateProject(projectId, newName, newKey) {
843
+ async duplicateProject(projectId, newName, newKey, targetUserId) {
612
844
  this._requireReady("duplicateProject");
613
845
  if (!projectId) {
614
846
  throw new Error("Project ID is required");
615
847
  }
616
848
  try {
617
- return await this._request(`/projects/${projectId}/duplicate`, {
849
+ const response = await this._request(`/projects/${projectId}/duplicate`, {
618
850
  method: "POST",
619
- body: JSON.stringify({ name: newName, key: newKey }),
851
+ body: JSON.stringify({ name: newName, key: newKey, targetUserId }),
620
852
  methodName: "duplicateProject"
621
853
  });
854
+ if (response.success) {
855
+ return response.data;
856
+ }
857
+ throw new Error(response.message);
622
858
  } catch (error) {
623
859
  throw new Error(`Failed to duplicate project: ${error.message}`);
624
860
  }
@@ -629,10 +865,14 @@ class CoreService extends import_BaseService.BaseService {
629
865
  throw new Error("Project ID is required");
630
866
  }
631
867
  try {
632
- return await this._request(`/projects/${projectId}`, {
868
+ const response = await this._request(`/projects/${projectId}`, {
633
869
  method: "DELETE",
634
870
  methodName: "removeProject"
635
871
  });
872
+ if (response.success) {
873
+ return response.data;
874
+ }
875
+ throw new Error(response.message);
636
876
  } catch (error) {
637
877
  throw new Error(`Failed to remove project: ${error.message}`);
638
878
  }
@@ -643,10 +883,14 @@ class CoreService extends import_BaseService.BaseService {
643
883
  throw new Error("Project key is required");
644
884
  }
645
885
  try {
646
- return await this._request(`/projects/check-key/${key}`, {
886
+ const response = await this._request(`/projects/check-key/${key}`, {
647
887
  method: "GET",
648
888
  methodName: "checkProjectKeyAvailability"
649
889
  });
890
+ if (response.success) {
891
+ return response.data;
892
+ }
893
+ throw new Error(response.message);
650
894
  } catch (error) {
651
895
  throw new Error(`Failed to check project key availability: ${error.message}`);
652
896
  }
@@ -658,40 +902,62 @@ class CoreService extends import_BaseService.BaseService {
658
902
  throw new Error("Project ID is required");
659
903
  }
660
904
  try {
661
- return await this._request(`/projects/${projectId}/members`, {
905
+ const response = await this._request(`/projects/${projectId}/members`, {
662
906
  method: "GET",
663
907
  methodName: "getProjectMembers"
664
908
  });
909
+ if (response.success) {
910
+ return response.data;
911
+ }
912
+ throw new Error(response.message);
665
913
  } catch (error) {
666
914
  throw new Error(`Failed to get project members: ${error.message}`);
667
915
  }
668
916
  }
669
- async inviteMember(projectId, email, message, role = "guest") {
917
+ async inviteMember(projectId, email, role = "guest", options = {}) {
670
918
  this._requireReady("inviteMember");
671
- if (!projectId || !email) {
672
- throw new Error("Project ID and email are required");
919
+ if (!projectId || !email || !role) {
920
+ throw new Error("Project ID, email, and role are required");
673
921
  }
922
+ const { name, callbackUrl } = options;
923
+ const defaultCallbackUrl = typeof window === "undefined" ? "https://app.symbols.com/accept-invite" : `${window.location.origin}/accept-invite`;
674
924
  try {
675
- return await this._request(`/projects/${projectId}/invite`, {
925
+ const requestBody = {
926
+ email,
927
+ role,
928
+ callbackUrl: callbackUrl || defaultCallbackUrl
929
+ };
930
+ if (name) {
931
+ requestBody.name = name;
932
+ }
933
+ const response = await this._request(`/projects/${projectId}/invite`, {
676
934
  method: "POST",
677
- body: JSON.stringify({ email, role, message }),
935
+ body: JSON.stringify(requestBody),
678
936
  methodName: "inviteMember"
679
937
  });
938
+ if (response.success) {
939
+ return response.data;
940
+ }
941
+ throw new Error(response.message);
680
942
  } catch (error) {
681
943
  throw new Error(`Failed to invite member: ${error.message}`);
682
944
  }
683
945
  }
684
- async acceptInvite(projectId, token) {
946
+ async acceptInvite(token) {
685
947
  this._requireReady("acceptInvite");
686
- if (!projectId || !token) {
687
- throw new Error("Project ID and token are required");
948
+ if (!token) {
949
+ throw new Error("Invitation token is required");
688
950
  }
689
951
  try {
690
- return await this._request(`/projects/${projectId}/accept-invite`, {
952
+ const response = await this._request("/projects/accept-invite", {
691
953
  method: "POST",
692
954
  body: JSON.stringify({ token }),
693
955
  methodName: "acceptInvite"
694
956
  });
957
+ if (response.success) {
958
+ return response.data;
959
+ }
960
+ throw new Error(response.message);
695
961
  } catch (error) {
696
962
  throw new Error(`Failed to accept invite: ${error.message}`);
697
963
  }
@@ -702,11 +968,15 @@ class CoreService extends import_BaseService.BaseService {
702
968
  throw new Error("Project ID, member ID, and role are required");
703
969
  }
704
970
  try {
705
- return await this._request(`/projects/${projectId}/members/${memberId}`, {
971
+ const response = await this._request(`/projects/${projectId}/members/${memberId}`, {
706
972
  method: "PATCH",
707
973
  body: JSON.stringify({ role }),
708
974
  methodName: "updateMemberRole"
709
975
  });
976
+ if (response.success) {
977
+ return response.data;
978
+ }
979
+ throw new Error(response.message);
710
980
  } catch (error) {
711
981
  throw new Error(`Failed to update member role: ${error.message}`);
712
982
  }
@@ -717,10 +987,14 @@ class CoreService extends import_BaseService.BaseService {
717
987
  throw new Error("Project ID and member ID are required");
718
988
  }
719
989
  try {
720
- return await this._request(`/projects/${projectId}/members/${memberId}`, {
990
+ const response = await this._request(`/projects/${projectId}/members/${memberId}`, {
721
991
  method: "DELETE",
722
992
  methodName: "removeMember"
723
993
  });
994
+ if (response.success) {
995
+ return response.data;
996
+ }
997
+ throw new Error(response.message);
724
998
  } catch (error) {
725
999
  throw new Error(`Failed to remove member: ${error.message}`);
726
1000
  }
@@ -730,10 +1004,14 @@ class CoreService extends import_BaseService.BaseService {
730
1004
  this._requireReady("getAvailableLibraries");
731
1005
  const queryParams = new URLSearchParams(params).toString();
732
1006
  try {
733
- return await this._request(`/projects/libraries/available?${queryParams}`, {
1007
+ const response = await this._request(`/projects/libraries/available?${queryParams}`, {
734
1008
  method: "GET",
735
1009
  methodName: "getAvailableLibraries"
736
1010
  });
1011
+ if (response.success) {
1012
+ return response.data;
1013
+ }
1014
+ throw new Error(response.message);
737
1015
  } catch (error) {
738
1016
  throw new Error(`Failed to get available libraries: ${error.message}`);
739
1017
  }
@@ -744,10 +1022,14 @@ class CoreService extends import_BaseService.BaseService {
744
1022
  throw new Error("Project ID is required");
745
1023
  }
746
1024
  try {
747
- return await this._request(`/projects/${projectId}/libraries`, {
1025
+ const response = await this._request(`/projects/${projectId}/libraries`, {
748
1026
  method: "GET",
749
1027
  methodName: "getProjectLibraries"
750
1028
  });
1029
+ if (response.success) {
1030
+ return response.data;
1031
+ }
1032
+ throw new Error(response.message);
751
1033
  } catch (error) {
752
1034
  throw new Error(`Failed to get project libraries: ${error.message}`);
753
1035
  }
@@ -758,11 +1040,15 @@ class CoreService extends import_BaseService.BaseService {
758
1040
  throw new Error("Project ID and library IDs are required");
759
1041
  }
760
1042
  try {
761
- return await this._request(`/projects/${projectId}/libraries`, {
1043
+ const response = await this._request(`/projects/${projectId}/libraries`, {
762
1044
  method: "POST",
763
1045
  body: JSON.stringify({ libraryIds }),
764
1046
  methodName: "addProjectLibraries"
765
1047
  });
1048
+ if (response.success) {
1049
+ return response.data;
1050
+ }
1051
+ throw new Error(response.message);
766
1052
  } catch (error) {
767
1053
  throw new Error(`Failed to add project libraries: ${error.message}`);
768
1054
  }
@@ -773,11 +1059,15 @@ class CoreService extends import_BaseService.BaseService {
773
1059
  throw new Error("Project ID and library IDs are required");
774
1060
  }
775
1061
  try {
776
- return await this._request(`/projects/${projectId}/libraries`, {
1062
+ const response = await this._request(`/projects/${projectId}/libraries`, {
777
1063
  method: "DELETE",
778
1064
  body: JSON.stringify({ libraryIds }),
779
1065
  methodName: "removeProjectLibraries"
780
1066
  });
1067
+ if (response.success) {
1068
+ return response.data;
1069
+ }
1070
+ throw new Error(response.message);
781
1071
  } catch (error) {
782
1072
  throw new Error(`Failed to remove project libraries: ${error.message}`);
783
1073
  }
@@ -797,19 +1087,28 @@ class CoreService extends import_BaseService.BaseService {
797
1087
  formData.append("tags", JSON.stringify(options.tags));
798
1088
  }
799
1089
  if (options.visibility) {
800
- formData.append("visibility", options.visibility);
1090
+ formData.append("visibility", options.visibility || "public");
801
1091
  }
802
1092
  if (options.metadata) {
803
1093
  formData.append("metadata", JSON.stringify(options.metadata));
804
1094
  }
805
1095
  try {
806
- return await this._request("/files/upload", {
1096
+ const response = await this._request("/files/upload", {
807
1097
  method: "POST",
808
1098
  body: formData,
809
1099
  headers: {},
810
1100
  // Let browser set Content-Type for FormData
811
1101
  methodName: "uploadFile"
812
1102
  });
1103
+ if (!response.success) {
1104
+ throw new Error(response.message);
1105
+ }
1106
+ return {
1107
+ id: response.data.id,
1108
+ src: `${this._apiUrl}/core/files/public/${response.data.id}/download`,
1109
+ success: true,
1110
+ message: response.message
1111
+ };
813
1112
  } catch (error) {
814
1113
  throw new Error(`File upload failed: ${error.message}`);
815
1114
  }
@@ -823,13 +1122,17 @@ class CoreService extends import_BaseService.BaseService {
823
1122
  formData.append("icon", iconFile);
824
1123
  formData.append("projectId", projectId);
825
1124
  try {
826
- return await this._request("/files/upload-project-icon", {
1125
+ const response = await this._request("/files/upload-project-icon", {
827
1126
  method: "POST",
828
1127
  body: formData,
829
1128
  headers: {},
830
1129
  // Let browser set Content-Type for FormData
831
1130
  methodName: "updateProjectIcon"
832
1131
  });
1132
+ if (response.success) {
1133
+ return response.data;
1134
+ }
1135
+ throw new Error(response.message);
833
1136
  } catch (error) {
834
1137
  throw new Error(`Failed to update project icon: ${error.message}`);
835
1138
  }
@@ -848,7 +1151,7 @@ class CoreService extends import_BaseService.BaseService {
848
1151
  throw new Error("Project ID is required for checkout");
849
1152
  }
850
1153
  try {
851
- return await this._request("/payments/checkout", {
1154
+ const response = await this._request("/payments/checkout", {
852
1155
  method: "POST",
853
1156
  body: JSON.stringify({
854
1157
  projectId,
@@ -859,6 +1162,10 @@ class CoreService extends import_BaseService.BaseService {
859
1162
  }),
860
1163
  methodName: "checkout"
861
1164
  });
1165
+ if (response.success) {
1166
+ return response.data;
1167
+ }
1168
+ throw new Error(response.message);
862
1169
  } catch (error) {
863
1170
  throw new Error(`Failed to checkout: ${error.message}`);
864
1171
  }
@@ -869,10 +1176,14 @@ class CoreService extends import_BaseService.BaseService {
869
1176
  throw new Error("Project ID is required");
870
1177
  }
871
1178
  try {
872
- return await this._request(`/payments/subscription/${projectId}`, {
1179
+ const response = await this._request(`/payments/subscription/${projectId}`, {
873
1180
  method: "GET",
874
1181
  methodName: "getSubscriptionStatus"
875
1182
  });
1183
+ if (response.success) {
1184
+ return response.data;
1185
+ }
1186
+ throw new Error(response.message);
876
1187
  } catch (error) {
877
1188
  throw new Error(`Failed to get subscription status: ${error.message}`);
878
1189
  }
@@ -884,11 +1195,15 @@ class CoreService extends import_BaseService.BaseService {
884
1195
  throw new Error("Domain is required");
885
1196
  }
886
1197
  try {
887
- return await this._request("/dns/records", {
1198
+ const response = await this._request("/dns/records", {
888
1199
  method: "POST",
889
1200
  body: JSON.stringify({ domain, ...options }),
890
1201
  methodName: "createDnsRecord"
891
1202
  });
1203
+ if (response.success) {
1204
+ return response.data;
1205
+ }
1206
+ throw new Error(response.message);
892
1207
  } catch (error) {
893
1208
  throw new Error(`Failed to create DNS record: ${error.message}`);
894
1209
  }
@@ -899,10 +1214,14 @@ class CoreService extends import_BaseService.BaseService {
899
1214
  throw new Error("Domain is required");
900
1215
  }
901
1216
  try {
902
- return await this._request(`/dns/records/${domain}`, {
1217
+ const response = await this._request(`/dns/records/${domain}`, {
903
1218
  method: "GET",
904
1219
  methodName: "getDnsRecord"
905
1220
  });
1221
+ if (response.success) {
1222
+ return response.data;
1223
+ }
1224
+ throw new Error(response.message);
906
1225
  } catch (error) {
907
1226
  throw new Error(`Failed to get DNS record: ${error.message}`);
908
1227
  }
@@ -913,10 +1232,14 @@ class CoreService extends import_BaseService.BaseService {
913
1232
  throw new Error("Domain is required");
914
1233
  }
915
1234
  try {
916
- return await this._request(`/dns/records/${domain}`, {
1235
+ const response = await this._request(`/dns/records/${domain}`, {
917
1236
  method: "DELETE",
918
1237
  methodName: "removeDnsRecord"
919
1238
  });
1239
+ if (response.success) {
1240
+ return response.data;
1241
+ }
1242
+ throw new Error(response.message);
920
1243
  } catch (error) {
921
1244
  throw new Error(`Failed to remove DNS record: ${error.message}`);
922
1245
  }
@@ -927,7 +1250,7 @@ class CoreService extends import_BaseService.BaseService {
927
1250
  throw new Error("Project key is required");
928
1251
  }
929
1252
  try {
930
- return await this._request("/dns/project-domains", {
1253
+ const response = await this._request("/dns/project-domains", {
931
1254
  method: "POST",
932
1255
  body: JSON.stringify({
933
1256
  projectKey,
@@ -936,6 +1259,10 @@ class CoreService extends import_BaseService.BaseService {
936
1259
  }),
937
1260
  methodName: "setProjectDomains"
938
1261
  });
1262
+ if (response.success) {
1263
+ return response.data;
1264
+ }
1265
+ throw new Error(response.message);
939
1266
  } catch (error) {
940
1267
  throw new Error(`Failed to set project domains: ${error.message}`);
941
1268
  }
@@ -943,10 +1270,14 @@ class CoreService extends import_BaseService.BaseService {
943
1270
  // ==================== UTILITY METHODS ====================
944
1271
  async getHealthStatus() {
945
1272
  try {
946
- return await this._request("/health", {
1273
+ const response = await this._request("/health", {
947
1274
  method: "GET",
948
1275
  methodName: "getHealthStatus"
949
1276
  });
1277
+ if (response.success) {
1278
+ return response.data;
1279
+ }
1280
+ throw new Error(response.message);
950
1281
  } catch (error) {
951
1282
  throw new Error(`Failed to get health status: ${error.message}`);
952
1283
  }
@@ -980,7 +1311,10 @@ class CoreService extends import_BaseService.BaseService {
980
1311
  }),
981
1312
  methodName: "applyProjectChanges"
982
1313
  });
983
- return response;
1314
+ if (response.success) {
1315
+ return response.data;
1316
+ }
1317
+ throw new Error(response.message);
984
1318
  } catch (error) {
985
1319
  throw new Error(`Failed to apply project changes: ${error.message}`);
986
1320
  }
@@ -996,17 +1330,23 @@ class CoreService extends import_BaseService.BaseService {
996
1330
  }
997
1331
  const {
998
1332
  branch = "main",
1333
+ version = "latest",
999
1334
  includeHistory = false
1000
1335
  } = options;
1001
1336
  const queryParams = new URLSearchParams({
1002
1337
  branch,
1338
+ version,
1003
1339
  includeHistory: includeHistory.toString()
1004
1340
  }).toString();
1005
1341
  try {
1006
- return await this._request(`/projects/${projectId}/data?${queryParams}`, {
1342
+ const response = await this._request(`/projects/${projectId}/data?${queryParams}`, {
1007
1343
  method: "GET",
1008
1344
  methodName: "getProjectData"
1009
1345
  });
1346
+ if (response.success) {
1347
+ return response.data;
1348
+ }
1349
+ throw new Error(response.message);
1010
1350
  } catch (error) {
1011
1351
  throw new Error(`Failed to get project data: ${error.message}`);
1012
1352
  }
@@ -1030,10 +1370,14 @@ class CoreService extends import_BaseService.BaseService {
1030
1370
  limit: limit.toString()
1031
1371
  }).toString();
1032
1372
  try {
1033
- return await this._request(`/projects/${projectId}/versions?${queryParams}`, {
1373
+ const response = await this._request(`/projects/${projectId}/versions?${queryParams}`, {
1034
1374
  method: "GET",
1035
1375
  methodName: "getProjectVersions"
1036
1376
  });
1377
+ if (response.success) {
1378
+ return response.data;
1379
+ }
1380
+ throw new Error(response.message);
1037
1381
  } catch (error) {
1038
1382
  throw new Error(`Failed to get project versions: ${error.message}`);
1039
1383
  }
@@ -1056,7 +1400,7 @@ class CoreService extends import_BaseService.BaseService {
1056
1400
  type = "patch"
1057
1401
  } = options;
1058
1402
  try {
1059
- return await this._request(`/projects/${projectId}/restore`, {
1403
+ const response = await this._request(`/projects/${projectId}/restore`, {
1060
1404
  method: "POST",
1061
1405
  body: JSON.stringify({
1062
1406
  version,
@@ -1066,6 +1410,10 @@ class CoreService extends import_BaseService.BaseService {
1066
1410
  }),
1067
1411
  methodName: "restoreProjectVersion"
1068
1412
  });
1413
+ if (response.success) {
1414
+ return response.data;
1415
+ }
1416
+ throw new Error(response.message);
1069
1417
  } catch (error) {
1070
1418
  throw new Error(`Failed to restore project version: ${error.message}`);
1071
1419
  }
@@ -1158,11 +1506,15 @@ class CoreService extends import_BaseService.BaseService {
1158
1506
  throw new Error("Source branch, target branch, and title are required");
1159
1507
  }
1160
1508
  try {
1161
- return await this._request(`/projects/${projectId}/pull-requests`, {
1509
+ const response = await this._request(`/projects/${projectId}/pull-requests`, {
1162
1510
  method: "POST",
1163
1511
  body: JSON.stringify(pullRequestData),
1164
1512
  methodName: "createPullRequest"
1165
1513
  });
1514
+ if (response.success) {
1515
+ return response.data;
1516
+ }
1517
+ throw new Error(response.message);
1166
1518
  } catch (error) {
1167
1519
  throw new Error(`Failed to create pull request: ${error.message}`);
1168
1520
  }
@@ -1194,10 +1546,14 @@ class CoreService extends import_BaseService.BaseService {
1194
1546
  queryParams.append("target", target);
1195
1547
  }
1196
1548
  try {
1197
- return await this._request(`/projects/${projectId}/pull-requests?${queryParams.toString()}`, {
1549
+ const response = await this._request(`/projects/${projectId}/pull-requests?${queryParams.toString()}`, {
1198
1550
  method: "GET",
1199
1551
  methodName: "listPullRequests"
1200
1552
  });
1553
+ if (response.success) {
1554
+ return response.data;
1555
+ }
1556
+ throw new Error(response.message);
1201
1557
  } catch (error) {
1202
1558
  throw new Error(`Failed to list pull requests: ${error.message}`);
1203
1559
  }
@@ -1214,10 +1570,14 @@ class CoreService extends import_BaseService.BaseService {
1214
1570
  throw new Error("Pull request ID is required");
1215
1571
  }
1216
1572
  try {
1217
- return await this._request(`/projects/${projectId}/pull-requests/${prId}`, {
1573
+ const response = await this._request(`/projects/${projectId}/pull-requests/${prId}`, {
1218
1574
  method: "GET",
1219
1575
  methodName: "getPullRequest"
1220
1576
  });
1577
+ if (response.success) {
1578
+ return response.data;
1579
+ }
1580
+ throw new Error(response.message);
1221
1581
  } catch (error) {
1222
1582
  throw new Error(`Failed to get pull request: ${error.message}`);
1223
1583
  }
@@ -1238,11 +1598,15 @@ class CoreService extends import_BaseService.BaseService {
1238
1598
  throw new Error(`Invalid review status. Must be one of: ${validStatuses.join(", ")}`);
1239
1599
  }
1240
1600
  try {
1241
- return await this._request(`/projects/${projectId}/pull-requests/${prId}/review`, {
1601
+ const response = await this._request(`/projects/${projectId}/pull-requests/${prId}/review`, {
1242
1602
  method: "POST",
1243
1603
  body: JSON.stringify(reviewData),
1244
1604
  methodName: "reviewPullRequest"
1245
1605
  });
1606
+ if (response.success) {
1607
+ return response.data;
1608
+ }
1609
+ throw new Error(response.message);
1246
1610
  } catch (error) {
1247
1611
  throw new Error(`Failed to review pull request: ${error.message}`);
1248
1612
  }
@@ -1262,11 +1626,15 @@ class CoreService extends import_BaseService.BaseService {
1262
1626
  throw new Error("Comment value is required");
1263
1627
  }
1264
1628
  try {
1265
- return await this._request(`/projects/${projectId}/pull-requests/${prId}/comment`, {
1629
+ const response = await this._request(`/projects/${projectId}/pull-requests/${prId}/comment`, {
1266
1630
  method: "POST",
1267
1631
  body: JSON.stringify(commentData),
1268
1632
  methodName: "addPullRequestComment"
1269
1633
  });
1634
+ if (response.success) {
1635
+ return response.data;
1636
+ }
1637
+ throw new Error(response.message);
1270
1638
  } catch (error) {
1271
1639
  throw new Error(`Failed to add pull request comment: ${error.message}`);
1272
1640
  }
@@ -1287,7 +1655,10 @@ class CoreService extends import_BaseService.BaseService {
1287
1655
  method: "POST",
1288
1656
  methodName: "mergePullRequest"
1289
1657
  });
1290
- return response;
1658
+ if (response.success) {
1659
+ return response.data;
1660
+ }
1661
+ throw new Error(response.message);
1291
1662
  } catch (error) {
1292
1663
  if (error.message.includes("conflicts") || error.message.includes("409")) {
1293
1664
  throw new Error(`Pull request has merge conflicts: ${error.message}`);
@@ -1307,10 +1678,14 @@ class CoreService extends import_BaseService.BaseService {
1307
1678
  throw new Error("Pull request ID is required");
1308
1679
  }
1309
1680
  try {
1310
- return await this._request(`/projects/${projectId}/pull-requests/${prId}/diff`, {
1681
+ const response = await this._request(`/projects/${projectId}/pull-requests/${prId}/diff`, {
1311
1682
  method: "GET",
1312
1683
  methodName: "getPullRequestDiff"
1313
1684
  });
1685
+ if (response.success) {
1686
+ return response.data;
1687
+ }
1688
+ throw new Error(response.message);
1314
1689
  } catch (error) {
1315
1690
  throw new Error(`Failed to get pull request diff: ${error.message}`);
1316
1691
  }
@@ -1424,10 +1799,14 @@ class CoreService extends import_BaseService.BaseService {
1424
1799
  throw new Error("Project ID is required");
1425
1800
  }
1426
1801
  try {
1427
- return await this._request(`/projects/${projectId}/branches`, {
1802
+ const response = await this._request(`/projects/${projectId}/branches`, {
1428
1803
  method: "GET",
1429
1804
  methodName: "listBranches"
1430
1805
  });
1806
+ if (response.success) {
1807
+ return response.data;
1808
+ }
1809
+ throw new Error(response.message);
1431
1810
  } catch (error) {
1432
1811
  throw new Error(`Failed to list branches: ${error.message}`);
1433
1812
  }
@@ -1445,11 +1824,15 @@ class CoreService extends import_BaseService.BaseService {
1445
1824
  }
1446
1825
  const { name, source = "main" } = branchData;
1447
1826
  try {
1448
- return await this._request(`/projects/${projectId}/branches`, {
1827
+ const response = await this._request(`/projects/${projectId}/branches`, {
1449
1828
  method: "POST",
1450
1829
  body: JSON.stringify({ name, source }),
1451
1830
  methodName: "createBranch"
1452
1831
  });
1832
+ if (response.success) {
1833
+ return response.data;
1834
+ }
1835
+ throw new Error(response.message);
1453
1836
  } catch (error) {
1454
1837
  throw new Error(`Failed to create branch: ${error.message}`);
1455
1838
  }
@@ -1469,10 +1852,14 @@ class CoreService extends import_BaseService.BaseService {
1469
1852
  throw new Error("Cannot delete main branch");
1470
1853
  }
1471
1854
  try {
1472
- return await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}`, {
1855
+ const response = await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}`, {
1473
1856
  method: "DELETE",
1474
1857
  methodName: "deleteBranch"
1475
1858
  });
1859
+ if (response.success) {
1860
+ return response.data;
1861
+ }
1862
+ throw new Error(response.message);
1476
1863
  } catch (error) {
1477
1864
  throw new Error(`Failed to delete branch: ${error.message}`);
1478
1865
  }
@@ -1495,11 +1882,15 @@ class CoreService extends import_BaseService.BaseService {
1495
1882
  throw new Error("Cannot rename main branch");
1496
1883
  }
1497
1884
  try {
1498
- return await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}/rename`, {
1885
+ const response = await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}/rename`, {
1499
1886
  method: "POST",
1500
1887
  body: JSON.stringify({ newName }),
1501
1888
  methodName: "renameBranch"
1502
1889
  });
1890
+ if (response.success) {
1891
+ return response.data;
1892
+ }
1893
+ throw new Error(response.message);
1503
1894
  } catch (error) {
1504
1895
  throw new Error(`Failed to rename branch: ${error.message}`);
1505
1896
  }
@@ -1507,7 +1898,7 @@ class CoreService extends import_BaseService.BaseService {
1507
1898
  /**
1508
1899
  * Get changes/diff for a branch compared to another version
1509
1900
  */
1510
- async getBranchChanges(projectId, branchName, options = {}) {
1901
+ async getBranchChanges(projectId, branchName = "main", options = {}) {
1511
1902
  this._requireReady("getBranchChanges");
1512
1903
  if (!projectId) {
1513
1904
  throw new Error("Project ID is required");
@@ -1529,10 +1920,14 @@ class CoreService extends import_BaseService.BaseService {
1529
1920
  const queryString = queryParams.toString();
1530
1921
  const url = `/projects/${projectId}/branches/${encodeURIComponent(branchName)}/changes${queryString ? `?${queryString}` : ""}`;
1531
1922
  try {
1532
- return await this._request(url, {
1923
+ const response = await this._request(url, {
1533
1924
  method: "GET",
1534
1925
  methodName: "getBranchChanges"
1535
1926
  });
1927
+ if (response.success) {
1928
+ return response.data;
1929
+ }
1930
+ throw new Error(response.message);
1536
1931
  } catch (error) {
1537
1932
  throw new Error(`Failed to get branch changes: ${error.message}`);
1538
1933
  }
@@ -1563,11 +1958,15 @@ class CoreService extends import_BaseService.BaseService {
1563
1958
  ...changes && { changes }
1564
1959
  };
1565
1960
  try {
1566
- return await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}/merge`, {
1961
+ const response = await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}/merge`, {
1567
1962
  method: "POST",
1568
1963
  body: JSON.stringify(requestBody),
1569
1964
  methodName: "mergeBranch"
1570
1965
  });
1966
+ if (response.success) {
1967
+ return response.data;
1968
+ }
1969
+ throw new Error(response.message);
1571
1970
  } catch (error) {
1572
1971
  if (error.message.includes("conflicts") || error.message.includes("409")) {
1573
1972
  throw new Error(`Merge conflicts detected: ${error.message}`);
@@ -1587,10 +1986,14 @@ class CoreService extends import_BaseService.BaseService {
1587
1986
  throw new Error("Branch name is required");
1588
1987
  }
1589
1988
  try {
1590
- return await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}/reset`, {
1989
+ const response = await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}/reset`, {
1591
1990
  method: "POST",
1592
1991
  methodName: "resetBranch"
1593
1992
  });
1993
+ if (response.success) {
1994
+ return response.data;
1995
+ }
1996
+ throw new Error(response.message);
1594
1997
  } catch (error) {
1595
1998
  throw new Error(`Failed to reset branch: ${error.message}`);
1596
1999
  }
@@ -1608,11 +2011,15 @@ class CoreService extends import_BaseService.BaseService {
1608
2011
  }
1609
2012
  const { version, branch = "main" } = publishData;
1610
2013
  try {
1611
- return await this._request(`/projects/${projectId}/publish`, {
2014
+ const response = await this._request(`/projects/${projectId}/publish`, {
1612
2015
  method: "POST",
1613
2016
  body: JSON.stringify({ version, branch }),
1614
2017
  methodName: "publishVersion"
1615
2018
  });
2019
+ if (response.success) {
2020
+ return response.data;
2021
+ }
2022
+ throw new Error(response.message);
1616
2023
  } catch (error) {
1617
2024
  throw new Error(`Failed to publish version: ${error.message}`);
1618
2025
  }
@@ -1738,6 +2145,143 @@ class CoreService extends import_BaseService.BaseService {
1738
2145
  }
1739
2146
  return await this.deleteBranch(projectId, branchName);
1740
2147
  }
2148
+ // ==================== ADMIN METHODS ====================
2149
+ /**
2150
+ * Get admin users list with comprehensive filtering and search capabilities
2151
+ * Requires admin or super_admin global role
2152
+ */
2153
+ async getAdminUsers(params = {}) {
2154
+ this._requireReady("getAdminUsers");
2155
+ const {
2156
+ emails,
2157
+ ids,
2158
+ query,
2159
+ status,
2160
+ page = 1,
2161
+ limit = 50,
2162
+ sort = { field: "createdAt", order: "desc" }
2163
+ } = params;
2164
+ const queryParams = new URLSearchParams();
2165
+ if (emails) {
2166
+ queryParams.append("emails", emails);
2167
+ }
2168
+ if (ids) {
2169
+ queryParams.append("ids", ids);
2170
+ }
2171
+ if (query) {
2172
+ queryParams.append("query", query);
2173
+ }
2174
+ if (status) {
2175
+ queryParams.append("status", status);
2176
+ }
2177
+ if (page) {
2178
+ queryParams.append("page", page.toString());
2179
+ }
2180
+ if (limit) {
2181
+ queryParams.append("limit", limit.toString());
2182
+ }
2183
+ if (sort && sort.field) {
2184
+ queryParams.append("sort[field]", sort.field);
2185
+ queryParams.append("sort[order]", sort.order || "desc");
2186
+ }
2187
+ const queryString = queryParams.toString();
2188
+ const url = `/users/admin/users${queryString ? `?${queryString}` : ""}`;
2189
+ try {
2190
+ const response = await this._request(url, {
2191
+ method: "GET",
2192
+ methodName: "getAdminUsers"
2193
+ });
2194
+ if (response.success) {
2195
+ return response.data;
2196
+ }
2197
+ throw new Error(response.message);
2198
+ } catch (error) {
2199
+ throw new Error(`Failed to get admin users: ${error.message}`);
2200
+ }
2201
+ }
2202
+ /**
2203
+ * Assign projects to a specific user
2204
+ * Requires admin or super_admin global role
2205
+ */
2206
+ async assignProjectsToUser(userId, options = {}) {
2207
+ this._requireReady("assignProjectsToUser");
2208
+ if (!userId) {
2209
+ throw new Error("User ID is required");
2210
+ }
2211
+ const {
2212
+ projectIds,
2213
+ role = "guest"
2214
+ } = options;
2215
+ const requestBody = {
2216
+ userId,
2217
+ role
2218
+ };
2219
+ if (projectIds && Array.isArray(projectIds)) {
2220
+ requestBody.projectIds = projectIds;
2221
+ }
2222
+ try {
2223
+ const response = await this._request("/assign-projects", {
2224
+ method: "POST",
2225
+ body: JSON.stringify(requestBody),
2226
+ methodName: "assignProjectsToUser"
2227
+ });
2228
+ if (response.success) {
2229
+ return response.data;
2230
+ }
2231
+ throw new Error(response.message);
2232
+ } catch (error) {
2233
+ throw new Error(`Failed to assign projects to user: ${error.message}`);
2234
+ }
2235
+ }
2236
+ /**
2237
+ * Helper method for admin users search
2238
+ */
2239
+ async searchAdminUsers(searchQuery, options = {}) {
2240
+ return await this.getAdminUsers({
2241
+ query: searchQuery,
2242
+ ...options
2243
+ });
2244
+ }
2245
+ /**
2246
+ * Helper method to get admin users by email list
2247
+ */
2248
+ async getAdminUsersByEmails(emails, options = {}) {
2249
+ const emailList = Array.isArray(emails) ? emails.join(",") : emails;
2250
+ return await this.getAdminUsers({
2251
+ emails: emailList,
2252
+ ...options
2253
+ });
2254
+ }
2255
+ /**
2256
+ * Helper method to get admin users by ID list
2257
+ */
2258
+ async getAdminUsersByIds(ids, options = {}) {
2259
+ const idList = Array.isArray(ids) ? ids.join(",") : ids;
2260
+ return await this.getAdminUsers({
2261
+ ids: idList,
2262
+ ...options
2263
+ });
2264
+ }
2265
+ /**
2266
+ * Helper method to assign specific projects to a user with a specific role
2267
+ */
2268
+ async assignSpecificProjectsToUser(userId, projectIds, role = "guest") {
2269
+ if (!Array.isArray(projectIds) || projectIds.length === 0) {
2270
+ throw new Error("Project IDs must be a non-empty array");
2271
+ }
2272
+ return await this.assignProjectsToUser(userId, {
2273
+ projectIds,
2274
+ role
2275
+ });
2276
+ }
2277
+ /**
2278
+ * Helper method to assign all projects to a user with a specific role
2279
+ */
2280
+ async assignAllProjectsToUser(userId, role = "guest") {
2281
+ return await this.assignProjectsToUser(userId, {
2282
+ role
2283
+ });
2284
+ }
1741
2285
  // Cleanup
1742
2286
  destroy() {
1743
2287
  if (this._tokenManager) {