@symbo.ls/sdk 2.34.4 → 2.34.7

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 (49) hide show
  1. package/dist/cjs/index.js +24 -0
  2. package/dist/cjs/services/BranchService.js +4 -4
  3. package/dist/cjs/services/IntegrationService.js +538 -0
  4. package/dist/cjs/services/MetricsService.js +62 -0
  5. package/dist/cjs/services/PaymentService.js +1 -1
  6. package/dist/cjs/services/PullRequestService.js +8 -6
  7. package/dist/cjs/services/WaitlistService.js +148 -0
  8. package/dist/cjs/services/index.js +13 -1
  9. package/dist/cjs/utils/services.js +26 -1
  10. package/dist/esm/index.js +751 -12
  11. package/dist/esm/services/BranchService.js +4 -4
  12. package/dist/esm/services/IntegrationService.js +1319 -0
  13. package/dist/esm/services/MetricsService.js +843 -0
  14. package/dist/esm/services/PaymentService.js +1 -1
  15. package/dist/esm/services/PullRequestService.js +8 -6
  16. package/dist/esm/services/WaitlistService.js +929 -0
  17. package/dist/esm/services/index.js +708 -12
  18. package/dist/esm/utils/services.js +26 -1
  19. package/dist/node/index.js +32 -2
  20. package/dist/node/services/BranchService.js +4 -4
  21. package/dist/node/services/IntegrationService.js +519 -0
  22. package/dist/node/services/MetricsService.js +43 -0
  23. package/dist/node/services/PaymentService.js +1 -1
  24. package/dist/node/services/PullRequestService.js +8 -6
  25. package/dist/node/services/WaitlistService.js +129 -0
  26. package/dist/node/services/index.js +13 -1
  27. package/dist/node/utils/services.js +26 -1
  28. package/package.json +8 -7
  29. package/src/index.js +40 -13
  30. package/src/services/BranchService.js +5 -5
  31. package/src/services/IntegrationService.js +548 -0
  32. package/src/services/MetricsService.js +40 -0
  33. package/src/services/PaymentService.js +1 -1
  34. package/src/services/PullRequestService.js +6 -6
  35. package/src/services/WaitlistService.js +130 -0
  36. package/src/services/index.js +16 -2
  37. package/src/services/tests/FileService/createFileFormData.test.js +74 -0
  38. package/src/services/tests/FileService/getFileUrl.test.js +69 -0
  39. package/src/services/tests/FileService/updateProjectIcon.test.js +109 -0
  40. package/src/services/tests/FileService/uploadDocument.test.js +36 -0
  41. package/src/services/tests/FileService/uploadFile.test.js +78 -0
  42. package/src/services/tests/FileService/uploadFileWithValidation.test.js +114 -0
  43. package/src/services/tests/FileService/uploadImage.test.js +36 -0
  44. package/src/services/tests/FileService/uploadMultipleFiles.test.js +111 -0
  45. package/src/services/tests/FileService/validateFile.test.js +63 -0
  46. package/src/services/tests/PlanService/getActivePlans.test.js +0 -2
  47. package/src/services/tests/PlanService/getPlanByKey.test.js +109 -0
  48. package/src/services/tests/PlanService/getPlansByPriceRange.test.js +109 -0
  49. package/src/utils/services.js +29 -1
@@ -273,7 +273,32 @@ var SERVICE_METHODS = {
273
273
  flushQueue: "tracking",
274
274
  getClient: "tracking",
275
275
  isEnabled: "tracking",
276
- isInitialized: "tracking"
276
+ isInitialized: "tracking",
277
+ // Waitlist methods
278
+ joinWaitlist: "waitlist",
279
+ listWaitlistEntries: "waitlist",
280
+ updateWaitlistEntry: "waitlist",
281
+ inviteWaitlistEntry: "waitlist",
282
+ // Metrics methods
283
+ getContributions: "metrics",
284
+ // Integration methods
285
+ integrationWhoami: "integration",
286
+ listIntegrations: "integration",
287
+ createIntegration: "integration",
288
+ updateIntegration: "integration",
289
+ createIntegrationApiKey: "integration",
290
+ listIntegrationApiKeys: "integration",
291
+ revokeIntegrationApiKey: "integration",
292
+ createIntegrationWebhook: "integration",
293
+ listIntegrationWebhooks: "integration",
294
+ updateIntegrationWebhook: "integration",
295
+ deleteIntegrationWebhook: "integration",
296
+ listIntegrationWebhookDeliveries: "integration",
297
+ replayIntegrationWebhookDelivery: "integration",
298
+ listGitHubConnectors: "integration",
299
+ createGitHubConnector: "integration",
300
+ updateGitHubConnector: "integration",
301
+ deleteGitHubConnector: "integration"
277
302
  };
278
303
  export {
279
304
  SERVICE_METHODS
@@ -11,7 +11,10 @@ import {
11
11
  createAdminService,
12
12
  createSubscriptionService,
13
13
  createScreenshotService,
14
- createTrackingService
14
+ createTrackingService,
15
+ createWaitlistService,
16
+ createMetricsService,
17
+ createIntegrationService
15
18
  } from "./services/index.js";
16
19
  import { SERVICE_METHODS } from "./utils/services.js";
17
20
  import environment from "./config/environment.js";
@@ -131,6 +134,27 @@ class SDK {
131
134
  context: this._context,
132
135
  options: this._options
133
136
  })
137
+ ),
138
+ this._initService(
139
+ "waitlist",
140
+ createWaitlistService({
141
+ context: this._context,
142
+ options: this._options
143
+ })
144
+ ),
145
+ this._initService(
146
+ "metrics",
147
+ createMetricsService({
148
+ context: this._context,
149
+ options: this._options
150
+ })
151
+ ),
152
+ this._initService(
153
+ "integration",
154
+ createIntegrationService({
155
+ context: this._context,
156
+ options: this._options
157
+ })
134
158
  )
135
159
  ]);
136
160
  return this;
@@ -259,7 +283,10 @@ import {
259
283
  createPullRequestService as createPullRequestService2,
260
284
  createAdminService as createAdminService2,
261
285
  createSubscriptionService as createSubscriptionService2,
262
- createTrackingService as createTrackingService2
286
+ createTrackingService as createTrackingService2,
287
+ createWaitlistService as createWaitlistService2,
288
+ createMetricsService as createMetricsService2,
289
+ createIntegrationService as createIntegrationService2
263
290
  } from "./services/index.js";
264
291
  import { default as default2 } from "./config/environment.js";
265
292
  export {
@@ -270,12 +297,15 @@ export {
270
297
  createCollabService2 as createCollabService,
271
298
  createDnsService2 as createDnsService,
272
299
  createFileService2 as createFileService,
300
+ createIntegrationService2 as createIntegrationService,
301
+ createMetricsService2 as createMetricsService,
273
302
  createPaymentService2 as createPaymentService,
274
303
  createPlanService2 as createPlanService,
275
304
  createProjectService2 as createProjectService,
276
305
  createPullRequestService2 as createPullRequestService,
277
306
  createSubscriptionService2 as createSubscriptionService,
278
307
  createTrackingService2 as createTrackingService,
308
+ createWaitlistService2 as createWaitlistService,
279
309
  index_default as default,
280
310
  default2 as environment,
281
311
  isLocalhost
@@ -195,7 +195,7 @@ class BranchService extends BaseService {
195
195
  throw new Error(response.message);
196
196
  } catch (error) {
197
197
  if (error.message.includes("conflicts") || error.message.includes("409")) {
198
- throw new Error(`Merge conflicts detected: ${error.message}`);
198
+ throw new Error(`Merge conflicts detected: ${error.message}`, { cause: error });
199
199
  }
200
200
  throw new Error(`Failed to merge branch: ${error.message}`, { cause: error });
201
201
  }
@@ -408,7 +408,7 @@ class BranchService extends BaseService {
408
408
  );
409
409
  return branchStatuses;
410
410
  } catch (error) {
411
- throw new Error(`Failed to get branches with status: ${error.message}`);
411
+ throw new Error(`Failed to get branches with status: ${error.message}`, { cause: error });
412
412
  }
413
413
  }
414
414
  /**
@@ -439,7 +439,7 @@ class BranchService extends BaseService {
439
439
  error: 'Cannot use "main" as a branch name'
440
440
  };
441
441
  }
442
- if (!/^[a-zA-Z0-9-_]+$/.test(branchName)) {
442
+ if (!/^[a-zA-Z0-9-_]+$/u.test(branchName)) {
443
443
  return {
444
444
  isValid: false,
445
445
  error: "Branch name can only contain letters, numbers, hyphens, and underscores"
@@ -457,7 +457,7 @@ class BranchService extends BaseService {
457
457
  if (!branchName) {
458
458
  return "";
459
459
  }
460
- return branchName.trim().toLowerCase().replace(/[^a-z0-9-_]/gu, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
460
+ return branchName.trim().toLowerCase().replace(/[^a-z0-9-_]/gu, "-").replace(/-+/gu, "-").replace(/^-|-$/gu, "");
461
461
  }
462
462
  }
463
463
  export {
@@ -0,0 +1,519 @@
1
+ import { BaseService } from "./BaseService.js";
2
+ class IntegrationService extends BaseService {
3
+ // ==================== INTEGRATION METHODS ====================
4
+ /**
5
+ * Programmatic auth sanity check (API key based).
6
+ *
7
+ * Mirrors: GET /integrations/whoami (requireApiKey)
8
+ *
9
+ * Assumption: backend reads API key from `x-api-key` header.
10
+ * You can override via `options.headers`.
11
+ */
12
+ async integrationWhoami(apiKey, options = {}) {
13
+ this._requireReady("integrationWhoami");
14
+ if (!apiKey) {
15
+ throw new Error("API key is required");
16
+ }
17
+ const headers = {
18
+ "x-api-key": apiKey,
19
+ ...options.headers || {}
20
+ };
21
+ try {
22
+ const response = await this._request("/integrations/whoami", {
23
+ method: "GET",
24
+ headers,
25
+ methodName: "integrationWhoami"
26
+ });
27
+ if (response.success) {
28
+ return response.data;
29
+ }
30
+ throw new Error(response.message);
31
+ } catch (error) {
32
+ throw new Error(`Failed to validate integration API key: ${error.message}`, { cause: error });
33
+ }
34
+ }
35
+ /**
36
+ * List integrations visible to the user.
37
+ *
38
+ * Mirrors: GET /integrations?orgId=&projectId=
39
+ */
40
+ async listIntegrations(options = {}) {
41
+ this._requireReady("listIntegrations");
42
+ const { orgId, projectId } = options || {};
43
+ const queryParams = new URLSearchParams();
44
+ if (orgId != null) {
45
+ queryParams.append("orgId", String(orgId));
46
+ }
47
+ if (projectId != null) {
48
+ queryParams.append("projectId", String(projectId));
49
+ }
50
+ const queryString = queryParams.toString();
51
+ const url = `/integrations${queryString ? `?${queryString}` : ""}`;
52
+ try {
53
+ const response = await this._request(url, {
54
+ method: "GET",
55
+ methodName: "listIntegrations"
56
+ });
57
+ if (response.success) {
58
+ return response.data;
59
+ }
60
+ throw new Error(response.message);
61
+ } catch (error) {
62
+ throw new Error(`Failed to list integrations: ${error.message}`, { cause: error });
63
+ }
64
+ }
65
+ /**
66
+ * Create an integration.
67
+ *
68
+ * Mirrors: POST /integrations
69
+ */
70
+ async createIntegration(data = {}) {
71
+ this._requireReady("createIntegration");
72
+ if (!data || typeof data !== "object") {
73
+ throw new Error("Integration payload is required");
74
+ }
75
+ if (!data.name) {
76
+ throw new Error("Integration name is required");
77
+ }
78
+ if (!data.ownerType) {
79
+ throw new Error("ownerType is required");
80
+ }
81
+ try {
82
+ const response = await this._request("/integrations", {
83
+ method: "POST",
84
+ body: JSON.stringify(data),
85
+ methodName: "createIntegration"
86
+ });
87
+ if (response.success) {
88
+ return response.data;
89
+ }
90
+ throw new Error(response.message);
91
+ } catch (error) {
92
+ throw new Error(`Failed to create integration: ${error.message}`, { cause: error });
93
+ }
94
+ }
95
+ /**
96
+ * Update an integration.
97
+ *
98
+ * Mirrors: PATCH /integrations/:integrationId
99
+ */
100
+ async updateIntegration(integrationId, update = {}) {
101
+ this._requireReady("updateIntegration");
102
+ if (!integrationId) {
103
+ throw new Error("Integration ID is required");
104
+ }
105
+ if (!update || typeof update !== "object") {
106
+ throw new Error("Update payload is required");
107
+ }
108
+ try {
109
+ const response = await this._request(`/integrations/${integrationId}`, {
110
+ method: "PATCH",
111
+ body: JSON.stringify(update),
112
+ methodName: "updateIntegration"
113
+ });
114
+ if (response.success) {
115
+ return response.data;
116
+ }
117
+ throw new Error(response.message);
118
+ } catch (error) {
119
+ throw new Error(`Failed to update integration: ${error.message}`, { cause: error });
120
+ }
121
+ }
122
+ // ==================== INTEGRATION API KEY METHODS ====================
123
+ /**
124
+ * Create a new API key for an integration.
125
+ *
126
+ * Mirrors: POST /integrations/:integrationId/api-keys
127
+ */
128
+ async createIntegrationApiKey(integrationId, data = {}) {
129
+ this._requireReady("createIntegrationApiKey");
130
+ if (!integrationId) {
131
+ throw new Error("Integration ID is required");
132
+ }
133
+ if (!data || typeof data !== "object") {
134
+ throw new Error("API key payload is required");
135
+ }
136
+ try {
137
+ const response = await this._request(`/integrations/${integrationId}/api-keys`, {
138
+ method: "POST",
139
+ body: JSON.stringify(data),
140
+ methodName: "createIntegrationApiKey"
141
+ });
142
+ if (response.success) {
143
+ return response.data;
144
+ }
145
+ throw new Error(response.message);
146
+ } catch (error) {
147
+ throw new Error(`Failed to create integration API key: ${error.message}`, { cause: error });
148
+ }
149
+ }
150
+ /**
151
+ * List API keys for an integration.
152
+ *
153
+ * Mirrors: GET /integrations/:integrationId/api-keys
154
+ */
155
+ async listIntegrationApiKeys(integrationId) {
156
+ this._requireReady("listIntegrationApiKeys");
157
+ if (!integrationId) {
158
+ throw new Error("Integration ID is required");
159
+ }
160
+ try {
161
+ const response = await this._request(`/integrations/${integrationId}/api-keys`, {
162
+ method: "GET",
163
+ methodName: "listIntegrationApiKeys"
164
+ });
165
+ if (response.success) {
166
+ return response.data;
167
+ }
168
+ throw new Error(response.message);
169
+ } catch (error) {
170
+ throw new Error(`Failed to list integration API keys: ${error.message}`, { cause: error });
171
+ }
172
+ }
173
+ /**
174
+ * Revoke an API key for an integration.
175
+ *
176
+ * Mirrors: POST /integrations/:integrationId/api-keys/:keyId/revoke
177
+ */
178
+ async revokeIntegrationApiKey(integrationId, keyId) {
179
+ this._requireReady("revokeIntegrationApiKey");
180
+ if (!integrationId) {
181
+ throw new Error("Integration ID is required");
182
+ }
183
+ if (!keyId) {
184
+ throw new Error("API key ID is required");
185
+ }
186
+ try {
187
+ const response = await this._request(
188
+ `/integrations/${integrationId}/api-keys/${keyId}/revoke`,
189
+ {
190
+ method: "POST",
191
+ methodName: "revokeIntegrationApiKey"
192
+ }
193
+ );
194
+ if (response.success) {
195
+ return response.data;
196
+ }
197
+ throw new Error(response.message);
198
+ } catch (error) {
199
+ throw new Error(`Failed to revoke integration API key: ${error.message}`, { cause: error });
200
+ }
201
+ }
202
+ // ==================== WEBHOOK METHODS ====================
203
+ /**
204
+ * Create a webhook endpoint for an integration.
205
+ *
206
+ * Mirrors: POST /integrations/:integrationId/webhooks
207
+ */
208
+ async createIntegrationWebhook(integrationId, data = {}) {
209
+ this._requireReady("createIntegrationWebhook");
210
+ if (!integrationId) {
211
+ throw new Error("Integration ID is required");
212
+ }
213
+ if (!data || typeof data !== "object") {
214
+ throw new Error("Webhook payload is required");
215
+ }
216
+ try {
217
+ const response = await this._request(`/integrations/${integrationId}/webhooks`, {
218
+ method: "POST",
219
+ body: JSON.stringify(data),
220
+ methodName: "createIntegrationWebhook"
221
+ });
222
+ if (response.success) {
223
+ return response.data;
224
+ }
225
+ throw new Error(response.message);
226
+ } catch (error) {
227
+ throw new Error(`Failed to create integration webhook: ${error.message}`, { cause: error });
228
+ }
229
+ }
230
+ /**
231
+ * List webhook endpoints for an integration.
232
+ *
233
+ * Mirrors: GET /integrations/:integrationId/webhooks
234
+ */
235
+ async listIntegrationWebhooks(integrationId) {
236
+ this._requireReady("listIntegrationWebhooks");
237
+ if (!integrationId) {
238
+ throw new Error("Integration ID is required");
239
+ }
240
+ try {
241
+ const response = await this._request(`/integrations/${integrationId}/webhooks`, {
242
+ method: "GET",
243
+ methodName: "listIntegrationWebhooks"
244
+ });
245
+ if (response.success) {
246
+ return response.data;
247
+ }
248
+ throw new Error(response.message);
249
+ } catch (error) {
250
+ throw new Error(`Failed to list integration webhooks: ${error.message}`, { cause: error });
251
+ }
252
+ }
253
+ /**
254
+ * Update a webhook endpoint for an integration.
255
+ *
256
+ * Mirrors: PATCH /integrations/:integrationId/webhooks/:webhookId
257
+ */
258
+ async updateIntegrationWebhook(integrationId, webhookId, update = {}) {
259
+ this._requireReady("updateIntegrationWebhook");
260
+ if (!integrationId) {
261
+ throw new Error("Integration ID is required");
262
+ }
263
+ if (!webhookId) {
264
+ throw new Error("Webhook ID is required");
265
+ }
266
+ if (!update || typeof update !== "object") {
267
+ throw new Error("Update payload is required");
268
+ }
269
+ try {
270
+ const response = await this._request(
271
+ `/integrations/${integrationId}/webhooks/${webhookId}`,
272
+ {
273
+ method: "PATCH",
274
+ body: JSON.stringify(update),
275
+ methodName: "updateIntegrationWebhook"
276
+ }
277
+ );
278
+ if (response.success) {
279
+ return response.data;
280
+ }
281
+ throw new Error(response.message);
282
+ } catch (error) {
283
+ throw new Error(`Failed to update integration webhook: ${error.message}`, { cause: error });
284
+ }
285
+ }
286
+ /**
287
+ * Delete a webhook endpoint for an integration.
288
+ *
289
+ * Mirrors: DELETE /integrations/:integrationId/webhooks/:webhookId
290
+ */
291
+ async deleteIntegrationWebhook(integrationId, webhookId) {
292
+ this._requireReady("deleteIntegrationWebhook");
293
+ if (!integrationId) {
294
+ throw new Error("Integration ID is required");
295
+ }
296
+ if (!webhookId) {
297
+ throw new Error("Webhook ID is required");
298
+ }
299
+ try {
300
+ const response = await this._request(
301
+ `/integrations/${integrationId}/webhooks/${webhookId}`,
302
+ {
303
+ method: "DELETE",
304
+ methodName: "deleteIntegrationWebhook"
305
+ }
306
+ );
307
+ if (response && response.success) {
308
+ return response.data;
309
+ }
310
+ if (response == null) {
311
+ return null;
312
+ }
313
+ throw new Error(response.message);
314
+ } catch (error) {
315
+ throw new Error(`Failed to delete integration webhook: ${error.message}`, { cause: error });
316
+ }
317
+ }
318
+ /**
319
+ * List webhook deliveries for an integration webhook.
320
+ *
321
+ * Mirrors: GET /integrations/:integrationId/webhooks/:webhookId/deliveries
322
+ */
323
+ async listIntegrationWebhookDeliveries(integrationId, webhookId, options = {}) {
324
+ this._requireReady("listIntegrationWebhookDeliveries");
325
+ if (!integrationId) {
326
+ throw new Error("Integration ID is required");
327
+ }
328
+ if (!webhookId) {
329
+ throw new Error("Webhook ID is required");
330
+ }
331
+ const { page, limit, status, includePayload } = options || {};
332
+ const queryParams = new URLSearchParams();
333
+ if (page != null) {
334
+ queryParams.append("page", String(page));
335
+ }
336
+ if (limit != null) {
337
+ queryParams.append("limit", String(limit));
338
+ }
339
+ if (status != null) {
340
+ queryParams.append("status", String(status));
341
+ }
342
+ if (includePayload != null) {
343
+ queryParams.append("includePayload", String(includePayload));
344
+ }
345
+ const queryString = queryParams.toString();
346
+ const url = `/integrations/${integrationId}/webhooks/${webhookId}/deliveries${queryString ? `?${queryString}` : ""}`;
347
+ try {
348
+ const response = await this._request(url, {
349
+ method: "GET",
350
+ methodName: "listIntegrationWebhookDeliveries"
351
+ });
352
+ if (response.success) {
353
+ return response.data;
354
+ }
355
+ throw new Error(response.message);
356
+ } catch (error) {
357
+ throw new Error(`Failed to list webhook deliveries: ${error.message}`, { cause: error });
358
+ }
359
+ }
360
+ /**
361
+ * Replay a webhook delivery.
362
+ *
363
+ * Mirrors: POST /integrations/:integrationId/webhooks/:webhookId/replay
364
+ * Body: { deliveryId }
365
+ */
366
+ async replayIntegrationWebhookDelivery(integrationId, webhookId, deliveryId) {
367
+ this._requireReady("replayIntegrationWebhookDelivery");
368
+ if (!integrationId) {
369
+ throw new Error("Integration ID is required");
370
+ }
371
+ if (!webhookId) {
372
+ throw new Error("Webhook ID is required");
373
+ }
374
+ if (!deliveryId) {
375
+ throw new Error("deliveryId is required");
376
+ }
377
+ try {
378
+ const response = await this._request(
379
+ `/integrations/${integrationId}/webhooks/${webhookId}/replay`,
380
+ {
381
+ method: "POST",
382
+ body: JSON.stringify({ deliveryId }),
383
+ methodName: "replayIntegrationWebhookDelivery"
384
+ }
385
+ );
386
+ if (response.success) {
387
+ return response.data;
388
+ }
389
+ throw new Error(response.message);
390
+ } catch (error) {
391
+ throw new Error(`Failed to replay webhook delivery: ${error.message}`, { cause: error });
392
+ }
393
+ }
394
+ // ==================== CONNECTOR METHODS (GITHUB) ====================
395
+ /**
396
+ * List GitHub connectors for an integration.
397
+ *
398
+ * Mirrors: GET /integrations/:integrationId/connectors/github
399
+ */
400
+ async listGitHubConnectors(integrationId) {
401
+ this._requireReady("listGitHubConnectors");
402
+ if (!integrationId) {
403
+ throw new Error("Integration ID is required");
404
+ }
405
+ try {
406
+ const response = await this._request(`/integrations/${integrationId}/connectors/github`, {
407
+ method: "GET",
408
+ methodName: "listGitHubConnectors"
409
+ });
410
+ if (response.success) {
411
+ return response.data;
412
+ }
413
+ throw new Error(response.message);
414
+ } catch (error) {
415
+ throw new Error(`Failed to list GitHub connectors: ${error.message}`, { cause: error });
416
+ }
417
+ }
418
+ /**
419
+ * Create a GitHub connector for an integration.
420
+ *
421
+ * Mirrors: POST /integrations/:integrationId/connectors/github
422
+ */
423
+ async createGitHubConnector(integrationId, data = {}) {
424
+ this._requireReady("createGitHubConnector");
425
+ if (!integrationId) {
426
+ throw new Error("Integration ID is required");
427
+ }
428
+ if (!data || typeof data !== "object") {
429
+ throw new Error("Connector payload is required");
430
+ }
431
+ if (!data.projectId) {
432
+ throw new Error("projectId is required");
433
+ }
434
+ if (!data.repository) {
435
+ throw new Error("repository is required");
436
+ }
437
+ try {
438
+ const response = await this._request(`/integrations/${integrationId}/connectors/github`, {
439
+ method: "POST",
440
+ body: JSON.stringify(data),
441
+ methodName: "createGitHubConnector"
442
+ });
443
+ if (response.success) {
444
+ return response.data;
445
+ }
446
+ throw new Error(response.message);
447
+ } catch (error) {
448
+ throw new Error(`Failed to create GitHub connector: ${error.message}`, { cause: error });
449
+ }
450
+ }
451
+ /**
452
+ * Update a GitHub connector.
453
+ *
454
+ * Mirrors: PATCH /integrations/:integrationId/connectors/github/:connectorId
455
+ */
456
+ async updateGitHubConnector(integrationId, connectorId, update = {}) {
457
+ this._requireReady("updateGitHubConnector");
458
+ if (!integrationId) {
459
+ throw new Error("Integration ID is required");
460
+ }
461
+ if (!connectorId) {
462
+ throw new Error("Connector ID is required");
463
+ }
464
+ if (!update || typeof update !== "object") {
465
+ throw new Error("Update payload is required");
466
+ }
467
+ try {
468
+ const response = await this._request(
469
+ `/integrations/${integrationId}/connectors/github/${connectorId}`,
470
+ {
471
+ method: "PATCH",
472
+ body: JSON.stringify(update),
473
+ methodName: "updateGitHubConnector"
474
+ }
475
+ );
476
+ if (response.success) {
477
+ return response.data;
478
+ }
479
+ throw new Error(response.message);
480
+ } catch (error) {
481
+ throw new Error(`Failed to update GitHub connector: ${error.message}`, { cause: error });
482
+ }
483
+ }
484
+ /**
485
+ * Delete a GitHub connector.
486
+ *
487
+ * Mirrors: DELETE /integrations/:integrationId/connectors/github/:connectorId
488
+ */
489
+ async deleteGitHubConnector(integrationId, connectorId) {
490
+ this._requireReady("deleteGitHubConnector");
491
+ if (!integrationId) {
492
+ throw new Error("Integration ID is required");
493
+ }
494
+ if (!connectorId) {
495
+ throw new Error("Connector ID is required");
496
+ }
497
+ try {
498
+ const response = await this._request(
499
+ `/integrations/${integrationId}/connectors/github/${connectorId}`,
500
+ {
501
+ method: "DELETE",
502
+ methodName: "deleteGitHubConnector"
503
+ }
504
+ );
505
+ if (response && response.success) {
506
+ return response.data;
507
+ }
508
+ if (response == null) {
509
+ return null;
510
+ }
511
+ throw new Error(response.message);
512
+ } catch (error) {
513
+ throw new Error(`Failed to delete GitHub connector: ${error.message}`, { cause: error });
514
+ }
515
+ }
516
+ }
517
+ export {
518
+ IntegrationService
519
+ };
@@ -0,0 +1,43 @@
1
+ import { BaseService } from "./BaseService.js";
2
+ class MetricsService extends BaseService {
3
+ // ==================== METRICS METHODS ====================
4
+ /**
5
+ * Contribution heat-map stats.
6
+ *
7
+ * Mirrors: GET /metrics/contributions (MetricsController.getContributions)
8
+ */
9
+ async getContributions(options = {}) {
10
+ this._requireReady("getContributions");
11
+ const { projectId, userId, from, to } = options || {};
12
+ const queryParams = new URLSearchParams();
13
+ if (projectId != null) {
14
+ queryParams.append("projectId", String(projectId));
15
+ }
16
+ if (userId != null) {
17
+ queryParams.append("userId", String(userId));
18
+ }
19
+ if (from != null) {
20
+ queryParams.append("from", String(from));
21
+ }
22
+ if (to != null) {
23
+ queryParams.append("to", String(to));
24
+ }
25
+ const queryString = queryParams.toString();
26
+ const url = `/metrics/contributions${queryString ? `?${queryString}` : ""}`;
27
+ try {
28
+ const response = await this._request(url, {
29
+ method: "GET",
30
+ methodName: "getContributions"
31
+ });
32
+ if (response.success) {
33
+ return response.data;
34
+ }
35
+ throw new Error(response.message);
36
+ } catch (error) {
37
+ throw new Error(`Failed to get contribution stats: ${error.message}`, { cause: error });
38
+ }
39
+ }
40
+ }
41
+ export {
42
+ MetricsService
43
+ };