cli / mcp for bitbucket
at main 169 lines 6.0 kB view raw
1import { 2 getRepositoriesByWorkspaceByRepoSlugPullrequests, 3 getRepositoriesByWorkspaceByRepoSlugPullrequestsByPullRequestId, 4 getRepositoriesByWorkspaceByRepoSlugPullrequestsByPullRequestIdComments, 5 getRepositoriesByWorkspaceByRepoSlugPullrequestsByPullRequestIdDiff, 6 postRepositoriesByWorkspaceByRepoSlugPullrequests, 7 postRepositoriesByWorkspaceByRepoSlugPullrequestsByPullRequestIdComments, 8 postRepositoriesByWorkspaceByRepoSlugPullrequestsByPullRequestIdDecline, 9 putRepositoriesByWorkspaceByRepoSlugPullrequestsByPullRequestId, 10} from '../generated/bitbucket-client/sdk.gen'; 11import type { Pullrequest, PullrequestComment } from '../generated/bitbucket-client/types.gen'; 12import type { PaginationParams } from '../types/pagination.types'; 13import { apiError, fail, ok, type Result } from '../types/result.types'; 14 15export type RepositoryParams = { 16 workspace: string; 17 repoSlug: string; 18}; 19 20export type PullRequestParams = RepositoryParams & { 21 prId: number; 22}; 23 24export type ListPullRequestsParams = RepositoryParams & 25 PaginationParams & { 26 state?: 'OPEN' | 'MERGED' | 'DECLINED' | 'SUPERSEDED'; 27 }; 28 29export type CreatePullRequestParams = RepositoryParams & { 30 sourceBranch: string; 31 destinationBranch: string; 32 title: string; 33 description?: string; 34}; 35 36export type UpdatePullRequestParams = PullRequestParams & { 37 updates: Partial<Pick<Pullrequest, 'title' | 'description' | 'destination'>>; 38}; 39 40export type AddCommentParams = PullRequestParams & { 41 content: string; 42}; 43 44export const listPullRequests = async ( 45 params: ListPullRequestsParams 46): Promise<Result<Pullrequest[]>> => { 47 const { workspace, repoSlug, state = 'OPEN' } = params; 48 const response = await getRepositoriesByWorkspaceByRepoSlugPullrequests({ 49 path: { workspace, repo_slug: repoSlug }, 50 query: { state }, 51 }); 52 53 if (response.error) { 54 return fail(apiError(response.response.status, `Failed to list PRs`, response.error)); 55 } 56 57 return ok(response.data?.values ?? []); 58}; 59 60export const getPullRequest = async (params: PullRequestParams): Promise<Result<Pullrequest>> => { 61 const { workspace, repoSlug, prId } = params; 62 const response = await getRepositoriesByWorkspaceByRepoSlugPullrequestsByPullRequestId({ 63 path: { workspace, repo_slug: repoSlug, pull_request_id: prId }, 64 }); 65 66 if (response.error) { 67 return fail(apiError(response.response.status, `PR #${prId} not found`, response.error)); 68 } 69 70 return response.data ? ok(response.data) : fail(apiError(404, `PR #${prId} not found`)); 71}; 72 73export const createPullRequest = async ( 74 params: CreatePullRequestParams 75): Promise<Result<Pullrequest>> => { 76 const { workspace, repoSlug, sourceBranch, destinationBranch, title, description } = params; 77 const response = await postRepositoriesByWorkspaceByRepoSlugPullrequests({ 78 path: { workspace, repo_slug: repoSlug }, 79 body: { 80 type: 'pullrequest', 81 title, 82 description: description ?? '', 83 source: { branch: { name: sourceBranch } }, 84 destination: { branch: { name: destinationBranch } }, 85 }, 86 }); 87 88 if (response.error) { 89 return fail(apiError(response.response.status, `Failed to create PR`, response.error)); 90 } 91 92 return response.data 93 ? ok(response.data) 94 : fail(apiError(500, 'No data returned from PR creation')); 95}; 96 97export const updatePullRequest = async ( 98 params: UpdatePullRequestParams 99): Promise<Result<Pullrequest>> => { 100 const { workspace, repoSlug, prId, updates } = params; 101 const response = await putRepositoriesByWorkspaceByRepoSlugPullrequestsByPullRequestId({ 102 path: { workspace, repo_slug: repoSlug, pull_request_id: prId }, 103 body: { type: 'pullrequest', ...updates }, 104 }); 105 106 if (response.error) { 107 return fail(apiError(response.response.status, `Failed to update PR #${prId}`, response.error)); 108 } 109 110 return response.data ? ok(response.data) : fail(apiError(500, 'No data returned from PR update')); 111}; 112 113export const addComment = async (params: AddCommentParams): Promise<Result<void>> => { 114 const { workspace, repoSlug, prId, content } = params; 115 const response = await postRepositoriesByWorkspaceByRepoSlugPullrequestsByPullRequestIdComments({ 116 path: { workspace, repo_slug: repoSlug, pull_request_id: prId }, 117 body: { type: 'pullrequest_comment', content: { raw: content } }, 118 }); 119 120 if (response.error) { 121 return fail(apiError(response.response.status, `Failed to add comment`, response.error)); 122 } 123 124 return ok(undefined); 125}; 126 127export const getPullRequestComments = async ( 128 params: PullRequestParams & PaginationParams 129): Promise<Result<PullrequestComment[]>> => { 130 const { workspace, repoSlug, prId } = params; 131 const response = await getRepositoriesByWorkspaceByRepoSlugPullrequestsByPullRequestIdComments({ 132 path: { workspace, repo_slug: repoSlug, pull_request_id: prId }, 133 }); 134 135 if (response.error) { 136 return fail(apiError(response.response.status, `Failed to get PR comments`, response.error)); 137 } 138 139 return ok(response.data?.values ?? []); 140}; 141 142export const declinePullRequest = async (params: PullRequestParams): Promise<Result<void>> => { 143 const { workspace, repoSlug, prId } = params; 144 const response = await postRepositoriesByWorkspaceByRepoSlugPullrequestsByPullRequestIdDecline({ 145 path: { workspace, repo_slug: repoSlug, pull_request_id: prId }, 146 }); 147 148 if (response.error) { 149 return fail( 150 apiError(response.response.status, `Failed to decline PR #${prId}`, response.error) 151 ); 152 } 153 154 return ok(undefined); 155}; 156 157export const getPullRequestDiff = async (params: PullRequestParams): Promise<Result<string>> => { 158 const { workspace, repoSlug, prId } = params; 159 const response = await getRepositoriesByWorkspaceByRepoSlugPullrequestsByPullRequestIdDiff({ 160 path: { workspace, repo_slug: repoSlug, pull_request_id: prId }, 161 parseAs: 'text', 162 }); 163 164 if (response.error) { 165 return fail(apiError(response.response.status, `Failed to get PR diff`, response.error)); 166 } 167 168 return ok((response.data as unknown as string) ?? ''); 169};