Files
bitbucket-mcp/src/bitbucket-client.ts

119 lines
8.2 KiB
TypeScript

import { ClientOptions } from './clients/base-client.js';
import { PullRequestClient, CreatePROptions, UpdatePROptions, MergePROptions } from './clients/pull-request-client.js';
import { RepositoryClient } from './clients/repository-client.js';
import { CommentClient, AddCommentOptions, CreateTaskOptions, UpdateTaskOptions } from './clients/comment-client.js';
export type { CreatePROptions, UpdatePROptions, MergePROptions };
export type { AddCommentOptions, CreateTaskOptions, UpdateTaskOptions };
export type { ClientOptions as BitbucketClientOptions };
export class BitbucketClient {
private pr!: PullRequestClient;
private repo!: RepositoryClient;
private comment!: CommentClient;
// ── Pull Request read ─────────────────────────────────────────────────────
listPullRequests!: (workspace: string, repo: string, options?: any) => Promise<any>;
getPullRequest!: (workspace: string, repo: string, prId: number) => Promise<any>;
getPullRequestActivities!: (workspace: string, repo: string, prId: number, options?: any) => Promise<any>;
getPullRequestChanges!: (workspace: string, repo: string, prId: number, options?: any) => Promise<any>;
getPullRequestCommits!: (workspace: string, repo: string, prId: number, options?: any) => Promise<any>;
getPullRequestDiff!: (workspace: string, repo: string, prId: number, options?: any) => Promise<any>;
getPullRequestPatch!: (workspace: string, repo: string, prId: number) => Promise<any>;
getPullRequestParticipants!: (workspace: string, repo: string, prId: number) => Promise<any>;
getPullRequestReviewers!: (workspace: string, repo: string, prId: number) => Promise<any>;
getPullRequestStatus!: (workspace: string, repo: string, prId: number) => Promise<any>;
getPullRequestTasks!: (workspace: string, repo: string, prId: number) => Promise<any>;
getPullRequestTaskCount!: (workspace: string, repo: string, prId: number) => Promise<any>;
getFullPullRequest!: (workspace: string, repo: string, prId: number) => Promise<any>;
// ── Pull Request write ────────────────────────────────────────────────────
createPullRequest!: (workspace: string, repo: string, options: CreatePROptions) => Promise<any>;
updatePullRequest!: (workspace: string, repo: string, prId: number, options: UpdatePROptions) => Promise<any>;
mergePullRequest!: (workspace: string, repo: string, prId: number, options: MergePROptions) => Promise<any>;
declinePullRequest!: (workspace: string, repo: string, prId: number) => Promise<any>;
approvePullRequest!: (workspace: string, repo: string, prId: number) => Promise<any>;
unapprovePullRequest!: (workspace: string, repo: string, prId: number) => Promise<any>;
requestChangesPullRequest!: (workspace: string, repo: string, prId: number) => Promise<any>;
removeRequestChangesPullRequest!: (workspace: string, repo: string, prId: number) => Promise<any>;
// ── Repository / workspace ────────────────────────────────────────────────
listWorkspaces!: (options?: any) => Promise<any>;
listRepositories!: (workspace: string, options?: any) => Promise<any>;
getRepository!: (workspace: string, repo: string) => Promise<any>;
listBranches!: (workspace: string, repo: string, options?: any) => Promise<any>;
// ── Comment read ──────────────────────────────────────────────────────────
getPullRequestComments!: (workspace: string, repo: string, prId: number, options?: any) => Promise<any>;
getPullRequestComment!: (workspace: string, repo: string, prId: number, commentId: number) => Promise<any>;
// ── Comment / task write ──────────────────────────────────────────────────
addPullRequestComment!: (workspace: string, repo: string, prId: number, options: AddCommentOptions) => Promise<any>;
updatePullRequestComment!: (workspace: string, repo: string, prId: number, commentId: number, options: AddCommentOptions) => Promise<any>;
deletePullRequestComment!: (workspace: string, repo: string, prId: number, commentId: number) => Promise<any>;
createPullRequestTask!: (workspace: string, repo: string, prId: number, options: CreateTaskOptions) => Promise<any>;
updatePullRequestTask!: (workspace: string, repo: string, prId: number, taskId: number, options: UpdateTaskOptions) => Promise<any>;
deletePullRequestTask!: (workspace: string, repo: string, prId: number, taskId: number) => Promise<any>;
constructor(options: ClientOptions = {}) {
this.pr = new PullRequestClient(options);
this.repo = new RepositoryClient(options);
this.comment = new CommentClient(options);
// Bind all PR methods
this.listPullRequests = this.pr.listPullRequests.bind(this.pr);
this.getPullRequest = this.pr.getPullRequest.bind(this.pr);
this.getPullRequestActivities = this.pr.getPullRequestActivities.bind(this.pr);
this.getPullRequestChanges = this.pr.getPullRequestChanges.bind(this.pr);
this.getPullRequestCommits = this.pr.getPullRequestCommits.bind(this.pr);
this.getPullRequestDiff = this.pr.getPullRequestDiff.bind(this.pr);
this.getPullRequestPatch = this.pr.getPullRequestPatch.bind(this.pr);
this.getPullRequestParticipants = this.pr.getPullRequestParticipants.bind(this.pr);
this.getPullRequestReviewers = this.pr.getPullRequestReviewers.bind(this.pr);
this.getPullRequestStatus = this.pr.getPullRequestStatus.bind(this.pr);
this.getPullRequestTasks = this.pr.getPullRequestTasks.bind(this.pr);
this.getPullRequestTaskCount = this.pr.getPullRequestTaskCount.bind(this.pr);
this.getFullPullRequest = this.pr.getFullPullRequest.bind(this.pr);
this.createPullRequest = this.pr.createPullRequest.bind(this.pr);
this.updatePullRequest = this.pr.updatePullRequest.bind(this.pr);
this.mergePullRequest = this.pr.mergePullRequest.bind(this.pr);
this.declinePullRequest = this.pr.declinePullRequest.bind(this.pr);
this.approvePullRequest = this.pr.approvePullRequest.bind(this.pr);
this.unapprovePullRequest = this.pr.unapprovePullRequest.bind(this.pr);
this.requestChangesPullRequest = this.pr.requestChangesPullRequest.bind(this.pr);
this.removeRequestChangesPullRequest = this.pr.removeRequestChangesPullRequest.bind(this.pr);
// Bind all repo methods
this.listWorkspaces = this.repo.listWorkspaces.bind(this.repo);
this.listRepositories = this.repo.listRepositories.bind(this.repo);
this.getRepository = this.repo.getRepository.bind(this.repo);
this.listBranches = this.repo.listBranches.bind(this.repo);
// Bind all comment methods
this.getPullRequestComments = this.comment.getPullRequestComments.bind(this.comment);
this.getPullRequestComment = this.comment.getPullRequestComment.bind(this.comment);
this.addPullRequestComment = this.comment.addPullRequestComment.bind(this.comment);
this.updatePullRequestComment = this.comment.updatePullRequestComment.bind(this.comment);
this.deletePullRequestComment = this.comment.deletePullRequestComment.bind(this.comment);
this.createPullRequestTask = this.comment.createPullRequestTask.bind(this.comment);
this.updatePullRequestTask = this.comment.updatePullRequestTask.bind(this.comment);
this.deletePullRequestTask = this.comment.deletePullRequestTask.bind(this.comment);
}
async validateToken(): Promise<{ valid: boolean; message: string }> {
try {
await this.repo.listWorkspaces({ pagelen: 1 });
return { valid: true, message: 'Token is valid' };
} catch (error: any) {
const status = error?.response?.status ?? error?.cause?.response?.status;
if (status === 401) return { valid: false, message: 'Token is invalid or expired' };
if (status === 403) return { valid: false, message: 'Token lacks required permissions' };
return { valid: false, message: `Token validation failed: ${error?.message || error}` };
}
}
}
export default BitbucketClient;