@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
@@ -67,12 +67,8 @@ var CONFIG = {
67
67
  // Environment-specific configurations
68
68
  local: {
69
69
  // local
70
- baseUrl: "http://localhost:8080",
71
- // For symstory api
72
70
  socketUrl: "http://localhost:8080",
73
71
  // For socket api
74
- routerUrl: "http://localhost:8080",
75
- // For router api
76
72
  apiUrl: "http://localhost:8080",
77
73
  // For server api
78
74
  basedEnv: "development",
@@ -90,29 +86,25 @@ var CONFIG = {
90
86
  }
91
87
  },
92
88
  development: {
93
- baseUrl: "https://dev.api.symbols.app",
94
89
  socketUrl: "https://dev.api.symbols.app",
95
- routerUrl: "https://dev.api.symbols.app",
96
90
  apiUrl: "https://dev.api.symbols.app",
97
- basedEnv: "development",
98
- basedProject: "platform-v2-sm",
99
- basedOrg: "symbols",
100
91
  githubClientId: "Ov23liHxyWFBxS8f1gnF"
101
92
  },
102
93
  testing: {
103
- baseUrl: "https://test.api.symbols.app",
104
94
  socketUrl: "https://test.api.symbols.app",
105
- routerUrl: "https://test.api.symbols.app",
106
95
  apiUrl: "https://test.api.symbols.app",
107
96
  basedEnv: "testing",
108
97
  basedProject: "platform-v2-sm",
109
98
  basedOrg: "symbols",
110
99
  githubClientId: "Ov23liHxyWFBxS8f1gnF"
111
100
  },
101
+ upcoming: {
102
+ socketUrl: "https://upcoming.api.symbols.app",
103
+ apiUrl: "https://upcoming.api.symbols.app",
104
+ githubClientId: "Ov23liWF7NvdZ056RV5J"
105
+ },
112
106
  staging: {
113
- baseUrl: "https://staging.api.symbols.app",
114
107
  socketUrl: "https://staging.api.symbols.app",
115
- routerUrl: "https://staging.api.symbols.app",
116
108
  apiUrl: "https://staging.api.symbols.app",
117
109
  basedEnv: "staging",
118
110
  basedProject: "platform-v2-sm",
@@ -120,9 +112,7 @@ var CONFIG = {
120
112
  githubClientId: "Ov23ligwZDQVD0VfuWNa"
121
113
  },
122
114
  production: {
123
- baseUrl: "https://api.symbols.app",
124
115
  socketUrl: "https://api.symbols.app",
125
- routerUrl: "https://api.symbols.app",
126
116
  apiUrl: "https://api.symbols.app",
127
117
  basedEnv: "production",
128
118
  basedProject: "platform-v2-sm",
@@ -143,9 +133,7 @@ var getConfig = () => {
143
133
  const envConfig = { ...CONFIG.common, ...CONFIG[env] };
144
134
  const finalConfig = {
145
135
  ...envConfig,
146
- baseUrl: process.env.SYMBOLS_APP_BASE_URL || envConfig.baseUrl,
147
136
  socketUrl: process.env.SYMBOLS_APP_SOCKET_URL || envConfig.socketUrl,
148
- routerUrl: process.env.SYMBOLS_APP_ROUTER_URL || envConfig.routerUrl,
149
137
  apiUrl: process.env.SYMBOLS_APP_API_URL || envConfig.apiUrl,
150
138
  basedEnv: process.env.SYMBOLS_APP_BASED_ENV || envConfig.basedEnv,
151
139
  basedProject: process.env.SYMBOLS_APP_BASED_PROJECT || envConfig.basedProject,
@@ -158,12 +146,8 @@ var getConfig = () => {
158
146
  // Store all environment variables for potential future use
159
147
  };
160
148
  const requiredFields = [
161
- "baseUrl",
162
149
  "socketUrl",
163
150
  "apiUrl",
164
- "basedEnv",
165
- "basedProject",
166
- "basedOrg",
167
151
  "githubClientId",
168
152
  "googleClientId"
169
153
  ];
@@ -322,7 +306,28 @@ var TokenManager = class {
322
306
  return true;
323
307
  }
324
308
  const now = Date.now();
325
- return now < this.tokens.expiresAt - this.config.refreshBuffer;
309
+ const isValid = now < this.tokens.expiresAt - this.config.refreshBuffer;
310
+ if (!isValid) {
311
+ console.log("[TokenManager] Access token is expired or near expiry:", {
312
+ now: new Date(now).toISOString(),
313
+ expiresAt: new Date(this.tokens.expiresAt).toISOString(),
314
+ refreshBuffer: this.config.refreshBuffer
315
+ });
316
+ }
317
+ return isValid;
318
+ }
319
+ /**
320
+ * Check if access token exists and is not expired (without refresh buffer)
321
+ */
322
+ isAccessTokenActuallyValid() {
323
+ if (!this.tokens.accessToken) {
324
+ return false;
325
+ }
326
+ if (!this.tokens.expiresAt) {
327
+ return true;
328
+ }
329
+ const now = Date.now();
330
+ return now < this.tokens.expiresAt;
326
331
  }
327
332
  /**
328
333
  * Check if tokens exist (regardless of expiry)
@@ -448,40 +453,54 @@ var TokenManager = class {
448
453
  * Save tokens to storage
449
454
  */
450
455
  saveTokens() {
451
- const { storage } = this;
452
- const keys = this.storageKeys;
453
- if (this.tokens.accessToken) {
454
- storage.setItem(keys.accessToken, this.tokens.accessToken);
455
- }
456
- if (this.tokens.refreshToken) {
457
- storage.setItem(keys.refreshToken, this.tokens.refreshToken);
458
- }
459
- if (this.tokens.expiresAt) {
460
- storage.setItem(keys.expiresAt, this.tokens.expiresAt.toString());
461
- }
462
- if (this.tokens.expiresIn) {
463
- storage.setItem(keys.expiresIn, this.tokens.expiresIn.toString());
456
+ try {
457
+ const { storage } = this;
458
+ const keys = this.storageKeys;
459
+ if (this.tokens.accessToken) {
460
+ storage.setItem(keys.accessToken, this.tokens.accessToken);
461
+ }
462
+ if (this.tokens.refreshToken) {
463
+ storage.setItem(keys.refreshToken, this.tokens.refreshToken);
464
+ }
465
+ if (this.tokens.expiresAt) {
466
+ storage.setItem(keys.expiresAt, this.tokens.expiresAt.toString());
467
+ }
468
+ if (this.tokens.expiresIn) {
469
+ storage.setItem(keys.expiresIn, this.tokens.expiresIn.toString());
470
+ }
471
+ } catch (error) {
472
+ console.error("[TokenManager] Error saving tokens to storage:", error);
464
473
  }
465
474
  }
466
475
  /**
467
476
  * Load tokens from storage
468
477
  */
469
478
  loadTokens() {
470
- const { storage } = this;
471
- const keys = this.storageKeys;
472
- const accessToken = storage.getItem(keys.accessToken);
473
- const refreshToken = storage.getItem(keys.refreshToken);
474
- const expiresAt = storage.getItem(keys.expiresAt);
475
- const expiresIn = storage.getItem(keys.expiresIn);
476
- if (accessToken) {
479
+ try {
480
+ const { storage } = this;
481
+ const keys = this.storageKeys;
482
+ const accessToken = storage.getItem(keys.accessToken);
483
+ const refreshToken = storage.getItem(keys.refreshToken);
484
+ const expiresAt = storage.getItem(keys.expiresAt);
485
+ const expiresIn = storage.getItem(keys.expiresIn);
486
+ if (accessToken) {
487
+ this.tokens = {
488
+ accessToken,
489
+ refreshToken,
490
+ expiresAt: expiresAt ? parseInt(expiresAt, 10) : null,
491
+ expiresIn: expiresIn ? parseInt(expiresIn, 10) : null,
492
+ tokenType: "Bearer"
493
+ };
494
+ this.scheduleRefresh();
495
+ }
496
+ } catch (error) {
497
+ console.error("[TokenManager] Error loading tokens from storage:", error);
477
498
  this.tokens = {
478
- accessToken,
479
- refreshToken,
480
- expiresAt: expiresAt ? parseInt(expiresAt, 10) : null,
481
- expiresIn: expiresIn ? parseInt(expiresIn, 10) : null,
482
- tokenType: "Bearer"
499
+ accessToken: null,
500
+ refreshToken: null,
501
+ expiresAt: null,
502
+ expiresIn: null
483
503
  };
484
- this.scheduleRefresh();
485
504
  }
486
505
  }
487
506
  /**
@@ -547,18 +566,18 @@ var CoreService = class extends BaseService {
547
566
  super(config);
548
567
  this._client = null;
549
568
  this._initialized = false;
550
- this._baseUrl = null;
569
+ this._apiUrl = null;
551
570
  this._tokenManager = null;
552
571
  }
553
572
  init({ context }) {
554
573
  try {
555
574
  const { appKey, authToken } = context || this._context;
556
- this._baseUrl = environment_default.apiUrl || environment_default.baseUrl;
557
- if (!this._baseUrl) {
575
+ this._apiUrl = environment_default.apiUrl;
576
+ if (!this._apiUrl) {
558
577
  throw new Error("Core service base URL not configured");
559
578
  }
560
579
  this._tokenManager = getTokenManager({
561
- apiUrl: this._baseUrl,
580
+ apiUrl: this._apiUrl,
562
581
  onTokenRefresh: (tokens) => {
563
582
  this.updateContext({ authToken: tokens.accessToken });
564
583
  },
@@ -569,12 +588,12 @@ var CoreService = class extends BaseService {
569
588
  console.error("Token management error:", error);
570
589
  }
571
590
  });
572
- if (authToken) {
591
+ if (authToken && !this._tokenManager.hasTokens()) {
573
592
  this._tokenManager.setTokens({ access_token: authToken });
574
593
  }
575
594
  this._info = {
576
595
  config: {
577
- baseUrl: this._baseUrl,
596
+ apiUrl: this._apiUrl,
578
597
  appKey: appKey ? `${appKey.substr(0, 4)}...${appKey.substr(-4)}` : null,
579
598
  hasToken: Boolean(authToken)
580
599
  }
@@ -592,11 +611,15 @@ var CoreService = class extends BaseService {
592
611
  "register",
593
612
  "login",
594
613
  "googleAuth",
614
+ "googleAuthCallback",
595
615
  "githubAuth",
596
616
  "requestPasswordReset",
597
617
  "confirmPasswordReset",
598
618
  "confirmRegistration",
599
- "verifyEmail"
619
+ "verifyEmail",
620
+ "listPublicProjects",
621
+ "getPublicProject",
622
+ "getHealthStatus"
600
623
  ]);
601
624
  return !noInitMethods.has(methodName);
602
625
  }
@@ -627,24 +650,34 @@ var CoreService = class extends BaseService {
627
650
  authHeader: this._tokenManager.getAuthHeader()
628
651
  };
629
652
  }
653
+ // Helper method to check if user is authenticated
654
+ isAuthenticated() {
655
+ if (!this._tokenManager) {
656
+ return false;
657
+ }
658
+ return this._tokenManager.hasTokens();
659
+ }
660
+ // Helper method to check if user has valid tokens
661
+ hasValidTokens() {
662
+ if (!this._tokenManager) {
663
+ return false;
664
+ }
665
+ return this._tokenManager.hasTokens() && this._tokenManager.isAccessTokenValid();
666
+ }
630
667
  // Helper method to make HTTP requests
631
668
  async _request(endpoint, options = {}) {
632
- const url = `${this._baseUrl}/core${endpoint}`;
633
- const defaultHeaders = {
634
- "Content-Type": "application/json"
635
- };
669
+ const url = `${this._apiUrl}/core${endpoint}`;
670
+ const defaultHeaders = {};
671
+ if (!(options.body instanceof FormData)) {
672
+ defaultHeaders["Content-Type"] = "application/json";
673
+ }
636
674
  if (this._requiresInit(options.methodName) && this._tokenManager) {
637
675
  try {
638
676
  const validToken = await this._tokenManager.ensureValidToken();
639
- console.log(`[CoreService] Token check for ${options.methodName}:`, {
640
- hasValidToken: Boolean(validToken),
641
- tokenPreview: validToken ? `${validToken.substring(0, 20)}...` : null
642
- });
643
677
  if (validToken) {
644
678
  const authHeader = this._tokenManager.getAuthHeader();
645
679
  if (authHeader) {
646
680
  defaultHeaders.Authorization = authHeader;
647
- console.log(`[CoreService] Added auth header for ${options.methodName}`);
648
681
  }
649
682
  }
650
683
  } catch (error) {
@@ -654,7 +687,6 @@ var CoreService = class extends BaseService {
654
687
  const { authToken } = this._context;
655
688
  if (authToken) {
656
689
  defaultHeaders.Authorization = `Bearer ${authToken}`;
657
- console.log(`[CoreService] Using context token for ${options.methodName}`);
658
690
  }
659
691
  }
660
692
  try {
@@ -681,11 +713,15 @@ var CoreService = class extends BaseService {
681
713
  // ==================== AUTH METHODS ====================
682
714
  async register(userData) {
683
715
  try {
684
- return await this._request("/auth/register", {
716
+ const response = await this._request("/auth/register", {
685
717
  method: "POST",
686
718
  body: JSON.stringify(userData),
687
719
  methodName: "register"
688
720
  });
721
+ if (response.success) {
722
+ return response.data;
723
+ }
724
+ throw new Error(response.message);
689
725
  } catch (error) {
690
726
  throw new Error(`Registration failed: ${error.message}`);
691
727
  }
@@ -711,7 +747,10 @@ var CoreService = class extends BaseService {
711
747
  }
712
748
  this.updateContext({ authToken: tokens.accessToken });
713
749
  }
714
- return response;
750
+ if (response.success) {
751
+ return response.data;
752
+ }
753
+ throw new Error(response.message);
715
754
  } catch (error) {
716
755
  throw new Error(`Login failed: ${error.message}`);
717
756
  }
@@ -737,11 +776,15 @@ var CoreService = class extends BaseService {
737
776
  }
738
777
  async refreshToken(refreshToken) {
739
778
  try {
740
- return await this._request("/auth/refresh", {
779
+ const response = await this._request("/auth/refresh", {
741
780
  method: "POST",
742
781
  body: JSON.stringify({ refreshToken }),
743
782
  methodName: "refreshToken"
744
783
  });
784
+ if (response.success) {
785
+ return response.data;
786
+ }
787
+ throw new Error(response.message);
745
788
  } catch (error) {
746
789
  throw new Error(`Token refresh failed: ${error.message}`);
747
790
  }
@@ -767,7 +810,10 @@ var CoreService = class extends BaseService {
767
810
  }
768
811
  this.updateContext({ authToken: tokens.accessToken });
769
812
  }
770
- return response;
813
+ if (response.success) {
814
+ return response.data;
815
+ }
816
+ throw new Error(response.message);
771
817
  } catch (error) {
772
818
  throw new Error(`Google auth failed: ${error.message}`);
773
819
  }
@@ -793,40 +839,84 @@ var CoreService = class extends BaseService {
793
839
  }
794
840
  this.updateContext({ authToken: tokens.accessToken });
795
841
  }
796
- return response;
842
+ if (response.success) {
843
+ return response.data;
844
+ }
845
+ throw new Error(response.message);
797
846
  } catch (error) {
798
847
  throw new Error(`GitHub auth failed: ${error.message}`);
799
848
  }
800
849
  }
850
+ async googleAuthCallback(code, redirectUri) {
851
+ var _a;
852
+ try {
853
+ const response = await this._request("/auth/google/callback", {
854
+ method: "POST",
855
+ body: JSON.stringify({ code, redirectUri }),
856
+ methodName: "googleAuthCallback"
857
+ });
858
+ if (response.success && response.data && response.data.tokens) {
859
+ const { tokens } = response.data;
860
+ const tokenData = {
861
+ access_token: tokens.accessToken,
862
+ refresh_token: tokens.refreshToken,
863
+ expires_in: (_a = tokens.accessTokenExp) == null ? void 0 : _a.expiresIn,
864
+ token_type: "Bearer"
865
+ };
866
+ if (this._tokenManager) {
867
+ this._tokenManager.setTokens(tokenData);
868
+ }
869
+ this.updateContext({ authToken: tokens.accessToken });
870
+ }
871
+ if (response.success) {
872
+ return response.data;
873
+ }
874
+ throw new Error(response.message);
875
+ } catch (error) {
876
+ throw new Error(`Google auth callback failed: ${error.message}`);
877
+ }
878
+ }
801
879
  async requestPasswordReset(email) {
802
880
  try {
803
- return await this._request("/auth/request-password-reset", {
881
+ const response = await this._request("/auth/request-password-reset", {
804
882
  method: "POST",
805
883
  body: JSON.stringify({ email }),
806
884
  methodName: "requestPasswordReset"
807
885
  });
886
+ if (response.success) {
887
+ return response.data;
888
+ }
889
+ throw new Error(response.message);
808
890
  } catch (error) {
809
891
  throw new Error(`Password reset request failed: ${error.message}`);
810
892
  }
811
893
  }
812
894
  async confirmPasswordReset(token, password) {
813
895
  try {
814
- return await this._request("/auth/reset-password-confirm", {
896
+ const response = await this._request("/auth/reset-password-confirm", {
815
897
  method: "POST",
816
898
  body: JSON.stringify({ token, password }),
817
899
  methodName: "confirmPasswordReset"
818
900
  });
901
+ if (response.success) {
902
+ return response.data;
903
+ }
904
+ throw new Error(response.message);
819
905
  } catch (error) {
820
906
  throw new Error(`Password reset confirmation failed: ${error.message}`);
821
907
  }
822
908
  }
823
909
  async confirmRegistration(token) {
824
910
  try {
825
- return await this._request("/auth/register-confirmation", {
911
+ const response = await this._request("/auth/register-confirmation", {
826
912
  method: "POST",
827
913
  body: JSON.stringify({ token }),
828
914
  methodName: "confirmRegistration"
829
915
  });
916
+ if (response.success) {
917
+ return response.data;
918
+ }
919
+ throw new Error(response.message);
830
920
  } catch (error) {
831
921
  throw new Error(`Registration confirmation failed: ${error.message}`);
832
922
  }
@@ -834,10 +924,14 @@ var CoreService = class extends BaseService {
834
924
  async requestPasswordChange() {
835
925
  this._requireReady("requestPasswordChange");
836
926
  try {
837
- return await this._request("/auth/request-password-change", {
927
+ const response = await this._request("/auth/request-password-change", {
838
928
  method: "POST",
839
929
  methodName: "requestPasswordChange"
840
930
  });
931
+ if (response.success) {
932
+ return response.data;
933
+ }
934
+ throw new Error(response.message);
841
935
  } catch (error) {
842
936
  throw new Error(`Password change request failed: ${error.message}`);
843
937
  }
@@ -845,11 +939,15 @@ var CoreService = class extends BaseService {
845
939
  async confirmPasswordChange(currentPassword, newPassword, code) {
846
940
  this._requireReady("confirmPasswordChange");
847
941
  try {
848
- return await this._request("/auth/confirm-password-change", {
942
+ const response = await this._request("/auth/confirm-password-change", {
849
943
  method: "POST",
850
944
  body: JSON.stringify({ currentPassword, newPassword, code }),
851
945
  methodName: "confirmPasswordChange"
852
946
  });
947
+ if (response.success) {
948
+ return response.data;
949
+ }
950
+ throw new Error(response.message);
853
951
  } catch (error) {
854
952
  throw new Error(`Password change confirmation failed: ${error.message}`);
855
953
  }
@@ -857,10 +955,14 @@ var CoreService = class extends BaseService {
857
955
  async getMe() {
858
956
  this._requireReady("getMe");
859
957
  try {
860
- return await this._request("/auth/me", {
958
+ const response = await this._request("/auth/me", {
861
959
  method: "GET",
862
960
  methodName: "getMe"
863
961
  });
962
+ if (response.success) {
963
+ return response.data;
964
+ }
965
+ throw new Error(response.message);
864
966
  } catch (error) {
865
967
  throw new Error(`Failed to get user profile: ${error.message}`);
866
968
  }
@@ -888,35 +990,57 @@ var CoreService = class extends BaseService {
888
990
  try {
889
991
  await this._tokenManager.ensureValidToken();
890
992
  } catch (error) {
891
- this._tokenManager.clearTokens();
993
+ console.warn("[CoreService] Token refresh failed:", error.message);
994
+ if (error.message.includes("401") || error.message.includes("403") || error.message.includes("invalid") || error.message.includes("expired")) {
995
+ this._tokenManager.clearTokens();
996
+ return {
997
+ userId: false,
998
+ authToken: false,
999
+ error: `Authentication failed: ${error.message}`
1000
+ };
1001
+ }
892
1002
  return {
893
1003
  userId: false,
894
- authToken: false,
895
- error: `Token refresh failed: ${error.message}`
1004
+ authToken: this._tokenManager.getAccessToken(),
1005
+ error: `Network error during token refresh: ${error.message}`,
1006
+ hasTokens: true
896
1007
  };
897
1008
  }
898
1009
  }
1010
+ const currentAccessToken = this._tokenManager.getAccessToken();
1011
+ if (!currentAccessToken) {
1012
+ return {
1013
+ userId: false,
1014
+ authToken: false
1015
+ };
1016
+ }
899
1017
  try {
900
1018
  const currentUser = await this.getMe();
901
- const userProjects = await this.getUserProjects();
902
1019
  return {
903
- userId: currentUser.data.id,
904
- authToken: this._tokenManager.getAccessToken(),
905
- user: {
906
- ...currentUser.data,
907
- projects: (userProjects == null ? void 0 : userProjects.data) || []
908
- },
1020
+ userId: currentUser.user.id,
1021
+ authToken: currentAccessToken,
1022
+ ...currentUser,
909
1023
  error: null
910
1024
  };
911
1025
  } catch (error) {
912
- this._tokenManager.clearTokens();
1026
+ console.warn("[CoreService] Failed to get user data:", error.message);
1027
+ if (error.message.includes("401") || error.message.includes("403")) {
1028
+ this._tokenManager.clearTokens();
1029
+ return {
1030
+ userId: false,
1031
+ authToken: false,
1032
+ error: `Authentication failed: ${error.message}`
1033
+ };
1034
+ }
913
1035
  return {
914
1036
  userId: false,
915
- authToken: false,
916
- error: `Failed to get user data: ${error.message}`
1037
+ authToken: currentAccessToken,
1038
+ error: `Failed to get user data: ${error.message}`,
1039
+ hasTokens: true
917
1040
  };
918
1041
  }
919
1042
  } catch (error) {
1043
+ console.error("[CoreService] Unexpected error in getStoredAuthState:", error);
920
1044
  return {
921
1045
  userId: false,
922
1046
  authToken: false,
@@ -928,10 +1052,14 @@ var CoreService = class extends BaseService {
928
1052
  async getUserProfile() {
929
1053
  this._requireReady("getUserProfile");
930
1054
  try {
931
- return await this._request("/users/profile", {
1055
+ const response = await this._request("/users/profile", {
932
1056
  method: "GET",
933
1057
  methodName: "getUserProfile"
934
1058
  });
1059
+ if (response.success) {
1060
+ return response.data;
1061
+ }
1062
+ throw new Error(response.message);
935
1063
  } catch (error) {
936
1064
  throw new Error(`Failed to get user profile: ${error.message}`);
937
1065
  }
@@ -939,11 +1067,15 @@ var CoreService = class extends BaseService {
939
1067
  async updateUserProfile(profileData) {
940
1068
  this._requireReady("updateUserProfile");
941
1069
  try {
942
- return await this._request("/users/profile", {
1070
+ const response = await this._request("/users/profile", {
943
1071
  method: "PATCH",
944
1072
  body: JSON.stringify(profileData),
945
1073
  methodName: "updateUserProfile"
946
1074
  });
1075
+ if (response.success) {
1076
+ return response.data;
1077
+ }
1078
+ throw new Error(response.message);
947
1079
  } catch (error) {
948
1080
  throw new Error(`Failed to update user profile: ${error.message}`);
949
1081
  }
@@ -951,10 +1083,17 @@ var CoreService = class extends BaseService {
951
1083
  async getUserProjects() {
952
1084
  this._requireReady("getUserProjects");
953
1085
  try {
954
- return await this._request("/users/projects", {
1086
+ const response = await this._request("/users/projects", {
955
1087
  method: "GET",
956
1088
  methodName: "getUserProjects"
957
1089
  });
1090
+ if (response.success) {
1091
+ return response.data.map((project) => ({
1092
+ ...project,
1093
+ ...project.icon && { icon: { src: `${this._apiUrl}/core/files/public/${project.icon.id}/download`, ...project.icon } }
1094
+ }));
1095
+ }
1096
+ throw new Error(response.message);
958
1097
  } catch (error) {
959
1098
  throw new Error(`Failed to get user projects: ${error.message}`);
960
1099
  }
@@ -965,10 +1104,14 @@ var CoreService = class extends BaseService {
965
1104
  throw new Error("User ID is required");
966
1105
  }
967
1106
  try {
968
- return await this._request(`/users/${userId}`, {
1107
+ const response = await this._request(`/users/${userId}`, {
969
1108
  method: "GET",
970
1109
  methodName: "getUser"
971
1110
  });
1111
+ if (response.success) {
1112
+ return response.data;
1113
+ }
1114
+ throw new Error(response.message);
972
1115
  } catch (error) {
973
1116
  throw new Error(`Failed to get user: ${error.message}`);
974
1117
  }
@@ -979,13 +1122,17 @@ var CoreService = class extends BaseService {
979
1122
  throw new Error("Email is required");
980
1123
  }
981
1124
  try {
982
- return await this._request("/auth/user", {
1125
+ const response = await this._request("/auth/user", {
983
1126
  method: "GET",
984
1127
  headers: {
985
1128
  "X-User-Email": email
986
1129
  },
987
1130
  methodName: "getUserByEmail"
988
1131
  });
1132
+ if (response.success) {
1133
+ return response.data;
1134
+ }
1135
+ throw new Error(response.message);
989
1136
  } catch (error) {
990
1137
  throw new Error(`Failed to get user by email: ${error.message}`);
991
1138
  }
@@ -994,50 +1141,134 @@ var CoreService = class extends BaseService {
994
1141
  async createProject(projectData) {
995
1142
  this._requireReady("createProject");
996
1143
  try {
997
- return await this._request("/projects", {
1144
+ const response = await this._request("/projects", {
998
1145
  method: "POST",
999
1146
  body: JSON.stringify(projectData),
1000
1147
  methodName: "createProject"
1001
1148
  });
1149
+ if (response.success) {
1150
+ return response.data;
1151
+ }
1152
+ throw new Error(response.message);
1002
1153
  } catch (error) {
1003
1154
  throw new Error(`Failed to create project: ${error.message}`);
1004
1155
  }
1005
1156
  }
1006
- async getProjects() {
1157
+ async getProjects(params = {}) {
1007
1158
  this._requireReady("getProjects");
1008
1159
  try {
1009
- return await this._request("/projects", {
1160
+ const queryParams = new URLSearchParams();
1161
+ Object.keys(params).forEach((key) => {
1162
+ if (params[key] != null) {
1163
+ queryParams.append(key, params[key]);
1164
+ }
1165
+ });
1166
+ const queryString = queryParams.toString();
1167
+ const url = `/projects${queryString ? `?${queryString}` : ""}`;
1168
+ const response = await this._request(url, {
1010
1169
  method: "GET",
1011
1170
  methodName: "getProjects"
1012
1171
  });
1172
+ if (response.success) {
1173
+ return response;
1174
+ }
1175
+ throw new Error(response.message);
1013
1176
  } catch (error) {
1014
1177
  throw new Error(`Failed to get projects: ${error.message}`);
1015
1178
  }
1016
1179
  }
1180
+ /**
1181
+ * Alias for getProjects for consistency with API naming
1182
+ */
1183
+ async listProjects(params = {}) {
1184
+ return await this.getProjects(params);
1185
+ }
1186
+ /**
1187
+ * List only public projects (no authentication required)
1188
+ */
1189
+ async listPublicProjects(params = {}) {
1190
+ try {
1191
+ const queryParams = new URLSearchParams();
1192
+ Object.keys(params).forEach((key) => {
1193
+ if (params[key] != null) {
1194
+ queryParams.append(key, params[key]);
1195
+ }
1196
+ });
1197
+ const queryString = queryParams.toString();
1198
+ const url = `/projects/public${queryString ? `?${queryString}` : ""}`;
1199
+ const response = await this._request(url, {
1200
+ method: "GET",
1201
+ methodName: "listPublicProjects"
1202
+ });
1203
+ if (response.success) {
1204
+ return response.data;
1205
+ }
1206
+ throw new Error(response.message);
1207
+ } catch (error) {
1208
+ throw new Error(`Failed to list public projects: ${error.message}`);
1209
+ }
1210
+ }
1017
1211
  async getProject(projectId) {
1018
1212
  this._requireReady("getProject");
1019
1213
  if (!projectId) {
1020
1214
  throw new Error("Project ID is required");
1021
1215
  }
1022
1216
  try {
1023
- return await this._request(`/projects/${projectId}`, {
1217
+ const response = await this._request(`/projects/${projectId}`, {
1024
1218
  method: "GET",
1025
1219
  methodName: "getProject"
1026
1220
  });
1221
+ if (response.success) {
1222
+ const iconSrc = response.data.icon ? `${this._apiUrl}/core/files/public/${response.data.icon.id}/download` : null;
1223
+ return {
1224
+ ...response.data,
1225
+ icon: { src: iconSrc, ...response.data.icon }
1226
+ };
1227
+ }
1228
+ throw new Error(response.message);
1027
1229
  } catch (error) {
1028
1230
  throw new Error(`Failed to get project: ${error.message}`);
1029
1231
  }
1030
1232
  }
1233
+ /**
1234
+ * Get a public project by ID (no authentication required)
1235
+ * Corresponds to router.get('/public/:projectId', ProjectController.getPublicProject)
1236
+ */
1237
+ async getPublicProject(projectId) {
1238
+ if (!projectId) {
1239
+ throw new Error("Project ID is required");
1240
+ }
1241
+ try {
1242
+ const response = await this._request(`/projects/public/${projectId}`, {
1243
+ method: "GET",
1244
+ methodName: "getPublicProject"
1245
+ });
1246
+ if (response.success) {
1247
+ const iconSrc = response.data.icon ? `${this._apiUrl}/core/files/public/${response.data.icon.id}/download` : null;
1248
+ return {
1249
+ ...response.data,
1250
+ icon: { src: iconSrc, ...response.data.icon }
1251
+ };
1252
+ }
1253
+ throw new Error(response.message);
1254
+ } catch (error) {
1255
+ throw new Error(`Failed to get public project: ${error.message}`);
1256
+ }
1257
+ }
1031
1258
  async getProjectByKey(key) {
1032
1259
  this._requireReady("getProjectByKey");
1033
1260
  if (!key) {
1034
1261
  throw new Error("Project key is required");
1035
1262
  }
1036
1263
  try {
1037
- return await this._request(`/projects/check-key/${key}`, {
1264
+ const response = await this._request(`/projects/check-key/${key}`, {
1038
1265
  method: "GET",
1039
1266
  methodName: "getProjectByKey"
1040
1267
  });
1268
+ if (response.success) {
1269
+ return response.data;
1270
+ }
1271
+ throw new Error(response.message);
1041
1272
  } catch (error) {
1042
1273
  throw new Error(`Failed to get project by key: ${error.message}`);
1043
1274
  }
@@ -1048,11 +1279,15 @@ var CoreService = class extends BaseService {
1048
1279
  throw new Error("Project ID is required");
1049
1280
  }
1050
1281
  try {
1051
- return await this._request(`/projects/${projectId}`, {
1282
+ const response = await this._request(`/projects/${projectId}`, {
1052
1283
  method: "PATCH",
1053
1284
  body: JSON.stringify(data),
1054
1285
  methodName: "updateProject"
1055
1286
  });
1287
+ if (response.success) {
1288
+ return response.data;
1289
+ }
1290
+ throw new Error(response.message);
1056
1291
  } catch (error) {
1057
1292
  throw new Error(`Failed to update project: ${error.message}`);
1058
1293
  }
@@ -1063,11 +1298,15 @@ var CoreService = class extends BaseService {
1063
1298
  throw new Error("Project ID is required");
1064
1299
  }
1065
1300
  try {
1066
- return await this._request(`/projects/${projectId}/components`, {
1301
+ const response = await this._request(`/projects/${projectId}/components`, {
1067
1302
  method: "PATCH",
1068
1303
  body: JSON.stringify({ components }),
1069
1304
  methodName: "updateProjectComponents"
1070
1305
  });
1306
+ if (response.success) {
1307
+ return response.data;
1308
+ }
1309
+ throw new Error(response.message);
1071
1310
  } catch (error) {
1072
1311
  throw new Error(`Failed to update project components: ${error.message}`);
1073
1312
  }
@@ -1078,11 +1317,15 @@ var CoreService = class extends BaseService {
1078
1317
  throw new Error("Project ID is required");
1079
1318
  }
1080
1319
  try {
1081
- return await this._request(`/projects/${projectId}/settings`, {
1320
+ const response = await this._request(`/projects/${projectId}/settings`, {
1082
1321
  method: "PATCH",
1083
1322
  body: JSON.stringify({ settings }),
1084
1323
  methodName: "updateProjectSettings"
1085
1324
  });
1325
+ if (response.success) {
1326
+ return response.data;
1327
+ }
1328
+ throw new Error(response.message);
1086
1329
  } catch (error) {
1087
1330
  throw new Error(`Failed to update project settings: ${error.message}`);
1088
1331
  }
@@ -1093,11 +1336,15 @@ var CoreService = class extends BaseService {
1093
1336
  throw new Error("Project ID is required");
1094
1337
  }
1095
1338
  try {
1096
- return await this._request(`/projects/${projectId}`, {
1339
+ const response = await this._request(`/projects/${projectId}`, {
1097
1340
  method: "PATCH",
1098
1341
  body: JSON.stringify({ name }),
1099
1342
  methodName: "updateProjectName"
1100
1343
  });
1344
+ if (response.success) {
1345
+ return response.data;
1346
+ }
1347
+ throw new Error(response.message);
1101
1348
  } catch (error) {
1102
1349
  throw new Error(`Failed to update project name: ${error.message}`);
1103
1350
  }
@@ -1108,26 +1355,34 @@ var CoreService = class extends BaseService {
1108
1355
  throw new Error("Project ID is required");
1109
1356
  }
1110
1357
  try {
1111
- return await this._request(`/projects/${projectId}/tier`, {
1358
+ const response = await this._request(`/projects/${projectId}/tier`, {
1112
1359
  method: "PATCH",
1113
1360
  body: JSON.stringify({ tier: pkg }),
1114
1361
  methodName: "updateProjectPackage"
1115
1362
  });
1363
+ if (response.success) {
1364
+ return response.data;
1365
+ }
1366
+ throw new Error(response.message);
1116
1367
  } catch (error) {
1117
1368
  throw new Error(`Failed to update project package: ${error.message}`);
1118
1369
  }
1119
1370
  }
1120
- async duplicateProject(projectId, newName, newKey) {
1371
+ async duplicateProject(projectId, newName, newKey, targetUserId) {
1121
1372
  this._requireReady("duplicateProject");
1122
1373
  if (!projectId) {
1123
1374
  throw new Error("Project ID is required");
1124
1375
  }
1125
1376
  try {
1126
- return await this._request(`/projects/${projectId}/duplicate`, {
1377
+ const response = await this._request(`/projects/${projectId}/duplicate`, {
1127
1378
  method: "POST",
1128
- body: JSON.stringify({ name: newName, key: newKey }),
1379
+ body: JSON.stringify({ name: newName, key: newKey, targetUserId }),
1129
1380
  methodName: "duplicateProject"
1130
1381
  });
1382
+ if (response.success) {
1383
+ return response.data;
1384
+ }
1385
+ throw new Error(response.message);
1131
1386
  } catch (error) {
1132
1387
  throw new Error(`Failed to duplicate project: ${error.message}`);
1133
1388
  }
@@ -1138,10 +1393,14 @@ var CoreService = class extends BaseService {
1138
1393
  throw new Error("Project ID is required");
1139
1394
  }
1140
1395
  try {
1141
- return await this._request(`/projects/${projectId}`, {
1396
+ const response = await this._request(`/projects/${projectId}`, {
1142
1397
  method: "DELETE",
1143
1398
  methodName: "removeProject"
1144
1399
  });
1400
+ if (response.success) {
1401
+ return response.data;
1402
+ }
1403
+ throw new Error(response.message);
1145
1404
  } catch (error) {
1146
1405
  throw new Error(`Failed to remove project: ${error.message}`);
1147
1406
  }
@@ -1152,10 +1411,14 @@ var CoreService = class extends BaseService {
1152
1411
  throw new Error("Project key is required");
1153
1412
  }
1154
1413
  try {
1155
- return await this._request(`/projects/check-key/${key}`, {
1414
+ const response = await this._request(`/projects/check-key/${key}`, {
1156
1415
  method: "GET",
1157
1416
  methodName: "checkProjectKeyAvailability"
1158
1417
  });
1418
+ if (response.success) {
1419
+ return response.data;
1420
+ }
1421
+ throw new Error(response.message);
1159
1422
  } catch (error) {
1160
1423
  throw new Error(`Failed to check project key availability: ${error.message}`);
1161
1424
  }
@@ -1167,40 +1430,62 @@ var CoreService = class extends BaseService {
1167
1430
  throw new Error("Project ID is required");
1168
1431
  }
1169
1432
  try {
1170
- return await this._request(`/projects/${projectId}/members`, {
1433
+ const response = await this._request(`/projects/${projectId}/members`, {
1171
1434
  method: "GET",
1172
1435
  methodName: "getProjectMembers"
1173
1436
  });
1437
+ if (response.success) {
1438
+ return response.data;
1439
+ }
1440
+ throw new Error(response.message);
1174
1441
  } catch (error) {
1175
1442
  throw new Error(`Failed to get project members: ${error.message}`);
1176
1443
  }
1177
1444
  }
1178
- async inviteMember(projectId, email, message, role = "guest") {
1445
+ async inviteMember(projectId, email, role = "guest", options = {}) {
1179
1446
  this._requireReady("inviteMember");
1180
- if (!projectId || !email) {
1181
- throw new Error("Project ID and email are required");
1447
+ if (!projectId || !email || !role) {
1448
+ throw new Error("Project ID, email, and role are required");
1182
1449
  }
1450
+ const { name, callbackUrl } = options;
1451
+ const defaultCallbackUrl = typeof window === "undefined" ? "https://app.symbols.com/accept-invite" : `${window.location.origin}/accept-invite`;
1183
1452
  try {
1184
- return await this._request(`/projects/${projectId}/invite`, {
1453
+ const requestBody = {
1454
+ email,
1455
+ role,
1456
+ callbackUrl: callbackUrl || defaultCallbackUrl
1457
+ };
1458
+ if (name) {
1459
+ requestBody.name = name;
1460
+ }
1461
+ const response = await this._request(`/projects/${projectId}/invite`, {
1185
1462
  method: "POST",
1186
- body: JSON.stringify({ email, role, message }),
1463
+ body: JSON.stringify(requestBody),
1187
1464
  methodName: "inviteMember"
1188
1465
  });
1466
+ if (response.success) {
1467
+ return response.data;
1468
+ }
1469
+ throw new Error(response.message);
1189
1470
  } catch (error) {
1190
1471
  throw new Error(`Failed to invite member: ${error.message}`);
1191
1472
  }
1192
1473
  }
1193
- async acceptInvite(projectId, token) {
1474
+ async acceptInvite(token) {
1194
1475
  this._requireReady("acceptInvite");
1195
- if (!projectId || !token) {
1196
- throw new Error("Project ID and token are required");
1476
+ if (!token) {
1477
+ throw new Error("Invitation token is required");
1197
1478
  }
1198
1479
  try {
1199
- return await this._request(`/projects/${projectId}/accept-invite`, {
1480
+ const response = await this._request("/projects/accept-invite", {
1200
1481
  method: "POST",
1201
1482
  body: JSON.stringify({ token }),
1202
1483
  methodName: "acceptInvite"
1203
1484
  });
1485
+ if (response.success) {
1486
+ return response.data;
1487
+ }
1488
+ throw new Error(response.message);
1204
1489
  } catch (error) {
1205
1490
  throw new Error(`Failed to accept invite: ${error.message}`);
1206
1491
  }
@@ -1211,11 +1496,15 @@ var CoreService = class extends BaseService {
1211
1496
  throw new Error("Project ID, member ID, and role are required");
1212
1497
  }
1213
1498
  try {
1214
- return await this._request(`/projects/${projectId}/members/${memberId}`, {
1499
+ const response = await this._request(`/projects/${projectId}/members/${memberId}`, {
1215
1500
  method: "PATCH",
1216
1501
  body: JSON.stringify({ role }),
1217
1502
  methodName: "updateMemberRole"
1218
1503
  });
1504
+ if (response.success) {
1505
+ return response.data;
1506
+ }
1507
+ throw new Error(response.message);
1219
1508
  } catch (error) {
1220
1509
  throw new Error(`Failed to update member role: ${error.message}`);
1221
1510
  }
@@ -1226,10 +1515,14 @@ var CoreService = class extends BaseService {
1226
1515
  throw new Error("Project ID and member ID are required");
1227
1516
  }
1228
1517
  try {
1229
- return await this._request(`/projects/${projectId}/members/${memberId}`, {
1518
+ const response = await this._request(`/projects/${projectId}/members/${memberId}`, {
1230
1519
  method: "DELETE",
1231
1520
  methodName: "removeMember"
1232
1521
  });
1522
+ if (response.success) {
1523
+ return response.data;
1524
+ }
1525
+ throw new Error(response.message);
1233
1526
  } catch (error) {
1234
1527
  throw new Error(`Failed to remove member: ${error.message}`);
1235
1528
  }
@@ -1239,10 +1532,14 @@ var CoreService = class extends BaseService {
1239
1532
  this._requireReady("getAvailableLibraries");
1240
1533
  const queryParams = new URLSearchParams(params).toString();
1241
1534
  try {
1242
- return await this._request(`/projects/libraries/available?${queryParams}`, {
1535
+ const response = await this._request(`/projects/libraries/available?${queryParams}`, {
1243
1536
  method: "GET",
1244
1537
  methodName: "getAvailableLibraries"
1245
1538
  });
1539
+ if (response.success) {
1540
+ return response.data;
1541
+ }
1542
+ throw new Error(response.message);
1246
1543
  } catch (error) {
1247
1544
  throw new Error(`Failed to get available libraries: ${error.message}`);
1248
1545
  }
@@ -1253,10 +1550,14 @@ var CoreService = class extends BaseService {
1253
1550
  throw new Error("Project ID is required");
1254
1551
  }
1255
1552
  try {
1256
- return await this._request(`/projects/${projectId}/libraries`, {
1553
+ const response = await this._request(`/projects/${projectId}/libraries`, {
1257
1554
  method: "GET",
1258
1555
  methodName: "getProjectLibraries"
1259
1556
  });
1557
+ if (response.success) {
1558
+ return response.data;
1559
+ }
1560
+ throw new Error(response.message);
1260
1561
  } catch (error) {
1261
1562
  throw new Error(`Failed to get project libraries: ${error.message}`);
1262
1563
  }
@@ -1267,11 +1568,15 @@ var CoreService = class extends BaseService {
1267
1568
  throw new Error("Project ID and library IDs are required");
1268
1569
  }
1269
1570
  try {
1270
- return await this._request(`/projects/${projectId}/libraries`, {
1571
+ const response = await this._request(`/projects/${projectId}/libraries`, {
1271
1572
  method: "POST",
1272
1573
  body: JSON.stringify({ libraryIds }),
1273
1574
  methodName: "addProjectLibraries"
1274
1575
  });
1576
+ if (response.success) {
1577
+ return response.data;
1578
+ }
1579
+ throw new Error(response.message);
1275
1580
  } catch (error) {
1276
1581
  throw new Error(`Failed to add project libraries: ${error.message}`);
1277
1582
  }
@@ -1282,11 +1587,15 @@ var CoreService = class extends BaseService {
1282
1587
  throw new Error("Project ID and library IDs are required");
1283
1588
  }
1284
1589
  try {
1285
- return await this._request(`/projects/${projectId}/libraries`, {
1590
+ const response = await this._request(`/projects/${projectId}/libraries`, {
1286
1591
  method: "DELETE",
1287
1592
  body: JSON.stringify({ libraryIds }),
1288
1593
  methodName: "removeProjectLibraries"
1289
1594
  });
1595
+ if (response.success) {
1596
+ return response.data;
1597
+ }
1598
+ throw new Error(response.message);
1290
1599
  } catch (error) {
1291
1600
  throw new Error(`Failed to remove project libraries: ${error.message}`);
1292
1601
  }
@@ -1306,19 +1615,28 @@ var CoreService = class extends BaseService {
1306
1615
  formData.append("tags", JSON.stringify(options.tags));
1307
1616
  }
1308
1617
  if (options.visibility) {
1309
- formData.append("visibility", options.visibility);
1618
+ formData.append("visibility", options.visibility || "public");
1310
1619
  }
1311
1620
  if (options.metadata) {
1312
1621
  formData.append("metadata", JSON.stringify(options.metadata));
1313
1622
  }
1314
1623
  try {
1315
- return await this._request("/files/upload", {
1624
+ const response = await this._request("/files/upload", {
1316
1625
  method: "POST",
1317
1626
  body: formData,
1318
1627
  headers: {},
1319
1628
  // Let browser set Content-Type for FormData
1320
1629
  methodName: "uploadFile"
1321
1630
  });
1631
+ if (!response.success) {
1632
+ throw new Error(response.message);
1633
+ }
1634
+ return {
1635
+ id: response.data.id,
1636
+ src: `${this._apiUrl}/core/files/public/${response.data.id}/download`,
1637
+ success: true,
1638
+ message: response.message
1639
+ };
1322
1640
  } catch (error) {
1323
1641
  throw new Error(`File upload failed: ${error.message}`);
1324
1642
  }
@@ -1332,13 +1650,17 @@ var CoreService = class extends BaseService {
1332
1650
  formData.append("icon", iconFile);
1333
1651
  formData.append("projectId", projectId);
1334
1652
  try {
1335
- return await this._request("/files/upload-project-icon", {
1653
+ const response = await this._request("/files/upload-project-icon", {
1336
1654
  method: "POST",
1337
1655
  body: formData,
1338
1656
  headers: {},
1339
1657
  // Let browser set Content-Type for FormData
1340
1658
  methodName: "updateProjectIcon"
1341
1659
  });
1660
+ if (response.success) {
1661
+ return response.data;
1662
+ }
1663
+ throw new Error(response.message);
1342
1664
  } catch (error) {
1343
1665
  throw new Error(`Failed to update project icon: ${error.message}`);
1344
1666
  }
@@ -1357,7 +1679,7 @@ var CoreService = class extends BaseService {
1357
1679
  throw new Error("Project ID is required for checkout");
1358
1680
  }
1359
1681
  try {
1360
- return await this._request("/payments/checkout", {
1682
+ const response = await this._request("/payments/checkout", {
1361
1683
  method: "POST",
1362
1684
  body: JSON.stringify({
1363
1685
  projectId,
@@ -1368,6 +1690,10 @@ var CoreService = class extends BaseService {
1368
1690
  }),
1369
1691
  methodName: "checkout"
1370
1692
  });
1693
+ if (response.success) {
1694
+ return response.data;
1695
+ }
1696
+ throw new Error(response.message);
1371
1697
  } catch (error) {
1372
1698
  throw new Error(`Failed to checkout: ${error.message}`);
1373
1699
  }
@@ -1378,10 +1704,14 @@ var CoreService = class extends BaseService {
1378
1704
  throw new Error("Project ID is required");
1379
1705
  }
1380
1706
  try {
1381
- return await this._request(`/payments/subscription/${projectId}`, {
1707
+ const response = await this._request(`/payments/subscription/${projectId}`, {
1382
1708
  method: "GET",
1383
1709
  methodName: "getSubscriptionStatus"
1384
1710
  });
1711
+ if (response.success) {
1712
+ return response.data;
1713
+ }
1714
+ throw new Error(response.message);
1385
1715
  } catch (error) {
1386
1716
  throw new Error(`Failed to get subscription status: ${error.message}`);
1387
1717
  }
@@ -1393,11 +1723,15 @@ var CoreService = class extends BaseService {
1393
1723
  throw new Error("Domain is required");
1394
1724
  }
1395
1725
  try {
1396
- return await this._request("/dns/records", {
1726
+ const response = await this._request("/dns/records", {
1397
1727
  method: "POST",
1398
1728
  body: JSON.stringify({ domain, ...options }),
1399
1729
  methodName: "createDnsRecord"
1400
1730
  });
1731
+ if (response.success) {
1732
+ return response.data;
1733
+ }
1734
+ throw new Error(response.message);
1401
1735
  } catch (error) {
1402
1736
  throw new Error(`Failed to create DNS record: ${error.message}`);
1403
1737
  }
@@ -1408,10 +1742,14 @@ var CoreService = class extends BaseService {
1408
1742
  throw new Error("Domain is required");
1409
1743
  }
1410
1744
  try {
1411
- return await this._request(`/dns/records/${domain}`, {
1745
+ const response = await this._request(`/dns/records/${domain}`, {
1412
1746
  method: "GET",
1413
1747
  methodName: "getDnsRecord"
1414
1748
  });
1749
+ if (response.success) {
1750
+ return response.data;
1751
+ }
1752
+ throw new Error(response.message);
1415
1753
  } catch (error) {
1416
1754
  throw new Error(`Failed to get DNS record: ${error.message}`);
1417
1755
  }
@@ -1422,10 +1760,14 @@ var CoreService = class extends BaseService {
1422
1760
  throw new Error("Domain is required");
1423
1761
  }
1424
1762
  try {
1425
- return await this._request(`/dns/records/${domain}`, {
1763
+ const response = await this._request(`/dns/records/${domain}`, {
1426
1764
  method: "DELETE",
1427
1765
  methodName: "removeDnsRecord"
1428
1766
  });
1767
+ if (response.success) {
1768
+ return response.data;
1769
+ }
1770
+ throw new Error(response.message);
1429
1771
  } catch (error) {
1430
1772
  throw new Error(`Failed to remove DNS record: ${error.message}`);
1431
1773
  }
@@ -1436,7 +1778,7 @@ var CoreService = class extends BaseService {
1436
1778
  throw new Error("Project key is required");
1437
1779
  }
1438
1780
  try {
1439
- return await this._request("/dns/project-domains", {
1781
+ const response = await this._request("/dns/project-domains", {
1440
1782
  method: "POST",
1441
1783
  body: JSON.stringify({
1442
1784
  projectKey,
@@ -1445,6 +1787,10 @@ var CoreService = class extends BaseService {
1445
1787
  }),
1446
1788
  methodName: "setProjectDomains"
1447
1789
  });
1790
+ if (response.success) {
1791
+ return response.data;
1792
+ }
1793
+ throw new Error(response.message);
1448
1794
  } catch (error) {
1449
1795
  throw new Error(`Failed to set project domains: ${error.message}`);
1450
1796
  }
@@ -1452,10 +1798,14 @@ var CoreService = class extends BaseService {
1452
1798
  // ==================== UTILITY METHODS ====================
1453
1799
  async getHealthStatus() {
1454
1800
  try {
1455
- return await this._request("/health", {
1801
+ const response = await this._request("/health", {
1456
1802
  method: "GET",
1457
1803
  methodName: "getHealthStatus"
1458
1804
  });
1805
+ if (response.success) {
1806
+ return response.data;
1807
+ }
1808
+ throw new Error(response.message);
1459
1809
  } catch (error) {
1460
1810
  throw new Error(`Failed to get health status: ${error.message}`);
1461
1811
  }
@@ -1489,7 +1839,10 @@ var CoreService = class extends BaseService {
1489
1839
  }),
1490
1840
  methodName: "applyProjectChanges"
1491
1841
  });
1492
- return response;
1842
+ if (response.success) {
1843
+ return response.data;
1844
+ }
1845
+ throw new Error(response.message);
1493
1846
  } catch (error) {
1494
1847
  throw new Error(`Failed to apply project changes: ${error.message}`);
1495
1848
  }
@@ -1505,17 +1858,23 @@ var CoreService = class extends BaseService {
1505
1858
  }
1506
1859
  const {
1507
1860
  branch = "main",
1861
+ version = "latest",
1508
1862
  includeHistory = false
1509
1863
  } = options;
1510
1864
  const queryParams = new URLSearchParams({
1511
1865
  branch,
1866
+ version,
1512
1867
  includeHistory: includeHistory.toString()
1513
1868
  }).toString();
1514
1869
  try {
1515
- return await this._request(`/projects/${projectId}/data?${queryParams}`, {
1870
+ const response = await this._request(`/projects/${projectId}/data?${queryParams}`, {
1516
1871
  method: "GET",
1517
1872
  methodName: "getProjectData"
1518
1873
  });
1874
+ if (response.success) {
1875
+ return response.data;
1876
+ }
1877
+ throw new Error(response.message);
1519
1878
  } catch (error) {
1520
1879
  throw new Error(`Failed to get project data: ${error.message}`);
1521
1880
  }
@@ -1539,10 +1898,14 @@ var CoreService = class extends BaseService {
1539
1898
  limit: limit.toString()
1540
1899
  }).toString();
1541
1900
  try {
1542
- return await this._request(`/projects/${projectId}/versions?${queryParams}`, {
1901
+ const response = await this._request(`/projects/${projectId}/versions?${queryParams}`, {
1543
1902
  method: "GET",
1544
1903
  methodName: "getProjectVersions"
1545
1904
  });
1905
+ if (response.success) {
1906
+ return response.data;
1907
+ }
1908
+ throw new Error(response.message);
1546
1909
  } catch (error) {
1547
1910
  throw new Error(`Failed to get project versions: ${error.message}`);
1548
1911
  }
@@ -1565,7 +1928,7 @@ var CoreService = class extends BaseService {
1565
1928
  type = "patch"
1566
1929
  } = options;
1567
1930
  try {
1568
- return await this._request(`/projects/${projectId}/restore`, {
1931
+ const response = await this._request(`/projects/${projectId}/restore`, {
1569
1932
  method: "POST",
1570
1933
  body: JSON.stringify({
1571
1934
  version,
@@ -1575,6 +1938,10 @@ var CoreService = class extends BaseService {
1575
1938
  }),
1576
1939
  methodName: "restoreProjectVersion"
1577
1940
  });
1941
+ if (response.success) {
1942
+ return response.data;
1943
+ }
1944
+ throw new Error(response.message);
1578
1945
  } catch (error) {
1579
1946
  throw new Error(`Failed to restore project version: ${error.message}`);
1580
1947
  }
@@ -1667,11 +2034,15 @@ var CoreService = class extends BaseService {
1667
2034
  throw new Error("Source branch, target branch, and title are required");
1668
2035
  }
1669
2036
  try {
1670
- return await this._request(`/projects/${projectId}/pull-requests`, {
2037
+ const response = await this._request(`/projects/${projectId}/pull-requests`, {
1671
2038
  method: "POST",
1672
2039
  body: JSON.stringify(pullRequestData),
1673
2040
  methodName: "createPullRequest"
1674
2041
  });
2042
+ if (response.success) {
2043
+ return response.data;
2044
+ }
2045
+ throw new Error(response.message);
1675
2046
  } catch (error) {
1676
2047
  throw new Error(`Failed to create pull request: ${error.message}`);
1677
2048
  }
@@ -1703,10 +2074,14 @@ var CoreService = class extends BaseService {
1703
2074
  queryParams.append("target", target);
1704
2075
  }
1705
2076
  try {
1706
- return await this._request(`/projects/${projectId}/pull-requests?${queryParams.toString()}`, {
2077
+ const response = await this._request(`/projects/${projectId}/pull-requests?${queryParams.toString()}`, {
1707
2078
  method: "GET",
1708
2079
  methodName: "listPullRequests"
1709
2080
  });
2081
+ if (response.success) {
2082
+ return response.data;
2083
+ }
2084
+ throw new Error(response.message);
1710
2085
  } catch (error) {
1711
2086
  throw new Error(`Failed to list pull requests: ${error.message}`);
1712
2087
  }
@@ -1723,10 +2098,14 @@ var CoreService = class extends BaseService {
1723
2098
  throw new Error("Pull request ID is required");
1724
2099
  }
1725
2100
  try {
1726
- return await this._request(`/projects/${projectId}/pull-requests/${prId}`, {
2101
+ const response = await this._request(`/projects/${projectId}/pull-requests/${prId}`, {
1727
2102
  method: "GET",
1728
2103
  methodName: "getPullRequest"
1729
2104
  });
2105
+ if (response.success) {
2106
+ return response.data;
2107
+ }
2108
+ throw new Error(response.message);
1730
2109
  } catch (error) {
1731
2110
  throw new Error(`Failed to get pull request: ${error.message}`);
1732
2111
  }
@@ -1747,11 +2126,15 @@ var CoreService = class extends BaseService {
1747
2126
  throw new Error(`Invalid review status. Must be one of: ${validStatuses.join(", ")}`);
1748
2127
  }
1749
2128
  try {
1750
- return await this._request(`/projects/${projectId}/pull-requests/${prId}/review`, {
2129
+ const response = await this._request(`/projects/${projectId}/pull-requests/${prId}/review`, {
1751
2130
  method: "POST",
1752
2131
  body: JSON.stringify(reviewData),
1753
2132
  methodName: "reviewPullRequest"
1754
2133
  });
2134
+ if (response.success) {
2135
+ return response.data;
2136
+ }
2137
+ throw new Error(response.message);
1755
2138
  } catch (error) {
1756
2139
  throw new Error(`Failed to review pull request: ${error.message}`);
1757
2140
  }
@@ -1771,11 +2154,15 @@ var CoreService = class extends BaseService {
1771
2154
  throw new Error("Comment value is required");
1772
2155
  }
1773
2156
  try {
1774
- return await this._request(`/projects/${projectId}/pull-requests/${prId}/comment`, {
2157
+ const response = await this._request(`/projects/${projectId}/pull-requests/${prId}/comment`, {
1775
2158
  method: "POST",
1776
2159
  body: JSON.stringify(commentData),
1777
2160
  methodName: "addPullRequestComment"
1778
2161
  });
2162
+ if (response.success) {
2163
+ return response.data;
2164
+ }
2165
+ throw new Error(response.message);
1779
2166
  } catch (error) {
1780
2167
  throw new Error(`Failed to add pull request comment: ${error.message}`);
1781
2168
  }
@@ -1796,7 +2183,10 @@ var CoreService = class extends BaseService {
1796
2183
  method: "POST",
1797
2184
  methodName: "mergePullRequest"
1798
2185
  });
1799
- return response;
2186
+ if (response.success) {
2187
+ return response.data;
2188
+ }
2189
+ throw new Error(response.message);
1800
2190
  } catch (error) {
1801
2191
  if (error.message.includes("conflicts") || error.message.includes("409")) {
1802
2192
  throw new Error(`Pull request has merge conflicts: ${error.message}`);
@@ -1816,10 +2206,14 @@ var CoreService = class extends BaseService {
1816
2206
  throw new Error("Pull request ID is required");
1817
2207
  }
1818
2208
  try {
1819
- return await this._request(`/projects/${projectId}/pull-requests/${prId}/diff`, {
2209
+ const response = await this._request(`/projects/${projectId}/pull-requests/${prId}/diff`, {
1820
2210
  method: "GET",
1821
2211
  methodName: "getPullRequestDiff"
1822
2212
  });
2213
+ if (response.success) {
2214
+ return response.data;
2215
+ }
2216
+ throw new Error(response.message);
1823
2217
  } catch (error) {
1824
2218
  throw new Error(`Failed to get pull request diff: ${error.message}`);
1825
2219
  }
@@ -1933,10 +2327,14 @@ var CoreService = class extends BaseService {
1933
2327
  throw new Error("Project ID is required");
1934
2328
  }
1935
2329
  try {
1936
- return await this._request(`/projects/${projectId}/branches`, {
2330
+ const response = await this._request(`/projects/${projectId}/branches`, {
1937
2331
  method: "GET",
1938
2332
  methodName: "listBranches"
1939
2333
  });
2334
+ if (response.success) {
2335
+ return response.data;
2336
+ }
2337
+ throw new Error(response.message);
1940
2338
  } catch (error) {
1941
2339
  throw new Error(`Failed to list branches: ${error.message}`);
1942
2340
  }
@@ -1954,11 +2352,15 @@ var CoreService = class extends BaseService {
1954
2352
  }
1955
2353
  const { name, source = "main" } = branchData;
1956
2354
  try {
1957
- return await this._request(`/projects/${projectId}/branches`, {
2355
+ const response = await this._request(`/projects/${projectId}/branches`, {
1958
2356
  method: "POST",
1959
2357
  body: JSON.stringify({ name, source }),
1960
2358
  methodName: "createBranch"
1961
2359
  });
2360
+ if (response.success) {
2361
+ return response.data;
2362
+ }
2363
+ throw new Error(response.message);
1962
2364
  } catch (error) {
1963
2365
  throw new Error(`Failed to create branch: ${error.message}`);
1964
2366
  }
@@ -1978,10 +2380,14 @@ var CoreService = class extends BaseService {
1978
2380
  throw new Error("Cannot delete main branch");
1979
2381
  }
1980
2382
  try {
1981
- return await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}`, {
2383
+ const response = await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}`, {
1982
2384
  method: "DELETE",
1983
2385
  methodName: "deleteBranch"
1984
2386
  });
2387
+ if (response.success) {
2388
+ return response.data;
2389
+ }
2390
+ throw new Error(response.message);
1985
2391
  } catch (error) {
1986
2392
  throw new Error(`Failed to delete branch: ${error.message}`);
1987
2393
  }
@@ -2004,11 +2410,15 @@ var CoreService = class extends BaseService {
2004
2410
  throw new Error("Cannot rename main branch");
2005
2411
  }
2006
2412
  try {
2007
- return await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}/rename`, {
2413
+ const response = await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}/rename`, {
2008
2414
  method: "POST",
2009
2415
  body: JSON.stringify({ newName }),
2010
2416
  methodName: "renameBranch"
2011
2417
  });
2418
+ if (response.success) {
2419
+ return response.data;
2420
+ }
2421
+ throw new Error(response.message);
2012
2422
  } catch (error) {
2013
2423
  throw new Error(`Failed to rename branch: ${error.message}`);
2014
2424
  }
@@ -2016,7 +2426,7 @@ var CoreService = class extends BaseService {
2016
2426
  /**
2017
2427
  * Get changes/diff for a branch compared to another version
2018
2428
  */
2019
- async getBranchChanges(projectId, branchName, options = {}) {
2429
+ async getBranchChanges(projectId, branchName = "main", options = {}) {
2020
2430
  this._requireReady("getBranchChanges");
2021
2431
  if (!projectId) {
2022
2432
  throw new Error("Project ID is required");
@@ -2038,10 +2448,14 @@ var CoreService = class extends BaseService {
2038
2448
  const queryString = queryParams.toString();
2039
2449
  const url = `/projects/${projectId}/branches/${encodeURIComponent(branchName)}/changes${queryString ? `?${queryString}` : ""}`;
2040
2450
  try {
2041
- return await this._request(url, {
2451
+ const response = await this._request(url, {
2042
2452
  method: "GET",
2043
2453
  methodName: "getBranchChanges"
2044
2454
  });
2455
+ if (response.success) {
2456
+ return response.data;
2457
+ }
2458
+ throw new Error(response.message);
2045
2459
  } catch (error) {
2046
2460
  throw new Error(`Failed to get branch changes: ${error.message}`);
2047
2461
  }
@@ -2072,11 +2486,15 @@ var CoreService = class extends BaseService {
2072
2486
  ...changes && { changes }
2073
2487
  };
2074
2488
  try {
2075
- return await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}/merge`, {
2489
+ const response = await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}/merge`, {
2076
2490
  method: "POST",
2077
2491
  body: JSON.stringify(requestBody),
2078
2492
  methodName: "mergeBranch"
2079
2493
  });
2494
+ if (response.success) {
2495
+ return response.data;
2496
+ }
2497
+ throw new Error(response.message);
2080
2498
  } catch (error) {
2081
2499
  if (error.message.includes("conflicts") || error.message.includes("409")) {
2082
2500
  throw new Error(`Merge conflicts detected: ${error.message}`);
@@ -2096,10 +2514,14 @@ var CoreService = class extends BaseService {
2096
2514
  throw new Error("Branch name is required");
2097
2515
  }
2098
2516
  try {
2099
- return await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}/reset`, {
2517
+ const response = await this._request(`/projects/${projectId}/branches/${encodeURIComponent(branchName)}/reset`, {
2100
2518
  method: "POST",
2101
2519
  methodName: "resetBranch"
2102
2520
  });
2521
+ if (response.success) {
2522
+ return response.data;
2523
+ }
2524
+ throw new Error(response.message);
2103
2525
  } catch (error) {
2104
2526
  throw new Error(`Failed to reset branch: ${error.message}`);
2105
2527
  }
@@ -2117,11 +2539,15 @@ var CoreService = class extends BaseService {
2117
2539
  }
2118
2540
  const { version, branch = "main" } = publishData;
2119
2541
  try {
2120
- return await this._request(`/projects/${projectId}/publish`, {
2542
+ const response = await this._request(`/projects/${projectId}/publish`, {
2121
2543
  method: "POST",
2122
2544
  body: JSON.stringify({ version, branch }),
2123
2545
  methodName: "publishVersion"
2124
2546
  });
2547
+ if (response.success) {
2548
+ return response.data;
2549
+ }
2550
+ throw new Error(response.message);
2125
2551
  } catch (error) {
2126
2552
  throw new Error(`Failed to publish version: ${error.message}`);
2127
2553
  }
@@ -2247,6 +2673,143 @@ var CoreService = class extends BaseService {
2247
2673
  }
2248
2674
  return await this.deleteBranch(projectId, branchName);
2249
2675
  }
2676
+ // ==================== ADMIN METHODS ====================
2677
+ /**
2678
+ * Get admin users list with comprehensive filtering and search capabilities
2679
+ * Requires admin or super_admin global role
2680
+ */
2681
+ async getAdminUsers(params = {}) {
2682
+ this._requireReady("getAdminUsers");
2683
+ const {
2684
+ emails,
2685
+ ids,
2686
+ query,
2687
+ status,
2688
+ page = 1,
2689
+ limit = 50,
2690
+ sort = { field: "createdAt", order: "desc" }
2691
+ } = params;
2692
+ const queryParams = new URLSearchParams();
2693
+ if (emails) {
2694
+ queryParams.append("emails", emails);
2695
+ }
2696
+ if (ids) {
2697
+ queryParams.append("ids", ids);
2698
+ }
2699
+ if (query) {
2700
+ queryParams.append("query", query);
2701
+ }
2702
+ if (status) {
2703
+ queryParams.append("status", status);
2704
+ }
2705
+ if (page) {
2706
+ queryParams.append("page", page.toString());
2707
+ }
2708
+ if (limit) {
2709
+ queryParams.append("limit", limit.toString());
2710
+ }
2711
+ if (sort && sort.field) {
2712
+ queryParams.append("sort[field]", sort.field);
2713
+ queryParams.append("sort[order]", sort.order || "desc");
2714
+ }
2715
+ const queryString = queryParams.toString();
2716
+ const url = `/users/admin/users${queryString ? `?${queryString}` : ""}`;
2717
+ try {
2718
+ const response = await this._request(url, {
2719
+ method: "GET",
2720
+ methodName: "getAdminUsers"
2721
+ });
2722
+ if (response.success) {
2723
+ return response.data;
2724
+ }
2725
+ throw new Error(response.message);
2726
+ } catch (error) {
2727
+ throw new Error(`Failed to get admin users: ${error.message}`);
2728
+ }
2729
+ }
2730
+ /**
2731
+ * Assign projects to a specific user
2732
+ * Requires admin or super_admin global role
2733
+ */
2734
+ async assignProjectsToUser(userId, options = {}) {
2735
+ this._requireReady("assignProjectsToUser");
2736
+ if (!userId) {
2737
+ throw new Error("User ID is required");
2738
+ }
2739
+ const {
2740
+ projectIds,
2741
+ role = "guest"
2742
+ } = options;
2743
+ const requestBody = {
2744
+ userId,
2745
+ role
2746
+ };
2747
+ if (projectIds && Array.isArray(projectIds)) {
2748
+ requestBody.projectIds = projectIds;
2749
+ }
2750
+ try {
2751
+ const response = await this._request("/assign-projects", {
2752
+ method: "POST",
2753
+ body: JSON.stringify(requestBody),
2754
+ methodName: "assignProjectsToUser"
2755
+ });
2756
+ if (response.success) {
2757
+ return response.data;
2758
+ }
2759
+ throw new Error(response.message);
2760
+ } catch (error) {
2761
+ throw new Error(`Failed to assign projects to user: ${error.message}`);
2762
+ }
2763
+ }
2764
+ /**
2765
+ * Helper method for admin users search
2766
+ */
2767
+ async searchAdminUsers(searchQuery, options = {}) {
2768
+ return await this.getAdminUsers({
2769
+ query: searchQuery,
2770
+ ...options
2771
+ });
2772
+ }
2773
+ /**
2774
+ * Helper method to get admin users by email list
2775
+ */
2776
+ async getAdminUsersByEmails(emails, options = {}) {
2777
+ const emailList = Array.isArray(emails) ? emails.join(",") : emails;
2778
+ return await this.getAdminUsers({
2779
+ emails: emailList,
2780
+ ...options
2781
+ });
2782
+ }
2783
+ /**
2784
+ * Helper method to get admin users by ID list
2785
+ */
2786
+ async getAdminUsersByIds(ids, options = {}) {
2787
+ const idList = Array.isArray(ids) ? ids.join(",") : ids;
2788
+ return await this.getAdminUsers({
2789
+ ids: idList,
2790
+ ...options
2791
+ });
2792
+ }
2793
+ /**
2794
+ * Helper method to assign specific projects to a user with a specific role
2795
+ */
2796
+ async assignSpecificProjectsToUser(userId, projectIds, role = "guest") {
2797
+ if (!Array.isArray(projectIds) || projectIds.length === 0) {
2798
+ throw new Error("Project IDs must be a non-empty array");
2799
+ }
2800
+ return await this.assignProjectsToUser(userId, {
2801
+ projectIds,
2802
+ role
2803
+ });
2804
+ }
2805
+ /**
2806
+ * Helper method to assign all projects to a user with a specific role
2807
+ */
2808
+ async assignAllProjectsToUser(userId, role = "guest") {
2809
+ return await this.assignProjectsToUser(userId, {
2810
+ role
2811
+ });
2812
+ }
2250
2813
  // Cleanup
2251
2814
  destroy() {
2252
2815
  if (this._tokenManager) {