@andrebuzeli/git-mcp 5.0.0 → 5.0.2

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.
@@ -0,0 +1,1179 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.GitHubProvider = void 0;
37
+ const base_provider_js_1 = require("./base-provider.js");
38
+ /**
39
+ * Provider específico para GitHub
40
+ * Implementa todas as operações VCS usando a API REST do GitHub
41
+ */
42
+ class GitHubProvider extends base_provider_js_1.BaseVcsProvider {
43
+ constructor(config) {
44
+ super(config);
45
+ }
46
+ getBaseUrl(config) {
47
+ return 'https://api.github.com';
48
+ }
49
+ getHeaders(config) {
50
+ return {
51
+ 'Authorization': `Bearer ${config.token}`,
52
+ 'Content-Type': 'application/json',
53
+ 'Accept': 'application/vnd.github.v3+json',
54
+ 'User-Agent': 'Gitea-MCP-MultiProvider/2.3.0'
55
+ };
56
+ }
57
+ // Usando normalizeError padrão do BaseVcsProvider
58
+ normalizeRepository(data) {
59
+ return {
60
+ id: data.id,
61
+ name: data.name,
62
+ full_name: data.full_name,
63
+ description: data.description,
64
+ private: data.private,
65
+ html_url: data.html_url,
66
+ clone_url: data.clone_url,
67
+ default_branch: data.default_branch,
68
+ created_at: data.created_at,
69
+ updated_at: data.updated_at,
70
+ owner: {
71
+ login: data.owner?.login,
72
+ type: data.owner?.type || 'User'
73
+ },
74
+ raw: data
75
+ };
76
+ }
77
+ normalizeBranch(data) {
78
+ return {
79
+ name: data.name,
80
+ commit: {
81
+ sha: data.commit?.sha,
82
+ url: data.commit?.url
83
+ },
84
+ protected: data.protected,
85
+ raw: data
86
+ };
87
+ }
88
+ normalizeFile(data) {
89
+ return {
90
+ name: data.name,
91
+ path: data.path,
92
+ sha: data.sha,
93
+ size: data.size,
94
+ url: data.url,
95
+ html_url: data.html_url,
96
+ git_url: data.git_url,
97
+ download_url: data.download_url,
98
+ type: data.type,
99
+ content: data.content,
100
+ encoding: data.encoding,
101
+ raw: data
102
+ };
103
+ }
104
+ normalizeCommit(data) {
105
+ return {
106
+ sha: data.sha,
107
+ message: data.commit?.message || data.message,
108
+ author: {
109
+ name: data.commit?.author?.name || data.author?.login,
110
+ email: data.commit?.author?.email,
111
+ date: data.commit?.author?.date
112
+ },
113
+ committer: {
114
+ name: data.commit?.committer?.name || data.committer?.login,
115
+ email: data.commit?.committer?.email,
116
+ date: data.commit?.committer?.date
117
+ },
118
+ commit: {
119
+ author: {
120
+ name: data.commit?.author?.name || '',
121
+ email: data.commit?.author?.email || '',
122
+ date: data.commit?.author?.date || ''
123
+ },
124
+ committer: {
125
+ name: data.commit?.committer?.name || '',
126
+ email: data.commit?.committer?.email || '',
127
+ date: data.commit?.committer?.date || ''
128
+ },
129
+ message: data.commit?.message || data.message || ''
130
+ },
131
+ url: data.url,
132
+ html_url: data.html_url,
133
+ raw: data
134
+ };
135
+ }
136
+ normalizeIssue(data) {
137
+ return {
138
+ id: data.id,
139
+ number: data.number,
140
+ title: data.title,
141
+ body: data.body,
142
+ state: data.state,
143
+ user: {
144
+ login: data.user?.login,
145
+ id: data.user?.id
146
+ },
147
+ assignees: data.assignees?.map((a) => ({
148
+ login: a.login,
149
+ id: a.id
150
+ })),
151
+ labels: data.labels?.map((l) => ({
152
+ name: l.name,
153
+ color: l.color
154
+ })),
155
+ created_at: data.created_at,
156
+ updated_at: data.updated_at,
157
+ closed_at: data.closed_at,
158
+ raw: data
159
+ };
160
+ }
161
+ normalizePullRequest(data) {
162
+ return {
163
+ id: data.id,
164
+ number: data.number,
165
+ title: data.title,
166
+ body: data.body,
167
+ state: data.state,
168
+ user: {
169
+ login: data.user?.login,
170
+ id: data.user?.id
171
+ },
172
+ head: {
173
+ ref: data.head?.ref,
174
+ sha: data.head?.sha,
175
+ repo: {
176
+ name: data.head?.repo?.name,
177
+ full_name: data.head?.repo?.full_name
178
+ }
179
+ },
180
+ base: {
181
+ ref: data.base?.ref,
182
+ sha: data.base?.sha,
183
+ repo: {
184
+ name: data.base?.repo?.name,
185
+ full_name: data.base?.repo?.full_name
186
+ }
187
+ },
188
+ created_at: data.created_at,
189
+ updated_at: data.updated_at,
190
+ closed_at: data.closed_at,
191
+ merged_at: data.merged_at,
192
+ mergeable: data.mergeable,
193
+ raw: data
194
+ };
195
+ }
196
+ normalizeRelease(data) {
197
+ return {
198
+ id: data.id,
199
+ tag_name: data.tag_name,
200
+ name: data.name,
201
+ body: data.body,
202
+ draft: data.draft,
203
+ prerelease: data.prerelease,
204
+ created_at: data.created_at,
205
+ published_at: data.published_at,
206
+ html_url: data.html_url,
207
+ tarball_url: data.tarball_url,
208
+ zipball_url: data.zipball_url,
209
+ raw: data
210
+ };
211
+ }
212
+ normalizeTag(data) {
213
+ return {
214
+ name: data.name,
215
+ commit: {
216
+ sha: data.commit?.sha,
217
+ url: data.commit?.url
218
+ },
219
+ zipball_url: data.zipball_url,
220
+ tarball_url: data.tarball_url,
221
+ raw: data
222
+ };
223
+ }
224
+ normalizeUser(data) {
225
+ return {
226
+ id: data.id,
227
+ login: data.login,
228
+ name: data.name,
229
+ email: data.email,
230
+ avatar_url: data.avatar_url,
231
+ html_url: data.html_url,
232
+ type: data.type,
233
+ raw: data
234
+ };
235
+ }
236
+ normalizeOrganization(data) {
237
+ return {
238
+ id: data.id,
239
+ login: data.login,
240
+ name: data.name,
241
+ description: data.description,
242
+ avatar_url: data.avatar_url,
243
+ html_url: data.html_url,
244
+ location: data.location,
245
+ website: data.blog,
246
+ public_repos: data.public_repos,
247
+ public_members: data.public_members,
248
+ raw: data
249
+ };
250
+ }
251
+ normalizeWebhook(data) {
252
+ return {
253
+ id: data.id,
254
+ type: data.type,
255
+ name: data.name,
256
+ active: data.active,
257
+ url: data.config?.url || data.url || '',
258
+ events: data.events,
259
+ config: {
260
+ url: data.config?.url,
261
+ content_type: data.config?.content_type,
262
+ secret: data.config?.secret
263
+ },
264
+ created_at: data.created_at,
265
+ updated_at: data.updated_at,
266
+ raw: data
267
+ };
268
+ }
269
+ // Implementações específicas do GitHub
270
+ async listRepositories(username, page = 1, limit = 30) {
271
+ const url = username ? `/users/${username}/repos` : '/user/repos';
272
+ const data = await this.get(url, { page, per_page: limit, sort: 'updated' });
273
+ return data.map(repo => this.normalizeRepository(repo));
274
+ }
275
+ async getRepository(owner, repo) {
276
+ const data = await this.get(`/repos/${owner}/${repo}`);
277
+ return this.normalizeRepository(data);
278
+ }
279
+ async createRepository(name, description, privateRepo = false) {
280
+ const data = await this.post('/user/repos', {
281
+ name,
282
+ description,
283
+ private: privateRepo,
284
+ auto_init: true
285
+ });
286
+ return this.normalizeRepository(data);
287
+ }
288
+ async updateRepository(owner, repo, updates) {
289
+ const data = await this.patch(`/repos/${owner}/${repo}`, updates);
290
+ return this.normalizeRepository(data);
291
+ }
292
+ async deleteRepository(owner, repo) {
293
+ await this.delete(`/repos/${owner}/${repo}`);
294
+ return true;
295
+ }
296
+ async forkRepository(owner, repo, organization) {
297
+ const payload = organization ? { organization } : {};
298
+ const data = await this.post(`/repos/${owner}/${repo}/forks`, payload);
299
+ return this.normalizeRepository(data);
300
+ }
301
+ async searchRepositories(query, page = 1, limit = 30) {
302
+ const data = await this.get('/search/repositories', {
303
+ q: query,
304
+ page,
305
+ per_page: limit,
306
+ sort: 'stars',
307
+ order: 'desc'
308
+ });
309
+ return data.items.map((repo) => this.normalizeRepository(repo));
310
+ }
311
+ async listBranches(owner, repo, page = 1, limit = 30) {
312
+ const data = await this.get(`/repos/${owner}/${repo}/branches`, { page, per_page: limit });
313
+ return data.map(branch => this.normalizeBranch(branch));
314
+ }
315
+ async getBranch(owner, repo, branch) {
316
+ const data = await this.get(`/repos/${owner}/${repo}/branches/${branch}`);
317
+ return this.normalizeBranch(data);
318
+ }
319
+ async createBranch(owner, repo, branchName, fromBranch) {
320
+ try {
321
+ // Get the source branch to get the commit SHA
322
+ const sourceBranch = await this.getBranch(owner, repo, fromBranch);
323
+ // Create the new branch reference
324
+ const data = await this.post(`/repos/${owner}/${repo}/git/refs`, {
325
+ ref: `refs/heads/${branchName}`,
326
+ sha: sourceBranch.commit.sha
327
+ });
328
+ return this.normalizeBranch({
329
+ name: branchName,
330
+ commit: {
331
+ sha: sourceBranch.commit.sha,
332
+ url: data.object?.url || `https://api.github.com/repos/${owner}/${repo}/git/commits/${sourceBranch.commit.sha}`
333
+ },
334
+ protected: false
335
+ });
336
+ }
337
+ catch (error) {
338
+ throw new Error(`Failed to create branch '${branchName}': ${error instanceof Error ? error.message : String(error)}`);
339
+ }
340
+ }
341
+ async deleteBranch(owner, repo, branch) {
342
+ try {
343
+ await this.delete(`/repos/${owner}/${repo}/git/refs/heads/${branch}`);
344
+ return true;
345
+ }
346
+ catch (error) {
347
+ throw new Error(`Failed to delete branch '${branch}': ${error instanceof Error ? error.message : String(error)}`);
348
+ }
349
+ }
350
+ async getFile(owner, repo, path, ref) {
351
+ const params = ref ? { ref } : {};
352
+ const data = await this.get(`/repos/${owner}/${repo}/contents/${path}`, params);
353
+ return this.normalizeFile(data);
354
+ }
355
+ async createFile(owner, repo, path, content, message, branch) {
356
+ const payload = {
357
+ message,
358
+ content: Buffer.from(content).toString('base64')
359
+ };
360
+ if (branch) {
361
+ payload.branch = branch;
362
+ }
363
+ const data = await this.put(`/repos/${owner}/${repo}/contents/${path}`, payload);
364
+ return this.normalizeFile(data.content);
365
+ }
366
+ async updateFile(owner, repo, path, content, message, sha, branch) {
367
+ const payload = {
368
+ message,
369
+ content: Buffer.from(content).toString('base64'),
370
+ sha
371
+ };
372
+ if (branch) {
373
+ payload.branch = branch;
374
+ }
375
+ const data = await this.put(`/repos/${owner}/${repo}/contents/${path}`, payload);
376
+ return this.normalizeFile(data.content);
377
+ }
378
+ async deleteFile(owner, repo, path, message, sha, branch) {
379
+ const payload = {
380
+ message,
381
+ sha
382
+ };
383
+ if (branch) {
384
+ payload.branch = branch;
385
+ }
386
+ await this.delete(`/repos/${owner}/${repo}/contents/${path}`, { data: payload });
387
+ return true;
388
+ }
389
+ async listFiles(owner, repo, path, ref) {
390
+ const params = ref ? { ref } : {};
391
+ const data = await this.get(`/repos/${owner}/${repo}/contents/${path}`, params);
392
+ return data.map(file => this.normalizeFile(file));
393
+ }
394
+ async uploadProject(owner, repo, projectPath, message, branch) {
395
+ const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
396
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
397
+ let uploaded = 0;
398
+ const errors = [];
399
+ try {
400
+ // Função recursiva para processar diretórios
401
+ const processDirectory = async (dirPath, relativePath = '') => {
402
+ const items = await fs.readdir(dirPath, { withFileTypes: true });
403
+ for (const item of items) {
404
+ const fullPath = path.join(dirPath, item.name);
405
+ const itemRelativePath = relativePath ? path.join(relativePath, item.name) : item.name;
406
+ // Pular diretórios que não devem ser enviados
407
+ if (item.isDirectory()) {
408
+ if (item.name === 'node_modules' || item.name === '.git' || item.name === 'dist') {
409
+ continue;
410
+ }
411
+ await processDirectory(fullPath, itemRelativePath);
412
+ }
413
+ else {
414
+ // Pular arquivos que não devem ser enviados
415
+ if (item.name.endsWith('.log') || item.name.endsWith('.tmp') || item.name.startsWith('.')) {
416
+ continue;
417
+ }
418
+ try {
419
+ const content = await fs.readFile(fullPath, 'utf-8');
420
+ await this.createFile(owner, repo, itemRelativePath, content, message, branch);
421
+ uploaded++;
422
+ }
423
+ catch (error) {
424
+ errors.push(`Erro ao enviar ${itemRelativePath}: ${error instanceof Error ? error.message : String(error)}`);
425
+ }
426
+ }
427
+ }
428
+ };
429
+ await processDirectory(projectPath);
430
+ return { uploaded, errors };
431
+ }
432
+ catch (error) {
433
+ throw new Error(`Falha ao fazer upload do projeto: ${error instanceof Error ? error.message : String(error)}`);
434
+ }
435
+ }
436
+ async listCommits(owner, repo, branch, page = 1, limit = 30) {
437
+ const params = { page, per_page: limit };
438
+ if (branch)
439
+ params.sha = branch;
440
+ const data = await this.get(`/repos/${owner}/${repo}/commits`, params);
441
+ return data.map(commit => this.normalizeCommit(commit));
442
+ }
443
+ async getCommit(owner, repo, sha) {
444
+ const data = await this.get(`/repos/${owner}/${repo}/git/commits/${sha}`);
445
+ return this.normalizeCommit(data);
446
+ }
447
+ async listIssues(owner, repo, state = 'open', page = 1, limit = 30) {
448
+ const data = await this.get(`/repos/${owner}/${repo}/issues`, {
449
+ state,
450
+ page,
451
+ per_page: limit,
452
+ filter: 'all'
453
+ });
454
+ return data.map(issue => this.normalizeIssue(issue));
455
+ }
456
+ async getIssue(owner, repo, issueNumber) {
457
+ const data = await this.get(`/repos/${owner}/${repo}/issues/${issueNumber}`);
458
+ return this.normalizeIssue(data);
459
+ }
460
+ async createIssue(owner, repo, title, body, assignees, labels) {
461
+ const payload = { title };
462
+ if (body)
463
+ payload.body = body;
464
+ if (assignees)
465
+ payload.assignees = assignees;
466
+ if (labels)
467
+ payload.labels = labels;
468
+ const data = await this.post(`/repos/${owner}/${repo}/issues`, payload);
469
+ return this.normalizeIssue(data);
470
+ }
471
+ async updateIssue(owner, repo, issueNumber, updates) {
472
+ const data = await this.patch(`/repos/${owner}/${repo}/issues/${issueNumber}`, updates);
473
+ return this.normalizeIssue(data);
474
+ }
475
+ async closeIssue(owner, repo, issueNumber) {
476
+ return this.updateIssue(owner, repo, issueNumber, { state: 'closed' });
477
+ }
478
+ async listPullRequests(owner, repo, state = 'open', page = 1, limit = 30) {
479
+ const data = await this.get(`/repos/${owner}/${repo}/pulls`, {
480
+ state,
481
+ page,
482
+ per_page: limit,
483
+ sort: 'updated',
484
+ direction: 'desc'
485
+ });
486
+ return data.map(pr => this.normalizePullRequest(pr));
487
+ }
488
+ async getPullRequest(owner, repo, pullNumber) {
489
+ const data = await this.get(`/repos/${owner}/${repo}/pulls/${pullNumber}`);
490
+ return this.normalizePullRequest(data);
491
+ }
492
+ async createPullRequest(owner, repo, title, body, head, base) {
493
+ const data = await this.post(`/repos/${owner}/${repo}/pulls`, {
494
+ title,
495
+ body,
496
+ head,
497
+ base
498
+ });
499
+ return this.normalizePullRequest(data);
500
+ }
501
+ async updatePullRequest(owner, repo, pullNumber, updates) {
502
+ const data = await this.patch(`/repos/${owner}/${repo}/pulls/${pullNumber}`, updates);
503
+ return this.normalizePullRequest(data);
504
+ }
505
+ async mergePullRequest(owner, repo, pullNumber, mergeMethod = 'merge') {
506
+ await this.put(`/repos/${owner}/${repo}/pulls/${pullNumber}/merge`, {
507
+ merge_method: mergeMethod
508
+ });
509
+ return true;
510
+ }
511
+ async listReleases(owner, repo, page = 1, limit = 30) {
512
+ const data = await this.get(`/repos/${owner}/${repo}/releases`, { page, per_page: limit });
513
+ return data.map(release => this.normalizeRelease(release));
514
+ }
515
+ async getRelease(owner, repo, releaseId) {
516
+ const data = await this.get(`/repos/${owner}/${repo}/releases/${releaseId}`);
517
+ return this.normalizeRelease(data);
518
+ }
519
+ async createRelease(owner, repo, releaseData) {
520
+ const data = await this.post(`/repos/${owner}/${repo}/releases`, {
521
+ tag_name: releaseData.tag_name,
522
+ name: releaseData.name || releaseData.tag_name,
523
+ body: releaseData.body || '',
524
+ draft: releaseData.draft || false,
525
+ prerelease: releaseData.prerelease || false,
526
+ target_commitish: releaseData.target_commitish || 'main'
527
+ });
528
+ return this.normalizeRelease(data);
529
+ }
530
+ async updateRelease(owner, repo, releaseId, updates) {
531
+ const data = await this.patch(`/repos/${owner}/${repo}/releases/${releaseId}`, updates);
532
+ return this.normalizeRelease(data);
533
+ }
534
+ async deleteRelease(owner, repo, releaseId) {
535
+ await this.delete(`/repos/${owner}/${repo}/releases/${releaseId}`);
536
+ return true;
537
+ }
538
+ async listTags(owner, repo, page = 1, limit = 30) {
539
+ const data = await this.get(`/repos/${owner}/${repo}/tags`, { page, per_page: limit });
540
+ return data.map(tag => this.normalizeTag(tag));
541
+ }
542
+ async getTag(owner, repo, tag) {
543
+ const data = await this.get(`/repos/${owner}/${repo}/git/refs/tags/${tag}`);
544
+ return this.normalizeTag(data);
545
+ }
546
+ async createTag(owner, repo, tagData) {
547
+ // First create the tag object
548
+ const tagObject = await this.post(`/repos/${owner}/${repo}/git/tags`, {
549
+ tag: tagData.tag_name,
550
+ message: tagData.message || `Tag ${tagData.tag_name}`,
551
+ object: tagData.target,
552
+ type: 'commit'
553
+ });
554
+ // Then create the tag reference
555
+ const tagRef = await this.post(`/repos/${owner}/${repo}/git/refs`, {
556
+ ref: `refs/tags/${tagData.tag_name}`,
557
+ sha: tagObject.sha
558
+ });
559
+ return this.normalizeTag({
560
+ name: tagData.tag_name,
561
+ commit: {
562
+ sha: tagObject.sha,
563
+ url: tagObject.url
564
+ },
565
+ zipball_url: `https://api.github.com/repos/${owner}/${repo}/zipball/${tagData.tag_name}`,
566
+ tarball_url: `https://api.github.com/repos/${owner}/${repo}/tarball/${tagData.tag_name}`,
567
+ ...tagObject
568
+ });
569
+ }
570
+ async deleteTag(owner, repo, tag) {
571
+ await this.delete(`/repos/${owner}/${repo}/git/refs/tags/${tag}`);
572
+ return true;
573
+ }
574
+ async getCurrentUser() {
575
+ const data = await this.get('/user');
576
+ return this.normalizeUser(data);
577
+ }
578
+ async getUser(username) {
579
+ const data = await this.get(`/users/${username}`);
580
+ return this.normalizeUser(data);
581
+ }
582
+ async listUsers(page = 1, limit = 30) {
583
+ const data = await this.get('/users', { since: (page - 1) * limit, per_page: limit });
584
+ return data.map(user => this.normalizeUser(user));
585
+ }
586
+ async searchUsers(query, page = 1, limit = 30) {
587
+ const data = await this.get('/search/users', {
588
+ q: query,
589
+ page,
590
+ per_page: limit,
591
+ sort: 'followers',
592
+ order: 'desc'
593
+ });
594
+ return data.items.map((user) => this.normalizeUser(user));
595
+ }
596
+ async getUserOrganizations(username, page = 1, limit = 30) {
597
+ const data = await this.get(`/users/${username}/orgs`, { page, per_page: limit });
598
+ return data.map((org) => this.normalizeOrganization(org));
599
+ }
600
+ async getUserRepositories(username, page = 1, limit = 30) {
601
+ const data = await this.get(`/users/${username}/repos`, {
602
+ page,
603
+ per_page: limit,
604
+ sort: 'updated',
605
+ direction: 'desc'
606
+ });
607
+ return data.map((repo) => this.normalizeRepository(repo));
608
+ }
609
+ async listWebhooks(owner, repo, page = 1, limit = 30) {
610
+ const data = await this.get(`/repos/${owner}/${repo}/hooks`, { page, per_page: limit });
611
+ return data.map(webhook => this.normalizeWebhook(webhook));
612
+ }
613
+ async getWebhook(owner, repo, webhookId) {
614
+ const data = await this.get(`/repos/${owner}/${repo}/hooks/${webhookId}`);
615
+ return this.normalizeWebhook(data);
616
+ }
617
+ async createWebhook(owner, repo, url, events, secret) {
618
+ const data = await this.post(`/repos/${owner}/${repo}/hooks`, {
619
+ name: 'web',
620
+ active: true,
621
+ events,
622
+ config: {
623
+ url,
624
+ content_type: 'json',
625
+ secret
626
+ }
627
+ });
628
+ return this.normalizeWebhook(data);
629
+ }
630
+ async updateWebhook(owner, repo, webhookId, updates) {
631
+ const data = await this.patch(`/repos/${owner}/${repo}/hooks/${webhookId}`, updates);
632
+ return this.normalizeWebhook(data);
633
+ }
634
+ async deleteWebhook(owner, repo, webhookId) {
635
+ await this.delete(`/repos/${owner}/${repo}/hooks/${webhookId}`);
636
+ return true;
637
+ }
638
+ async createCommit(owner, repo, message, branch, changes) {
639
+ // Para criar um commit no GitHub, precisamos:
640
+ // 1. Obter o último commit da branch
641
+ // 2. Criar uma nova árvore com as mudanças
642
+ // 3. Criar o commit
643
+ // 4. Atualizar a referência da branch
644
+ try {
645
+ // Obter informações da branch
646
+ const branchData = await this.getBranch(owner, repo, branch);
647
+ // Para simplificar, vamos usar o endpoint de criação de commit direto
648
+ const commitData = {
649
+ message,
650
+ tree: changes?.tree_sha || branchData.commit.sha,
651
+ parents: [branchData.commit.sha]
652
+ };
653
+ const data = await this.post(`/repos/${owner}/${repo}/git/commits`, commitData);
654
+ // Atualizar a referência da branch
655
+ await this.post(`/repos/${owner}/${repo}/git/refs/heads/${branch}`, {
656
+ sha: data.sha,
657
+ force: false
658
+ });
659
+ return this.normalizeCommit(data);
660
+ }
661
+ catch (error) {
662
+ console.error('Erro ao criar commit:', error);
663
+ throw new Error(`Falha ao criar commit: ${error instanceof Error ? error.message : String(error)}`);
664
+ }
665
+ }
666
+ // Implementações básicas para funcionalidades suportadas pelo GitHub
667
+ async listWorkflows(params) {
668
+ const { owner, repo } = params;
669
+ const data = await this.get(`/repos/${owner}/${repo}/actions/workflows`);
670
+ return data;
671
+ }
672
+ async listWorkflowRuns(params) {
673
+ const { owner, repo } = params;
674
+ const data = await this.get(`/repos/${owner}/${repo}/actions/runs`);
675
+ return data;
676
+ }
677
+ async listDeployments(params) {
678
+ const { owner, repo } = params;
679
+ const data = await this.get(`/repos/${owner}/${repo}/deployments`);
680
+ return data;
681
+ }
682
+ async runSecurityScan(params) {
683
+ const { owner, repo } = params;
684
+ // GitHub Security tab - basic implementation
685
+ const data = await this.get(`/repos/${owner}/${repo}`);
686
+ return {
687
+ security: {
688
+ enabled: data.security_and_analysis?.advanced_security?.status === 'enabled',
689
+ secret_scanning: data.security_and_analysis?.secret_scanning?.status === 'enabled',
690
+ dependabot: data.security_and_analysis?.dependabot_security_updates?.status === 'enabled'
691
+ }
692
+ };
693
+ }
694
+ async getTrafficStats(params) {
695
+ const { owner, repo, metricType } = params;
696
+ let endpoint = '';
697
+ switch (metricType) {
698
+ case 'views':
699
+ endpoint = `/repos/${owner}/${repo}/traffic/views`;
700
+ break;
701
+ case 'clones':
702
+ endpoint = `/repos/${owner}/${repo}/traffic/clones`;
703
+ break;
704
+ case 'popular':
705
+ endpoint = `/repos/${owner}/${repo}/traffic/popular/paths`;
706
+ break;
707
+ case 'referrers':
708
+ endpoint = `/repos/${owner}/${repo}/traffic/popular/referrers`;
709
+ break;
710
+ default:
711
+ endpoint = `/repos/${owner}/${repo}/traffic/views`;
712
+ }
713
+ return await this.get(endpoint);
714
+ error: 'Traffic stats not available',
715
+ message;
716
+ 'Repository traffic statistics require special permissions or may not be available for this repository',
717
+ metricType,
718
+ available;
719
+ false;
720
+ }
721
+ ;
722
+ }
723
+ exports.GitHubProvider = GitHubProvider;
724
+ async;
725
+ cloneRepository(params, any);
726
+ Promise < any > {
727
+ throw: new Error('Funcionalidade não suportada por este provider: Provider não implementa cloneRepository')
728
+ };
729
+ async;
730
+ archiveRepository(params, any);
731
+ Promise < any > {
732
+ throw: new Error('Funcionalidade não suportada por este provider: Provider não implementa archiveRepository')
733
+ };
734
+ async;
735
+ transferRepository(params, any);
736
+ Promise < any > {
737
+ const: { owner, repo, newOwner } = params,
738
+ const: data = await this.post(`/repos/${owner}/${repo}/transfer`, { new_owner: newOwner }),
739
+ return: data.owner.login === newOwner
740
+ };
741
+ async;
742
+ createFromTemplate(params, any);
743
+ Promise < any > {
744
+ const: { templateOwner, templateRepo, name, ...options } = params,
745
+ const: data = await this.post(`/repos/${templateOwner}/${templateRepo}/generate`, {
746
+ name,
747
+ ...options
748
+ }),
749
+ return: this.normalizeRepository(data)
750
+ };
751
+ async;
752
+ mirrorRepository(params, any);
753
+ Promise < any > {
754
+ throw: new Error('Funcionalidade não suportada por este provider: Provider não implementa mirrorRepository')
755
+ };
756
+ // Implementações para analytics e outras funcionalidades
757
+ async;
758
+ analyzeContributors(params, any);
759
+ Promise < any > {
760
+ const: { owner, repo } = params,
761
+ try: {
762
+ const: contributors = await this.get(`/repos/${owner}/${repo}/contributors`),
763
+ return: {
764
+ totalContributors: contributors.length,
765
+ contributors: contributors.map(c => ({
766
+ login: c.login,
767
+ contributions: c.contributions,
768
+ type: c.type
769
+ })),
770
+ period: 'all_time'
771
+ }
772
+ }, catch(error) {
773
+ return {
774
+ error: 'Contributors analysis failed',
775
+ message: 'Could not retrieve contributor information',
776
+ available: false
777
+ };
778
+ }
779
+ };
780
+ async;
781
+ getActivityStats(params, any);
782
+ Promise < any > {
783
+ const: { owner, repo } = params,
784
+ try: {
785
+ const: commits = await this.get(`/repos/${owner}/${repo}/commits?per_page=100`),
786
+ const: issues = await this.get(`/repos/${owner}/${repo}/issues?state=all&per_page=100`),
787
+ return: {
788
+ recentCommits: commits.length,
789
+ totalIssues: issues.length,
790
+ openIssues: issues.filter(i => i.state === 'open').length,
791
+ closedIssues: issues.filter(i => i.state === 'closed').length,
792
+ activity: commits.length > 10 ? 'high' : commits.length > 5 ? 'medium' : 'low'
793
+ }
794
+ }, catch(error) {
795
+ return {
796
+ error: 'Activity stats failed',
797
+ message: 'Could not retrieve activity information',
798
+ available: false
799
+ };
800
+ }
801
+ };
802
+ async;
803
+ getRepositoryInsights(params, any);
804
+ Promise < any > {
805
+ const: { owner, repo } = params,
806
+ try: {
807
+ const: repoData = await this.get(`/repos/${owner}/${repo}`),
808
+ return: {
809
+ insights: {
810
+ stars: repoData.stargazers_count,
811
+ forks: repoData.forks_count,
812
+ watchers: repoData.watchers_count,
813
+ language: repoData.language,
814
+ size: repoData.size,
815
+ created: repoData.created_at,
816
+ updated: repoData.updated_at,
817
+ isArchived: repoData.archived,
818
+ isDisabled: repoData.disabled,
819
+ license: repoData.license?.name,
820
+ topics: repoData.topics || []
821
+ }
822
+ }
823
+ }, catch(error) {
824
+ return {
825
+ error: 'Repository insights failed',
826
+ message: 'Could not retrieve repository insights',
827
+ available: false
828
+ };
829
+ }
830
+ };
831
+ // Implementações para funcionalidades faltantes
832
+ async;
833
+ createDeployment(params, any);
834
+ Promise < any > {
835
+ const: { owner, repo, ref, environment, description, task, auto_merge, required_contexts, payload } = params,
836
+ try: {
837
+ const: deploymentData, any = {
838
+ ref,
839
+ environment: environment || 'production',
840
+ description: description || 'Deployment created via API',
841
+ auto_merge: auto_merge || false,
842
+ required_contexts: required_contexts || []
843
+ },
844
+ if(task) { }, deploymentData, : .task = task,
845
+ if(payload) { }, deploymentData, : .payload = payload,
846
+ const: data = await this.post(`/repos/${owner}/${repo}/deployments`, deploymentData),
847
+ return: {
848
+ id: data.id,
849
+ ref: data.ref,
850
+ environment: data.environment,
851
+ description: data.description,
852
+ created_at: data.created_at,
853
+ statuses_url: data.statuses_url,
854
+ repository_url: data.repository_url,
855
+ url: data.url
856
+ }
857
+ }, catch(error) {
858
+ throw new Error(`Falha ao criar deployment: ${error instanceof Error ? error.message : String(error)}`);
859
+ }
860
+ };
861
+ async;
862
+ updateDeploymentStatus(params, any);
863
+ Promise < any > {
864
+ const: { owner, repo, deployment_id, state, log_url, environment_url, description } = params,
865
+ try: {
866
+ const: statusData, any = {
867
+ state,
868
+ log_url: log_url || '',
869
+ environment_url: environment_url || '',
870
+ description: description || `Status updated to ${state}`
871
+ },
872
+ const: data = await this.post(`/repos/${owner}/${repo}/deployments/${deployment_id}/statuses`, statusData),
873
+ return: {
874
+ id: data.id,
875
+ state: data.state,
876
+ description: data.description,
877
+ environment: data.environment,
878
+ target_url: data.target_url,
879
+ log_url: data.log_url,
880
+ environment_url: data.environment_url,
881
+ created_at: data.created_at,
882
+ updated_at: data.updated_at,
883
+ deployment_url: data.deployment_url,
884
+ repository_url: data.repository_url
885
+ }
886
+ }, catch(error) {
887
+ throw new Error(`Falha ao atualizar status do deployment: ${error instanceof Error ? error.message : String(error)}`);
888
+ }
889
+ };
890
+ async;
891
+ manageSecurityAlerts(params, any);
892
+ Promise < any > {
893
+ const: { owner, repo, action, alert_number, dismiss_reason, dismiss_comment } = params,
894
+ try: {
895
+ if(action) { }
896
+ } === 'dismiss'
897
+ };
898
+ {
899
+ const dismissData = {
900
+ dismissed_reason: dismiss_reason || 'tolerable_risk'
901
+ };
902
+ if (dismiss_comment)
903
+ dismissData.dismissed_comment = dismiss_comment;
904
+ const data = await this.patch(`/repos/${owner}/${repo}/dependabot/alerts/${alert_number}`, dismissData);
905
+ return {
906
+ number: data.number,
907
+ state: data.state,
908
+ dismissed_reason: data.dismissed_reason,
909
+ dismissed_comment: data.dismissed_comment,
910
+ dismissed_at: data.dismissed_at,
911
+ dismissed_by: data.dismissed_by
912
+ };
913
+ }
914
+ if (action === 'reopen') {
915
+ const data = await this.patch(`/repos/${owner}/${repo}/dependabot/alerts/${alert_number}`, {
916
+ state: 'open'
917
+ });
918
+ return {
919
+ number: data.number,
920
+ state: data.state,
921
+ created_at: data.created_at,
922
+ updated_at: data.updated_at
923
+ };
924
+ }
925
+ else {
926
+ throw new Error(`Ação não suportada: ${action}`);
927
+ }
928
+ try { }
929
+ catch (error) {
930
+ throw new Error(`Falha ao gerenciar alertas de segurança: ${error instanceof Error ? error.message : String(error)}`);
931
+ }
932
+ async;
933
+ listSecurityVulnerabilities(params, any);
934
+ Promise < any > {
935
+ const: { owner, repo, state, severity, ecosystem, package_name } = params,
936
+ try: {
937
+ const: queryParams, any = {},
938
+ if(state) { }, queryParams, : .state = state,
939
+ if(severity) { }, queryParams, : .severity = severity,
940
+ if(ecosystem) { }, queryParams, : .ecosystem = ecosystem,
941
+ if(package_name) { }, queryParams, : .package = package_name,
942
+ const: data = await this.get(`/repos/${owner}/${repo}/dependabot/alerts`, queryParams),
943
+ return: {
944
+ total_count: data.length,
945
+ vulnerabilities: data.map(alert => ({
946
+ number: alert.number,
947
+ state: alert.state,
948
+ severity: alert.security_advisory?.severity,
949
+ summary: alert.security_advisory?.summary,
950
+ description: alert.security_advisory?.description,
951
+ created_at: alert.created_at,
952
+ updated_at: alert.updated_at,
953
+ dismissed_at: alert.dismissed_at,
954
+ dismissed_reason: alert.dismissed_reason,
955
+ dismissed_comment: alert.dismissed_comment,
956
+ dismissed_by: alert.dismissed_by,
957
+ dependency: {
958
+ package: alert.dependency?.package?.name,
959
+ ecosystem: alert.dependency?.package?.ecosystem,
960
+ manifest_path: alert.dependency?.manifest_path
961
+ }
962
+ }))
963
+ }
964
+ }, catch(error) {
965
+ return {
966
+ total_count: 0,
967
+ vulnerabilities: [],
968
+ note: 'Vulnerabilidades não disponíveis neste provider'
969
+ };
970
+ }
971
+ };
972
+ async;
973
+ createWorkflow(params, any);
974
+ Promise < any > {
975
+ const: { owner, repo, name, description, workflow_content } = params,
976
+ try: {
977
+ // Criar o arquivo de workflow
978
+ const: workflowPath = `.github/workflows/${name.toLowerCase().replace(/\s+/g, '-')}.yml`,
979
+ const: data = await this.createFile(owner, repo, workflowPath, workflow_content, `Add ${name} workflow`),
980
+ return: {
981
+ id: `workflow-${Date.now()}`,
982
+ name,
983
+ path: workflowPath,
984
+ state: 'active',
985
+ created_at: new Date().toISOString(),
986
+ updated_at: new Date().toISOString(),
987
+ url: data.html_url,
988
+ html_url: data.html_url
989
+ }
990
+ }, catch(error) {
991
+ throw new Error(`Falha ao criar workflow: ${error instanceof Error ? error.message : String(error)}`);
992
+ }
993
+ };
994
+ async;
995
+ triggerWorkflow(params, any);
996
+ Promise < any > {
997
+ const: { owner, repo, workflow_id, ref, inputs } = params,
998
+ try: {
999
+ const: triggerData, any = {
1000
+ ref: ref || 'main'
1001
+ },
1002
+ if(inputs) { }, triggerData, : .inputs = inputs,
1003
+ const: data = await this.post(`/repos/${owner}/${repo}/actions/workflows/${workflow_id}/dispatches`, triggerData),
1004
+ return: {
1005
+ success: true,
1006
+ message: 'Workflow triggered successfully',
1007
+ workflow_id,
1008
+ ref,
1009
+ inputs
1010
+ }
1011
+ }, catch(error) {
1012
+ throw new Error(`Falha ao disparar workflow: ${error instanceof Error ? error.message : String(error)}`);
1013
+ }
1014
+ };
1015
+ async;
1016
+ getWorkflowStatus(params, any);
1017
+ Promise < any > {
1018
+ const: { owner, repo, run_id } = params,
1019
+ try: {
1020
+ const: data = await this.get(`/repos/${owner}/${repo}/actions/runs/${run_id}`),
1021
+ return: {
1022
+ id: data.id,
1023
+ name: data.name,
1024
+ status: data.status,
1025
+ conclusion: data.conclusion,
1026
+ workflow_id: data.workflow_id,
1027
+ head_branch: data.head_branch,
1028
+ head_sha: data.head_sha,
1029
+ run_number: data.run_number,
1030
+ event: data.event,
1031
+ created_at: data.created_at,
1032
+ updated_at: data.updated_at,
1033
+ run_started_at: data.run_started_at,
1034
+ jobs_url: data.jobs_url,
1035
+ logs_url: data.logs_url,
1036
+ check_suite_url: data.check_suite_url,
1037
+ artifacts_url: data.artifacts_url,
1038
+ cancel_url: data.cancel_url,
1039
+ rerun_url: data.rerun_url,
1040
+ workflow_url: data.workflow_url,
1041
+ head_commit: data.head_commit,
1042
+ repository: data.repository,
1043
+ head_repository: data.head_repository
1044
+ }
1045
+ }, catch(error) {
1046
+ throw new Error(`Falha ao obter status do workflow: ${error instanceof Error ? error.message : String(error)}`);
1047
+ }
1048
+ };
1049
+ async;
1050
+ getWorkflowLogs(params, any);
1051
+ Promise < any > {
1052
+ const: { owner, repo, run_id, job_id, step_number } = params,
1053
+ try: {
1054
+ let, endpoint = `/repos/${owner}/${repo}/actions/runs/${run_id}/logs`,
1055
+ if(job_id) {
1056
+ endpoint = `/repos/${owner}/${repo}/actions/jobs/${job_id}/logs`;
1057
+ if (step_number) {
1058
+ endpoint += `?step=${step_number}`;
1059
+ }
1060
+ },
1061
+ const: data = await this.get(endpoint),
1062
+ return: {
1063
+ logs: data,
1064
+ run_id,
1065
+ job_id,
1066
+ step_number,
1067
+ downloaded_at: new Date().toISOString()
1068
+ }
1069
+ }, catch(error) {
1070
+ throw new Error(`Falha ao obter logs do workflow: ${error instanceof Error ? error.message : String(error)}`);
1071
+ }
1072
+ };
1073
+ async;
1074
+ listWorkflowArtifacts(params, any);
1075
+ Promise < any > {
1076
+ const: { owner, repo, run_id } = params,
1077
+ try: {
1078
+ const: data = await this.get(`/repos/${owner}/${repo}/actions/runs/${run_id}/artifacts`),
1079
+ return: {
1080
+ total_count: data.total_count,
1081
+ artifacts: data.artifacts.map((artifact) => ({
1082
+ id: artifact.id,
1083
+ node_id: artifact.node_id,
1084
+ name: artifact.name,
1085
+ size_in_bytes: artifact.size_in_bytes,
1086
+ url: artifact.url,
1087
+ archive_download_url: artifact.archive_download_url,
1088
+ expired: artifact.expired,
1089
+ created_at: artifact.created_at,
1090
+ updated_at: artifact.updated_at,
1091
+ expires_at: artifact.expires_at
1092
+ }))
1093
+ }
1094
+ }, catch(error) {
1095
+ return {
1096
+ total_count: 0,
1097
+ artifacts: [],
1098
+ note: 'Artefatos não disponíveis'
1099
+ };
1100
+ }
1101
+ };
1102
+ async;
1103
+ downloadArtifact(params, any);
1104
+ Promise < any > {
1105
+ const: { owner, repo, artifact_id, download_path } = params,
1106
+ try: {
1107
+ const: data = await this.get(`/repos/${owner}/${repo}/actions/artifacts/${artifact_id}/zip`),
1108
+ return: {
1109
+ success: true,
1110
+ artifact_id,
1111
+ download_path,
1112
+ downloaded_at: new Date().toISOString(),
1113
+ message: 'Artefato baixado com sucesso'
1114
+ }
1115
+ }, catch(error) {
1116
+ throw new Error(`Falha ao baixar artefato: ${error instanceof Error ? error.message : String(error)}`);
1117
+ }
1118
+ };
1119
+ async;
1120
+ listSecrets(params, any);
1121
+ Promise < any > {
1122
+ const: { owner, repo } = params,
1123
+ try: {
1124
+ const: data = await this.get(`/repos/${owner}/${repo}/actions/secrets`),
1125
+ return: {
1126
+ total_count: data.total_count,
1127
+ secrets: data.secrets.map((secret) => ({
1128
+ name: secret.name,
1129
+ created_at: secret.created_at,
1130
+ updated_at: secret.updated_at
1131
+ }))
1132
+ }
1133
+ }, catch(error) {
1134
+ return {
1135
+ total_count: 0,
1136
+ secrets: [],
1137
+ note: 'Secrets não disponíveis'
1138
+ };
1139
+ }
1140
+ };
1141
+ async;
1142
+ listJobs(params, any);
1143
+ Promise < any > {
1144
+ const: { owner, repo, run_id } = params,
1145
+ try: {
1146
+ const: data = await this.get(`/repos/${owner}/${repo}/actions/runs/${run_id}/jobs`),
1147
+ return: {
1148
+ total_count: data.total_count,
1149
+ jobs: data.jobs.map((job) => ({
1150
+ id: job.id,
1151
+ run_id: job.run_id,
1152
+ run_url: job.run_url,
1153
+ node_id: job.node_id,
1154
+ head_sha: job.head_sha,
1155
+ url: job.url,
1156
+ html_url: job.html_url,
1157
+ status: job.status,
1158
+ conclusion: job.conclusion,
1159
+ started_at: job.started_at,
1160
+ completed_at: job.completed_at,
1161
+ name: job.name,
1162
+ steps: job.steps,
1163
+ check_run_url: job.check_run_url,
1164
+ labels: job.labels,
1165
+ runner_id: job.runner_id,
1166
+ runner_name: job.runner_name,
1167
+ runner_group_id: job.runner_group_id,
1168
+ runner_group_name: job.runner_group_name
1169
+ }))
1170
+ }
1171
+ }, catch(error) {
1172
+ return {
1173
+ total_count: 0,
1174
+ jobs: [],
1175
+ note: 'Jobs não disponíveis'
1176
+ };
1177
+ }
1178
+ };
1179
+ //# sourceMappingURL=github-provider-backup.js.map