@gitkraken/core-gitlens 0.7.1 → 0.8.0
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/CHANGELOG.md +48 -1
- package/dist/git/cache.d.ts +18 -5
- package/dist/git/cache.js +26 -8
- package/dist/git/cache.js.map +1 -1
- package/dist/git/context.d.ts +5 -1
- package/dist/git/context.js.map +1 -1
- package/dist/git/errors.d.ts +28 -1
- package/dist/git/errors.js +45 -1
- package/dist/git/errors.js.map +1 -1
- package/dist/git/providers/branches.d.ts +5 -1
- package/dist/git/providers/commits.d.ts +24 -1
- package/dist/git/providers/config.d.ts +7 -1
- package/dist/git/providers/operations.d.ts +6 -0
- package/dist/git/providers/provider.d.ts +17 -0
- package/dist/git/providers/refs.d.ts +38 -3
- package/dist/git/providers/revision.d.ts +5 -1
- package/dist/git/providers/staging.d.ts +12 -0
- package/dist/git/providers/worktrees.d.ts +23 -3
- package/dist/git/run.types.d.ts +6 -0
- package/dist/git-cli/cliGitProvider.d.ts +17 -1
- package/dist/git-cli/cliGitProvider.js +37 -1
- package/dist/git-cli/cliGitProvider.js.map +1 -1
- package/dist/git-cli/exec/git.d.ts +12 -2
- package/dist/git-cli/exec/git.js +48 -17
- package/dist/git-cli/exec/git.js.map +1 -1
- package/dist/git-cli/exec/gitQueue.d.ts +4 -1
- package/dist/git-cli/exec/gitQueue.js +1 -1
- package/dist/git-cli/exec/gitQueue.js.map +1 -1
- package/dist/git-cli/providers/branches.d.ts +10 -1
- package/dist/git-cli/providers/branches.js +15 -8
- package/dist/git-cli/providers/branches.js.map +1 -1
- package/dist/git-cli/providers/commits.d.ts +23 -1
- package/dist/git-cli/providers/commits.js +57 -8
- package/dist/git-cli/providers/commits.js.map +1 -1
- package/dist/git-cli/providers/config.js +4 -3
- package/dist/git-cli/providers/config.js.map +1 -1
- package/dist/git-cli/providers/operations.d.ts +1 -0
- package/dist/git-cli/providers/operations.js +39 -3
- package/dist/git-cli/providers/operations.js.map +1 -1
- package/dist/git-cli/providers/patch.js +20 -41
- package/dist/git-cli/providers/patch.js.map +1 -1
- package/dist/git-cli/providers/pausedOperations.js +2 -2
- package/dist/git-cli/providers/pausedOperations.js.map +1 -1
- package/dist/git-cli/providers/refs.d.ts +15 -3
- package/dist/git-cli/providers/refs.js +115 -10
- package/dist/git-cli/providers/refs.js.map +1 -1
- package/dist/git-cli/providers/revision.d.ts +3 -1
- package/dist/git-cli/providers/revision.js +9 -5
- package/dist/git-cli/providers/revision.js.map +1 -1
- package/dist/git-cli/providers/staging.d.ts +8 -0
- package/dist/git-cli/providers/staging.js +59 -7
- package/dist/git-cli/providers/staging.js.map +1 -1
- package/dist/git-cli/providers/worktrees.d.ts +31 -2
- package/dist/git-cli/providers/worktrees.js +75 -7
- package/dist/git-cli/providers/worktrees.js.map +1 -1
- package/dist/ipc/discovery.js +1 -1
- package/dist/plus/agents/providers/claudeCodeTranscript.js +6 -6
- package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -1
- package/dist/plus/ai/providers/openAICompatibleProviderBase.js +1 -1
- package/dist/plus/git-github/api/github.d.ts +64 -3
- package/dist/plus/git-github/api/github.js +237 -24
- package/dist/plus/git-github/api/github.js.map +1 -1
- package/dist/plus/git-github/providers/github/branches.d.ts +3 -1
- package/dist/plus/git-github/providers/github/branches.js +2 -1
- package/dist/plus/git-github/providers/github/branches.js.map +1 -1
- package/dist/plus/git-github/providers/github/refs.d.ts +10 -3
- package/dist/plus/git-github/providers/github/refs.js +4 -4
- package/dist/plus/git-github/providers/github/refs.js.map +1 -1
- package/dist/plus/git-github/providers/github/revision.d.ts +3 -1
- package/dist/plus/git-github/providers/github/revision.js +1 -1
- package/dist/plus/git-github/providers/github/revision.js.map +1 -1
- package/dist/plus/integrations/collectionMetadata.d.ts +48 -3
- package/dist/plus/integrations/collectionMetadata.js +138 -8
- package/dist/plus/integrations/collectionMetadata.js.map +1 -1
- package/dist/plus/integrations/errors.d.ts +3 -1
- package/dist/plus/integrations/errors.js +7 -3
- package/dist/plus/integrations/errors.js.map +1 -1
- package/dist/plus/integrations/index.d.ts +6 -3
- package/dist/plus/integrations/index.js.map +1 -1
- package/dist/plus/integrations/integrationService.d.ts +36 -10
- package/dist/plus/integrations/integrationService.js +16 -3
- package/dist/plus/integrations/integrationService.js.map +1 -1
- package/dist/plus/integrations/manager.d.ts +107 -37
- package/dist/plus/integrations/models/gitHostIntegration.d.ts +129 -14
- package/dist/plus/integrations/models/gitHostIntegration.js +142 -18
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
- package/dist/plus/integrations/models/integration.d.ts +117 -11
- package/dist/plus/integrations/models/integration.js +175 -13
- package/dist/plus/integrations/models/integration.js.map +1 -1
- package/dist/plus/integrations/models/issuesIntegration.d.ts +18 -5
- package/dist/plus/integrations/models/issuesIntegration.js +42 -10
- package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
- package/dist/plus/integrations/providers/azure/azure.d.ts +1 -1
- package/dist/plus/integrations/providers/azure/azure.js +14 -18
- package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
- package/dist/plus/integrations/providers/azure/models.d.ts +29 -0
- package/dist/plus/integrations/providers/azure/models.js +112 -1
- package/dist/plus/integrations/providers/azure/models.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOps.d.ts +73 -3
- package/dist/plus/integrations/providers/azureDevOps.js +117 -3
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOpsServer.js +2 -1
- package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts +61 -0
- package/dist/plus/integrations/providers/bitbucket/bitbucket.js +165 -23
- package/dist/plus/integrations/providers/bitbucket/bitbucket.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket/models.d.ts +6 -1
- package/dist/plus/integrations/providers/bitbucket/models.js +4 -3
- package/dist/plus/integrations/providers/bitbucket/models.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js +2 -2
- package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server.d.ts +48 -2
- package/dist/plus/integrations/providers/bitbucket-server.js +51 -1
- package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket.d.ts +45 -2
- package/dist/plus/integrations/providers/bitbucket.js +41 -2
- package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
- package/dist/plus/integrations/providers/github.d.ts +49 -5
- package/dist/plus/integrations/providers/github.js +102 -7
- package/dist/plus/integrations/providers/github.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab/gitlab.d.ts +35 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.js +132 -15
- package/dist/plus/integrations/providers/gitlab/gitlab.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab/models.d.ts +1 -0
- package/dist/plus/integrations/providers/gitlab/models.js +1 -1
- package/dist/plus/integrations/providers/gitlab/models.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab.d.ts +49 -2
- package/dist/plus/integrations/providers/gitlab.js +80 -4
- package/dist/plus/integrations/providers/gitlab.js.map +1 -1
- package/dist/plus/integrations/providers/jira-server.d.ts +3 -3
- package/dist/plus/integrations/providers/jira-server.js +5 -8
- package/dist/plus/integrations/providers/jira-server.js.map +1 -1
- package/dist/plus/integrations/providers/jira.d.ts +9 -0
- package/dist/plus/integrations/providers/jira.js +13 -1
- package/dist/plus/integrations/providers/jira.js.map +1 -1
- package/dist/plus/integrations/providers/linear.js +1 -1
- package/dist/plus/integrations/providers/models.d.ts +13 -2
- package/dist/plus/integrations/providers/models.js +11 -1
- package/dist/plus/integrations/providers/models.js.map +1 -1
- package/dist/plus/integrations/providers/providerErrors.d.ts +9 -1
- package/dist/plus/integrations/providers/providerErrors.js +10 -1
- package/dist/plus/integrations/providers/providerErrors.js.map +1 -1
- package/dist/plus/integrations/providers/providersApi.d.ts +60 -1
- package/dist/plus/integrations/providers/providersApi.js +137 -2
- package/dist/plus/integrations/providers/providersApi.js.map +1 -1
- package/dist/plus/integrations/providers/utils/providerPaging.d.ts +42 -0
- package/dist/plus/integrations/providers/utils/providerPaging.js +58 -1
- package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
- package/dist/plus/integrations/providers/utils.d.ts +1 -1
- package/dist/plus/integrations/reads/broaden.js +1 -1
- package/dist/plus/integrations/reads/context.d.ts +1 -1
- package/dist/plus/integrations/reads/counts.js +1 -1
- package/dist/plus/integrations/reads/currentAccount.d.ts +35 -0
- package/dist/plus/integrations/reads/currentAccount.js +46 -0
- package/dist/plus/integrations/reads/currentAccount.js.map +1 -0
- package/dist/plus/integrations/reads/drains.d.ts +5 -2
- package/dist/plus/integrations/reads/drains.js +8 -4
- package/dist/plus/integrations/reads/drains.js.map +1 -1
- package/dist/plus/integrations/reads/hierarchy.js +1 -1
- package/dist/plus/integrations/reads/hierarchy.utils.js +1 -1
- package/dist/plus/integrations/reads/issueBatch.d.ts +72 -12
- package/dist/plus/integrations/reads/issueBatch.js +193 -48
- package/dist/plus/integrations/reads/issueBatch.js.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.js +1 -1
- package/dist/plus/integrations/reads/issues.js +1 -1
- package/dist/plus/integrations/reads/pullRequestBatch.d.ts +57 -0
- package/dist/plus/integrations/reads/pullRequestBatch.js +80 -0
- package/dist/plus/integrations/reads/pullRequestBatch.js.map +1 -0
- package/dist/plus/integrations/reads/pullRequestBranches.d.ts +58 -0
- package/dist/plus/integrations/reads/pullRequestBranches.js +111 -0
- package/dist/plus/integrations/reads/pullRequestBranches.js.map +1 -0
- package/dist/plus/integrations/reads/pullRequests.js +3 -3
- package/dist/plus/integrations/reads/pullRequests.js.map +1 -1
- package/dist/plus/integrations/reads/resolveRepository.js +1 -1
- package/dist/plus/integrations/reads/sweeps.js +4 -4
- package/dist/plus/integrations/reads/sweeps.js.map +1 -1
- package/dist/plus/integrations/results.d.ts +87 -6
- package/dist/plus/integrations/results.js +9 -2
- package/dist/plus/integrations/results.js.map +1 -1
- package/dist/utils/env/node/exec.js +3 -3
- package/dist/utils/env/node/exec.js.map +1 -1
- package/docs/integrations.md +175 -35
- package/docs/kepler-git-write-api-parity.md +239 -0
- package/docs/kepler-read-api-parity.md +75 -28
- package/package.json +1 -1
- package/dist/plus/integrations/reads/trackerIssue.d.ts +0 -33
- package/dist/plus/integrations/reads/trackerIssue.js +0 -60
- package/dist/plus/integrations/reads/trackerIssue.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bitbucket.js","names":["Logger"],"sources":["../../../../../../plus/integrations/src/providers/bitbucket/bitbucket.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport type { Account, CommitAuthor, UnidentifiedAuthor } from '@gitlens/git/models/author.js';\nimport type { DefaultBranch } from '@gitlens/git/models/defaultBranch.js';\nimport type { Issue } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequest, IssueOrPullRequestType } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type { PullRequest } from '@gitlens/git/models/pullRequest.js';\nimport type { Provider } from '@gitlens/git/models/remoteProvider.js';\nimport type { RepositoryMetadata } from '@gitlens/git/models/repositoryMetadata.js';\nimport { CancellationError, isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { trace } from '@gitlens/utils/decorators/log.js';\nimport type { Disposable } from '@gitlens/utils/disposable.js';\nimport { Logger } from '@gitlens/utils/logger.js';\nimport type { ScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { maybeStopWatch } from '@gitlens/utils/stopwatch.js';\nimport type { TokenWithInfo } from '../../authentication/models.js';\nimport type { IntegrationServiceContext } from '../../context.js';\nimport {\n\tAuthenticationError,\n\tAuthenticationErrorReason,\n\tisRateLimitResponse,\n\tProviderFetchError,\n\tRequestClientError,\n\tRequestNotFoundError,\n\ttoRateLimitError,\n} from '../../errors.js';\nimport type { ProviderApiConfig } from '../apiConfig.js';\nimport { baseProviderApiConfig } from '../apiConfig.js';\nimport type { BitbucketServerCommit, BitbucketServerPullRequest } from '../bitbucket-server/models.js';\nimport { normalizeBitbucketServerPullRequest } from '../bitbucket-server/models.js';\nimport { fromProviderPullRequest } from '../models.js';\nimport type { BitbucketCommit, BitbucketIssue, BitbucketPullRequest, BitbucketRepository } from './models.js';\nimport {\n\tbitbucketIssueStateToState,\n\tfromBitbucketIssue,\n\tfromBitbucketPullRequest,\n\tparseRawBitbucketAuthor,\n} from './models.js';\n\nexport class BitbucketApi implements Disposable {\n\tprivate readonly _disposable: Disposable | undefined;\n\n\tconstructor(private readonly config: ProviderApiConfig) {\n\t\tthis._disposable = config.onConfigChanged?.(() => this.resetCaches());\n\t}\n\n\tdispose(): void {\n\t\tthis._disposable?.dispose();\n\t}\n\n\tprivate resetCaches(): void {}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getPullRequestForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst response = await this.request<{\n\t\t\tvalues: BitbucketPullRequest[];\n\t\t\tpagelen: number;\n\t\t\tsize: number;\n\t\t\tpage: number;\n\t\t}>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`repositories/${owner}/${repo}/pullrequests?q=source.branch.name=\"${branch}\"&fields=%2Bvalues.reviewers,%2Bvalues.participants`,\n\t\t\t{\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t\tscope,\n\t\t);\n\n\t\tif (!response?.values?.length) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn fromBitbucketPullRequest(response.values[0], provider);\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequestForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst response = await this.request<{\n\t\t\tvalues: BitbucketServerPullRequest[];\n\t\t\tpagelen: number;\n\t\t\tsize: number;\n\t\t\tpage: number;\n\t\t}>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`projects/${owner}/repos/${repo}/pull-requests?at=refs/heads/${branch}&direction=OUTGOING&state=ALL`,\n\t\t\t{\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t\tscope,\n\t\t);\n\n\t\tif (!response?.values?.length) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst providersPr = normalizeBitbucketServerPullRequest(response.values[0]);\n\t\tconst gitlensPr = fromProviderPullRequest(providersPr, provider);\n\t\treturn gitlensPr;\n\t}\n\n\t@trace({\n\t\targs: (provider, token, userUuid, owner, repo, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\tuserUuid: userUuid,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getUsersIssuesForRepo(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\tuserUuid: string,\n\t\towner: string,\n\t\trepo: string,\n\t\tbaseUrl: string,\n\t): Promise<Issue[] | undefined> {\n\t\tconst scope = getScopedLogger();\n\t\tconst query = encodeURIComponent(`assignee.uuid=\"${userUuid}\" OR reporter.uuid=\"${userUuid}\"`);\n\n\t\tconst response = await this.request<{\n\t\t\tvalues: BitbucketIssue[];\n\t\t\tpagelen: number;\n\t\t\tsize: number;\n\t\t\tpage: number;\n\t\t}>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`repositories/${owner}/${repo}/issues?q=${query}`,\n\t\t\t{\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t\tscope,\n\t\t);\n\n\t\tif (!response?.values?.length) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn response.values.map(issue => fromBitbucketIssue(issue, provider));\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getIssue(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t): Promise<Issue | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.request<BitbucketIssue>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/issues/${id}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t);\n\n\t\t\tif (response) {\n\t\t\t\treturn fromBitbucketIssue(response, provider);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getIssueOrPullRequest(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t\toptions?: {\n\t\t\ttype?: IssueOrPullRequestType;\n\t\t},\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif (options?.type === undefined || options?.type === 'pullrequest') {\n\t\t\ttry {\n\t\t\t\tconst prResponse = await this.request<BitbucketPullRequest>(\n\t\t\t\t\tprovider,\n\t\t\t\t\ttoken,\n\t\t\t\t\tbaseUrl,\n\t\t\t\t\t`repositories/${owner}/${repo}/pullrequests/${id}?fields=%2Bvalues.reviewers,%2Bvalues.participants`,\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\t},\n\t\t\t\t\tscope,\n\t\t\t\t);\n\n\t\t\t\tif (prResponse) {\n\t\t\t\t\treturn fromBitbucketPullRequest(prResponse, provider);\n\t\t\t\t}\n\t\t\t} catch (ex) {\n\t\t\t\tif (ex.original?.status !== 404) {\n\t\t\t\t\tscope?.error(ex);\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (options?.type === undefined || options?.type === 'issue') {\n\t\t\ttry {\n\t\t\t\tconst issueResponse = await this.request<BitbucketIssue>(\n\t\t\t\t\tprovider,\n\t\t\t\t\ttoken,\n\t\t\t\t\tbaseUrl,\n\t\t\t\t\t`repositories/${owner}/${repo}/issues/${id}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\t},\n\t\t\t\t\tscope,\n\t\t\t\t);\n\n\t\t\t\tif (issueResponse) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: issueResponse.id.toString(),\n\t\t\t\t\t\ttype: 'issue',\n\t\t\t\t\t\tnodeId: issueResponse.id.toString(),\n\t\t\t\t\t\tprovider: provider,\n\t\t\t\t\t\tcreatedDate: new Date(issueResponse.created_on),\n\t\t\t\t\t\tupdatedDate: new Date(issueResponse.updated_on),\n\t\t\t\t\t\tstate: bitbucketIssueStateToState(issueResponse.state),\n\t\t\t\t\t\tclosed: issueResponse.state === 'closed',\n\t\t\t\t\t\ttitle: issueResponse.title,\n\t\t\t\t\t\turl: issueResponse.links.html.href,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} catch (ex) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequestById(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst prResponse = await this.request<BitbucketServerPullRequest>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${owner}/repos/${repo}/pull-requests/${id}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t);\n\n\t\t\tif (prResponse) {\n\t\t\t\tconst providersPr = normalizeBitbucketServerPullRequest(prResponse);\n\t\t\t\tconst gitlensPr = fromProviderPullRequest(providersPr, provider);\n\t\t\t\treturn gitlensPr;\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\tif (ex.original?.status !== 404) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t@trace({\n\t\targs: (provider, token, workspace) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\tworkspace: workspace,\n\t\t}),\n\t})\n\tasync getRepositoriesForWorkspace(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\tworkspace: string,\n\t\toptions: {\n\t\t\tbaseUrl: string;\n\t\t},\n\t): Promise<RepositoryMetadata[] | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tinterface BitbucketRepositoriesResponse {\n\t\t\t\tsize: number;\n\t\t\t\tpage: number;\n\t\t\t\tpagelen: number;\n\t\t\t\tnext?: string;\n\t\t\t\tprevious?: string;\n\t\t\t\tvalues: BitbucketRepository[];\n\t\t\t}\n\n\t\t\tconst response = await this.request<BitbucketRepositoriesResponse>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\toptions.baseUrl,\n\t\t\t\t`repositories/${workspace}?role=contributor&fields=%2Bvalues.parent.workspace`, // field=+<field> must be encoded as field=%2B<field>\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t);\n\n\t\t\tif (response) {\n\t\t\t\treturn response.values.map(repo => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tprovider: provider,\n\t\t\t\t\t\towner: repo.workspace.slug,\n\t\t\t\t\t\tname: repo.slug,\n\t\t\t\t\t\tisFork: Boolean(repo.parent),\n\t\t\t\t\t\tparent: repo.parent\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\towner: repo.parent.workspace.slug,\n\t\t\t\t\t\t\t\t\tname: repo.parent.slug,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t}),\n\t})\n\tasync getRepositoryMetadata(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\toptions: {\n\t\t\tbaseUrl: string;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<RepositoryMetadata | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.getRepository(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\towner,\n\t\t\t\trepo,\n\t\t\t\toptions.baseUrl,\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (response == null) return undefined;\n\n\t\t\tlet parent: RepositoryMetadata['parent'];\n\t\t\tif (response.parent != null) {\n\t\t\t\t// Derive the parent from `full_name` (\"owner/repo\") rather than `parent.workspace`, which is a\n\t\t\t\t// requested field expansion Bitbucket doesn't always honor (an unexpanded parent would otherwise\n\t\t\t\t// throw and null out the whole result).\n\t\t\t\t// `full_name` is \"owner/repo\"; only report a parent when both parts are present so a malformed\n\t\t\t\t// value doesn't produce a parent with an undefined owner/name while `isFork` stays true.\n\t\t\t\tconst [parentOwner, parentName] = response.parent.full_name.split('/');\n\t\t\t\tif (parentOwner && parentName) {\n\t\t\t\t\tparent = { owner: parentOwner, name: parentName };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tprovider: provider,\n\t\t\t\towner: response.workspace.slug,\n\t\t\t\tname: response.slug,\n\t\t\t\tisFork: response.parent != null,\n\t\t\t\tparent: parent,\n\t\t\t} satisfies RepositoryMetadata;\n\t\t} catch (ex) {\n\t\t\t// Cancellations and 404s are expected outcomes for a probe; don't log them as errors.\n\t\t\tif (!isCancellationError(ex) && !(ex instanceof RequestNotFoundError)) {\n\t\t\t\tscope?.error(ex);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t}),\n\t})\n\tasync getDefaultBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\toptions: {\n\t\t\tbaseUrl: string;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<DefaultBranch | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.getRepository(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\towner,\n\t\t\t\trepo,\n\t\t\t\toptions.baseUrl,\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst name = response?.mainbranch?.name;\n\t\t\tif (name == null) return undefined;\n\n\t\t\treturn { provider: provider, name: name } satisfies DefaultBranch;\n\t\t} catch (ex) {\n\t\t\t// Cancellations and 404s are expected outcomes for a probe; don't log them as errors.\n\t\t\tif (!isCancellationError(ex) && !(ex instanceof RequestNotFoundError)) {\n\t\t\t\tscope?.error(ex);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate getRepository(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbaseUrl: string,\n\t\tscope: ScopedLogger | undefined,\n\t\tcancellation?: AbortSignal,\n\t): Promise<BitbucketRepository | undefined> {\n\t\treturn this.request<BitbucketRepository>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`repositories/${owner}/${repo}`,\n\t\t\t{ method: 'GET' },\n\t\t\tscope,\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getServerPullRequestForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.request<{ values: BitbucketServerPullRequest[] }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${owner}/repos/${repo}/commits/${rev}/pull-requests`, //?fields=${fieldsParam}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst prResponse = response?.values?.reduce<BitbucketServerPullRequest | undefined>(\n\t\t\t\t(acc, pr) => (!acc || pr.updatedDate > acc.updatedDate ? pr : acc),\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tif (!prResponse) return undefined;\n\n\t\t\tconst providersPr = normalizeBitbucketServerPullRequest(prResponse);\n\t\t\tconst gitlensPr = fromProviderPullRequest(providersPr, provider);\n\t\t\treturn gitlensPr;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getPullRequestForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst fields = [\n\t\t\t\t'+values.*',\n\t\t\t\t'+values.destination.repository',\n\t\t\t\t'+values.destination.branch.*',\n\t\t\t\t'+values.destination.commit.*',\n\t\t\t\t'+values.source.repository.*',\n\t\t\t\t'+values.source.branch.*',\n\t\t\t\t'+values.source.commit.*',\n\t\t\t];\n\t\t\tconst fieldsParam = encodeURIComponent(fields.join(','));\n\t\t\tconst response = await this.request<{ values: BitbucketPullRequest[] }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/commit/${rev}/pullrequests?fields=${fieldsParam}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst pr = response?.values?.reduce<BitbucketPullRequest | undefined>(\n\t\t\t\t(acc, pr) => (!acc || pr.updated_on > acc.updated_on ? pr : acc),\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tif (!pr) return undefined;\n\t\t\treturn fromBitbucketPullRequest(pr, provider);\n\t\t} catch (ex) {\n\t\t\tif (ex.original instanceof ProviderFetchError) {\n\t\t\t\tconst json = await ex.original.response.json();\n\t\t\t\tif (json?.error === 'Invalid or unknown installation') {\n\t\t\t\t\t// TODO: In future get it on to home as an warning on the integration itself \"this integration has issues\"\n\t\t\t\t\t// even user suppresses the message it's still visible with some capacity. It's a broader thing to get other errors.\n\t\t\t\t\tconst commitWebUrl = `https://bitbucket.org/${owner}/${repo}/commits/${rev}`;\n\t\t\t\t\tthis.config.onBitbucketCommitLinksAppMissing?.(commitWebUrl);\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getAccountForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst commit = await this.request<BitbucketCommit>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/commit/${rev}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (!commit) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst { name, email } = parseRawBitbucketAuthor(commit.author.raw);\n\t\t\tconst commitAuthor: CommitAuthor = {\n\t\t\t\tprovider: provider,\n\t\t\t\tid: commit.author.user?.account_id,\n\t\t\t\tusername: commit.author.user?.nickname,\n\t\t\t\tname: commit.author.user?.display_name || name,\n\t\t\t\temail: email,\n\t\t\t\tavatarUrl: commit.author.user?.links?.avatar?.href,\n\t\t\t};\n\t\t\tif (commitAuthor.id != null && commitAuthor.username != null) {\n\t\t\t\treturn {\n\t\t\t\t\t...commitAuthor,\n\t\t\t\t\tid: commitAuthor.id,\n\t\t\t\t} satisfies Account;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...commitAuthor,\n\t\t\t\tid: undefined,\n\t\t\t\tusername: undefined,\n\t\t\t} satisfies UnidentifiedAuthor;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getServerAccountForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst commit = await this.request<BitbucketServerCommit>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${owner}/repos/${repo}/commits/${rev}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (!commit?.author) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (commit.author.id != null) {\n\t\t\t\treturn {\n\t\t\t\t\tprovider: provider,\n\t\t\t\t\tid: commit.author.id.toString(),\n\t\t\t\t\tusername: commit.author.name,\n\t\t\t\t\tname: commit.author.name,\n\t\t\t\t\temail: commit.author.emailAddress,\n\t\t\t\t\tavatarUrl: commit.author?.avatarUrl,\n\t\t\t\t} satisfies Account;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tprovider: provider,\n\t\t\t\tid: undefined,\n\t\t\t\tusername: undefined,\n\t\t\t\tname: commit.author.name,\n\t\t\t\temail: commit.author.emailAddress,\n\t\t\t\tavatarUrl: undefined,\n\t\t\t} satisfies UnidentifiedAuthor;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate async request<T>(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\tbaseUrl: string,\n\t\troute: string,\n\t\toptions?: { method: RequestInit['method'] } & Record<string, unknown>,\n\t\tscope?: ScopedLogger | undefined,\n\t\tcancellation?: AbortSignal | undefined,\n\t): Promise<T | undefined> {\n\t\tconst { accessToken } = token;\n\t\tconst url = `${baseUrl}/${route}`;\n\n\t\tlet rsp: Response;\n\t\ttry {\n\t\t\tconst sw = maybeStopWatch(`[BITBUCKET] ${options?.method ?? 'GET'} ${url}`, { log: { onlyExit: true } });\n\n\t\t\ttry {\n\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\trsp = await this.config.wrapForForcedInsecureSSL(provider.getIgnoreSSLErrors(), () =>\n\t\t\t\t\tthis.config.fetch(url, {\n\t\t\t\t\t\theaders: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' },\n\t\t\t\t\t\tsignal: cancellation,\n\t\t\t\t\t\t...options,\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\tif (rsp.ok) {\n\t\t\t\t\treturn (await rsp.json()) as T;\n\t\t\t\t}\n\n\t\t\t\t// Reads the body so the 403 branch below can tell a throttled request from a permission failure.\n\t\t\t\tthrow await ProviderFetchError.fromResponse('Bitbucket', rsp);\n\t\t\t} finally {\n\t\t\t\tsw?.stop();\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof ProviderFetchError || ex.name === 'AbortError') {\n\t\t\t\tthis.handleRequestError(provider, token, ex, scope);\n\t\t\t} else if (Logger.isDebugging) {\n\t\t\t\tthis.config.onError?.(`Bitbucket request failed: ${ex.message}`);\n\t\t\t}\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\tprivate handleRequestError(\n\t\tprovider: Provider | undefined,\n\t\ttoken: TokenWithInfo,\n\t\tex: ProviderFetchError | (Error & { name: 'AbortError' }),\n\t\tscope: ScopedLogger | undefined,\n\t): void {\n\t\tif (ex.name === 'AbortError' || !(ex instanceof ProviderFetchError)) throw new CancellationError(ex);\n\n\t\tconst { accessToken, ...tokenInfo } = token;\n\t\tswitch (ex.status) {\n\t\t\tcase 404: // Not found\n\t\t\tcase 410: // Gone\n\t\t\tcase 422: // Unprocessable Entity\n\t\t\t\tthrow new RequestNotFoundError(ex);\n\t\t\tcase 401: // Unauthorized\n\t\t\t\tthrow new AuthenticationError(tokenInfo, AuthenticationErrorReason.Unauthorized, ex);\n\t\t\tcase 429: // Too Many Requests\n\t\t\t\tthrow toRateLimitError(ex, accessToken);\n\t\t\tcase 403: // Forbidden\n\t\t\t\t// Bitbucket returns 403 for both a permission failure and a throttled request (\"API rate limit\n\t\t\t\t// exceeded\"), so the message is the discriminant. Reporting a throttle as `auth` would prompt the\n\t\t\t\t// user to re-authenticate a healthy connection instead of retrying (see `isRateLimitResponse`).\n\t\t\t\tif (isRateLimitResponse(ex)) throw toRateLimitError(ex, accessToken);\n\n\t\t\t\tthrow new AuthenticationError(tokenInfo, AuthenticationErrorReason.Forbidden, ex);\n\t\t\tcase 500: // Internal Server Error\n\t\t\t\tscope?.error(ex);\n\t\t\t\tif (ex.response != null) {\n\t\t\t\t\tprovider?.trackRequestException();\n\t\t\t\t\tthis.config.onRequestFailed?.(\n\t\t\t\t\t\tprovider == null || provider.id === 'bitbucket'\n\t\t\t\t\t\t\t? l10n.t(\n\t\t\t\t\t\t\t\t\t'{0} failed to respond and might be experiencing issues. Please visit the [Bitbucket status page](https://bitbucket.status.atlassian.com/) for more information.',\n\t\t\t\t\t\t\t\t\tprovider?.name ?? 'Bitbucket',\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: l10n.t('{0} failed to respond and might be experiencing issues.', provider.name),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase 502: // Bad Gateway\n\t\t\t\tscope?.error(ex);\n\t\t\t\t// TODO: Learn the Bitbucket API docs and put it in order:\n\t\t\t\t// if (ex.message.includes('timeout')) {\n\t\t\t\t// \tprovider?.trackRequestException();\n\t\t\t\t// \tvoid showIntegrationRequestTimedOutWarningMessage(provider?.name ?? 'Bitbucket');\n\t\t\t\t// \treturn;\n\t\t\t\t// }\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (ex.status >= 400 && ex.status < 500) throw new RequestClientError(ex);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tscope?.error(ex);\n\t\tif (Logger.isDebugging) {\n\t\t\tthis.config.onError?.(\n\t\t\t\t`Bitbucket request failed: ${(ex.response as any)?.errors?.[0]?.message ?? ex.message}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/** Wires a {@link BitbucketApi} from the full runtime context, mapping `ctx` down to the narrow config. */\nexport function createBitbucketApi(ctx: IntegrationServiceContext): BitbucketApi {\n\tconst config: ProviderApiConfig = {\n\t\t...baseProviderApiConfig(ctx),\n\t\tonBitbucketCommitLinksAppMissing: revLink => ctx.hooks?.ui?.onBitbucketCommitLinksAppMissing?.(revLink),\n\t};\n\n\treturn new BitbucketApi(config);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bitbucket.js","names":["Logger"],"sources":["../../../../../../plus/integrations/src/providers/bitbucket/bitbucket.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport { reportRequestFailure } from '@gitlens/git/errors.js';\nimport type { Account, CommitAuthor, UnidentifiedAuthor } from '@gitlens/git/models/author.js';\nimport type { DefaultBranch } from '@gitlens/git/models/defaultBranch.js';\nimport type { Issue } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequest, IssueOrPullRequestType } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type { PullRequest } from '@gitlens/git/models/pullRequest.js';\nimport type { Provider } from '@gitlens/git/models/remoteProvider.js';\nimport type { RepositoryMetadata } from '@gitlens/git/models/repositoryMetadata.js';\nimport { CancellationError, isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { trace } from '@gitlens/utils/decorators/log.js';\nimport type { Disposable } from '@gitlens/utils/disposable.js';\nimport { Logger } from '@gitlens/utils/logger.js';\nimport type { ScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { maybeStopWatch } from '@gitlens/utils/stopwatch.js';\nimport { equalsIgnoreCase } from '@gitlens/utils/string.js';\nimport type { TokenWithInfo } from '../../authentication/models.js';\nimport type { IntegrationServiceContext } from '../../context.js';\nimport {\n\tAuthenticationError,\n\tAuthenticationErrorReason,\n\tisRateLimitResponse,\n\tProviderFetchError,\n\tRequestClientError,\n\tRequestNotFoundError,\n\ttoRateLimitError,\n} from '../../errors.js';\nimport type { ProviderApiConfig } from '../apiConfig.js';\nimport { baseProviderApiConfig } from '../apiConfig.js';\nimport type { BitbucketServerCommit, BitbucketServerPullRequest } from '../bitbucket-server/models.js';\nimport { normalizeBitbucketServerPullRequest } from '../bitbucket-server/models.js';\nimport { fromProviderPullRequest } from '../models.js';\nimport { selectBranchPullRequests } from '../utils/providerPaging.js';\nimport type { BitbucketCommit, BitbucketIssue, BitbucketPullRequest, BitbucketRepository } from './models.js';\nimport {\n\tbitbucketIssueStateToState,\n\tfromBitbucketIssue,\n\tfromBitbucketPullRequest,\n\tparseRawBitbucketAuthor,\n} from './models.js';\n\n/** `handleRequestError` maps 410 and 422 to the same error as a 404, but only a 404 proves the resource absent. */\nfunction isNotFoundResponse(ex: unknown): boolean {\n\treturn RequestNotFoundError.is(ex) && ex.original instanceof ProviderFetchError && ex.original.status === 404;\n}\n\nexport class BitbucketApi implements Disposable {\n\tprivate readonly _disposable: Disposable | undefined;\n\n\tconstructor(private readonly config: ProviderApiConfig) {\n\t\tthis._disposable = config.onConfigChanged?.(() => this.resetCaches());\n\t}\n\n\tdispose(): void {\n\t\tthis._disposable?.dispose();\n\t}\n\n\tprivate resetCaches(): void {}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getPullRequestForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst response = await this.request<{\n\t\t\tvalues: BitbucketPullRequest[];\n\t\t\tpagelen: number;\n\t\t\tsize: number;\n\t\t\tpage: number;\n\t\t}>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`repositories/${owner}/${repo}/pullrequests?q=source.branch.name=\"${branch}\"&fields=%2Bvalues.reviewers,%2Bvalues.participants`,\n\t\t\t{\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t\tscope,\n\t\t);\n\n\t\tif (!response?.values?.length) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn fromBitbucketPullRequest(response.values[0], provider);\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequestForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst response = await this.request<{\n\t\t\tvalues: BitbucketServerPullRequest[];\n\t\t\tpagelen: number;\n\t\t\tsize: number;\n\t\t\tpage: number;\n\t\t}>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`projects/${owner}/repos/${repo}/pull-requests?at=refs/heads/${branch}&direction=OUTGOING&state=ALL`,\n\t\t\t{\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t\tscope,\n\t\t);\n\n\t\tif (!response?.values?.length) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst providersPr = normalizeBitbucketServerPullRequest(response.values[0]);\n\t\tconst gitlensPr = fromProviderPullRequest(providersPr, provider);\n\t\treturn gitlensPr;\n\t}\n\n\t@trace({\n\t\targs: (provider, token, userUuid, owner, repo, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\tuserUuid: userUuid,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getUsersIssuesForRepo(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\tuserUuid: string,\n\t\towner: string,\n\t\trepo: string,\n\t\tbaseUrl: string,\n\t): Promise<Issue[] | undefined> {\n\t\tconst scope = getScopedLogger();\n\t\tconst query = encodeURIComponent(`assignee.uuid=\"${userUuid}\" OR reporter.uuid=\"${userUuid}\"`);\n\n\t\tconst response = await this.request<{\n\t\t\tvalues: BitbucketIssue[];\n\t\t\tpagelen: number;\n\t\t\tsize: number;\n\t\t\tpage: number;\n\t\t}>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`repositories/${owner}/${repo}/issues?q=${query}`,\n\t\t\t{\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t\tscope,\n\t\t);\n\n\t\tif (!response?.values?.length) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn response.values.map(issue => fromBitbucketIssue(issue, provider));\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getIssue(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t): Promise<Issue | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.request<BitbucketIssue>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/issues/${id}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t);\n\n\t\t\tif (response) {\n\t\t\t\treturn fromBitbucketIssue(response, provider);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getIssueOrPullRequest(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t\toptions?: {\n\t\t\ttype?: IssueOrPullRequestType;\n\t\t},\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif (options?.type === undefined || options?.type === 'pullrequest') {\n\t\t\ttry {\n\t\t\t\tconst pr = await this.getPullRequest(provider, token, owner, repo, id, baseUrl);\n\t\t\t\tif (pr != null) return pr;\n\t\t\t} catch (ex) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\n\t\tif (options?.type === undefined || options?.type === 'issue') {\n\t\t\ttry {\n\t\t\t\tconst issueResponse = await this.request<BitbucketIssue>(\n\t\t\t\t\tprovider,\n\t\t\t\t\ttoken,\n\t\t\t\t\tbaseUrl,\n\t\t\t\t\t`repositories/${owner}/${repo}/issues/${id}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\t},\n\t\t\t\t\tscope,\n\t\t\t\t);\n\n\t\t\t\tif (issueResponse) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: issueResponse.id.toString(),\n\t\t\t\t\t\ttype: 'issue',\n\t\t\t\t\t\tnodeId: issueResponse.id.toString(),\n\t\t\t\t\t\tprovider: provider,\n\t\t\t\t\t\tcreatedDate: new Date(issueResponse.created_on),\n\t\t\t\t\t\tupdatedDate: new Date(issueResponse.updated_on),\n\t\t\t\t\t\tstate: bitbucketIssueStateToState(issueResponse.state),\n\t\t\t\t\t\tclosed: issueResponse.state === 'closed',\n\t\t\t\t\t\ttitle: issueResponse.title,\n\t\t\t\t\t\turl: issueResponse.links.html.href,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} catch (ex) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequestById(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\treturn await this.getServerPullRequest(provider, token, owner, repo, id, baseUrl);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * A Bitbucket Cloud pull request by id. Strict, unlike {@link getIssueOrPullRequest}: `undefined` means a 404,\n\t * and every other failure throws, so the answer can be cached as a proven absence.\n\t */\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getPullRequest(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t\toptions?: { currentAccount?: { id: string; username?: string }; deferFailure?: boolean },\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst pr = await this.request<BitbucketPullRequest>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/pullrequests/${id}?fields=%2Bvalues.reviewers,%2Bvalues.participants`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tundefined,\n\t\t\t\toptions?.deferFailure,\n\t\t\t);\n\t\t\tif (pr == null) throw new Error(`Bitbucket returned no pull request for ${owner}/${repo}#${id}`);\n\n\t\t\treturn fromBitbucketPullRequest(pr, provider, { currentAccount: options?.currentAccount });\n\t\t} catch (ex) {\n\t\t\tif (isNotFoundResponse(ex)) return undefined;\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/**\n\t * A Bitbucket Data Center pull request by id. Strict, unlike {@link getServerPullRequestById}: `undefined` means\n\t * a 404, and every other failure throws, so the answer can be cached as a proven absence.\n\t */\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequest(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t\toptions?: { currentAccount?: { id: string; username?: string }; deferFailure?: boolean },\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst pr = await this.request<BitbucketServerPullRequest>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${owner}/repos/${repo}/pull-requests/${id}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tundefined,\n\t\t\t\toptions?.deferFailure,\n\t\t\t);\n\t\t\tif (pr == null) throw new Error(`Bitbucket returned no pull request for ${owner}/${repo}#${id}`);\n\n\t\t\treturn fromProviderPullRequest(normalizeBitbucketServerPullRequest(pr), provider, {\n\t\t\t\tcurrentAccount: options?.currentAccount,\n\t\t\t});\n\t\t} catch (ex) {\n\t\t\tif (isNotFoundResponse(ex)) return undefined;\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/**\n\t * Every Bitbucket Cloud pull request into `owner/repo` whose source is `branch`, in any state, newest first, at\n\t * most `limit`: from the repository itself when `headOwner` is omitted, otherwise from a fork in the `headOwner`\n\t * workspace. Keyed on the source branch NAME, so a merged pull request whose branch was deleted still matches.\n\t *\n\t * Strict like {@link getPullRequest}: a 404 (a missing repository) is an empty list, and every other failure\n\t * throws.\n\t */\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getPullRequestsForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t\toptions: {\n\t\t\theadOwner?: string;\n\t\t\tlimit: number;\n\t\t\tcurrentAccount?: { id: string; username?: string };\n\t\t\tdeferFailure?: boolean;\n\t\t},\n\t): Promise<{ pullRequests: PullRequest[]; truncated: boolean }> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst escapedBranch = branch.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n\t\tconst params = new URLSearchParams({\n\t\t\t// Every state named: Bitbucket answers only OPEN pull requests unless asked for the others.\n\t\t\tq: `source.branch.name=\"${escapedBranch}\" AND (state=\"OPEN\" OR state=\"MERGED\" OR state=\"DECLINED\" OR state=\"SUPERSEDED\")`,\n\t\t\tsort: '-updated_on',\n\t\t\tpagelen: String(options.limit),\n\t\t\tfields: '+values.reviewers,+values.participants',\n\t\t});\n\n\t\ttry {\n\t\t\tconst response = await this.request<{ values: BitbucketPullRequest[]; next?: string }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pullrequests?${params.toString()}`,\n\t\t\t\t{ method: 'GET' },\n\t\t\t\tscope,\n\t\t\t\tundefined,\n\t\t\t\toptions.deferFailure,\n\t\t\t);\n\t\t\tif (response?.values == null) {\n\t\t\t\tthrow new Error(`Bitbucket returned no pull requests for ${owner}/${repo}:${branch}`);\n\t\t\t}\n\n\t\t\tconst headOwner = options.headOwner;\n\t\t\tconst { values, truncated } = selectBranchPullRequests(response.values, {\n\t\t\t\tmatchesHead: pr => {\n\t\t\t\t\tconst source = pr.source.repository;\n\t\t\t\t\tif (pr.source.branch.name !== branch || source == null) return false;\n\t\t\t\t\tif (headOwner == null) return source.uuid === pr.destination.repository.uuid;\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\tsource.uuid !== pr.destination.repository.uuid &&\n\t\t\t\t\t\tequalsIgnoreCase(source.full_name.split('/')[0], headOwner)\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tupdatedAt: pr => Date.parse(pr.updated_on),\n\t\t\t\tmap: pr => fromBitbucketPullRequest(pr, provider, { currentAccount: options.currentAccount }),\n\t\t\t\tlimit: options.limit,\n\t\t\t\tmore: response.next != null,\n\t\t\t});\n\t\t\treturn { pullRequests: values, truncated: truncated };\n\t\t} catch (ex) {\n\t\t\tif (isNotFoundResponse(ex)) return { pullRequests: [], truncated: false };\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/**\n\t * Every Bitbucket Data Center pull request whose source is `branch` in `owner/repo` and whose target is that same\n\t * repository, in any state, newest first, at most `limit`. Asked of the repository the branch lives in\n\t * (`direction=OUTGOING`), which is why a fork's pull requests can't be found through the repository they target.\n\t *\n\t * Strict like {@link getServerPullRequest}: a 404 (a missing repository) is an empty list, and every other\n\t * failure throws.\n\t */\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequestsForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t\toptions: { limit: number; currentAccount?: { id: string; username?: string }; deferFailure?: boolean },\n\t): Promise<{ pullRequests: PullRequest[]; truncated: boolean }> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst ref = `refs/heads/${branch}`;\n\t\tconst params = new URLSearchParams({\n\t\t\tat: ref,\n\t\t\tdirection: 'OUTGOING',\n\t\t\tstate: 'ALL',\n\t\t\torder: 'NEWEST',\n\t\t\tlimit: String(options.limit),\n\t\t});\n\n\t\ttry {\n\t\t\tconst response = await this.request<{ values: BitbucketServerPullRequest[]; isLastPage?: boolean }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${encodeURIComponent(owner)}/repos/${encodeURIComponent(repo)}/pull-requests?${params.toString()}`,\n\t\t\t\t{ method: 'GET' },\n\t\t\t\tscope,\n\t\t\t\tundefined,\n\t\t\t\toptions.deferFailure,\n\t\t\t);\n\t\t\tif (response?.values == null) {\n\t\t\t\tthrow new Error(`Bitbucket returned no pull requests for ${owner}/${repo}:${branch}`);\n\t\t\t}\n\n\t\t\tconst { values, truncated } = selectBranchPullRequests(response.values, {\n\t\t\t\t// `OUTGOING` also lists this branch's pull requests into other repositories, e.g. the upstream of a\n\t\t\t\t// repository that is itself a fork.\n\t\t\t\tmatchesHead: pr => pr.fromRef.id === ref && pr.fromRef.repository.id === pr.toRef.repository.id,\n\t\t\t\tupdatedAt: pr => pr.updatedDate,\n\t\t\t\tmap: pr =>\n\t\t\t\t\tfromProviderPullRequest(normalizeBitbucketServerPullRequest(pr), provider, {\n\t\t\t\t\t\tcurrentAccount: options.currentAccount,\n\t\t\t\t\t}),\n\t\t\t\tlimit: options.limit,\n\t\t\t\tmore: response.isLastPage !== true,\n\t\t\t});\n\t\t\treturn { pullRequests: values, truncated: truncated };\n\t\t} catch (ex) {\n\t\t\tif (isNotFoundResponse(ex)) return { pullRequests: [], truncated: false };\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, workspace) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\tworkspace: workspace,\n\t\t}),\n\t})\n\tasync getRepositoriesForWorkspace(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\tworkspace: string,\n\t\toptions: {\n\t\t\tbaseUrl: string;\n\t\t},\n\t): Promise<RepositoryMetadata[] | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tinterface BitbucketRepositoriesResponse {\n\t\t\t\tsize: number;\n\t\t\t\tpage: number;\n\t\t\t\tpagelen: number;\n\t\t\t\tnext?: string;\n\t\t\t\tprevious?: string;\n\t\t\t\tvalues: BitbucketRepository[];\n\t\t\t}\n\n\t\t\tconst response = await this.request<BitbucketRepositoriesResponse>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\toptions.baseUrl,\n\t\t\t\t`repositories/${workspace}?role=contributor&fields=%2Bvalues.parent.workspace`, // field=+<field> must be encoded as field=%2B<field>\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t);\n\n\t\t\tif (response) {\n\t\t\t\treturn response.values.map(repo => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tprovider: provider,\n\t\t\t\t\t\towner: repo.workspace.slug,\n\t\t\t\t\t\tname: repo.slug,\n\t\t\t\t\t\tisFork: Boolean(repo.parent),\n\t\t\t\t\t\tparent: repo.parent\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\towner: repo.parent.workspace.slug,\n\t\t\t\t\t\t\t\t\tname: repo.parent.slug,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t}),\n\t})\n\tasync getRepositoryMetadata(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\toptions: {\n\t\t\tbaseUrl: string;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<RepositoryMetadata | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.getRepository(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\towner,\n\t\t\t\trepo,\n\t\t\t\toptions.baseUrl,\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (response == null) return undefined;\n\n\t\t\tlet parent: RepositoryMetadata['parent'];\n\t\t\tif (response.parent != null) {\n\t\t\t\t// Derive the parent from `full_name` (\"owner/repo\") rather than `parent.workspace`, which is a\n\t\t\t\t// requested field expansion Bitbucket doesn't always honor (an unexpanded parent would otherwise\n\t\t\t\t// throw and null out the whole result).\n\t\t\t\t// `full_name` is \"owner/repo\"; only report a parent when both parts are present so a malformed\n\t\t\t\t// value doesn't produce a parent with an undefined owner/name while `isFork` stays true.\n\t\t\t\tconst [parentOwner, parentName] = response.parent.full_name.split('/');\n\t\t\t\tif (parentOwner && parentName) {\n\t\t\t\t\tparent = { owner: parentOwner, name: parentName };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tprovider: provider,\n\t\t\t\towner: response.workspace.slug,\n\t\t\t\tname: response.slug,\n\t\t\t\tisFork: response.parent != null,\n\t\t\t\tparent: parent,\n\t\t\t} satisfies RepositoryMetadata;\n\t\t} catch (ex) {\n\t\t\t// Cancellations and 404s are expected outcomes for a probe; don't log them as errors.\n\t\t\tif (!isCancellationError(ex) && !(ex instanceof RequestNotFoundError)) {\n\t\t\t\tscope?.error(ex);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t}),\n\t})\n\tasync getDefaultBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\toptions: {\n\t\t\tbaseUrl: string;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<DefaultBranch | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.getRepository(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\towner,\n\t\t\t\trepo,\n\t\t\t\toptions.baseUrl,\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst name = response?.mainbranch?.name;\n\t\t\tif (name == null) return undefined;\n\n\t\t\treturn { provider: provider, name: name } satisfies DefaultBranch;\n\t\t} catch (ex) {\n\t\t\t// Cancellations and 404s are expected outcomes for a probe; don't log them as errors.\n\t\t\tif (!isCancellationError(ex) && !(ex instanceof RequestNotFoundError)) {\n\t\t\t\tscope?.error(ex);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate getRepository(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbaseUrl: string,\n\t\tscope: ScopedLogger | undefined,\n\t\tcancellation?: AbortSignal,\n\t): Promise<BitbucketRepository | undefined> {\n\t\treturn this.request<BitbucketRepository>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`repositories/${owner}/${repo}`,\n\t\t\t{ method: 'GET' },\n\t\t\tscope,\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getServerPullRequestForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.request<{ values: BitbucketServerPullRequest[] }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${owner}/repos/${repo}/commits/${rev}/pull-requests`, //?fields=${fieldsParam}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst prResponse = response?.values?.reduce<BitbucketServerPullRequest | undefined>(\n\t\t\t\t(acc, pr) => (!acc || pr.updatedDate > acc.updatedDate ? pr : acc),\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tif (!prResponse) return undefined;\n\n\t\t\tconst providersPr = normalizeBitbucketServerPullRequest(prResponse);\n\t\t\tconst gitlensPr = fromProviderPullRequest(providersPr, provider);\n\t\t\treturn gitlensPr;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getPullRequestForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst fields = [\n\t\t\t\t'+values.*',\n\t\t\t\t'+values.destination.repository',\n\t\t\t\t'+values.destination.branch.*',\n\t\t\t\t'+values.destination.commit.*',\n\t\t\t\t'+values.source.repository.*',\n\t\t\t\t'+values.source.branch.*',\n\t\t\t\t'+values.source.commit.*',\n\t\t\t];\n\t\t\tconst fieldsParam = encodeURIComponent(fields.join(','));\n\t\t\tconst response = await this.request<{ values: BitbucketPullRequest[] }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/commit/${rev}/pullrequests?fields=${fieldsParam}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst pr = response?.values?.reduce<BitbucketPullRequest | undefined>(\n\t\t\t\t(acc, pr) => (!acc || pr.updated_on > acc.updated_on ? pr : acc),\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tif (!pr) return undefined;\n\t\t\treturn fromBitbucketPullRequest(pr, provider);\n\t\t} catch (ex) {\n\t\t\tif (ex.original instanceof ProviderFetchError) {\n\t\t\t\tconst json = await ex.original.response.json();\n\t\t\t\tif (json?.error === 'Invalid or unknown installation') {\n\t\t\t\t\t// TODO: In future get it on to home as an warning on the integration itself \"this integration has issues\"\n\t\t\t\t\t// even user suppresses the message it's still visible with some capacity. It's a broader thing to get other errors.\n\t\t\t\t\tconst commitWebUrl = `https://bitbucket.org/${owner}/${repo}/commits/${rev}`;\n\t\t\t\t\tthis.config.onBitbucketCommitLinksAppMissing?.(commitWebUrl);\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getAccountForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst commit = await this.request<BitbucketCommit>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/commit/${rev}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (!commit) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst { name, email } = parseRawBitbucketAuthor(commit.author.raw);\n\t\t\tconst commitAuthor: CommitAuthor = {\n\t\t\t\tprovider: provider,\n\t\t\t\tid: commit.author.user?.account_id,\n\t\t\t\tusername: commit.author.user?.nickname,\n\t\t\t\tname: commit.author.user?.display_name || name,\n\t\t\t\temail: email,\n\t\t\t\tavatarUrl: commit.author.user?.links?.avatar?.href,\n\t\t\t};\n\t\t\tif (commitAuthor.id != null && commitAuthor.username != null) {\n\t\t\t\treturn {\n\t\t\t\t\t...commitAuthor,\n\t\t\t\t\tid: commitAuthor.id,\n\t\t\t\t} satisfies Account;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...commitAuthor,\n\t\t\t\tid: undefined,\n\t\t\t\tusername: undefined,\n\t\t\t} satisfies UnidentifiedAuthor;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getServerAccountForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst commit = await this.request<BitbucketServerCommit>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${owner}/repos/${repo}/commits/${rev}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (!commit?.author) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (commit.author.id != null) {\n\t\t\t\treturn {\n\t\t\t\t\tprovider: provider,\n\t\t\t\t\tid: commit.author.id.toString(),\n\t\t\t\t\tusername: commit.author.name,\n\t\t\t\t\tname: commit.author.name,\n\t\t\t\t\temail: commit.author.emailAddress,\n\t\t\t\t\tavatarUrl: commit.author?.avatarUrl,\n\t\t\t\t} satisfies Account;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tprovider: provider,\n\t\t\t\tid: undefined,\n\t\t\t\tusername: undefined,\n\t\t\t\tname: commit.author.name,\n\t\t\t\temail: commit.author.emailAddress,\n\t\t\t\tavatarUrl: undefined,\n\t\t\t} satisfies UnidentifiedAuthor;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate async request<T>(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\tbaseUrl: string,\n\t\troute: string,\n\t\toptions?: { method: RequestInit['method'] } & Record<string, unknown>,\n\t\tscope?: ScopedLogger | undefined,\n\t\tcancellation?: AbortSignal | undefined,\n\t\tdeferFailure?: boolean,\n\t): Promise<T | undefined> {\n\t\tconst { accessToken } = token;\n\t\tconst url = `${baseUrl}/${route}`;\n\n\t\tlet rsp: Response;\n\t\ttry {\n\t\t\tconst sw = maybeStopWatch(`[BITBUCKET] ${options?.method ?? 'GET'} ${url}`, { log: { onlyExit: true } });\n\n\t\t\ttry {\n\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\trsp = await this.config.wrapForForcedInsecureSSL(provider.getIgnoreSSLErrors(), () =>\n\t\t\t\t\tthis.config.fetch(url, {\n\t\t\t\t\t\theaders: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' },\n\t\t\t\t\t\tsignal: cancellation,\n\t\t\t\t\t\t...options,\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\tif (rsp.ok) {\n\t\t\t\t\treturn (await rsp.json()) as T;\n\t\t\t\t}\n\n\t\t\t\t// Reads the body so the 403 branch below can tell a throttled request from a permission failure.\n\t\t\t\tthrow await ProviderFetchError.fromResponse('Bitbucket', rsp);\n\t\t\t} finally {\n\t\t\t\tsw?.stop();\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof ProviderFetchError || ex.name === 'AbortError') {\n\t\t\t\tthis.handleRequestError(provider, token, ex, scope, deferFailure);\n\t\t\t} else if (Logger.isDebugging) {\n\t\t\t\tthis.config.onError?.(`Bitbucket request failed: ${ex.message}`);\n\t\t\t}\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\tprivate handleRequestError(\n\t\tprovider: Provider | undefined,\n\t\ttoken: TokenWithInfo,\n\t\tex: ProviderFetchError | (Error & { name: 'AbortError' }),\n\t\tscope: ScopedLogger | undefined,\n\t\tdeferFailure: boolean | undefined,\n\t): void {\n\t\tif (ex.name === 'AbortError' || !(ex instanceof ProviderFetchError)) throw new CancellationError(ex);\n\n\t\tconst { accessToken, ...tokenInfo } = token;\n\t\tswitch (ex.status) {\n\t\t\tcase 404: // Not found\n\t\t\tcase 410: // Gone\n\t\t\tcase 422: // Unprocessable Entity\n\t\t\t\tthrow new RequestNotFoundError(ex);\n\t\t\tcase 401: // Unauthorized\n\t\t\t\tthrow new AuthenticationError(tokenInfo, AuthenticationErrorReason.Unauthorized, ex);\n\t\t\tcase 429: // Too Many Requests\n\t\t\t\tthrow toRateLimitError(ex, accessToken);\n\t\t\tcase 403: // Forbidden\n\t\t\t\t// Bitbucket returns 403 for both a permission failure and a throttled request (\"API rate limit\n\t\t\t\t// exceeded\"), so the message is the discriminant. Reporting a throttle as `auth` would prompt the\n\t\t\t\t// user to re-authenticate a healthy connection instead of retrying (see `isRateLimitResponse`).\n\t\t\t\tif (isRateLimitResponse(ex)) throw toRateLimitError(ex, accessToken);\n\n\t\t\t\tthrow new AuthenticationError(tokenInfo, AuthenticationErrorReason.Forbidden, ex);\n\t\t\tcase 500: // Internal Server Error\n\t\t\t\tscope?.error(ex);\n\t\t\t\tif (ex.response != null) {\n\t\t\t\t\treportRequestFailure(\n\t\t\t\t\t\tprovider,\n\t\t\t\t\t\tex,\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\tthis.config.onRequestFailed?.(\n\t\t\t\t\t\t\t\tprovider == null || provider.id === 'bitbucket'\n\t\t\t\t\t\t\t\t\t? l10n.t(\n\t\t\t\t\t\t\t\t\t\t\t'{0} failed to respond and might be experiencing issues. Please visit the [Bitbucket status page](https://bitbucket.status.atlassian.com/) for more information.',\n\t\t\t\t\t\t\t\t\t\t\tprovider?.name ?? 'Bitbucket',\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t: l10n.t('{0} failed to respond and might be experiencing issues.', provider.name),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\tdeferFailure,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase 502: // Bad Gateway\n\t\t\t\tscope?.error(ex);\n\t\t\t\t// TODO: Learn the Bitbucket API docs and put it in order:\n\t\t\t\t// if (ex.message.includes('timeout')) {\n\t\t\t\t// \tprovider?.trackRequestException();\n\t\t\t\t// \tvoid showIntegrationRequestTimedOutWarningMessage(provider?.name ?? 'Bitbucket');\n\t\t\t\t// \treturn;\n\t\t\t\t// }\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (ex.status >= 400 && ex.status < 500) throw new RequestClientError(ex);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tscope?.error(ex);\n\t\tif (Logger.isDebugging) {\n\t\t\tthis.config.onError?.(\n\t\t\t\t`Bitbucket request failed: ${(ex.response as any)?.errors?.[0]?.message ?? ex.message}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/** Wires a {@link BitbucketApi} from the full runtime context, mapping `ctx` down to the narrow config. */\nexport function createBitbucketApi(ctx: IntegrationServiceContext): BitbucketApi {\n\tconst config: ProviderApiConfig = {\n\t\t...baseProviderApiConfig(ctx),\n\t\tonBitbucketCommitLinksAppMissing: revLink => ctx.hooks?.ui?.onBitbucketCommitLinksAppMissing?.(revLink),\n\t};\n\n\treturn new BitbucketApi(config);\n}\n"],"mappings":"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"}
|
|
@@ -217,6 +217,11 @@ export declare function isClosedBitbucketIssueState(state: BitbucketIssueState):
|
|
|
217
217
|
export declare function fromBitbucketUser(user: BitbucketUser): PullRequestMember;
|
|
218
218
|
export declare function fromBitbucketParticipantToReviewer(prt: BitbucketPullRequestParticipant, closedBy: BitbucketUser | null, prState: BitbucketPullRequestState): PullRequestReviewer;
|
|
219
219
|
export declare function fromBitbucketIssue(issue: BitbucketIssue, provider: Provider): Issue;
|
|
220
|
-
export declare function fromBitbucketPullRequest(pr: BitbucketPullRequest, provider: Provider
|
|
220
|
+
export declare function fromBitbucketPullRequest(pr: BitbucketPullRequest, provider: Provider, options?: {
|
|
221
|
+
currentAccount?: {
|
|
222
|
+
id: string;
|
|
223
|
+
username?: string;
|
|
224
|
+
};
|
|
225
|
+
}): PullRequest;
|
|
221
226
|
//#endregion
|
|
222
227
|
//# sourceMappingURL=models.d.ts.map
|
|
@@ -84,8 +84,9 @@ function fromBitbucketIssue(issue, provider) {
|
|
|
84
84
|
resourceName: issue.repository.project.name
|
|
85
85
|
});
|
|
86
86
|
}
|
|
87
|
-
function fromBitbucketPullRequest(pr, provider) {
|
|
88
|
-
|
|
87
|
+
function fromBitbucketPullRequest(pr, provider, options) {
|
|
88
|
+
const author = fromBitbucketUser(pr.author);
|
|
89
|
+
return new PullRequest(provider, author, pr.id.toString(), pr.id.toString(), pr.title, pr.links.html.href, fromBitbucketRepository(pr.destination.repository), bitbucketPullRequestStateToState(pr.state), new Date(pr.created_on), new Date(pr.updated_on), pr.closed_by ? new Date(pr.updated_on) : void 0, pr.state === "MERGED" ? new Date(pr.updated_on) : void 0, "Mergeable", void 0, {
|
|
89
90
|
base: {
|
|
90
91
|
branch: pr.destination.branch.name,
|
|
91
92
|
sha: pr.destination.commit.hash,
|
|
@@ -103,7 +104,7 @@ function fromBitbucketPullRequest(pr, provider) {
|
|
|
103
104
|
url: pr.source.repository.links.html.href
|
|
104
105
|
},
|
|
105
106
|
isCrossRepository: pr.source.repository.uuid !== pr.destination.repository.uuid
|
|
106
|
-
}, void 0, void 0, void 0, void 0, void 0, getBitbucketReviewDecision(pr), pr.participants?.filter((prt) => prt.role === "REVIEWER").map((prt) => fromBitbucketParticipantToReviewer(prt, pr.closed_by, pr.state)).filter((rv) => rv.state === "REVIEW_REQUESTED"), pr.participants?.filter((prt) => prt.participated_on != null).map((prt) => fromBitbucketParticipantToReviewer(prt, pr.closed_by, pr.state)), void 0, void 0, void 0);
|
|
107
|
+
}, void 0, void 0, void 0, void 0, void 0, getBitbucketReviewDecision(pr), pr.participants?.filter((prt) => prt.role === "REVIEWER").map((prt) => fromBitbucketParticipantToReviewer(prt, pr.closed_by, pr.state)).filter((rv) => rv.state === "REVIEW_REQUESTED"), pr.participants?.filter((prt) => prt.participated_on != null).map((prt) => fromBitbucketParticipantToReviewer(prt, pr.closed_by, pr.state)), void 0, void 0, void 0, void 0, void 0, void 0, void 0, pr.description ?? void 0, pr.id, options?.currentAccount != null ? author.id === options.currentAccount.id : void 0);
|
|
107
108
|
}
|
|
108
109
|
//#endregion
|
|
109
110
|
export { bitbucketIssueStateToState, bitbucketPullRequestStateToState, fromBitbucketIssue, fromBitbucketParticipantToReviewer, fromBitbucketPullRequest, fromBitbucketUser, isClosedBitbucketIssueState, isClosedBitbucketPullRequestState, parseRawBitbucketAuthor };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.js","names":[],"sources":["../../../../../../plus/integrations/src/providers/bitbucket/models.ts"],"sourcesContent":["import type { IssueRepository } from '@gitlens/git/models/issue.js';\nimport { Issue, RepositoryAccessLevel } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequestState } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type { PullRequestMember, PullRequestReviewer } from '@gitlens/git/models/pullRequest.js';\nimport {\n\tPullRequest,\n\tPullRequestMergeableState,\n\tPullRequestReviewDecision,\n\tPullRequestReviewState,\n} from '@gitlens/git/models/pullRequest.js';\nimport type { Provider } from '@gitlens/git/models/remoteProvider.js';\nimport type { ResourceDescriptor } from '@gitlens/git/models/resourceDescriptor.js';\n\nexport interface BitbucketRepositoryDescriptor extends ResourceDescriptor {\n\towner: string;\n\tname: string;\n}\n\nexport interface BitbucketWorkspaceDescriptor extends ResourceDescriptor {\n\tid: string;\n\tname: string;\n\tslug: string;\n}\n\nexport type BitbucketPullRequestState = 'OPEN' | 'DECLINED' | 'MERGED' | 'SUPERSEDED';\n\ninterface BitbucketLink {\n\thref: string;\n\tname?: string;\n}\n\ninterface BitbucketUser {\n\ttype: 'user';\n\tuuid: string;\n\tdisplay_name: string;\n\taccount_id?: string;\n\tnickname?: string;\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\tavatar: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t};\n}\n\ninterface BitbucketWorkspace {\n\ttype: 'workspace';\n\tuuid: string;\n\tname: string;\n\tslug: string;\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t\tavatar: BitbucketLink;\n\t};\n}\n\ninterface BitbucketProject {\n\ttype: 'project';\n\tkey: string;\n\tuuid: string;\n\tname: string;\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t\tavatar: BitbucketLink;\n\t};\n}\n\ninterface BitbucketPullRequestParticipant {\n\ttype: 'participant';\n\tuser: BitbucketUser;\n\trole: 'PARTICIPANT' | 'REVIEWER';\n\tapproved: boolean;\n\tstate: null | 'approved' | 'changes_requested';\n\tparticipated_on: null | string;\n}\n\nexport interface BitbucketRepository {\n\ttype: 'repository';\n\tuuid: string;\n\tfull_name: string;\n\tname: string;\n\tslug: string;\n\tdescription?: string;\n\tis_private: boolean;\n\tparent: null | BitbucketRepository;\n\tscm: 'git';\n\towner: BitbucketUser;\n\tworkspace: BitbucketWorkspace;\n\tproject: BitbucketProject;\n\tcreated_on: string;\n\tupdated_on: string;\n\tsize: number;\n\tlanguage: string;\n\thas_issues: boolean;\n\thas_wiki: boolean;\n\tfork_policy: 'allow_forks' | 'no_public_forks' | 'no_forks';\n\twebsite: string;\n\tmainbranch?: BitbucketBranch;\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t\tavatar: BitbucketLink;\n\t};\n}\n\ninterface BitbucketCommitAuthor {\n\ttype: 'author';\n\traw: string;\n\tuser: BitbucketUser;\n}\n\ntype BitbucketMergeStrategy =\n\t| 'merge_commit'\n\t| 'squash'\n\t| 'fast_forward'\n\t| 'squash_fast_forward'\n\t| 'rebase_fast_forward'\n\t| 'rebase_merge';\n\ninterface BitbucketBranch {\n\tname: string;\n\tmerge_strategies?: BitbucketMergeStrategy[];\n\tdefault_merge_strategy?: BitbucketMergeStrategy;\n}\n\n// It parses a raw author sitring like \"Sergei Shmakov GK <sergei.shmakov@gitkraken.com>\" to name and email\nconst parseRawBitbucketAuthorRegex = /^(.*) <(.*)>$/;\nexport function parseRawBitbucketAuthor(raw: string): { name: string; email: string } {\n\tconst match = raw.match(parseRawBitbucketAuthorRegex);\n\tif (match) {\n\t\treturn { name: match[1], email: match[2] };\n\t}\n\treturn { name: raw, email: '' };\n}\n\nexport interface BitbucketCommit extends BitbucketBriefCommit {\n\tauthor: BitbucketCommitAuthor;\n\tdate: string;\n\tlinks: {\n\t\tapprove: BitbucketLink;\n\t\tcomments: BitbucketLink;\n\t\tdiff: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t\tself: BitbucketLink;\n\t\tstatuses: BitbucketLink;\n\t};\n\tmessage: string;\n\tparents: BitbucketBriefCommit[];\n\tparticipants: BitbucketPullRequestParticipant[];\n\trendered: {\n\t\tmessage: string;\n\t};\n\trepository: BitbucketRepository;\n\tsummary: {\n\t\ttype: 'rendered';\n\t\traw: string;\n\t\tmarkup: string;\n\t\thtml: string;\n\t};\n}\n\ninterface BitbucketBriefCommit {\n\ttype: 'commit';\n\thash: string;\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t};\n}\n\nexport type BitbucketIssueState =\n\t| 'submitted'\n\t| 'new'\n\t| 'open'\n\t| 'resolved'\n\t| 'on hold'\n\t| 'invalid'\n\t| 'duplicate'\n\t| 'wontfix'\n\t| 'closed';\n\nexport interface BitbucketPullRequest {\n\ttype: 'pullrequest';\n\tid: number;\n\ttitle: string;\n\tdescription: string;\n\tstate: BitbucketPullRequestState;\n\tmerge_commit: null | BitbucketBriefCommit;\n\tcomment_count: number;\n\ttask_count: number;\n\tclose_source_branch: boolean;\n\tclosed_by: BitbucketUser | null;\n\tauthor: BitbucketUser;\n\treason: string;\n\tcreated_on: string;\n\tupdated_on: string;\n\tdestination: {\n\t\tbranch: BitbucketBranch;\n\t\tcommit: BitbucketBriefCommit;\n\t\trepository: BitbucketRepository;\n\t};\n\tsource: {\n\t\tbranch: BitbucketBranch;\n\t\tcommit: BitbucketBriefCommit;\n\t\trepository: BitbucketRepository;\n\t};\n\tsummary: {\n\t\ttype: 'rendered';\n\t\traw: string;\n\t\tmarkup: string;\n\t\thtml: string;\n\t};\n\treviewers?: BitbucketUser[];\n\tparticipants?: BitbucketPullRequestParticipant[];\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t\tcommits: BitbucketLink;\n\t\tapprove: BitbucketLink;\n\t\t'request-changes': BitbucketLink;\n\t\tdiff: BitbucketLink;\n\t\tdiffstat: BitbucketLink;\n\t\tcomments: BitbucketLink;\n\t\tactivity: BitbucketLink;\n\t\tmerge: BitbucketLink;\n\t\tdecline: BitbucketLink;\n\t\tstatuses: BitbucketLink;\n\t};\n}\n\nexport interface BitbucketIssue {\n\ttype: string;\n\tid: number;\n\ttitle: string;\n\treporter: BitbucketUser;\n\tassignee?: BitbucketUser;\n\tstate: BitbucketIssueState;\n\tcreated_on: string;\n\tupdated_on: string;\n\trepository: BitbucketRepository;\n\tvotes?: number;\n\tcontent: {\n\t\traw: string;\n\t\tmarkup: string;\n\t\thtml: string;\n\t};\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t\tcomments: BitbucketLink;\n\t\tattachments: BitbucketLink;\n\t\twatch: BitbucketLink;\n\t\tvote: BitbucketLink;\n\t};\n}\n\nexport function bitbucketPullRequestStateToState(state: BitbucketPullRequestState): IssueOrPullRequestState {\n\tswitch (state) {\n\t\tcase 'DECLINED':\n\t\tcase 'SUPERSEDED':\n\t\t\treturn 'closed';\n\t\tcase 'MERGED':\n\t\t\treturn 'merged';\n\t\tcase 'OPEN':\n\t\tdefault:\n\t\t\treturn 'opened';\n\t}\n}\n\nexport function bitbucketIssueStateToState(state: BitbucketIssueState): IssueOrPullRequestState {\n\tswitch (state) {\n\t\tcase 'resolved':\n\t\tcase 'invalid':\n\t\tcase 'duplicate':\n\t\tcase 'wontfix':\n\t\tcase 'closed':\n\t\t\treturn 'closed';\n\t\tcase 'submitted':\n\t\tcase 'new':\n\t\tcase 'open':\n\t\tcase 'on hold':\n\t\tdefault:\n\t\t\treturn 'opened';\n\t}\n}\n\nexport function isClosedBitbucketPullRequestState(state: BitbucketPullRequestState): boolean {\n\treturn bitbucketPullRequestStateToState(state) !== 'opened';\n}\n\nexport function isClosedBitbucketIssueState(state: BitbucketIssueState): boolean {\n\treturn bitbucketIssueStateToState(state) !== 'opened';\n}\n\nexport function fromBitbucketUser(user: BitbucketUser): PullRequestMember {\n\treturn {\n\t\tavatarUrl: user.links.avatar.href,\n\t\tname: user.display_name,\n\t\tusername: user.nickname,\n\t\turl: user.links.html.href,\n\t\tid: user.uuid,\n\t};\n}\n\nexport function fromBitbucketParticipantToReviewer(\n\tprt: BitbucketPullRequestParticipant,\n\tclosedBy: BitbucketUser | null,\n\tprState: BitbucketPullRequestState,\n): PullRequestReviewer {\n\treturn {\n\t\treviewer: fromBitbucketUser(prt.user),\n\t\tstate: prt.approved\n\t\t\t? PullRequestReviewState.Approved\n\t\t\t: prt.state === 'changes_requested'\n\t\t\t\t? PullRequestReviewState.ChangesRequested\n\t\t\t\t: prt.participated_on != null\n\t\t\t\t\t? PullRequestReviewState.Commented\n\t\t\t\t\t: prt.user.uuid === closedBy?.uuid && prState === 'DECLINED'\n\t\t\t\t\t\t? PullRequestReviewState.Dismissed\n\t\t\t\t\t\t: PullRequestReviewState.ReviewRequested,\n\t};\n}\n\nfunction getBitbucketReviewDecision(pr: BitbucketPullRequest): PullRequestReviewDecision | undefined {\n\tif (!pr.participants?.length && pr.reviewers?.length) {\n\t\treturn PullRequestReviewDecision.ReviewRequired;\n\t}\n\tif (!pr.participants) {\n\t\treturn undefined;\n\t}\n\n\tlet hasReviews = false;\n\tlet hasChangeRequests = false;\n\tlet hasApprovals = false;\n\tfor (const prt of pr.participants) {\n\t\tif (prt.participated_on != null) {\n\t\t\thasReviews = true;\n\t\t}\n\t\tif (prt.approved) {\n\t\t\thasApprovals = true;\n\t\t}\n\t\tif (prt.state === 'changes_requested') {\n\t\t\thasChangeRequests = true;\n\t\t}\n\t}\n\tif (hasChangeRequests) return PullRequestReviewDecision.ChangesRequested;\n\tif (hasApprovals) return PullRequestReviewDecision.Approved;\n\tif (hasReviews) return undefined; // not approved, not rejected, but reviewed\n\treturn PullRequestReviewDecision.ReviewRequired; // nobody has reviewed yet.\n}\n\nfunction fromBitbucketRepository(repo: BitbucketRepository): IssueRepository {\n\treturn {\n\t\towner: repo.full_name.split('/')[0],\n\t\trepo: repo.name,\n\t\tid: repo.uuid,\n\t\t// TODO: Remove this assumption once actual access level is available\n\t\taccessLevel: RepositoryAccessLevel.Write,\n\t};\n}\n\nexport function fromBitbucketIssue(issue: BitbucketIssue, provider: Provider): Issue {\n\treturn new Issue(\n\t\tprovider,\n\t\tissue.id.toString(),\n\t\tissue.id.toString(),\n\t\tissue.title,\n\t\tissue.links.html.href,\n\t\tnew Date(issue.created_on),\n\t\tnew Date(issue.updated_on),\n\t\tisClosedBitbucketIssueState(issue.state),\n\t\tbitbucketIssueStateToState(issue.state),\n\t\tfromBitbucketUser(issue.reporter),\n\t\tissue.assignee ? [fromBitbucketUser(issue.assignee)] : [],\n\t\tfromBitbucketRepository(issue.repository),\n\t\tundefined, // closedDate\n\t\tundefined, // labels\n\t\tundefined, // commentsCount\n\t\tissue.votes, // thumbsUpCount\n\t\tissue.content.html, // body\n\t\t!issue.repository?.project\n\t\t\t? undefined\n\t\t\t: {\n\t\t\t\t\tid: issue.repository.project.uuid,\n\t\t\t\t\tname: issue.repository.project.name,\n\t\t\t\t\tresourceId: issue.repository.project.uuid,\n\t\t\t\t\tresourceName: issue.repository.project.name,\n\t\t\t\t},\n\t);\n}\n\nexport function fromBitbucketPullRequest(pr: BitbucketPullRequest, provider: Provider): PullRequest {\n\treturn new PullRequest(\n\t\tprovider,\n\t\tfromBitbucketUser(pr.author),\n\t\tpr.id.toString(),\n\t\tpr.id.toString(),\n\t\tpr.title,\n\t\tpr.links.html.href,\n\t\tfromBitbucketRepository(pr.destination.repository),\n\t\tbitbucketPullRequestStateToState(pr.state),\n\t\tnew Date(pr.created_on),\n\t\tnew Date(pr.updated_on),\n\t\tpr.closed_by ? new Date(pr.updated_on) : undefined,\n\t\tpr.state === 'MERGED' ? new Date(pr.updated_on) : undefined,\n\t\t// TODO: Remove this assumption once actual mergeable state is available\n\t\tPullRequestMergeableState.Mergeable, // mergeableState\n\t\tundefined, // viewerCanUpdate\n\t\t{\n\t\t\tbase: {\n\t\t\t\tbranch: pr.destination.branch.name,\n\t\t\t\tsha: pr.destination.commit.hash,\n\t\t\t\trepo: pr.destination.repository.name,\n\t\t\t\towner: pr.destination.repository.full_name.split('/')[0],\n\t\t\t\texists: true,\n\t\t\t\turl: pr.destination.repository.links.html.href,\n\t\t\t},\n\t\t\thead: {\n\t\t\t\tbranch: pr.source.branch.name,\n\t\t\t\tsha: pr.source.commit.hash,\n\t\t\t\trepo: pr.source.repository.name,\n\t\t\t\towner: pr.source.repository.full_name.split('/')[0],\n\t\t\t\texists: true,\n\t\t\t\turl: pr.source.repository.links.html.href,\n\t\t\t},\n\t\t\tisCrossRepository: pr.source.repository.uuid !== pr.destination.repository.uuid,\n\t\t},\n\t\tundefined, // isDraft\n\t\tundefined, // additions\n\t\tundefined, // deletions\n\t\tundefined, // commentsCount\n\t\tundefined, // thumbsCount\n\t\tgetBitbucketReviewDecision(pr),\n\t\tpr.participants // reviewRequests:PullRequestReviewer[]\n\t\t\t?.filter(prt => prt.role === 'REVIEWER')\n\t\t\t.map(prt => fromBitbucketParticipantToReviewer(prt, pr.closed_by, pr.state))\n\t\t\t.filter(rv => rv.state === PullRequestReviewState.ReviewRequested),\n\t\tpr.participants // latestReviews:PullRequestReviewer[]\n\t\t\t?.filter(prt => prt.participated_on != null)\n\t\t\t.map(prt => fromBitbucketParticipantToReviewer(prt, pr.closed_by, pr.state)),\n\t\tundefined, // assignees:PullRequestMember[] -- it looks like there is no such thing as assignees on Bitbucket\n\t\tundefined, // PullRequestStatusCheckRollupState\n\t\tundefined, // IssueProject\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"models.js","names":[],"sources":["../../../../../../plus/integrations/src/providers/bitbucket/models.ts"],"sourcesContent":["import type { IssueRepository } from '@gitlens/git/models/issue.js';\nimport { Issue, RepositoryAccessLevel } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequestState } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type { PullRequestMember, PullRequestReviewer } from '@gitlens/git/models/pullRequest.js';\nimport {\n\tPullRequest,\n\tPullRequestMergeableState,\n\tPullRequestReviewDecision,\n\tPullRequestReviewState,\n} from '@gitlens/git/models/pullRequest.js';\nimport type { Provider } from '@gitlens/git/models/remoteProvider.js';\nimport type { ResourceDescriptor } from '@gitlens/git/models/resourceDescriptor.js';\n\nexport interface BitbucketRepositoryDescriptor extends ResourceDescriptor {\n\towner: string;\n\tname: string;\n}\n\nexport interface BitbucketWorkspaceDescriptor extends ResourceDescriptor {\n\tid: string;\n\tname: string;\n\tslug: string;\n}\n\nexport type BitbucketPullRequestState = 'OPEN' | 'DECLINED' | 'MERGED' | 'SUPERSEDED';\n\ninterface BitbucketLink {\n\thref: string;\n\tname?: string;\n}\n\ninterface BitbucketUser {\n\ttype: 'user';\n\tuuid: string;\n\tdisplay_name: string;\n\taccount_id?: string;\n\tnickname?: string;\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\tavatar: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t};\n}\n\ninterface BitbucketWorkspace {\n\ttype: 'workspace';\n\tuuid: string;\n\tname: string;\n\tslug: string;\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t\tavatar: BitbucketLink;\n\t};\n}\n\ninterface BitbucketProject {\n\ttype: 'project';\n\tkey: string;\n\tuuid: string;\n\tname: string;\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t\tavatar: BitbucketLink;\n\t};\n}\n\ninterface BitbucketPullRequestParticipant {\n\ttype: 'participant';\n\tuser: BitbucketUser;\n\trole: 'PARTICIPANT' | 'REVIEWER';\n\tapproved: boolean;\n\tstate: null | 'approved' | 'changes_requested';\n\tparticipated_on: null | string;\n}\n\nexport interface BitbucketRepository {\n\ttype: 'repository';\n\tuuid: string;\n\tfull_name: string;\n\tname: string;\n\tslug: string;\n\tdescription?: string;\n\tis_private: boolean;\n\tparent: null | BitbucketRepository;\n\tscm: 'git';\n\towner: BitbucketUser;\n\tworkspace: BitbucketWorkspace;\n\tproject: BitbucketProject;\n\tcreated_on: string;\n\tupdated_on: string;\n\tsize: number;\n\tlanguage: string;\n\thas_issues: boolean;\n\thas_wiki: boolean;\n\tfork_policy: 'allow_forks' | 'no_public_forks' | 'no_forks';\n\twebsite: string;\n\tmainbranch?: BitbucketBranch;\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t\tavatar: BitbucketLink;\n\t};\n}\n\ninterface BitbucketCommitAuthor {\n\ttype: 'author';\n\traw: string;\n\tuser: BitbucketUser;\n}\n\ntype BitbucketMergeStrategy =\n\t| 'merge_commit'\n\t| 'squash'\n\t| 'fast_forward'\n\t| 'squash_fast_forward'\n\t| 'rebase_fast_forward'\n\t| 'rebase_merge';\n\ninterface BitbucketBranch {\n\tname: string;\n\tmerge_strategies?: BitbucketMergeStrategy[];\n\tdefault_merge_strategy?: BitbucketMergeStrategy;\n}\n\n// It parses a raw author sitring like \"Sergei Shmakov GK <sergei.shmakov@gitkraken.com>\" to name and email\nconst parseRawBitbucketAuthorRegex = /^(.*) <(.*)>$/;\nexport function parseRawBitbucketAuthor(raw: string): { name: string; email: string } {\n\tconst match = raw.match(parseRawBitbucketAuthorRegex);\n\tif (match) {\n\t\treturn { name: match[1], email: match[2] };\n\t}\n\treturn { name: raw, email: '' };\n}\n\nexport interface BitbucketCommit extends BitbucketBriefCommit {\n\tauthor: BitbucketCommitAuthor;\n\tdate: string;\n\tlinks: {\n\t\tapprove: BitbucketLink;\n\t\tcomments: BitbucketLink;\n\t\tdiff: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t\tself: BitbucketLink;\n\t\tstatuses: BitbucketLink;\n\t};\n\tmessage: string;\n\tparents: BitbucketBriefCommit[];\n\tparticipants: BitbucketPullRequestParticipant[];\n\trendered: {\n\t\tmessage: string;\n\t};\n\trepository: BitbucketRepository;\n\tsummary: {\n\t\ttype: 'rendered';\n\t\traw: string;\n\t\tmarkup: string;\n\t\thtml: string;\n\t};\n}\n\ninterface BitbucketBriefCommit {\n\ttype: 'commit';\n\thash: string;\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t};\n}\n\nexport type BitbucketIssueState =\n\t| 'submitted'\n\t| 'new'\n\t| 'open'\n\t| 'resolved'\n\t| 'on hold'\n\t| 'invalid'\n\t| 'duplicate'\n\t| 'wontfix'\n\t| 'closed';\n\nexport interface BitbucketPullRequest {\n\ttype: 'pullrequest';\n\tid: number;\n\ttitle: string;\n\tdescription: string;\n\tstate: BitbucketPullRequestState;\n\tmerge_commit: null | BitbucketBriefCommit;\n\tcomment_count: number;\n\ttask_count: number;\n\tclose_source_branch: boolean;\n\tclosed_by: BitbucketUser | null;\n\tauthor: BitbucketUser;\n\treason: string;\n\tcreated_on: string;\n\tupdated_on: string;\n\tdestination: {\n\t\tbranch: BitbucketBranch;\n\t\tcommit: BitbucketBriefCommit;\n\t\trepository: BitbucketRepository;\n\t};\n\tsource: {\n\t\tbranch: BitbucketBranch;\n\t\tcommit: BitbucketBriefCommit;\n\t\trepository: BitbucketRepository;\n\t};\n\tsummary: {\n\t\ttype: 'rendered';\n\t\traw: string;\n\t\tmarkup: string;\n\t\thtml: string;\n\t};\n\treviewers?: BitbucketUser[];\n\tparticipants?: BitbucketPullRequestParticipant[];\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t\tcommits: BitbucketLink;\n\t\tapprove: BitbucketLink;\n\t\t'request-changes': BitbucketLink;\n\t\tdiff: BitbucketLink;\n\t\tdiffstat: BitbucketLink;\n\t\tcomments: BitbucketLink;\n\t\tactivity: BitbucketLink;\n\t\tmerge: BitbucketLink;\n\t\tdecline: BitbucketLink;\n\t\tstatuses: BitbucketLink;\n\t};\n}\n\nexport interface BitbucketIssue {\n\ttype: string;\n\tid: number;\n\ttitle: string;\n\treporter: BitbucketUser;\n\tassignee?: BitbucketUser;\n\tstate: BitbucketIssueState;\n\tcreated_on: string;\n\tupdated_on: string;\n\trepository: BitbucketRepository;\n\tvotes?: number;\n\tcontent: {\n\t\traw: string;\n\t\tmarkup: string;\n\t\thtml: string;\n\t};\n\tlinks: {\n\t\tself: BitbucketLink;\n\t\thtml: BitbucketLink;\n\t\tcomments: BitbucketLink;\n\t\tattachments: BitbucketLink;\n\t\twatch: BitbucketLink;\n\t\tvote: BitbucketLink;\n\t};\n}\n\nexport function bitbucketPullRequestStateToState(state: BitbucketPullRequestState): IssueOrPullRequestState {\n\tswitch (state) {\n\t\tcase 'DECLINED':\n\t\tcase 'SUPERSEDED':\n\t\t\treturn 'closed';\n\t\tcase 'MERGED':\n\t\t\treturn 'merged';\n\t\tcase 'OPEN':\n\t\tdefault:\n\t\t\treturn 'opened';\n\t}\n}\n\nexport function bitbucketIssueStateToState(state: BitbucketIssueState): IssueOrPullRequestState {\n\tswitch (state) {\n\t\tcase 'resolved':\n\t\tcase 'invalid':\n\t\tcase 'duplicate':\n\t\tcase 'wontfix':\n\t\tcase 'closed':\n\t\t\treturn 'closed';\n\t\tcase 'submitted':\n\t\tcase 'new':\n\t\tcase 'open':\n\t\tcase 'on hold':\n\t\tdefault:\n\t\t\treturn 'opened';\n\t}\n}\n\nexport function isClosedBitbucketPullRequestState(state: BitbucketPullRequestState): boolean {\n\treturn bitbucketPullRequestStateToState(state) !== 'opened';\n}\n\nexport function isClosedBitbucketIssueState(state: BitbucketIssueState): boolean {\n\treturn bitbucketIssueStateToState(state) !== 'opened';\n}\n\nexport function fromBitbucketUser(user: BitbucketUser): PullRequestMember {\n\treturn {\n\t\tavatarUrl: user.links.avatar.href,\n\t\tname: user.display_name,\n\t\tusername: user.nickname,\n\t\turl: user.links.html.href,\n\t\tid: user.uuid,\n\t};\n}\n\nexport function fromBitbucketParticipantToReviewer(\n\tprt: BitbucketPullRequestParticipant,\n\tclosedBy: BitbucketUser | null,\n\tprState: BitbucketPullRequestState,\n): PullRequestReviewer {\n\treturn {\n\t\treviewer: fromBitbucketUser(prt.user),\n\t\tstate: prt.approved\n\t\t\t? PullRequestReviewState.Approved\n\t\t\t: prt.state === 'changes_requested'\n\t\t\t\t? PullRequestReviewState.ChangesRequested\n\t\t\t\t: prt.participated_on != null\n\t\t\t\t\t? PullRequestReviewState.Commented\n\t\t\t\t\t: prt.user.uuid === closedBy?.uuid && prState === 'DECLINED'\n\t\t\t\t\t\t? PullRequestReviewState.Dismissed\n\t\t\t\t\t\t: PullRequestReviewState.ReviewRequested,\n\t};\n}\n\nfunction getBitbucketReviewDecision(pr: BitbucketPullRequest): PullRequestReviewDecision | undefined {\n\tif (!pr.participants?.length && pr.reviewers?.length) {\n\t\treturn PullRequestReviewDecision.ReviewRequired;\n\t}\n\tif (!pr.participants) {\n\t\treturn undefined;\n\t}\n\n\tlet hasReviews = false;\n\tlet hasChangeRequests = false;\n\tlet hasApprovals = false;\n\tfor (const prt of pr.participants) {\n\t\tif (prt.participated_on != null) {\n\t\t\thasReviews = true;\n\t\t}\n\t\tif (prt.approved) {\n\t\t\thasApprovals = true;\n\t\t}\n\t\tif (prt.state === 'changes_requested') {\n\t\t\thasChangeRequests = true;\n\t\t}\n\t}\n\tif (hasChangeRequests) return PullRequestReviewDecision.ChangesRequested;\n\tif (hasApprovals) return PullRequestReviewDecision.Approved;\n\tif (hasReviews) return undefined; // not approved, not rejected, but reviewed\n\treturn PullRequestReviewDecision.ReviewRequired; // nobody has reviewed yet.\n}\n\nfunction fromBitbucketRepository(repo: BitbucketRepository): IssueRepository {\n\treturn {\n\t\towner: repo.full_name.split('/')[0],\n\t\trepo: repo.name,\n\t\tid: repo.uuid,\n\t\t// TODO: Remove this assumption once actual access level is available\n\t\taccessLevel: RepositoryAccessLevel.Write,\n\t};\n}\n\nexport function fromBitbucketIssue(issue: BitbucketIssue, provider: Provider): Issue {\n\treturn new Issue(\n\t\tprovider,\n\t\tissue.id.toString(),\n\t\tissue.id.toString(),\n\t\tissue.title,\n\t\tissue.links.html.href,\n\t\tnew Date(issue.created_on),\n\t\tnew Date(issue.updated_on),\n\t\tisClosedBitbucketIssueState(issue.state),\n\t\tbitbucketIssueStateToState(issue.state),\n\t\tfromBitbucketUser(issue.reporter),\n\t\tissue.assignee ? [fromBitbucketUser(issue.assignee)] : [],\n\t\tfromBitbucketRepository(issue.repository),\n\t\tundefined, // closedDate\n\t\tundefined, // labels\n\t\tundefined, // commentsCount\n\t\tissue.votes, // thumbsUpCount\n\t\tissue.content.html, // body\n\t\t!issue.repository?.project\n\t\t\t? undefined\n\t\t\t: {\n\t\t\t\t\tid: issue.repository.project.uuid,\n\t\t\t\t\tname: issue.repository.project.name,\n\t\t\t\t\tresourceId: issue.repository.project.uuid,\n\t\t\t\t\tresourceName: issue.repository.project.name,\n\t\t\t\t},\n\t);\n}\n\nexport function fromBitbucketPullRequest(\n\tpr: BitbucketPullRequest,\n\tprovider: Provider,\n\toptions?: { currentAccount?: { id: string; username?: string } },\n): PullRequest {\n\tconst author = fromBitbucketUser(pr.author);\n\treturn new PullRequest(\n\t\tprovider,\n\t\tauthor,\n\t\tpr.id.toString(),\n\t\tpr.id.toString(),\n\t\tpr.title,\n\t\tpr.links.html.href,\n\t\tfromBitbucketRepository(pr.destination.repository),\n\t\tbitbucketPullRequestStateToState(pr.state),\n\t\tnew Date(pr.created_on),\n\t\tnew Date(pr.updated_on),\n\t\tpr.closed_by ? new Date(pr.updated_on) : undefined,\n\t\tpr.state === 'MERGED' ? new Date(pr.updated_on) : undefined,\n\t\t// TODO: Remove this assumption once actual mergeable state is available\n\t\tPullRequestMergeableState.Mergeable, // mergeableState\n\t\tundefined, // viewerCanUpdate\n\t\t{\n\t\t\tbase: {\n\t\t\t\tbranch: pr.destination.branch.name,\n\t\t\t\tsha: pr.destination.commit.hash,\n\t\t\t\trepo: pr.destination.repository.name,\n\t\t\t\towner: pr.destination.repository.full_name.split('/')[0],\n\t\t\t\texists: true,\n\t\t\t\turl: pr.destination.repository.links.html.href,\n\t\t\t},\n\t\t\thead: {\n\t\t\t\tbranch: pr.source.branch.name,\n\t\t\t\tsha: pr.source.commit.hash,\n\t\t\t\trepo: pr.source.repository.name,\n\t\t\t\towner: pr.source.repository.full_name.split('/')[0],\n\t\t\t\texists: true,\n\t\t\t\turl: pr.source.repository.links.html.href,\n\t\t\t},\n\t\t\tisCrossRepository: pr.source.repository.uuid !== pr.destination.repository.uuid,\n\t\t},\n\t\tundefined, // isDraft\n\t\tundefined, // additions\n\t\tundefined, // deletions\n\t\tundefined, // commentsCount\n\t\tundefined, // thumbsCount\n\t\tgetBitbucketReviewDecision(pr),\n\t\tpr.participants // reviewRequests:PullRequestReviewer[]\n\t\t\t?.filter(prt => prt.role === 'REVIEWER')\n\t\t\t.map(prt => fromBitbucketParticipantToReviewer(prt, pr.closed_by, pr.state))\n\t\t\t.filter(rv => rv.state === PullRequestReviewState.ReviewRequested),\n\t\tpr.participants // latestReviews:PullRequestReviewer[]\n\t\t\t?.filter(prt => prt.participated_on != null)\n\t\t\t.map(prt => fromBitbucketParticipantToReviewer(prt, pr.closed_by, pr.state)),\n\t\tundefined, // assignees:PullRequestMember[] -- it looks like there is no such thing as assignees on Bitbucket\n\t\tundefined, // PullRequestStatusCheckRollupState\n\t\tundefined, // IssueProject\n\t\tundefined, // version\n\t\tundefined, // commitCount\n\t\tundefined, // stack\n\t\tundefined, // filesChanged\n\t\tpr.description ?? undefined,\n\t\tpr.id,\n\t\toptions?.currentAccount != null ? author.id === options.currentAccount.id : undefined,\n\t);\n}\n"],"mappings":";;;AA+HA,MAAM,+BAA+B;AACrC,SAAgB,wBAAwB,KAA8C;CACrF,MAAM,QAAQ,IAAI,MAAM,4BAA4B;CACpD,IAAI,OACH,OAAO;EAAE,MAAM,MAAM;EAAI,OAAO,MAAM;CAAG;CAE1C,OAAO;EAAE,MAAM;EAAK,OAAO;CAAG;AAC/B;AA2HA,SAAgB,iCAAiC,OAA2D;CAC3G,QAAQ,OAAR;EACC,KAAK;EACL,KAAK,cACJ,OAAO;EACR,KAAK,UACJ,OAAO;EAER,SACC,OAAO;CACT;AACD;AAEA,SAAgB,2BAA2B,OAAqD;CAC/F,QAAQ,OAAR;EACC,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,UACJ,OAAO;EAKR,SACC,OAAO;CACT;AACD;AAEA,SAAgB,kCAAkC,OAA2C;CAC5F,OAAO,iCAAiC,KAAK,MAAM;AACpD;AAEA,SAAgB,4BAA4B,OAAqC;CAChF,OAAO,2BAA2B,KAAK,MAAM;AAC9C;AAEA,SAAgB,kBAAkB,MAAwC;CACzE,OAAO;EACN,WAAW,KAAK,MAAM,OAAO;EAC7B,MAAM,KAAK;EACX,UAAU,KAAK;EACf,KAAK,KAAK,MAAM,KAAK;EACrB,IAAI,KAAK;CACV;AACD;AAEA,SAAgB,mCACf,KACA,UACA,SACsB;CACtB,OAAO;EACN,UAAU,kBAAkB,IAAI,IAAI;EACpC,OAAO,IAAI,WAAA,aAER,IAAI,UAAU,sBAAA,sBAEb,IAAI,mBAAmB,OAAA,cAEtB,IAAI,KAAK,SAAS,UAAU,QAAQ,YAAY,aAAA,cAAA;CAGtD;AACD;AAEA,SAAS,2BAA2B,IAAiE;CACpG,IAAI,CAAC,GAAG,cAAc,UAAU,GAAG,WAAW,QAC7C,OAAA;CAED,IAAI,CAAC,GAAG,cACP;CAGD,IAAI,aAAa;CACjB,IAAI,oBAAoB;CACxB,IAAI,eAAe;CACnB,KAAK,MAAM,OAAO,GAAG,cAAc;EAClC,IAAI,IAAI,mBAAmB,MAC1B,aAAa;EAEd,IAAI,IAAI,UACP,eAAe;EAEhB,IAAI,IAAI,UAAU,qBACjB,oBAAoB;CAEtB;CACA,IAAI,mBAAmB,OAAA;CACvB,IAAI,cAAc,OAAA;CAClB,IAAI,YAAY,OAAO,KAAA;CACvB,OAAA;AACD;AAEA,SAAS,wBAAwB,MAA4C;CAC5E,OAAO;EACN,OAAO,KAAK,UAAU,MAAM,GAAG,CAAC,CAAC;EACjC,MAAM,KAAK;EACX,IAAI,KAAK;EAET,aAAA;CACD;AACD;AAEA,SAAgB,mBAAmB,OAAuB,UAA2B;CACpF,OAAO,IAAI,MACV,UACA,MAAM,GAAG,SAAS,GAClB,MAAM,GAAG,SAAS,GAClB,MAAM,OACN,MAAM,MAAM,KAAK,MACjB,IAAI,KAAK,MAAM,UAAU,GACzB,IAAI,KAAK,MAAM,UAAU,GACzB,4BAA4B,MAAM,KAAK,GACvC,2BAA2B,MAAM,KAAK,GACtC,kBAAkB,MAAM,QAAQ,GAChC,MAAM,WAAW,CAAC,kBAAkB,MAAM,QAAQ,CAAC,IAAI,CAAC,GACxD,wBAAwB,MAAM,UAAU,GACxC,KAAA,GACA,KAAA,GACA,KAAA,GACA,MAAM,OACN,MAAM,QAAQ,MACd,CAAC,MAAM,YAAY,UAChB,KAAA,IACA;EACA,IAAI,MAAM,WAAW,QAAQ;EAC7B,MAAM,MAAM,WAAW,QAAQ;EAC/B,YAAY,MAAM,WAAW,QAAQ;EACrC,cAAc,MAAM,WAAW,QAAQ;CACxC,CACH;AACD;AAEA,SAAgB,yBACf,IACA,UACA,SACc;CACd,MAAM,SAAS,kBAAkB,GAAG,MAAM;CAC1C,OAAO,IAAI,YACV,UACA,QACA,GAAG,GAAG,SAAS,GACf,GAAG,GAAG,SAAS,GACf,GAAG,OACH,GAAG,MAAM,KAAK,MACd,wBAAwB,GAAG,YAAY,UAAU,GACjD,iCAAiC,GAAG,KAAK,GACzC,IAAI,KAAK,GAAG,UAAU,GACtB,IAAI,KAAK,GAAG,UAAU,GACtB,GAAG,YAAY,IAAI,KAAK,GAAG,UAAU,IAAI,KAAA,GACzC,GAAG,UAAU,WAAW,IAAI,KAAK,GAAG,UAAU,IAAI,KAAA,GAAA,aAGlD,KAAA,GACA;EACC,MAAM;GACL,QAAQ,GAAG,YAAY,OAAO;GAC9B,KAAK,GAAG,YAAY,OAAO;GAC3B,MAAM,GAAG,YAAY,WAAW;GAChC,OAAO,GAAG,YAAY,WAAW,UAAU,MAAM,GAAG,CAAC,CAAC;GACtD,QAAQ;GACR,KAAK,GAAG,YAAY,WAAW,MAAM,KAAK;EAC3C;EACA,MAAM;GACL,QAAQ,GAAG,OAAO,OAAO;GACzB,KAAK,GAAG,OAAO,OAAO;GACtB,MAAM,GAAG,OAAO,WAAW;GAC3B,OAAO,GAAG,OAAO,WAAW,UAAU,MAAM,GAAG,CAAC,CAAC;GACjD,QAAQ;GACR,KAAK,GAAG,OAAO,WAAW,MAAM,KAAK;EACtC;EACA,mBAAmB,GAAG,OAAO,WAAW,SAAS,GAAG,YAAY,WAAW;CAC5E,GACA,KAAA,GACA,KAAA,GACA,KAAA,GACA,KAAA,GACA,KAAA,GACA,2BAA2B,EAAE,GAC7B,GAAG,cACA,QAAO,QAAO,IAAI,SAAS,UAAU,CAAC,CACvC,KAAI,QAAO,mCAAmC,KAAK,GAAG,WAAW,GAAG,KAAK,CAAC,CAAC,CAC3E,QAAO,OAAM,GAAG,UAAA,kBAAgD,GAClE,GAAG,cACA,QAAO,QAAO,IAAI,mBAAmB,IAAI,CAAC,CAC3C,KAAI,QAAO,mCAAmC,KAAK,GAAG,WAAW,GAAG,KAAK,CAAC,GAC5E,KAAA,GACA,KAAA,GACA,KAAA,GACA,KAAA,GACA,KAAA,GACA,KAAA,GACA,KAAA,GACA,GAAG,eAAe,KAAA,GAClB,GAAG,IACH,SAAS,kBAAkB,OAAO,OAAO,OAAO,QAAQ,eAAe,KAAK,KAAA,CAC7E;AACD"}
|
|
@@ -5,10 +5,10 @@ import { AuthenticationError } from "../../../../git/errors.js";
|
|
|
5
5
|
import { getNonce, sha256 } from "../../../../utils/crypto.js";
|
|
6
6
|
import "../../../../git/models/pullRequest.js";
|
|
7
7
|
import { getPullRequestComparator } from "../../../../git/utils/pullRequest.utils.js";
|
|
8
|
+
import { throwProviderError } from "../providerErrors.js";
|
|
8
9
|
import { toCollectionScopeFailure } from "../../collectionMetadata.js";
|
|
9
10
|
import { fromProviderPullRequest } from "../models.js";
|
|
10
11
|
import { normalizeBitbucketServerPullRequest } from "./models.js";
|
|
11
|
-
import { throwProviderError } from "../providerErrors.js";
|
|
12
12
|
//#region ../plus/integrations/src/providers/bitbucket-server/pullRequestSearch.ts
|
|
13
13
|
/**
|
|
14
14
|
* The relationships Bitbucket Data Center can express, in the canonical order its facets (and so its cursor) are
|
|
@@ -118,7 +118,7 @@ async function searchBitbucketServerPullRequestsPage(request, token, options, ca
|
|
|
118
118
|
truncated
|
|
119
119
|
};
|
|
120
120
|
return {
|
|
121
|
-
values: values.map((pr) => fromProviderPullRequest(pr, options.provider, {
|
|
121
|
+
values: values.map((pr) => fromProviderPullRequest(pr, options.provider, { currentAccount: options.currentUser?.id != null ? { id: options.currentUser.id } : void 0 })).sort(comparator),
|
|
122
122
|
cursor: hasMore ? JSON.stringify({
|
|
123
123
|
key,
|
|
124
124
|
page: cursor.page + 1,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pullRequestSearch.js","names":[],"sources":["../../../../../../plus/integrations/src/providers/bitbucket-server/pullRequestSearch.ts"],"sourcesContent":["import type { CollectionScope, CollectionScopeFailure, CollectionScopeFailureKind } from '@gitkraken/provider-apis';\nimport type {\n\tPullRequestSearchCriteria,\n\tPullRequestSorting,\n\tPullRequestStateFilter,\n} from '@gitlens/git/models/pullRequest.js';\nimport { defaultPullRequestSort, PullRequestFilter } from '@gitlens/git/models/pullRequest.js';\nimport type { Provider } from '@gitlens/git/models/remoteProvider.js';\nimport { getPullRequestComparator } from '@gitlens/git/utils/pullRequest.utils.js';\nimport { CancellationError, isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { getNonce, sha256 } from '@gitlens/utils/crypto.js';\nimport { Logger } from '@gitlens/utils/logger.js';\nimport { mapSettledBounded } from '@gitlens/utils/promise.js';\nimport type { TokenWithInfo } from '../../authentication/models.js';\nimport { toCollectionScopeFailure } from '../../collectionMetadata.js';\nimport type { GitSelfManagedHostIntegrationId } from '../../constants.js';\nimport { AuthenticationError, AuthenticationErrorReason } from '../../errors.js';\nimport type { ProviderPullRequestCount, ProviderPullRequestSearchPage } from '../../models/pullRequestReads.js';\nimport type { ProviderPullRequest, ProviderRepoInput, ProviderRequestFunction } from '../models.js';\nimport { fromProviderPullRequest } from '../models.js';\nimport { throwProviderError } from '../providerErrors.js';\nimport type {\n\tBitbucketServerPagedResponse,\n\tBitbucketServerPullRequest,\n\tBitbucketServerPullRequestUser,\n\tBitbucketServerUser,\n} from './models.js';\nimport { normalizeBitbucketServerPullRequest } from './models.js';\n\ntype Token = TokenWithInfo<GitSelfManagedHostIntegrationId.BitbucketServer>;\ntype BitbucketServerPullRequestState = BitbucketServerPullRequest['state'];\n\n/**\n * The relationships Bitbucket Data Center can express, in the canonical order its facets (and so its cursor) are\n * built in. A Bitbucket pull request has no assignee, and none of its pull-request endpoints filter by mention.\n */\nconst relationships = [\n\tPullRequestFilter.Author,\n\tPullRequestFilter.ReviewRequested,\n\tPullRequestFilter.Reviewed,\n] as const;\ntype Relationship = (typeof relationships)[number];\n\n/** The current user, which both the server-side participant filters and their client-side re-check identify. */\nexport interface BitbucketServerSearchUser {\n\tid: string;\n\tusername: string;\n}\n\n/**\n * One provider query of the search: a repository or the current user's dashboard, times one relationship.\n *\n * A repository facet reads `/projects/{key}/repos/{slug}/pull-requests`, which filters participants, text and draft\n * state server-side, so a page narrowed to a few repositories holds only matches. Without repositories a relationship\n * reads `/dashboard/pull-requests`, the only cross-repository pull-request list Bitbucket Data Center has; it can't\n * filter text or draft state, so those are re-checked on its rows. There is no project-wide list at all, which is\n * why the capability declares no organization scope.\n *\n * States are not a facet axis: every facet asks the server for the one requested state, or for every state when\n * several are requested, and keeps the requested ones — reading the unrequested rows rather than spending one more\n * request per state.\n */\ninterface Facet {\n\trepo?: ProviderRepoInput;\n\trelationship?: Relationship;\n\t/**\n\t * The dashboard role a `Reviewed` facet reads. The dashboard only applies `participantStatus` together with\n\t * `role` — without one it returns every pull request the user is involved in, authored ones included, whatever\n\t * the status — so `Reviewed` is read as two facets, the reviewer list and the (non-reviewer) participant list,\n\t * each filtered by status server-side. Absent for every other facet.\n\t */\n\trole?: DashboardRole;\n}\n\ntype DashboardRole = 'REVIEWER' | 'PARTICIPANT';\n\ninterface SearchOptions {\n\tbaseUrl: string;\n\trepos?: ProviderRepoInput[];\n\t/** Refused when set: Bitbucket Data Center has no project-wide pull-request list to scope it to. */\n\torg?: string;\n\tcriteria?: PullRequestSearchCriteria;\n\t/** Required when `criteria.relationships` is non-empty. */\n\tcurrentUser?: BitbucketServerSearchUser;\n}\n\n/** A resolved query, shared by every facet of one search or count. */\ninterface Query extends SearchOptions {\n\tfacets: Facet[];\n\t/** The requested relationships, in canonical order — the order {@link ownsRow} gives a shared row to. */\n\trelationships: Relationship[];\n\t/** The requested states, or `undefined` for every state. */\n\tstates: Set<BitbucketServerPullRequestState> | undefined;\n\tsort: PullRequestSorting;\n}\n\n/** Bitbucket answers an unspecified page size with 25; a search page asks for this many per facet instead. */\nconst defaultSearchPageSize = 30;\n/**\n * The server's own cap on a page (`page.max.pullrequests`, 1000 unless an administrator lowered it), and the one\n * page a count reads per facet: past it the count is a floor rather than more of a customer-run server's capacity\n * spent on a figure the caller uses as a cost hint.\n */\nconst maxPageSize = 1000;\n/** Matches the SDK's own cap on concurrent Bitbucket Data Center pull-request requests. */\nconst facetConcurrency = 5;\n\n/** The server states each facade state covers. `closed` is two, so it can't be sent as one `state` filter. */\nconst pullRequestStates: Record<Exclude<PullRequestStateFilter, 'all'>, BitbucketServerPullRequestState[]> = {\n\topen: ['OPEN'],\n\tclosed: ['DECLINED', 'SUPERSEDED'],\n\tmerged: ['MERGED'],\n};\n\nconst orderParams: Partial<Record<PullRequestSorting, string>> = {\n\t'updated:desc': 'NEWEST',\n\t'updated:asc': 'OLDEST',\n};\n\n/**\n * Pull requests matching `criteria` over the requested repositories, or over the current user's relationships when\n * none are given.\n *\n * Every facet reads its own page, and the merged page is re-ordered as a whole. Each facet keeps its own\n * `nextPageStart` in the cursor, which is bound to this connection, installation and query: a cursor handed back\n * under anything else is refused rather than read as page 1 of a different search. A pull request several\n * relationships match is served by exactly one of them, the first in canonical order (see {@link ownsRow}), so facets\n * that advance independently never serve it twice across pages and the cursor carries no history of what it emitted.\n *\n * Every criterion the server applies is applied again to the rows it returns, so a server that ignores a parameter\n * (one older than 8.18, which shipped drafts, has no `draft`) narrows the page instead of silently widening it.\n *\n * A facet that fails is reported in `metadata` while its siblings still answer, and keeps its offset, so the next page\n * retries the page it missed — a transient failure recovers the rows it cost. A facet that fails its retry too is\n * dropped, and reported on every later page, which no longer reads it; one retry keeps a facet that will never answer\n * from holding `hasMore` open forever. If every facet fails on the first page, the first failure is thrown instead.\n */\nexport async function searchBitbucketServerPullRequestsPage(\n\trequest: ProviderRequestFunction,\n\ttoken: Token,\n\toptions: SearchOptions & { connectionId: string; provider: Provider; cursor?: string; pageSize?: number },\n\tcancellation?: AbortSignal,\n): Promise<ProviderPullRequestSearchPage> {\n\tconst query = toQuery(options);\n\tconst comparator = getPullRequestComparator(query.sort)!;\n\tconst key = await getCursorKey(options.connectionId, query);\n\tconst cursor = await parseCursor(options.cursor, key, query.facets);\n\tconst active = query.facets.flatMap((facet, index) =>\n\t\tcursor.starts[index] != null ? [{ facet: facet, start: cursor.starts[index], index: index }] : [],\n\t);\n\t// A facet dropped on an earlier page is gone from this one's reads, and the hole is still in the result.\n\tconst failed = [...cursor.failed];\n\tconst failures = failed.map(f => toEarlierFailure(token, query.facets[f.facet], f.kind));\n\tconst retrying: number[] = [];\n\tif (active.length === 0) {\n\t\treturn {\n\t\t\tvalues: [],\n\t\t\thasMore: false,\n\t\t\tpage: cursor.page,\n\t\t\ttruncated: cursor.truncated,\n\t\t\tmetadata: toMetadata(failures),\n\t\t};\n\t}\n\n\tconst limit = Math.min(maxPageSize, Math.max(1, Math.trunc(options.pageSize ?? defaultSearchPageSize)));\n\tconst results = await mapSettledBounded(active, facetConcurrency, ({ facet, start }) =>\n\t\treadFacetPage(request, token, query, facet, start, limit, false, cancellation),\n\t);\n\tconst rejected = results.filter((r): r is PromiseRejectedResult => r.status === 'rejected');\n\tconst cancelled = rejected.find(r => isCancellationError(r.reason));\n\tif (cancelled != null) throw cancelled.reason;\n\n\t// A rejected credential is the connection failing rather than one scope, so it is thrown on any page: the\n\t// integration's session recovery then runs once, from the thrown error, and the failure is never carried in the\n\t// cursor where every later page would report it again. (A repository refusing the token isn't one; see\n\t// `toFacetError`.)\n\tconst credential = rejected.find(r => r.reason instanceof AuthenticationError);\n\tif (credential != null) throw credential.reason;\n\t// Only a first page on which every facet failed is a failed read. On a later page an earlier one already proved\n\t// some facet answered, so the rows it served stand and this page's failures join the partial-result report.\n\tif (cursor.page === 1 && rejected.length === results.length) throw rejected[0].reason;\n\n\tconst nextStarts: (number | null)[] = cursor.starts.map(() => null);\n\tconst values: ProviderPullRequest[] = [];\n\tlet truncated = cursor.truncated;\n\tfor (let i = 0; i < results.length; i++) {\n\t\tconst { facet, index } = active[i];\n\t\tconst result = results[i];\n\t\tif (result.status === 'rejected') {\n\t\t\tconst failure = toCollectionScopeFailure(toCollectionScope(token, facet), result.reason);\n\t\t\tfailures.push(failure);\n\t\t\tif (cursor.retrying.includes(index)) {\n\t\t\t\t// Its retry failed too: dropped, and carried so every later page still reports the hole.\n\t\t\t\tfailed.push({ facet: index, kind: failure.kind });\n\t\t\t} else {\n\t\t\t\t// Kept at the offset it missed, so the next page retries it.\n\t\t\t\tnextStarts[index] = active[i].start;\n\t\t\t\tretrying.push(index);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tnextStarts[index] = result.value.next;\n\t\ttruncated ||= result.value.stalled;\n\t\tfor (const { raw, normalized } of result.value.matches) {\n\t\t\t// Another relationship owns a row they both match, and serves it from its own facet on whichever page\n\t\t\t// reaches it — which also settles two facets reaching it on this one.\n\t\t\tif (!ownsRow(raw, facet, query)) continue;\n\n\t\t\tvalues.push(normalized);\n\t\t}\n\t}\n\n\tconst hasMore = nextStarts.some(start => start != null);\n\t// Written on every continuation, complete or not, so removing it can't pass an incomplete read off as complete.\n\tconst state = { failed: failed, retrying: retrying, truncated: truncated };\n\treturn {\n\t\tvalues: values\n\t\t\t.map(pr => fromProviderPullRequest(pr, options.provider, { currentAccountId: options.currentUser?.id }))\n\t\t\t.sort(comparator),\n\t\tcursor: hasMore\n\t\t\t? JSON.stringify({\n\t\t\t\t\tkey: key,\n\t\t\t\t\tpage: cursor.page + 1,\n\t\t\t\t\tstarts: nextStarts,\n\t\t\t\t\tstate: { ...state, signature: await signState(key, cursor.page + 1, nextStarts, state) },\n\t\t\t\t})\n\t\t\t: undefined,\n\t\thasMore: hasMore,\n\t\tpage: cursor.page,\n\t\ttruncated: truncated,\n\t\tmetadata: toMetadata(failures),\n\t};\n}\n\nfunction toMetadata(failures: CollectionScopeFailure[]): ProviderPullRequestSearchPage['metadata'] {\n\treturn failures.length > 0 ? { completeness: 'partial', failures: failures } : undefined;\n}\n\n/**\n * A facet failure carried over from an earlier page, rebuilt from the query rather than from the cursor: the cursor\n * records only which facet failed and how, so it can't name a scope or a message the read never produced.\n */\nfunction toEarlierFailure(token: Token, facet: Facet, kind: CollectionScopeFailureKind): CollectionScopeFailure {\n\treturn {\n\t\tscope: toCollectionScope(token, facet),\n\t\tkind: kind,\n\t\tmessage: 'Failed on an earlier page of this search, so later pages did not read it',\n\t};\n}\n\n/**\n * How many pull requests match `criteria`: the same facets, predicates and identity the search uses, so the count\n * is the number of distinct rows the search would return — the union of the requested states, not the largest of\n * them, since Bitbucket has no per-search ceiling for a maximum to stay under.\n *\n * Bitbucket Data Center has no count query and reports no total, so each facet reads one page of up to\n * {@link maxPageSize} and the count is a floor (`lowerBound`) when any facet had more. Unlike the search, one failed\n * facet fails the whole count: a count missing a facet is a wrong number rather than a partial one.\n */\nexport async function countBitbucketServerPullRequests(\n\trequest: ProviderRequestFunction,\n\ttoken: Token,\n\toptions: SearchOptions,\n\tcancellation?: AbortSignal,\n): Promise<ProviderPullRequestCount> {\n\tconst query = toQuery(options);\n\tconst seen = new Set<string>();\n\tlet lowerBound = false;\n\t// One facet at a time: the facade already counts several scopes concurrently.\n\tfor (const facet of query.facets) {\n\t\tconst result = await readFacetPage(request, token, query, facet, 0, maxPageSize, true, cancellation);\n\t\tfor (const { raw } of result.matches) {\n\t\t\tseen.add(toIdentity(raw));\n\t\t}\n\t\tlowerBound ||= result.next != null || result.stalled;\n\t}\n\n\treturn { count: seen.size, lowerBound: lowerBound || undefined };\n}\n\n/**\n * Resolves the criteria into the facets and predicates every page applies, refusing — by throwing, which the read\n * reports as a failed request — anything the capability table does not declare. The facade validates the same\n * table first, so reaching a refusal here means a caller bypassed it; refusing rather than dropping the criterion\n * keeps that caller from reading a wider set than it asked for.\n */\nfunction toQuery(options: SearchOptions): Query {\n\tif (options.org != null && options.org.length > 0) {\n\t\tthrow new Error('Bitbucket Data Center cannot scope a pull request search to a project');\n\t}\n\n\tconst criteria = options.criteria;\n\t// No endpoint filters by date, and filtering the rows read would page through everything before the cutoff.\n\tif (criteria?.updatedAfter != null || criteria?.createdAfter != null) {\n\t\tthrow new Error('Bitbucket Data Center cannot filter a pull request search by date');\n\t}\n\n\tconst sort = criteria?.sort ?? defaultPullRequestSort;\n\tif (orderParams[sort] == null) {\n\t\tthrow new Error(`Bitbucket Data Center cannot order a pull request search by '${sort}'`);\n\t}\n\n\tconst requested = criteria?.relationships ?? [];\n\tconst unsupported = requested.find(r => !(relationships as readonly PullRequestFilter[]).includes(r));\n\tif (unsupported != null) {\n\t\tthrow new Error(`Bitbucket Data Center cannot search pull requests by the '${unsupported}' relationship`);\n\t}\n\n\tconst facetRelationships = relationships.filter(r => requested.includes(r));\n\tif (facetRelationships.length > 0 && options.currentUser == null) {\n\t\tthrow new Error('A Bitbucket Data Center relationship search requires the current user');\n\t}\n\n\tconst requestedStates: PullRequestStateFilter[] = criteria?.states?.length ? criteria.states : ['open'];\n\tconst states = requestedStates.includes('all')\n\t\t? undefined\n\t\t: new Set(requestedStates.flatMap(s => pullRequestStates[s as Exclude<PullRequestStateFilter, 'all'>]));\n\n\t// Sorted and deduplicated so the facets, and so the cursor, don't depend on the order repositories were passed.\n\tconst repos = [...new Map((options.repos ?? []).map(r => [repoKey(r), r])).entries()]\n\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t.map(([, repo]) => repo);\n\tfor (const repo of repos) {\n\t\tfor (const segment of [repo.namespace, repo.name]) {\n\t\t\tif (!segment || segment === '.' || segment === '..') {\n\t\t\t\tthrow new Error('Invalid Bitbucket Data Center repository for a pull request search');\n\t\t\t}\n\t\t}\n\t}\n\n\tlet facets: Facet[];\n\tif (repos.length > 0) {\n\t\tconst scoped = facetRelationships.length > 0 ? facetRelationships : [undefined];\n\t\tfacets = repos.flatMap(repo => scoped.map(relationship => ({ repo: repo, relationship: relationship })));\n\t} else if (facetRelationships.length > 0) {\n\t\tfacets = facetRelationships.flatMap<Facet>(relationship =>\n\t\t\trelationship === PullRequestFilter.Reviewed\n\t\t\t\t? [\n\t\t\t\t\t\t{ relationship: relationship, role: 'REVIEWER' },\n\t\t\t\t\t\t{ relationship: relationship, role: 'PARTICIPANT' },\n\t\t\t\t\t]\n\t\t\t\t: [{ relationship: relationship }],\n\t\t);\n\t} else {\n\t\tthrow new Error('A Bitbucket Data Center pull request search must be scoped by repositories or a relationship');\n\t}\n\n\treturn { ...options, facets: facets, relationships: facetRelationships, states: states, sort: sort };\n}\n\n/** Project keys and repository slugs resolve case-insensitively, so two spellings name one repository. */\nfunction repoKey(repo: ProviderRepoInput): string {\n\treturn `${repo.namespace}/${repo.name}`.toLowerCase();\n}\n\n/**\n * A facet's classified failure, with the one correction the provider-wide classification can't make: a 403 on a\n * REPOSITORY is Bitbucket refusing that repository (the token lacks `REPO_READ` there), not the credential failing.\n *\n * Made here, where every read of a facet passes, so the search and the count can't disagree about it on any path —\n * a sibling repository's failure, a first page where every repository failed, or a count. Left an\n * `AuthenticationError`, it would reach the integration's exception handling and mark a connection that works\n * everywhere else for recovery and toward disconnecting; as a plain error naming the repository it is reported as\n * that scope's failure alone. A 401 anywhere, and a 403 on the user's own dashboard, stay the credential failing.\n */\nfunction toFacetError(ex: unknown, facet: Facet): unknown {\n\tif (!(ex instanceof AuthenticationError) || facet.repo == null) return ex;\n\tif (ex.reason !== AuthenticationErrorReason.Forbidden) return ex;\n\n\treturn new Error(\n\t\t`Bitbucket Data Center refused access to ${facet.repo.namespace}/${facet.repo.name}: ${(ex.original ?? ex).message}`,\n\t\t{ cause: ex },\n\t);\n}\n\n/** A pull request's identity across every facet and endpoint: its id is only unique within its repository. */\nfunction toIdentity(pr: BitbucketServerPullRequest): string {\n\treturn `${pr.toRef.repository.id}/${pr.id}`;\n}\n\n/**\n * Binds a cursor to everything that decides what it continues: the connection and installation it was read from,\n * the facets and every criterion. Hashed, so neither the query nor the address is published inside the cursor.\n */\nfunction getCursorKey(connectionId: string, query: Query): Promise<string> {\n\treturn sha256(\n\t\tJSON.stringify([\n\t\t\tconnectionId,\n\t\t\tquery.baseUrl,\n\t\t\tquery.facets.map(f => [f.repo != null ? repoKey(f.repo) : null, f.relationship ?? null, f.role ?? null]),\n\t\t\tquery.states != null ? [...query.states].sort() : null,\n\t\t\tquery.criteria?.text?.trim() ?? '',\n\t\t\tquery.criteria?.draft ?? null,\n\t\t\tquery.criteria?.includeArchived === true,\n\t\t\t// Both: the server filters participants by username and the rows are re-checked by id or username, so a\n\t\t\t// renamed account is a different query even under the same id.\n\t\t\tquery.currentUser != null ? [query.currentUser.id, query.currentUser.username] : null,\n\t\t\tquery.sort,\n\t\t]),\n\t);\n}\n\n/**\n * Signs a continuation — its page, every facet's offset, which facets failed, and whether a facet stalled — so an\n * edited cursor can't pass for complete: ending a facet early by nulling its offset, or claiming a failure its read\n * never had. The key only binds a cursor to its query and travels inside it; this is keyed by a secret that never\n * leaves this process, so a signature can't be recomputed outside it. A cursor that outlives the process keeps\n * continuing, and reports its read as unconfirmed rather than as complete (see {@link parseCursor}).\n */\nconst stateSecret = getNonce();\n\nfunction signState(\n\tkey: string,\n\tpage: number,\n\tstarts: (number | null)[],\n\tstate: Pick<SearchCursor, 'failed' | 'retrying' | 'truncated'>,\n): Promise<string> {\n\treturn sha256(JSON.stringify([stateSecret, key, page, starts, state.failed, state.retrying, state.truncated]));\n}\n\n/** The failure kinds a cursor may carry — the SDK's closed set, so a cursor can't name one the facade never maps. */\nconst failureKinds: ReadonlySet<string> = new Set<CollectionScopeFailureKind>([\n\t'authentication',\n\t'rate-limit',\n\t'not-found',\n\t'network',\n\t'provider',\n\t'unknown',\n]);\n\ninterface SearchCursor {\n\tpage: number;\n\tstarts: (number | null)[];\n\ttruncated: boolean;\n\t/** The facets dropped after failing their retry, by index, and how. They are never read again. */\n\tfailed: { facet: number; kind: CollectionScopeFailureKind }[];\n\t/** The facets that failed on the previous page and are retried at the offset they missed, by index. */\n\tretrying: number[];\n}\n\n/**\n * Parses a cursor this module wrote for the same connection and query.\n *\n * The key binds a cursor to its connection, installation and query, but travels inside it, so the offsets can be\n * edited; the signature below covers them, so an edited cursor still reads but can't report its read as complete. The completeness state is\n * the part that could be turned against it, so it is signed and written on every continuation. A state that is\n * missing or doesn't verify is not refused, since that is also what a cursor from an earlier process looks like, and\n * failing a read that still works helps no one; but it can't be passed off as complete either — it degrades to\n * `truncated`, \"completeness not confirmed\", without the failures it can't prove. A failure is rebuilt from the facet\n * it names regardless, so even a verified one can't name a scope or text the read never produced.\n */\nasync function parseCursor(cursor: string | undefined, key: string, facets: Facet[]): Promise<SearchCursor> {\n\tconst facetCount = facets.length;\n\tif (cursor == null || cursor === '{}') {\n\t\treturn {\n\t\t\tpage: 1,\n\t\t\tstarts: new Array<number | null>(facetCount).fill(0),\n\t\t\ttruncated: false,\n\t\t\tfailed: [],\n\t\t\tretrying: [],\n\t\t};\n\t}\n\n\tlet parsed: { key?: unknown; page?: unknown; starts?: unknown; state?: unknown } | undefined;\n\ttry {\n\t\tparsed = (JSON.parse(cursor) as typeof parsed) ?? undefined;\n\t} catch {}\n\n\tconst starts = parsed?.starts;\n\tif (\n\t\tparsed == null ||\n\t\tparsed.key !== key ||\n\t\ttypeof parsed.page !== 'number' ||\n\t\t!Number.isSafeInteger(parsed.page) ||\n\t\tparsed.page < 2 ||\n\t\t!Array.isArray(starts) ||\n\t\tstarts.length !== facetCount ||\n\t\t// 0 is a facet retrying the first page it missed; every other offset is past a page already read.\n\t\t!starts.every(start => start === null || (Number.isSafeInteger(start) && (start as number) >= 0)) ||\n\t\t!starts.some(start => start !== null)\n\t) {\n\t\tthrow new Error('Invalid Bitbucket Data Center pull request search cursor for this connection or query');\n\t}\n\n\treturn {\n\t\tpage: parsed.page,\n\t\tstarts: starts as (number | null)[],\n\t\t...(await parseState(parsed.state, key, parsed.page, starts as (number | null)[])),\n\t};\n}\n\n/**\n * The signed completeness state of a continuation, verified together with its page and offsets. Every continuation\n * carries one, so a state that is missing, malformed, not signed by this process, or signed for other offsets says\n * the read's completeness can't be confirmed — never that it was whole.\n */\nasync function parseState(\n\tstate: unknown,\n\tkey: string,\n\tpage: number,\n\tstarts: (number | null)[],\n): Promise<Pick<SearchCursor, 'failed' | 'retrying' | 'truncated'>> {\n\tconst unconfirmed = { failed: [], retrying: [], truncated: true };\n\tif (state == null || typeof state !== 'object') return unconfirmed;\n\n\tconst { failed, retrying, truncated, signature } = state as {\n\t\tfailed?: unknown;\n\t\tretrying?: unknown;\n\t\ttruncated?: unknown;\n\t\tsignature?: unknown;\n\t};\n\tif (\n\t\ttypeof truncated !== 'boolean' ||\n\t\t!Array.isArray(retrying) ||\n\t\t// A retried facet is read again, so it must still have the offset it missed.\n\t\t!retrying.every(i => Number.isSafeInteger(i) && i >= 0 && i < starts.length && starts[i as number] !== null) ||\n\t\t!Array.isArray(failed) ||\n\t\t!failed.every(\n\t\t\t(f: { facet?: unknown; kind?: unknown } | null) =>\n\t\t\t\tf != null &&\n\t\t\t\tNumber.isSafeInteger(f.facet) &&\n\t\t\t\t(f.facet as number) >= 0 &&\n\t\t\t\t(f.facet as number) < starts.length &&\n\t\t\t\t// A failed facet is never read again, so it has no offset left to continue from.\n\t\t\t\tstarts[f.facet as number] === null &&\n\t\t\t\ttypeof f.kind === 'string' &&\n\t\t\t\tfailureKinds.has(f.kind),\n\t\t)\n\t) {\n\t\treturn unconfirmed;\n\t}\n\n\tconst verified = { failed: failed as SearchCursor['failed'], retrying: retrying as number[], truncated: truncated };\n\treturn signature === (await signState(key, page, starts, verified)) ? verified : unconfirmed;\n}\n\nfunction toCollectionScope(token: Token, facet: Facet): CollectionScope {\n\treturn facet.repo != null\n\t\t? { providerId: token.providerId, repositoryId: `${facet.repo.namespace}/${facet.repo.name}` }\n\t\t: { providerId: token.providerId };\n}\n\ninterface FacetPage {\n\t/**\n\t * The rows that match the query AND map to a pull request, with their mapping. Mapped here rather than by each\n\t * caller, so the count skips exactly the rows the search can't show and the two can't disagree about them.\n\t */\n\tmatches: { raw: BitbucketServerPullRequest; normalized: ProviderPullRequest }[];\n\t/** The next page's `start`, or `null` when this facet is exhausted or can't be continued. */\n\tnext: number | null;\n\t/** The server reported another page but no offset past this one to reach it. */\n\tstalled: boolean;\n}\n\nasync function readFacetPage(\n\trequest: ProviderRequestFunction,\n\ttoken: Token,\n\tquery: Query,\n\tfacet: Facet,\n\tstart: number,\n\tlimit: number,\n\tcountOnly: boolean,\n\tcancellation: AbortSignal | undefined,\n): Promise<FacetPage> {\n\tif (cancellation?.aborted) throw new CancellationError();\n\n\tlet body: BitbucketServerPagedResponse<BitbucketServerPullRequest> | undefined;\n\ttry {\n\t\t({ body } = await request<BitbucketServerPagedResponse<BitbucketServerPullRequest>>({\n\t\t\turl: toFacetUrl(query, facet, start, limit, countOnly),\n\t\t\theaders: { Authorization: `Bearer ${token.accessToken}` },\n\t\t\t// Aborts the request itself, so a cancelled search doesn't wait on up to a page of 1,000 per facet.\n\t\t\tsignal: cancellation,\n\t\t}));\n\t\tif (\n\t\t\tbody == null ||\n\t\t\t!Array.isArray(body.values) ||\n\t\t\ttypeof body.isLastPage !== 'boolean' ||\n\t\t\tbody.start !== start\n\t\t) {\n\t\t\tthrow new Error('Invalid Bitbucket Data Center pull request page');\n\t\t}\n\t} catch (ex) {\n\t\t// A request the signal aborted is the cancellation, never a failed facet whose siblings answered.\n\t\tif (isCancellationError(ex)) throw ex;\n\t\tif (cancellation?.aborted) throw new CancellationError(ex instanceof Error ? ex : undefined);\n\n\t\ttry {\n\t\t\tthrowProviderError(token, ex);\n\t\t} catch (classified) {\n\t\t\tthrow toFacetError(classified, facet);\n\t\t}\n\t}\n\tif (cancellation?.aborted) throw new CancellationError();\n\n\tconst next = body.nextPageStart;\n\tconst more = !body.isLastPage && Number.isSafeInteger(next) && next > start;\n\tconst matches: FacetPage['matches'] = [];\n\tfor (const raw of body.values) {\n\t\tif (!matchesFacet(raw, facet, query)) continue;\n\n\t\ttry {\n\t\t\tmatches.push({ raw: raw, normalized: normalizeBitbucketServerPullRequest(raw) });\n\t\t} catch (ex) {\n\t\t\tLogger.warn(`Skipped an unmappable Bitbucket Data Center pull request; id=${raw.id}, ex=${String(ex)}`);\n\t\t}\n\t}\n\n\treturn {\n\t\tmatches: matches,\n\t\tnext: more ? next : null,\n\t\tstalled: !body.isLastPage && !more,\n\t};\n}\n\nfunction toFacetUrl(query: Query, facet: Facet, start: number, limit: number, countOnly: boolean): string {\n\tconst criteria = query.criteria;\n\t// One requested state goes to the server; several — including `closed`, which is DECLINED and SUPERSEDED — are\n\t// read as every state and kept by `matchesFacet`.\n\tconst state = query.states?.size === 1 ? [...query.states][0] : undefined;\n\tlet url: URL;\n\tif (facet.repo != null) {\n\t\turl = new URL(\n\t\t\t`${query.baseUrl}/projects/${encodeURIComponent(facet.repo.namespace)}/repos/${encodeURIComponent(\n\t\t\t\tfacet.repo.name,\n\t\t\t)}/pull-requests`,\n\t\t);\n\t\turl.searchParams.set('state', state ?? 'ALL');\n\t\tconst text = criteria?.text?.trim();\n\t\tif (text) {\n\t\t\turl.searchParams.set('filterText', text);\n\t\t}\n\t\tif (criteria?.draft != null) {\n\t\t\turl.searchParams.set('draft', String(criteria.draft));\n\t\t}\n\t\tif (facet.relationship != null) {\n\t\t\turl.searchParams.set('username.1', query.currentUser!.username);\n\t\t\tswitch (facet.relationship) {\n\t\t\t\tcase PullRequestFilter.Author:\n\t\t\t\t\turl.searchParams.set('role.1', 'AUTHOR');\n\t\t\t\t\tbreak;\n\t\t\t\tcase PullRequestFilter.ReviewRequested:\n\t\t\t\t\turl.searchParams.set('role.1', 'REVIEWER');\n\t\t\t\t\turl.searchParams.set('approved.1', 'false');\n\t\t\t\t\tbreak;\n\t\t\t\tcase PullRequestFilter.Reviewed:\n\t\t\t\t\t// Any role: a participant who isn't a listed reviewer can still approve or ask for changes.\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t// Properties carry the comment count a search row shows and a count never reads.\n\t\tif (countOnly) {\n\t\t\turl.searchParams.set('withProperties', 'false');\n\t\t}\n\t} else {\n\t\turl = new URL(`${query.baseUrl}/dashboard/pull-requests`);\n\t\t// The dashboard reads every state when `state` is omitted, and documents no `ALL`.\n\t\tif (state != null) {\n\t\t\turl.searchParams.set('state', state);\n\t\t}\n\t\tswitch (facet.relationship) {\n\t\t\tcase PullRequestFilter.Author:\n\t\t\t\turl.searchParams.set('role', 'AUTHOR');\n\t\t\t\tbreak;\n\t\t\tcase PullRequestFilter.ReviewRequested:\n\t\t\t\turl.searchParams.set('role', 'REVIEWER');\n\t\t\t\turl.searchParams.set('participantStatus', 'UNAPPROVED');\n\t\t\t\tbreak;\n\t\t\tcase PullRequestFilter.Reviewed:\n\t\t\t\t// The status only filters alongside a role (see `Facet.role`), so each of the two lists is its own facet.\n\t\t\t\turl.searchParams.set('role', facet.role!);\n\t\t\t\turl.searchParams.set('participantStatus', 'APPROVED,NEEDS_WORK');\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\turl.searchParams.set('order', orderParams[query.sort]!);\n\turl.searchParams.set('start', String(start));\n\turl.searchParams.set('limit', String(limit));\n\treturn url.toString();\n}\n\n/**\n * Re-applies every constraint of the query to a row the server returned, so what the server was asked to filter and\n * what it actually filtered can't differ in the result: the dashboard has no text or draft filter, a server older\n * than 8.18 ignores `draft`, several states are read as every state, a reviewer filter can't tell a pending review\n * from one that asked for changes, and no endpoint excludes archived repositories.\n */\nfunction matchesFacet(pr: BitbucketServerPullRequest, facet: Facet, query: Query): boolean {\n\tconst repository = pr.toRef?.repository;\n\t// Without both there is no identity to deduplicate or count it by.\n\tif (pr.id == null || repository?.id == null) return false;\n\tif (query.states != null && !query.states.has(pr.state)) return false;\n\tif (facet.repo != null && `${repository.project?.key}/${repository.slug}`.toLowerCase() !== repoKey(facet.repo)) {\n\t\treturn false;\n\t}\n\n\tconst criteria = query.criteria;\n\tif (criteria?.includeArchived !== true && repository.archived === true) return false;\n\tif (criteria?.draft != null && (pr.draft === true) !== criteria.draft) return false;\n\n\tconst text = criteria?.text?.trim().toLowerCase();\n\tif (text && !pr.title?.toLowerCase().includes(text) && !pr.description?.toLowerCase().includes(text)) {\n\t\treturn false;\n\t}\n\n\treturn facet.relationship == null || matchesRelationship(pr, facet.relationship, query.currentUser!, facet.role);\n}\n\n/**\n * Whether `facet` is the one that serves `pr`: the first requested relationship the pull request matches, in canonical\n * order. A pull request I authored and reviewed is served by the author facet alone, so the reviewed facet skips it\n * on whichever page it reaches it. Between the two `Reviewed` dashboard facets the reviewer list wins, should a\n * server ever list the user in both.\n *\n * Stateless, which is the point: two facets reach a shared row pages apart, and remembering what earlier pages emitted\n * would make the cursor grow with every row read. The rule only needs the row itself, and the count applies the same\n * union through its own deduplication, so list and count agree. One thing no page-based read can settle is a pull\n * request whose review state changes between two pages — it can then match a different relationship on each and be\n * served by both, just as a row updated mid-read can move between offsets.\n */\nfunction ownsRow(pr: BitbucketServerPullRequest, facet: Facet, query: Query): boolean {\n\tif (facet.relationship == null) return true;\n\n\tconst user = query.currentUser!;\n\tconst owner = query.relationships.find(r => matchesRelationship(pr, r, user));\n\tif (owner !== facet.relationship) return false;\n\tif (facet.role == null) return true;\n\n\tconst ownerRole: DashboardRole = matchesRelationship(pr, facet.relationship, user, 'REVIEWER')\n\t\t? 'REVIEWER'\n\t\t: 'PARTICIPANT';\n\treturn ownerRole === facet.role;\n}\n\n/** `role` narrows `Reviewed` to one participant list; every other relationship ignores it. */\nfunction matchesRelationship(\n\tpr: BitbucketServerPullRequest,\n\trelationship: Relationship,\n\tuser: BitbucketServerSearchUser,\n\trole?: DashboardRole,\n): boolean {\n\tconst isCurrentUser = (candidate: BitbucketServerUser | undefined): boolean =>\n\t\tcandidate != null &&\n\t\t(String(candidate.id) === user.id || candidate.name?.toLowerCase() === user.username.toLowerCase());\n\tconst hasStatus = (participants: BitbucketServerPullRequestUser[] | undefined, statuses: string[]): boolean =>\n\t\tparticipants?.some(p => isCurrentUser(p.user) && statuses.includes(p.status)) ?? false;\n\n\tswitch (relationship) {\n\t\tcase PullRequestFilter.Author:\n\t\t\treturn isCurrentUser(pr.author?.user);\n\t\tcase PullRequestFilter.ReviewRequested:\n\t\t\treturn hasStatus(pr.reviewers, ['UNAPPROVED']);\n\t\tcase PullRequestFilter.Reviewed:\n\t\t\treturn (\n\t\t\t\t(role !== 'PARTICIPANT' && hasStatus(pr.reviewers, ['APPROVED', 'NEEDS_WORK'])) ||\n\t\t\t\t(role !== 'REVIEWER' && hasStatus(pr.participants, ['APPROVED', 'NEEDS_WORK']))\n\t\t\t);\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pullRequestSearch.js","names":[],"sources":["../../../../../../plus/integrations/src/providers/bitbucket-server/pullRequestSearch.ts"],"sourcesContent":["import type { CollectionScope, CollectionScopeFailure, CollectionScopeFailureKind } from '@gitkraken/provider-apis';\nimport type {\n\tPullRequestSearchCriteria,\n\tPullRequestSorting,\n\tPullRequestStateFilter,\n} from '@gitlens/git/models/pullRequest.js';\nimport { defaultPullRequestSort, PullRequestFilter } from '@gitlens/git/models/pullRequest.js';\nimport type { Provider } from '@gitlens/git/models/remoteProvider.js';\nimport { getPullRequestComparator } from '@gitlens/git/utils/pullRequest.utils.js';\nimport { CancellationError, isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { getNonce, sha256 } from '@gitlens/utils/crypto.js';\nimport { Logger } from '@gitlens/utils/logger.js';\nimport { mapSettledBounded } from '@gitlens/utils/promise.js';\nimport type { TokenWithInfo } from '../../authentication/models.js';\nimport { toCollectionScopeFailure } from '../../collectionMetadata.js';\nimport type { GitSelfManagedHostIntegrationId } from '../../constants.js';\nimport { AuthenticationError, AuthenticationErrorReason } from '../../errors.js';\nimport type { ProviderPullRequestCount, ProviderPullRequestSearchPage } from '../../models/pullRequestReads.js';\nimport type { ProviderPullRequest, ProviderRepoInput, ProviderRequestFunction } from '../models.js';\nimport { fromProviderPullRequest } from '../models.js';\nimport { throwProviderError } from '../providerErrors.js';\nimport type {\n\tBitbucketServerPagedResponse,\n\tBitbucketServerPullRequest,\n\tBitbucketServerPullRequestUser,\n\tBitbucketServerUser,\n} from './models.js';\nimport { normalizeBitbucketServerPullRequest } from './models.js';\n\ntype Token = TokenWithInfo<GitSelfManagedHostIntegrationId.BitbucketServer>;\ntype BitbucketServerPullRequestState = BitbucketServerPullRequest['state'];\n\n/**\n * The relationships Bitbucket Data Center can express, in the canonical order its facets (and so its cursor) are\n * built in. A Bitbucket pull request has no assignee, and none of its pull-request endpoints filter by mention.\n */\nconst relationships = [\n\tPullRequestFilter.Author,\n\tPullRequestFilter.ReviewRequested,\n\tPullRequestFilter.Reviewed,\n] as const;\ntype Relationship = (typeof relationships)[number];\n\n/** The current user, which both the server-side participant filters and their client-side re-check identify. */\nexport interface BitbucketServerSearchUser {\n\tid: string;\n\tusername: string;\n}\n\n/**\n * One provider query of the search: a repository or the current user's dashboard, times one relationship.\n *\n * A repository facet reads `/projects/{key}/repos/{slug}/pull-requests`, which filters participants, text and draft\n * state server-side, so a page narrowed to a few repositories holds only matches. Without repositories a relationship\n * reads `/dashboard/pull-requests`, the only cross-repository pull-request list Bitbucket Data Center has; it can't\n * filter text or draft state, so those are re-checked on its rows. There is no project-wide list at all, which is\n * why the capability declares no organization scope.\n *\n * States are not a facet axis: every facet asks the server for the one requested state, or for every state when\n * several are requested, and keeps the requested ones — reading the unrequested rows rather than spending one more\n * request per state.\n */\ninterface Facet {\n\trepo?: ProviderRepoInput;\n\trelationship?: Relationship;\n\t/**\n\t * The dashboard role a `Reviewed` facet reads. The dashboard only applies `participantStatus` together with\n\t * `role` — without one it returns every pull request the user is involved in, authored ones included, whatever\n\t * the status — so `Reviewed` is read as two facets, the reviewer list and the (non-reviewer) participant list,\n\t * each filtered by status server-side. Absent for every other facet.\n\t */\n\trole?: DashboardRole;\n}\n\ntype DashboardRole = 'REVIEWER' | 'PARTICIPANT';\n\ninterface SearchOptions {\n\tbaseUrl: string;\n\trepos?: ProviderRepoInput[];\n\t/** Refused when set: Bitbucket Data Center has no project-wide pull-request list to scope it to. */\n\torg?: string;\n\tcriteria?: PullRequestSearchCriteria;\n\t/** Required when `criteria.relationships` is non-empty. */\n\tcurrentUser?: BitbucketServerSearchUser;\n}\n\n/** A resolved query, shared by every facet of one search or count. */\ninterface Query extends SearchOptions {\n\tfacets: Facet[];\n\t/** The requested relationships, in canonical order — the order {@link ownsRow} gives a shared row to. */\n\trelationships: Relationship[];\n\t/** The requested states, or `undefined` for every state. */\n\tstates: Set<BitbucketServerPullRequestState> | undefined;\n\tsort: PullRequestSorting;\n}\n\n/** Bitbucket answers an unspecified page size with 25; a search page asks for this many per facet instead. */\nconst defaultSearchPageSize = 30;\n/**\n * The server's own cap on a page (`page.max.pullrequests`, 1000 unless an administrator lowered it), and the one\n * page a count reads per facet: past it the count is a floor rather than more of a customer-run server's capacity\n * spent on a figure the caller uses as a cost hint.\n */\nconst maxPageSize = 1000;\n/** Matches the SDK's own cap on concurrent Bitbucket Data Center pull-request requests. */\nconst facetConcurrency = 5;\n\n/** The server states each facade state covers. `closed` is two, so it can't be sent as one `state` filter. */\nconst pullRequestStates: Record<Exclude<PullRequestStateFilter, 'all'>, BitbucketServerPullRequestState[]> = {\n\topen: ['OPEN'],\n\tclosed: ['DECLINED', 'SUPERSEDED'],\n\tmerged: ['MERGED'],\n};\n\nconst orderParams: Partial<Record<PullRequestSorting, string>> = {\n\t'updated:desc': 'NEWEST',\n\t'updated:asc': 'OLDEST',\n};\n\n/**\n * Pull requests matching `criteria` over the requested repositories, or over the current user's relationships when\n * none are given.\n *\n * Every facet reads its own page, and the merged page is re-ordered as a whole. Each facet keeps its own\n * `nextPageStart` in the cursor, which is bound to this connection, installation and query: a cursor handed back\n * under anything else is refused rather than read as page 1 of a different search. A pull request several\n * relationships match is served by exactly one of them, the first in canonical order (see {@link ownsRow}), so facets\n * that advance independently never serve it twice across pages and the cursor carries no history of what it emitted.\n *\n * Every criterion the server applies is applied again to the rows it returns, so a server that ignores a parameter\n * (one older than 8.18, which shipped drafts, has no `draft`) narrows the page instead of silently widening it.\n *\n * A facet that fails is reported in `metadata` while its siblings still answer, and keeps its offset, so the next page\n * retries the page it missed — a transient failure recovers the rows it cost. A facet that fails its retry too is\n * dropped, and reported on every later page, which no longer reads it; one retry keeps a facet that will never answer\n * from holding `hasMore` open forever. If every facet fails on the first page, the first failure is thrown instead.\n */\nexport async function searchBitbucketServerPullRequestsPage(\n\trequest: ProviderRequestFunction,\n\ttoken: Token,\n\toptions: SearchOptions & { connectionId: string; provider: Provider; cursor?: string; pageSize?: number },\n\tcancellation?: AbortSignal,\n): Promise<ProviderPullRequestSearchPage> {\n\tconst query = toQuery(options);\n\tconst comparator = getPullRequestComparator(query.sort)!;\n\tconst key = await getCursorKey(options.connectionId, query);\n\tconst cursor = await parseCursor(options.cursor, key, query.facets);\n\tconst active = query.facets.flatMap((facet, index) =>\n\t\tcursor.starts[index] != null ? [{ facet: facet, start: cursor.starts[index], index: index }] : [],\n\t);\n\t// A facet dropped on an earlier page is gone from this one's reads, and the hole is still in the result.\n\tconst failed = [...cursor.failed];\n\tconst failures = failed.map(f => toEarlierFailure(token, query.facets[f.facet], f.kind));\n\tconst retrying: number[] = [];\n\tif (active.length === 0) {\n\t\treturn {\n\t\t\tvalues: [],\n\t\t\thasMore: false,\n\t\t\tpage: cursor.page,\n\t\t\ttruncated: cursor.truncated,\n\t\t\tmetadata: toMetadata(failures),\n\t\t};\n\t}\n\n\tconst limit = Math.min(maxPageSize, Math.max(1, Math.trunc(options.pageSize ?? defaultSearchPageSize)));\n\tconst results = await mapSettledBounded(active, facetConcurrency, ({ facet, start }) =>\n\t\treadFacetPage(request, token, query, facet, start, limit, false, cancellation),\n\t);\n\tconst rejected = results.filter((r): r is PromiseRejectedResult => r.status === 'rejected');\n\tconst cancelled = rejected.find(r => isCancellationError(r.reason));\n\tif (cancelled != null) throw cancelled.reason;\n\n\t// A rejected credential is the connection failing rather than one scope, so it is thrown on any page: the\n\t// integration's session recovery then runs once, from the thrown error, and the failure is never carried in the\n\t// cursor where every later page would report it again. (A repository refusing the token isn't one; see\n\t// `toFacetError`.)\n\tconst credential = rejected.find(r => r.reason instanceof AuthenticationError);\n\tif (credential != null) throw credential.reason;\n\t// Only a first page on which every facet failed is a failed read. On a later page an earlier one already proved\n\t// some facet answered, so the rows it served stand and this page's failures join the partial-result report.\n\tif (cursor.page === 1 && rejected.length === results.length) throw rejected[0].reason;\n\n\tconst nextStarts: (number | null)[] = cursor.starts.map(() => null);\n\tconst values: ProviderPullRequest[] = [];\n\tlet truncated = cursor.truncated;\n\tfor (let i = 0; i < results.length; i++) {\n\t\tconst { facet, index } = active[i];\n\t\tconst result = results[i];\n\t\tif (result.status === 'rejected') {\n\t\t\tconst failure = toCollectionScopeFailure(toCollectionScope(token, facet), result.reason);\n\t\t\tfailures.push(failure);\n\t\t\tif (cursor.retrying.includes(index)) {\n\t\t\t\t// Its retry failed too: dropped, and carried so every later page still reports the hole.\n\t\t\t\tfailed.push({ facet: index, kind: failure.kind });\n\t\t\t} else {\n\t\t\t\t// Kept at the offset it missed, so the next page retries it.\n\t\t\t\tnextStarts[index] = active[i].start;\n\t\t\t\tretrying.push(index);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tnextStarts[index] = result.value.next;\n\t\ttruncated ||= result.value.stalled;\n\t\tfor (const { raw, normalized } of result.value.matches) {\n\t\t\t// Another relationship owns a row they both match, and serves it from its own facet on whichever page\n\t\t\t// reaches it — which also settles two facets reaching it on this one.\n\t\t\tif (!ownsRow(raw, facet, query)) continue;\n\n\t\t\tvalues.push(normalized);\n\t\t}\n\t}\n\n\tconst hasMore = nextStarts.some(start => start != null);\n\t// Written on every continuation, complete or not, so removing it can't pass an incomplete read off as complete.\n\tconst state = { failed: failed, retrying: retrying, truncated: truncated };\n\treturn {\n\t\tvalues: values\n\t\t\t.map(pr =>\n\t\t\t\tfromProviderPullRequest(pr, options.provider, {\n\t\t\t\t\tcurrentAccount: options.currentUser?.id != null ? { id: options.currentUser.id } : undefined,\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.sort(comparator),\n\t\tcursor: hasMore\n\t\t\t? JSON.stringify({\n\t\t\t\t\tkey: key,\n\t\t\t\t\tpage: cursor.page + 1,\n\t\t\t\t\tstarts: nextStarts,\n\t\t\t\t\tstate: { ...state, signature: await signState(key, cursor.page + 1, nextStarts, state) },\n\t\t\t\t})\n\t\t\t: undefined,\n\t\thasMore: hasMore,\n\t\tpage: cursor.page,\n\t\ttruncated: truncated,\n\t\tmetadata: toMetadata(failures),\n\t};\n}\n\nfunction toMetadata(failures: CollectionScopeFailure[]): ProviderPullRequestSearchPage['metadata'] {\n\treturn failures.length > 0 ? { completeness: 'partial', failures: failures } : undefined;\n}\n\n/**\n * A facet failure carried over from an earlier page, rebuilt from the query rather than from the cursor: the cursor\n * records only which facet failed and how, so it can't name a scope or a message the read never produced.\n */\nfunction toEarlierFailure(token: Token, facet: Facet, kind: CollectionScopeFailureKind): CollectionScopeFailure {\n\treturn {\n\t\tscope: toCollectionScope(token, facet),\n\t\tkind: kind,\n\t\tmessage: 'Failed on an earlier page of this search, so later pages did not read it',\n\t};\n}\n\n/**\n * How many pull requests match `criteria`: the same facets, predicates and identity the search uses, so the count\n * is the number of distinct rows the search would return — the union of the requested states, not the largest of\n * them, since Bitbucket has no per-search ceiling for a maximum to stay under.\n *\n * Bitbucket Data Center has no count query and reports no total, so each facet reads one page of up to\n * {@link maxPageSize} and the count is a floor (`lowerBound`) when any facet had more. Unlike the search, one failed\n * facet fails the whole count: a count missing a facet is a wrong number rather than a partial one.\n */\nexport async function countBitbucketServerPullRequests(\n\trequest: ProviderRequestFunction,\n\ttoken: Token,\n\toptions: SearchOptions,\n\tcancellation?: AbortSignal,\n): Promise<ProviderPullRequestCount> {\n\tconst query = toQuery(options);\n\tconst seen = new Set<string>();\n\tlet lowerBound = false;\n\t// One facet at a time: the facade already counts several scopes concurrently.\n\tfor (const facet of query.facets) {\n\t\tconst result = await readFacetPage(request, token, query, facet, 0, maxPageSize, true, cancellation);\n\t\tfor (const { raw } of result.matches) {\n\t\t\tseen.add(toIdentity(raw));\n\t\t}\n\t\tlowerBound ||= result.next != null || result.stalled;\n\t}\n\n\treturn { count: seen.size, lowerBound: lowerBound || undefined };\n}\n\n/**\n * Resolves the criteria into the facets and predicates every page applies, refusing — by throwing, which the read\n * reports as a failed request — anything the capability table does not declare. The facade validates the same\n * table first, so reaching a refusal here means a caller bypassed it; refusing rather than dropping the criterion\n * keeps that caller from reading a wider set than it asked for.\n */\nfunction toQuery(options: SearchOptions): Query {\n\tif (options.org != null && options.org.length > 0) {\n\t\tthrow new Error('Bitbucket Data Center cannot scope a pull request search to a project');\n\t}\n\n\tconst criteria = options.criteria;\n\t// No endpoint filters by date, and filtering the rows read would page through everything before the cutoff.\n\tif (criteria?.updatedAfter != null || criteria?.createdAfter != null) {\n\t\tthrow new Error('Bitbucket Data Center cannot filter a pull request search by date');\n\t}\n\n\tconst sort = criteria?.sort ?? defaultPullRequestSort;\n\tif (orderParams[sort] == null) {\n\t\tthrow new Error(`Bitbucket Data Center cannot order a pull request search by '${sort}'`);\n\t}\n\n\tconst requested = criteria?.relationships ?? [];\n\tconst unsupported = requested.find(r => !(relationships as readonly PullRequestFilter[]).includes(r));\n\tif (unsupported != null) {\n\t\tthrow new Error(`Bitbucket Data Center cannot search pull requests by the '${unsupported}' relationship`);\n\t}\n\n\tconst facetRelationships = relationships.filter(r => requested.includes(r));\n\tif (facetRelationships.length > 0 && options.currentUser == null) {\n\t\tthrow new Error('A Bitbucket Data Center relationship search requires the current user');\n\t}\n\n\tconst requestedStates: PullRequestStateFilter[] = criteria?.states?.length ? criteria.states : ['open'];\n\tconst states = requestedStates.includes('all')\n\t\t? undefined\n\t\t: new Set(requestedStates.flatMap(s => pullRequestStates[s as Exclude<PullRequestStateFilter, 'all'>]));\n\n\t// Sorted and deduplicated so the facets, and so the cursor, don't depend on the order repositories were passed.\n\tconst repos = [...new Map((options.repos ?? []).map(r => [repoKey(r), r])).entries()]\n\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t.map(([, repo]) => repo);\n\tfor (const repo of repos) {\n\t\tfor (const segment of [repo.namespace, repo.name]) {\n\t\t\tif (!segment || segment === '.' || segment === '..') {\n\t\t\t\tthrow new Error('Invalid Bitbucket Data Center repository for a pull request search');\n\t\t\t}\n\t\t}\n\t}\n\n\tlet facets: Facet[];\n\tif (repos.length > 0) {\n\t\tconst scoped = facetRelationships.length > 0 ? facetRelationships : [undefined];\n\t\tfacets = repos.flatMap(repo => scoped.map(relationship => ({ repo: repo, relationship: relationship })));\n\t} else if (facetRelationships.length > 0) {\n\t\tfacets = facetRelationships.flatMap<Facet>(relationship =>\n\t\t\trelationship === PullRequestFilter.Reviewed\n\t\t\t\t? [\n\t\t\t\t\t\t{ relationship: relationship, role: 'REVIEWER' },\n\t\t\t\t\t\t{ relationship: relationship, role: 'PARTICIPANT' },\n\t\t\t\t\t]\n\t\t\t\t: [{ relationship: relationship }],\n\t\t);\n\t} else {\n\t\tthrow new Error('A Bitbucket Data Center pull request search must be scoped by repositories or a relationship');\n\t}\n\n\treturn { ...options, facets: facets, relationships: facetRelationships, states: states, sort: sort };\n}\n\n/** Project keys and repository slugs resolve case-insensitively, so two spellings name one repository. */\nfunction repoKey(repo: ProviderRepoInput): string {\n\treturn `${repo.namespace}/${repo.name}`.toLowerCase();\n}\n\n/**\n * A facet's classified failure, with the one correction the provider-wide classification can't make: a 403 on a\n * REPOSITORY is Bitbucket refusing that repository (the token lacks `REPO_READ` there), not the credential failing.\n *\n * Made here, where every read of a facet passes, so the search and the count can't disagree about it on any path —\n * a sibling repository's failure, a first page where every repository failed, or a count. Left an\n * `AuthenticationError`, it would reach the integration's exception handling and mark a connection that works\n * everywhere else for recovery and toward disconnecting; as a plain error naming the repository it is reported as\n * that scope's failure alone. A 401 anywhere, and a 403 on the user's own dashboard, stay the credential failing.\n */\nfunction toFacetError(ex: unknown, facet: Facet): unknown {\n\tif (!(ex instanceof AuthenticationError) || facet.repo == null) return ex;\n\tif (ex.reason !== AuthenticationErrorReason.Forbidden) return ex;\n\n\treturn new Error(\n\t\t`Bitbucket Data Center refused access to ${facet.repo.namespace}/${facet.repo.name}: ${(ex.original ?? ex).message}`,\n\t\t{ cause: ex },\n\t);\n}\n\n/** A pull request's identity across every facet and endpoint: its id is only unique within its repository. */\nfunction toIdentity(pr: BitbucketServerPullRequest): string {\n\treturn `${pr.toRef.repository.id}/${pr.id}`;\n}\n\n/**\n * Binds a cursor to everything that decides what it continues: the connection and installation it was read from,\n * the facets and every criterion. Hashed, so neither the query nor the address is published inside the cursor.\n */\nfunction getCursorKey(connectionId: string, query: Query): Promise<string> {\n\treturn sha256(\n\t\tJSON.stringify([\n\t\t\tconnectionId,\n\t\t\tquery.baseUrl,\n\t\t\tquery.facets.map(f => [f.repo != null ? repoKey(f.repo) : null, f.relationship ?? null, f.role ?? null]),\n\t\t\tquery.states != null ? [...query.states].sort() : null,\n\t\t\tquery.criteria?.text?.trim() ?? '',\n\t\t\tquery.criteria?.draft ?? null,\n\t\t\tquery.criteria?.includeArchived === true,\n\t\t\t// Both: the server filters participants by username and the rows are re-checked by id or username, so a\n\t\t\t// renamed account is a different query even under the same id.\n\t\t\tquery.currentUser != null ? [query.currentUser.id, query.currentUser.username] : null,\n\t\t\tquery.sort,\n\t\t]),\n\t);\n}\n\n/**\n * Signs a continuation — its page, every facet's offset, which facets failed, and whether a facet stalled — so an\n * edited cursor can't pass for complete: ending a facet early by nulling its offset, or claiming a failure its read\n * never had. The key only binds a cursor to its query and travels inside it; this is keyed by a secret that never\n * leaves this process, so a signature can't be recomputed outside it. A cursor that outlives the process keeps\n * continuing, and reports its read as unconfirmed rather than as complete (see {@link parseCursor}).\n */\nconst stateSecret = getNonce();\n\nfunction signState(\n\tkey: string,\n\tpage: number,\n\tstarts: (number | null)[],\n\tstate: Pick<SearchCursor, 'failed' | 'retrying' | 'truncated'>,\n): Promise<string> {\n\treturn sha256(JSON.stringify([stateSecret, key, page, starts, state.failed, state.retrying, state.truncated]));\n}\n\n/** The failure kinds a cursor may carry — the SDK's closed set, so a cursor can't name one the facade never maps. */\nconst failureKinds: ReadonlySet<string> = new Set<CollectionScopeFailureKind>([\n\t'authentication',\n\t'rate-limit',\n\t'not-found',\n\t'network',\n\t'provider',\n\t'unknown',\n]);\n\ninterface SearchCursor {\n\tpage: number;\n\tstarts: (number | null)[];\n\ttruncated: boolean;\n\t/** The facets dropped after failing their retry, by index, and how. They are never read again. */\n\tfailed: { facet: number; kind: CollectionScopeFailureKind }[];\n\t/** The facets that failed on the previous page and are retried at the offset they missed, by index. */\n\tretrying: number[];\n}\n\n/**\n * Parses a cursor this module wrote for the same connection and query.\n *\n * The key binds a cursor to its connection, installation and query, but travels inside it, so the offsets can be\n * edited; the signature below covers them, so an edited cursor still reads but can't report its read as complete. The completeness state is\n * the part that could be turned against it, so it is signed and written on every continuation. A state that is\n * missing or doesn't verify is not refused, since that is also what a cursor from an earlier process looks like, and\n * failing a read that still works helps no one; but it can't be passed off as complete either — it degrades to\n * `truncated`, \"completeness not confirmed\", without the failures it can't prove. A failure is rebuilt from the facet\n * it names regardless, so even a verified one can't name a scope or text the read never produced.\n */\nasync function parseCursor(cursor: string | undefined, key: string, facets: Facet[]): Promise<SearchCursor> {\n\tconst facetCount = facets.length;\n\tif (cursor == null || cursor === '{}') {\n\t\treturn {\n\t\t\tpage: 1,\n\t\t\tstarts: new Array<number | null>(facetCount).fill(0),\n\t\t\ttruncated: false,\n\t\t\tfailed: [],\n\t\t\tretrying: [],\n\t\t};\n\t}\n\n\tlet parsed: { key?: unknown; page?: unknown; starts?: unknown; state?: unknown } | undefined;\n\ttry {\n\t\tparsed = (JSON.parse(cursor) as typeof parsed) ?? undefined;\n\t} catch {}\n\n\tconst starts = parsed?.starts;\n\tif (\n\t\tparsed == null ||\n\t\tparsed.key !== key ||\n\t\ttypeof parsed.page !== 'number' ||\n\t\t!Number.isSafeInteger(parsed.page) ||\n\t\tparsed.page < 2 ||\n\t\t!Array.isArray(starts) ||\n\t\tstarts.length !== facetCount ||\n\t\t// 0 is a facet retrying the first page it missed; every other offset is past a page already read.\n\t\t!starts.every(start => start === null || (Number.isSafeInteger(start) && (start as number) >= 0)) ||\n\t\t!starts.some(start => start !== null)\n\t) {\n\t\tthrow new Error('Invalid Bitbucket Data Center pull request search cursor for this connection or query');\n\t}\n\n\treturn {\n\t\tpage: parsed.page,\n\t\tstarts: starts as (number | null)[],\n\t\t...(await parseState(parsed.state, key, parsed.page, starts as (number | null)[])),\n\t};\n}\n\n/**\n * The signed completeness state of a continuation, verified together with its page and offsets. Every continuation\n * carries one, so a state that is missing, malformed, not signed by this process, or signed for other offsets says\n * the read's completeness can't be confirmed — never that it was whole.\n */\nasync function parseState(\n\tstate: unknown,\n\tkey: string,\n\tpage: number,\n\tstarts: (number | null)[],\n): Promise<Pick<SearchCursor, 'failed' | 'retrying' | 'truncated'>> {\n\tconst unconfirmed = { failed: [], retrying: [], truncated: true };\n\tif (state == null || typeof state !== 'object') return unconfirmed;\n\n\tconst { failed, retrying, truncated, signature } = state as {\n\t\tfailed?: unknown;\n\t\tretrying?: unknown;\n\t\ttruncated?: unknown;\n\t\tsignature?: unknown;\n\t};\n\tif (\n\t\ttypeof truncated !== 'boolean' ||\n\t\t!Array.isArray(retrying) ||\n\t\t// A retried facet is read again, so it must still have the offset it missed.\n\t\t!retrying.every(i => Number.isSafeInteger(i) && i >= 0 && i < starts.length && starts[i as number] !== null) ||\n\t\t!Array.isArray(failed) ||\n\t\t!failed.every(\n\t\t\t(f: { facet?: unknown; kind?: unknown } | null) =>\n\t\t\t\tf != null &&\n\t\t\t\tNumber.isSafeInteger(f.facet) &&\n\t\t\t\t(f.facet as number) >= 0 &&\n\t\t\t\t(f.facet as number) < starts.length &&\n\t\t\t\t// A failed facet is never read again, so it has no offset left to continue from.\n\t\t\t\tstarts[f.facet as number] === null &&\n\t\t\t\ttypeof f.kind === 'string' &&\n\t\t\t\tfailureKinds.has(f.kind),\n\t\t)\n\t) {\n\t\treturn unconfirmed;\n\t}\n\n\tconst verified = { failed: failed as SearchCursor['failed'], retrying: retrying as number[], truncated: truncated };\n\treturn signature === (await signState(key, page, starts, verified)) ? verified : unconfirmed;\n}\n\nfunction toCollectionScope(token: Token, facet: Facet): CollectionScope {\n\treturn facet.repo != null\n\t\t? { providerId: token.providerId, repositoryId: `${facet.repo.namespace}/${facet.repo.name}` }\n\t\t: { providerId: token.providerId };\n}\n\ninterface FacetPage {\n\t/**\n\t * The rows that match the query AND map to a pull request, with their mapping. Mapped here rather than by each\n\t * caller, so the count skips exactly the rows the search can't show and the two can't disagree about them.\n\t */\n\tmatches: { raw: BitbucketServerPullRequest; normalized: ProviderPullRequest }[];\n\t/** The next page's `start`, or `null` when this facet is exhausted or can't be continued. */\n\tnext: number | null;\n\t/** The server reported another page but no offset past this one to reach it. */\n\tstalled: boolean;\n}\n\nasync function readFacetPage(\n\trequest: ProviderRequestFunction,\n\ttoken: Token,\n\tquery: Query,\n\tfacet: Facet,\n\tstart: number,\n\tlimit: number,\n\tcountOnly: boolean,\n\tcancellation: AbortSignal | undefined,\n): Promise<FacetPage> {\n\tif (cancellation?.aborted) throw new CancellationError();\n\n\tlet body: BitbucketServerPagedResponse<BitbucketServerPullRequest> | undefined;\n\ttry {\n\t\t({ body } = await request<BitbucketServerPagedResponse<BitbucketServerPullRequest>>({\n\t\t\turl: toFacetUrl(query, facet, start, limit, countOnly),\n\t\t\theaders: { Authorization: `Bearer ${token.accessToken}` },\n\t\t\t// Aborts the request itself, so a cancelled search doesn't wait on up to a page of 1,000 per facet.\n\t\t\tsignal: cancellation,\n\t\t}));\n\t\tif (\n\t\t\tbody == null ||\n\t\t\t!Array.isArray(body.values) ||\n\t\t\ttypeof body.isLastPage !== 'boolean' ||\n\t\t\tbody.start !== start\n\t\t) {\n\t\t\tthrow new Error('Invalid Bitbucket Data Center pull request page');\n\t\t}\n\t} catch (ex) {\n\t\t// A request the signal aborted is the cancellation, never a failed facet whose siblings answered.\n\t\tif (isCancellationError(ex)) throw ex;\n\t\tif (cancellation?.aborted) throw new CancellationError(ex instanceof Error ? ex : undefined);\n\n\t\ttry {\n\t\t\tthrowProviderError(token, ex);\n\t\t} catch (classified) {\n\t\t\tthrow toFacetError(classified, facet);\n\t\t}\n\t}\n\tif (cancellation?.aborted) throw new CancellationError();\n\n\tconst next = body.nextPageStart;\n\tconst more = !body.isLastPage && Number.isSafeInteger(next) && next > start;\n\tconst matches: FacetPage['matches'] = [];\n\tfor (const raw of body.values) {\n\t\tif (!matchesFacet(raw, facet, query)) continue;\n\n\t\ttry {\n\t\t\tmatches.push({ raw: raw, normalized: normalizeBitbucketServerPullRequest(raw) });\n\t\t} catch (ex) {\n\t\t\tLogger.warn(`Skipped an unmappable Bitbucket Data Center pull request; id=${raw.id}, ex=${String(ex)}`);\n\t\t}\n\t}\n\n\treturn {\n\t\tmatches: matches,\n\t\tnext: more ? next : null,\n\t\tstalled: !body.isLastPage && !more,\n\t};\n}\n\nfunction toFacetUrl(query: Query, facet: Facet, start: number, limit: number, countOnly: boolean): string {\n\tconst criteria = query.criteria;\n\t// One requested state goes to the server; several — including `closed`, which is DECLINED and SUPERSEDED — are\n\t// read as every state and kept by `matchesFacet`.\n\tconst state = query.states?.size === 1 ? [...query.states][0] : undefined;\n\tlet url: URL;\n\tif (facet.repo != null) {\n\t\turl = new URL(\n\t\t\t`${query.baseUrl}/projects/${encodeURIComponent(facet.repo.namespace)}/repos/${encodeURIComponent(\n\t\t\t\tfacet.repo.name,\n\t\t\t)}/pull-requests`,\n\t\t);\n\t\turl.searchParams.set('state', state ?? 'ALL');\n\t\tconst text = criteria?.text?.trim();\n\t\tif (text) {\n\t\t\turl.searchParams.set('filterText', text);\n\t\t}\n\t\tif (criteria?.draft != null) {\n\t\t\turl.searchParams.set('draft', String(criteria.draft));\n\t\t}\n\t\tif (facet.relationship != null) {\n\t\t\turl.searchParams.set('username.1', query.currentUser!.username);\n\t\t\tswitch (facet.relationship) {\n\t\t\t\tcase PullRequestFilter.Author:\n\t\t\t\t\turl.searchParams.set('role.1', 'AUTHOR');\n\t\t\t\t\tbreak;\n\t\t\t\tcase PullRequestFilter.ReviewRequested:\n\t\t\t\t\turl.searchParams.set('role.1', 'REVIEWER');\n\t\t\t\t\turl.searchParams.set('approved.1', 'false');\n\t\t\t\t\tbreak;\n\t\t\t\tcase PullRequestFilter.Reviewed:\n\t\t\t\t\t// Any role: a participant who isn't a listed reviewer can still approve or ask for changes.\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t// Properties carry the comment count a search row shows and a count never reads.\n\t\tif (countOnly) {\n\t\t\turl.searchParams.set('withProperties', 'false');\n\t\t}\n\t} else {\n\t\turl = new URL(`${query.baseUrl}/dashboard/pull-requests`);\n\t\t// The dashboard reads every state when `state` is omitted, and documents no `ALL`.\n\t\tif (state != null) {\n\t\t\turl.searchParams.set('state', state);\n\t\t}\n\t\tswitch (facet.relationship) {\n\t\t\tcase PullRequestFilter.Author:\n\t\t\t\turl.searchParams.set('role', 'AUTHOR');\n\t\t\t\tbreak;\n\t\t\tcase PullRequestFilter.ReviewRequested:\n\t\t\t\turl.searchParams.set('role', 'REVIEWER');\n\t\t\t\turl.searchParams.set('participantStatus', 'UNAPPROVED');\n\t\t\t\tbreak;\n\t\t\tcase PullRequestFilter.Reviewed:\n\t\t\t\t// The status only filters alongside a role (see `Facet.role`), so each of the two lists is its own facet.\n\t\t\t\turl.searchParams.set('role', facet.role!);\n\t\t\t\turl.searchParams.set('participantStatus', 'APPROVED,NEEDS_WORK');\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\turl.searchParams.set('order', orderParams[query.sort]!);\n\turl.searchParams.set('start', String(start));\n\turl.searchParams.set('limit', String(limit));\n\treturn url.toString();\n}\n\n/**\n * Re-applies every constraint of the query to a row the server returned, so what the server was asked to filter and\n * what it actually filtered can't differ in the result: the dashboard has no text or draft filter, a server older\n * than 8.18 ignores `draft`, several states are read as every state, a reviewer filter can't tell a pending review\n * from one that asked for changes, and no endpoint excludes archived repositories.\n */\nfunction matchesFacet(pr: BitbucketServerPullRequest, facet: Facet, query: Query): boolean {\n\tconst repository = pr.toRef?.repository;\n\t// Without both there is no identity to deduplicate or count it by.\n\tif (pr.id == null || repository?.id == null) return false;\n\tif (query.states != null && !query.states.has(pr.state)) return false;\n\tif (facet.repo != null && `${repository.project?.key}/${repository.slug}`.toLowerCase() !== repoKey(facet.repo)) {\n\t\treturn false;\n\t}\n\n\tconst criteria = query.criteria;\n\tif (criteria?.includeArchived !== true && repository.archived === true) return false;\n\tif (criteria?.draft != null && (pr.draft === true) !== criteria.draft) return false;\n\n\tconst text = criteria?.text?.trim().toLowerCase();\n\tif (text && !pr.title?.toLowerCase().includes(text) && !pr.description?.toLowerCase().includes(text)) {\n\t\treturn false;\n\t}\n\n\treturn facet.relationship == null || matchesRelationship(pr, facet.relationship, query.currentUser!, facet.role);\n}\n\n/**\n * Whether `facet` is the one that serves `pr`: the first requested relationship the pull request matches, in canonical\n * order. A pull request I authored and reviewed is served by the author facet alone, so the reviewed facet skips it\n * on whichever page it reaches it. Between the two `Reviewed` dashboard facets the reviewer list wins, should a\n * server ever list the user in both.\n *\n * Stateless, which is the point: two facets reach a shared row pages apart, and remembering what earlier pages emitted\n * would make the cursor grow with every row read. The rule only needs the row itself, and the count applies the same\n * union through its own deduplication, so list and count agree. One thing no page-based read can settle is a pull\n * request whose review state changes between two pages — it can then match a different relationship on each and be\n * served by both, just as a row updated mid-read can move between offsets.\n */\nfunction ownsRow(pr: BitbucketServerPullRequest, facet: Facet, query: Query): boolean {\n\tif (facet.relationship == null) return true;\n\n\tconst user = query.currentUser!;\n\tconst owner = query.relationships.find(r => matchesRelationship(pr, r, user));\n\tif (owner !== facet.relationship) return false;\n\tif (facet.role == null) return true;\n\n\tconst ownerRole: DashboardRole = matchesRelationship(pr, facet.relationship, user, 'REVIEWER')\n\t\t? 'REVIEWER'\n\t\t: 'PARTICIPANT';\n\treturn ownerRole === facet.role;\n}\n\n/** `role` narrows `Reviewed` to one participant list; every other relationship ignores it. */\nfunction matchesRelationship(\n\tpr: BitbucketServerPullRequest,\n\trelationship: Relationship,\n\tuser: BitbucketServerSearchUser,\n\trole?: DashboardRole,\n): boolean {\n\tconst isCurrentUser = (candidate: BitbucketServerUser | undefined): boolean =>\n\t\tcandidate != null &&\n\t\t(String(candidate.id) === user.id || candidate.name?.toLowerCase() === user.username.toLowerCase());\n\tconst hasStatus = (participants: BitbucketServerPullRequestUser[] | undefined, statuses: string[]): boolean =>\n\t\tparticipants?.some(p => isCurrentUser(p.user) && statuses.includes(p.status)) ?? false;\n\n\tswitch (relationship) {\n\t\tcase PullRequestFilter.Author:\n\t\t\treturn isCurrentUser(pr.author?.user);\n\t\tcase PullRequestFilter.ReviewRequested:\n\t\t\treturn hasStatus(pr.reviewers, ['UNAPPROVED']);\n\t\tcase PullRequestFilter.Reviewed:\n\t\t\treturn (\n\t\t\t\t(role !== 'PARTICIPANT' && hasStatus(pr.reviewers, ['APPROVED', 'NEEDS_WORK'])) ||\n\t\t\t\t(role !== 'REVIEWER' && hasStatus(pr.participants, ['APPROVED', 'NEEDS_WORK']))\n\t\t\t);\n\t}\n}\n"],"mappings":"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"}
|