@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.
- package/README.md +2 -2
- package/dist/cjs/config/environment.js +5 -21
- package/dist/cjs/index.js +6 -26
- package/dist/cjs/services/AIService.js +3 -3
- package/dist/cjs/services/CollabService.js +420 -0
- package/dist/cjs/services/CoreService.js +651 -107
- package/dist/cjs/services/SocketService.js +207 -59
- package/dist/cjs/services/index.js +5 -13
- package/dist/cjs/state/RootStateManager.js +86 -0
- package/dist/cjs/state/rootEventBus.js +65 -0
- package/dist/cjs/utils/CollabClient.js +157 -0
- package/dist/cjs/utils/TokenManager.js +62 -27
- package/dist/cjs/utils/jsonDiff.js +103 -0
- package/dist/cjs/utils/services.js +129 -88
- package/dist/cjs/utils/symstoryClient.js +5 -5
- package/dist/esm/config/environment.js +5 -21
- package/dist/esm/index.js +20459 -9286
- package/dist/esm/services/AIService.js +3 -3
- package/dist/esm/services/BasedService.js +5 -21
- package/dist/esm/services/CollabService.js +18028 -0
- package/dist/esm/services/CoreService.js +718 -155
- package/dist/esm/services/SocketService.js +323 -58
- package/dist/esm/services/SymstoryService.js +10 -26
- package/dist/esm/services/index.js +20305 -9158
- package/dist/esm/state/RootStateManager.js +102 -0
- package/dist/esm/state/rootEventBus.js +47 -0
- package/dist/esm/utils/CollabClient.js +17483 -0
- package/dist/esm/utils/TokenManager.js +62 -27
- package/dist/esm/utils/jsonDiff.js +6096 -0
- package/dist/esm/utils/services.js +129 -88
- package/dist/esm/utils/symstoryClient.js +10 -26
- package/dist/node/config/environment.js +5 -21
- package/dist/node/index.js +10 -34
- package/dist/node/services/AIService.js +3 -3
- package/dist/node/services/CollabService.js +401 -0
- package/dist/node/services/CoreService.js +651 -107
- package/dist/node/services/SocketService.js +197 -59
- package/dist/node/services/index.js +5 -13
- package/dist/node/state/RootStateManager.js +57 -0
- package/dist/node/state/rootEventBus.js +46 -0
- package/dist/node/utils/CollabClient.js +128 -0
- package/dist/node/utils/TokenManager.js +62 -27
- package/dist/node/utils/jsonDiff.js +74 -0
- package/dist/node/utils/services.js +129 -88
- package/dist/node/utils/symstoryClient.js +5 -5
- package/package.json +12 -6
- package/src/config/environment.js +5 -19
- package/src/index.js +9 -31
- package/src/services/AIService.js +3 -3
- package/src/services/BasedService.js +1 -0
- package/src/services/CollabService.js +491 -0
- package/src/services/CoreService.js +715 -110
- package/src/services/SocketService.js +227 -59
- package/src/services/index.js +6 -13
- package/src/state/RootStateManager.js +71 -0
- package/src/state/rootEventBus.js +48 -0
- package/src/utils/CollabClient.js +161 -0
- package/src/utils/TokenManager.js +68 -30
- package/src/utils/jsonDiff.js +109 -0
- package/src/utils/services.js +140 -88
- package/src/utils/symstoryClient.js +5 -5
- package/dist/cjs/services/SocketIOService.js +0 -307
- package/dist/esm/services/SocketIOService.js +0 -470
- package/dist/node/services/SocketIOService.js +0 -278
- 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.
|
|
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.
|
|
48
|
-
if (!this.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
124
|
-
const defaultHeaders = {
|
|
125
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
386
|
-
error: `
|
|
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.
|
|
395
|
-
authToken:
|
|
396
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
917
|
+
async inviteMember(projectId, email, role = "guest", options = {}) {
|
|
670
918
|
this._requireReady("inviteMember");
|
|
671
|
-
if (!projectId || !email) {
|
|
672
|
-
throw new Error("Project ID and
|
|
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
|
-
|
|
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(
|
|
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(
|
|
946
|
+
async acceptInvite(token) {
|
|
685
947
|
this._requireReady("acceptInvite");
|
|
686
|
-
if (!
|
|
687
|
-
throw new Error("
|
|
948
|
+
if (!token) {
|
|
949
|
+
throw new Error("Invitation token is required");
|
|
688
950
|
}
|
|
689
951
|
try {
|
|
690
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) {
|