@gitkraken/core-gitlens 0.9.3 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/CHANGELOG.md +34 -1
  2. package/dist/git/models/issue.d.ts +25 -2
  3. package/dist/git/models/issue.js +3 -1
  4. package/dist/git/models/issue.js.map +1 -1
  5. package/dist/git/models/pullRequest.d.ts +55 -5
  6. package/dist/git/models/pullRequest.js +5 -1
  7. package/dist/git/models/pullRequest.js.map +1 -1
  8. package/dist/git/utils/issue.utils.d.ts +4 -0
  9. package/dist/git/utils/issue.utils.js +4 -0
  10. package/dist/git/utils/issue.utils.js.map +1 -1
  11. package/dist/git/utils/pullRequest.utils.d.ts +4 -0
  12. package/dist/git/utils/pullRequest.utils.js +8 -0
  13. package/dist/git/utils/pullRequest.utils.js.map +1 -1
  14. package/dist/plus/git-github/api/github.d.ts +64 -4
  15. package/dist/plus/git-github/api/github.js +232 -15
  16. package/dist/plus/git-github/api/github.js.map +1 -1
  17. package/dist/plus/git-github/models.d.ts +48 -6
  18. package/dist/plus/git-github/models.js +11 -10
  19. package/dist/plus/git-github/models.js.map +1 -1
  20. package/dist/plus/integrations/fieldPresence.d.ts +75 -0
  21. package/dist/plus/integrations/fieldPresence.js +381 -0
  22. package/dist/plus/integrations/fieldPresence.js.map +1 -0
  23. package/dist/plus/integrations/index.d.ts +6 -4
  24. package/dist/plus/integrations/index.js +2 -1
  25. package/dist/plus/integrations/index.js.map +1 -1
  26. package/dist/plus/integrations/integrationService.d.ts +13 -4
  27. package/dist/plus/integrations/integrationService.js.map +1 -1
  28. package/dist/plus/integrations/manager.d.ts +62 -7
  29. package/dist/plus/integrations/models/gitHostIntegration.d.ts +103 -9
  30. package/dist/plus/integrations/models/gitHostIntegration.js +116 -5
  31. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  32. package/dist/plus/integrations/models/integration.d.ts +91 -4
  33. package/dist/plus/integrations/models/integration.js +56 -7
  34. package/dist/plus/integrations/models/integration.js.map +1 -1
  35. package/dist/plus/integrations/models/issueReads.d.ts +14 -0
  36. package/dist/plus/integrations/models/issuesIntegration.d.ts +44 -3
  37. package/dist/plus/integrations/models/issuesIntegration.js +51 -1
  38. package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
  39. package/dist/plus/integrations/providers/azure/azure.js +3 -3
  40. package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
  41. package/dist/plus/integrations/providers/azure/models.d.ts +36 -4
  42. package/dist/plus/integrations/providers/azure/models.js +118 -8
  43. package/dist/plus/integrations/providers/azure/models.js.map +1 -1
  44. package/dist/plus/integrations/providers/azureDevOps.d.ts +102 -5
  45. package/dist/plus/integrations/providers/azureDevOps.js +264 -45
  46. package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
  47. package/dist/plus/integrations/providers/azureDevOpsServer.d.ts +30 -6
  48. package/dist/plus/integrations/providers/azureDevOpsServer.js +82 -21
  49. package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -1
  50. package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts +21 -1
  51. package/dist/plus/integrations/providers/bitbucket/bitbucket.js +74 -10
  52. package/dist/plus/integrations/providers/bitbucket/bitbucket.js.map +1 -1
  53. package/dist/plus/integrations/providers/bitbucket/models.d.ts +45 -8
  54. package/dist/plus/integrations/providers/bitbucket/models.js +32 -9
  55. package/dist/plus/integrations/providers/bitbucket/models.js.map +1 -1
  56. package/dist/plus/integrations/providers/bitbucket-server/models.d.ts +2 -6
  57. package/dist/plus/integrations/providers/bitbucket-server/models.js +1 -3
  58. package/dist/plus/integrations/providers/bitbucket-server/models.js.map +1 -1
  59. package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.d.ts +3 -1
  60. package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js +4 -1
  61. package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js.map +1 -1
  62. package/dist/plus/integrations/providers/bitbucket-server.d.ts +2 -2
  63. package/dist/plus/integrations/providers/bitbucket-server.js +7 -5
  64. package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
  65. package/dist/plus/integrations/providers/bitbucket.d.ts +22 -2
  66. package/dist/plus/integrations/providers/bitbucket.js +29 -6
  67. package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
  68. package/dist/plus/integrations/providers/github.d.ts +40 -3
  69. package/dist/plus/integrations/providers/github.js +133 -11
  70. package/dist/plus/integrations/providers/github.js.map +1 -1
  71. package/dist/plus/integrations/providers/gitlab/gitlab.d.ts +34 -1
  72. package/dist/plus/integrations/providers/gitlab/gitlab.js +118 -4
  73. package/dist/plus/integrations/providers/gitlab/gitlab.js.map +1 -1
  74. package/dist/plus/integrations/providers/gitlab/models.d.ts +70 -5
  75. package/dist/plus/integrations/providers/gitlab/models.js +106 -13
  76. package/dist/plus/integrations/providers/gitlab/models.js.map +1 -1
  77. package/dist/plus/integrations/providers/gitlab.d.ts +31 -2
  78. package/dist/plus/integrations/providers/gitlab.js +48 -8
  79. package/dist/plus/integrations/providers/gitlab.js.map +1 -1
  80. package/dist/plus/integrations/providers/jira-server.d.ts +3 -2
  81. package/dist/plus/integrations/providers/jira-server.js +18 -9
  82. package/dist/plus/integrations/providers/jira-server.js.map +1 -1
  83. package/dist/plus/integrations/providers/jira.d.ts +26 -2
  84. package/dist/plus/integrations/providers/jira.js +120 -9
  85. package/dist/plus/integrations/providers/jira.js.map +1 -1
  86. package/dist/plus/integrations/providers/jiraIssueByKey.d.ts +79 -0
  87. package/dist/plus/integrations/providers/jiraIssueByKey.js +58 -7
  88. package/dist/plus/integrations/providers/jiraIssueByKey.js.map +1 -1
  89. package/dist/plus/integrations/providers/linear.d.ts +19 -1
  90. package/dist/plus/integrations/providers/linear.js +105 -7
  91. package/dist/plus/integrations/providers/linear.js.map +1 -1
  92. package/dist/plus/integrations/providers/linearIssuesEtag.d.ts +42 -0
  93. package/dist/plus/integrations/providers/linearIssuesEtag.js +94 -0
  94. package/dist/plus/integrations/providers/linearIssuesEtag.js.map +1 -0
  95. package/dist/plus/integrations/providers/models.d.ts +70 -8
  96. package/dist/plus/integrations/providers/models.js +59 -21
  97. package/dist/plus/integrations/providers/models.js.map +1 -1
  98. package/dist/plus/integrations/providers/providerErrors.js +8 -1
  99. package/dist/plus/integrations/providers/providerErrors.js.map +1 -1
  100. package/dist/plus/integrations/providers/providersApi.d.ts +70 -4
  101. package/dist/plus/integrations/providers/providersApi.js +148 -4
  102. package/dist/plus/integrations/providers/providersApi.js.map +1 -1
  103. package/dist/plus/integrations/providers/pullRequestReviews.d.ts +13 -0
  104. package/dist/plus/integrations/providers/pullRequestReviews.js +30 -6
  105. package/dist/plus/integrations/providers/pullRequestReviews.js.map +1 -1
  106. package/dist/plus/integrations/providers/trello.js +11 -7
  107. package/dist/plus/integrations/providers/trello.js.map +1 -1
  108. package/dist/plus/integrations/providers/utils/providerPaging.d.ts +11 -0
  109. package/dist/plus/integrations/providers/utils/providerPaging.js +47 -1
  110. package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
  111. package/dist/plus/integrations/providers/utils.d.ts +1 -1
  112. package/dist/plus/integrations/reads/batchEtags.d.ts +69 -0
  113. package/dist/plus/integrations/reads/batchEtags.js +114 -0
  114. package/dist/plus/integrations/reads/batchEtags.js.map +1 -0
  115. package/dist/plus/integrations/reads/counts.js +2 -2
  116. package/dist/plus/integrations/reads/counts.js.map +1 -1
  117. package/dist/plus/integrations/reads/currentAccount.js +2 -2
  118. package/dist/plus/integrations/reads/currentAccount.js.map +1 -1
  119. package/dist/plus/integrations/reads/cursors.d.ts +8 -0
  120. package/dist/plus/integrations/reads/cursors.js +5 -3
  121. package/dist/plus/integrations/reads/cursors.js.map +1 -1
  122. package/dist/plus/integrations/reads/drains.d.ts +13 -4
  123. package/dist/plus/integrations/reads/drains.js +29 -5
  124. package/dist/plus/integrations/reads/drains.js.map +1 -1
  125. package/dist/plus/integrations/reads/etag.d.ts +26 -0
  126. package/dist/plus/integrations/reads/etag.js +108 -0
  127. package/dist/plus/integrations/reads/etag.js.map +1 -0
  128. package/dist/plus/integrations/reads/filters.d.ts +8 -0
  129. package/dist/plus/integrations/reads/filters.js +2 -1
  130. package/dist/plus/integrations/reads/filters.js.map +1 -1
  131. package/dist/plus/integrations/reads/hierarchy.js +3 -3
  132. package/dist/plus/integrations/reads/hierarchy.js.map +1 -1
  133. package/dist/plus/integrations/reads/issueBatch.d.ts +47 -16
  134. package/dist/plus/integrations/reads/issueBatch.js +55 -87
  135. package/dist/plus/integrations/reads/issueBatch.js.map +1 -1
  136. package/dist/plus/integrations/reads/issueTracker.d.ts +10 -2
  137. package/dist/plus/integrations/reads/issueTracker.js +23 -6
  138. package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
  139. package/dist/plus/integrations/reads/issues.d.ts +1 -1
  140. package/dist/plus/integrations/reads/issues.js +4 -4
  141. package/dist/plus/integrations/reads/issues.js.map +1 -1
  142. package/dist/plus/integrations/reads/pullRequestBatch.d.ts +44 -6
  143. package/dist/plus/integrations/reads/pullRequestBatch.js +31 -34
  144. package/dist/plus/integrations/reads/pullRequestBatch.js.map +1 -1
  145. package/dist/plus/integrations/reads/pullRequestBranches.d.ts +5 -2
  146. package/dist/plus/integrations/reads/pullRequestBranches.js +4 -3
  147. package/dist/plus/integrations/reads/pullRequestBranches.js.map +1 -1
  148. package/dist/plus/integrations/reads/pullRequests.js +8 -4
  149. package/dist/plus/integrations/reads/pullRequests.js.map +1 -1
  150. package/dist/plus/integrations/reads/sweeps.js +8 -4
  151. package/dist/plus/integrations/reads/sweeps.js.map +1 -1
  152. package/dist/plus/integrations/reads/warnings.d.ts +23 -8
  153. package/dist/plus/integrations/reads/warnings.js +43 -19
  154. package/dist/plus/integrations/reads/warnings.js.map +1 -1
  155. package/dist/plus/integrations/results.d.ts +12 -4
  156. package/dist/plus/integrations/results.js +2 -0
  157. package/dist/plus/integrations/results.js.map +1 -1
  158. package/docs/integrations.md +389 -23
  159. package/docs/kepler-read-api-parity.md +16 -2
  160. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"bitbucket-server.js","names":[],"sources":["../../../../../plus/integrations/src/providers/bitbucket-server.ts"],"sourcesContent":["import type { Account, UnidentifiedAuthor } from '@gitlens/git/models/author.js';\nimport type { DefaultBranch } from '@gitlens/git/models/defaultBranch.js';\nimport type { Issue, IssueShape } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequest, IssueOrPullRequestType } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type {\n\tPullRequest,\n\tPullRequestMergeMethod,\n\tPullRequestSearchCriteria,\n\tPullRequestShape,\n\tPullRequestState,\n\tPullRequestStateFilter,\n} from '@gitlens/git/models/pullRequest.js';\nimport type { GitRemote } from '@gitlens/git/models/remote.js';\nimport type { RepositoryMetadata } from '@gitlens/git/models/repositoryMetadata.js';\nimport type { PullRequestUrlIdentity } from '@gitlens/git/utils/pullRequest.utils.js';\nimport { CancellationError, raceWithSignal } from '@gitlens/utils/cancellation.js';\nimport { md5 } from '@gitlens/utils/crypto.js';\nimport type { Emitter } from '@gitlens/utils/event.js';\nimport type { PagedResult } from '@gitlens/utils/paging.js';\nimport { mapSettledBounded, nonnullSettled } from '@gitlens/utils/promise.js';\nimport type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider.js';\nimport type { IntegrationAuthenticationService } from '../authentication/integrationAuthenticationService.js';\nimport type {\n\tAuthenticationSessionLike as AuthenticationSession,\n\tProviderAuthenticationSession,\n} from '../authentication/models.js';\nimport { toTokenWithInfo } from '../authentication/models.js';\nimport { GitSelfManagedHostIntegrationId, providerFanOutConcurrency } from '../constants.js';\nimport type { IntegrationServiceContext } from '../context.js';\nimport type { ResponseHeaders } from '../errors.js';\nimport { AuthenticationError, getResponseHeader } from '../errors.js';\nimport type { IntegrationConnectionChangeEvent } from '../integrationService.js';\nimport type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';\nimport { GitHostIntegration } from '../models/gitHostIntegration.js';\nimport type { IntegrationKey, ProviderPullRequestCount, ProviderPullRequestSearchPage } from '../models/integration.js';\nimport type { BitbucketServerSearchUser } from './bitbucket-server/pullRequestSearch.js';\nimport { getBitbucketServerPullRequestIdentityFromMaybeUrl } from './bitbucket/bitbucket.utils.js';\nimport type { BitbucketRepositoryDescriptor } from './bitbucket/models.js';\nimport type {\n\tProviderHierarchyResult,\n\tProviderOrganization,\n\tProviderPullRequest,\n\tProviderRepoInput,\n\tProviderRepository,\n} from './models.js';\nimport {\n\tfromProviderPullRequest,\n\tproviderPullRequestMatchesSearch,\n\tProviderPullRequestReviewState,\n\tprovidersMetadata,\n\tPullRequestFilter,\n\ttoProviderPullRequestStates,\n} from './models.js';\nimport type { ProvidersApi } from './providersApi.js';\nimport {\n\tcollectProviderPagedResult,\n\tflatSettledOrThrow,\n\tparsePageCursor,\n\ttoPageCursor,\n} from './utils/providerPaging.js';\n\nconst metadata = providersMetadata[GitSelfManagedHostIntegrationId.BitbucketServer];\nconst authProvider = Object.freeze({ id: metadata.id, scopes: metadata.scopes });\n\nexport class BitbucketServerIntegration extends GitHostIntegration<\n\tGitSelfManagedHostIntegrationId.BitbucketServer,\n\tBitbucketRepositoryDescriptor\n> {\n\treadonly authProvider: IntegrationAuthenticationProviderDescriptor = authProvider;\n\treadonly id = GitSelfManagedHostIntegrationId.BitbucketServer;\n\tprotected readonly key =\n\t\t`${this.id}:${this.domain}` satisfies IntegrationKey<GitSelfManagedHostIntegrationId.BitbucketServer>;\n\treadonly name: string = 'Bitbucket Data Center';\n\n\tconstructor(\n\t\tctx: IntegrationServiceContext,\n\t\tauthenticationService: IntegrationAuthenticationService,\n\t\tgetProvidersApi: () => Promise<ProvidersApi>,\n\t\tdidChangeConnection: Emitter<IntegrationConnectionChangeEvent>,\n\t\tprivate readonly _domain: string,\n\t) {\n\t\tsuper(ctx, authenticationService, getProvidersApi, didChangeConnection);\n\t}\n\n\tget domain(): string {\n\t\treturn this._domain;\n\t}\n\n\tprotected apiBaseUrlFor(session: ProviderAuthenticationSession): string {\n\t\treturn this.getSelfManagedApiBaseUrl(session);\n\t}\n\n\tprotected override async mergeProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\tpr: PullRequest,\n\t\toptions?: {\n\t\t\tmergeMethod?: PullRequestMergeMethod;\n\t\t},\n\t): Promise<boolean> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.mergePullRequest(toTokenWithInfo(this.id, session), pr, {\n\t\t\tmergeMethod: options?.mergeMethod,\n\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t});\n\t}\n\n\tprotected override async getProviderAccountForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\trev: string,\n\t\toptions?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getServerAccountForCommit(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\trev,\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t\t{\n\t\t\t\tavatarSize: options?.avatarSize,\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderAccountForEmail(\n\t\t_session: AuthenticationSession,\n\t\t_repo: BitbucketRepositoryDescriptor,\n\t\t_email: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t): Promise<Account | undefined> {\n\t\treturn Promise.resolve(undefined);\n\t}\n\n\tprotected override async getProviderDefaultBranch(\n\t\t_session: AuthenticationSession,\n\t\t_repo: BitbucketRepositoryDescriptor,\n\t): Promise<DefaultBranch | undefined> {\n\t\treturn Promise.resolve(undefined);\n\t}\n\n\tprotected override async getProviderLinkedIssueOrPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\t{ id }: { id: string; key: string },\n\t\ttype: undefined | IssueOrPullRequestType,\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\tif (type === 'issue') {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getServerPullRequestById(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tid,\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t);\n\t}\n\n\t/**\n\t * One request per target, settled independently so one target's failure rejects only its own slot:\n\t * provider-apis has no single pull request read for Bitbucket, so this uses our own.\n\t */\n\tprotected override async getProviderPullRequestsBatch(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string } } | undefined,\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<PullRequestShape | undefined>[] | undefined> {\n\t\tconst api = await this.authenticationService.apis.bitbucket;\n\t\tif (api == null) return undefined;\n\n\t\tconst tokenWithInfo = toTokenWithInfo(this.id, session);\n\t\treturn mapSettledBounded(coordinates, providerFanOutConcurrency, c =>\n\t\t\tapi.getServerPullRequest(\n\t\t\t\tthis,\n\t\t\t\ttokenWithInfo,\n\t\t\t\tc.owner,\n\t\t\t\tc.repo,\n\t\t\t\tString(c.number),\n\t\t\t\tthis.apiBaseUrlFor(session),\n\t\t\t\t{\n\t\t\t\t\tcurrentAccount: options?.currentAccount,\n\t\t\t\t\tdeferFailure: true,\n\t\t\t\t},\n\t\t\t),\n\t\t);\n\t}\n\n\t/**\n\t * One request per target, settled independently, through our own client: provider-apis' pull request list has\n\t * no source-branch filter. Serves only a branch in the base repository — the manager read refuses a `headOwner`\n\t * naming another owner here, since Bitbucket Data Center finds a branch's pull requests only through the\n\t * repository the branch lives in, and a fork's slug can't be derived from its owner.\n\t */\n\tprotected override async getProviderPullRequestsForBranches(\n\t\tsession: ProviderAuthenticationSession,\n\t\ttargets: readonly { owner: string; repo: string; project?: string; branch: string; headOwner?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string }; limit: number },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<{ pullRequests: PullRequestShape[]; truncated: boolean }>[] | undefined> {\n\t\tconst api = await this.authenticationService.apis.bitbucket;\n\t\tif (api == null) return undefined;\n\n\t\tconst tokenWithInfo = toTokenWithInfo(this.id, session);\n\t\treturn mapSettledBounded(targets, providerFanOutConcurrency, async t => {\n\t\t\tif (t.headOwner != null) {\n\t\t\t\tthrow new Error(`Bitbucket Data Center can't find ${t.branch}'s pull requests in a fork by its owner`);\n\t\t\t}\n\n\t\t\treturn api.getServerPullRequestsForBranch(\n\t\t\t\tthis,\n\t\t\t\ttokenWithInfo,\n\t\t\t\tt.owner,\n\t\t\t\tt.repo,\n\t\t\t\tt.branch,\n\t\t\t\tthis.apiBaseUrlFor(session),\n\t\t\t\t{\n\t\t\t\t\tlimit: options.limit,\n\t\t\t\t\tcurrentAccount: options.currentAccount,\n\t\t\t\t\tdeferFailure: true,\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tprotected override async getProviderIssue(\n\t\t_session: AuthenticationSession,\n\t\t_repo: BitbucketRepositoryDescriptor,\n\t\t_id: string,\n\t): Promise<Issue | undefined> {\n\t\treturn Promise.resolve(undefined);\n\t}\n\n\tprotected override async getProviderPullRequestForBranch(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\tbranch: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t\tinclude?: PullRequestState[];\n\t\t},\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getServerPullRequestForBranch(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tbranch,\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequestForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\trev: string,\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getServerPullRequestForCommit(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\trev,\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\tresource: BitbucketRepositoryDescriptor,\n\t\tid: string,\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getServerPullRequest(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tresource.owner,\n\t\t\tresource.name,\n\t\t\tid,\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t);\n\t}\n\n\tprotected override getProviderPullRequestIdentityFromMaybeUrl(search: string): PullRequestUrlIdentity | undefined {\n\t\treturn getBitbucketServerPullRequestIdentityFromMaybeUrl(search, this.id);\n\t}\n\n\tpublic override async getRepoInfo(repo: {\n\t\towner: string;\n\t\tname: string;\n\t\tproject?: string;\n\t\tconnectionId?: string;\n\t}): Promise<ProviderRepository | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(repo.connectionId, undefined);\n\t\tif (session == null) return undefined;\n\n\t\treturn api.getRepo(toTokenWithInfo(this.id, session), repo.owner, repo.name, repo.project, {\n\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t});\n\t}\n\n\tprotected override async getProviderRepositoryMetadata(\n\t\t_session: AuthenticationSession,\n\t\t_repo: BitbucketRepositoryDescriptor,\n\t\t_cancellation?: AbortSignal,\n\t): Promise<RepositoryMetadata | undefined> {\n\t\treturn Promise.resolve(undefined);\n\t}\n\n\t/**\n\t * Accounts by {@link getAccountKey}. One integration serves every installation on its host, and installations\n\t * mounted at different context paths are different servers whose users differ, even under the same token.\n\t */\n\tprivate _accounts: Map<string, Account | undefined> | undefined;\n\n\t/** The installation the session's reads address, plus the credential — what decides whose account it is. */\n\tprivate getAccountKey(session: ProviderAuthenticationSession): string {\n\t\treturn `${this.apiBaseUrlFor(session)}\\n${session.accessToken}`;\n\t}\n\n\t/**\n\t * The account request the account cache would otherwise answer; see `IntegrationBase.validateCredential`. Needed\n\t * without any discovery cache: a repo-scoped pull request read fans out across its repositories in the SDK with\n\t * no request to the connection first, so a dead token comes back as one refused repository per request.\n\t *\n\t * A project access token never confirms: its bot user authenticates, but `/users` does not list it, so the SDK\n\t * cannot find the current user and the check proves nothing.\n\t */\n\tprotected override async validateCredential(session: ProviderAuthenticationSession): Promise<void> {\n\t\tconst api = await this.getProvidersApi();\n\t\tconst user = await api\n\t\t\t.getCurrentUser(toTokenWithInfo(this.id, session), { baseUrl: this.apiBaseUrlFor(session) })\n\t\t\t.catch((ex: unknown) => {\n\t\t\t\tif (!(ex instanceof AuthenticationError)) throw ex;\n\n\t\t\t\t// Bitbucket Data Center names the user it authenticated in `X-AUSERNAME`, and answers a dead token\n\t\t\t\t// exactly as it answers no credential: the same 401 and body, without that header. So a refusal that\n\t\t\t\t// names a user, or says the user holds no license, came from a credential that authenticated, and\n\t\t\t\t// proves nothing about the scopes' refusals.\n\t\t\t\tconst response = (ex.original as { response?: { headers?: ResponseHeaders } } | undefined)?.response;\n\t\t\t\tif (\n\t\t\t\t\tgetResponseHeader(response?.headers, 'x-ausername') ||\n\t\t\t\t\t/not (?:a|currently) licensed/i.test(ex.original?.message ?? '')\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error('Bitbucket Data Center could not confirm the credential', { cause: ex });\n\t\t\t\t}\n\t\t\t\tthrow ex;\n\t\t\t});\n\t\tif (user == null) {\n\t\t\tthrow new Error('Bitbucket Data Center did not confirm the credential');\n\t\t}\n\t}\n\n\tprotected override async getProviderCurrentAccount(\n\t\tsession: ProviderAuthenticationSession,\n\t): Promise<Account | undefined> {\n\t\tconst key = this.getAccountKey(session);\n\t\tthis._accounts ??= new Map<string, Account | undefined>();\n\n\t\tconst cachedAccount = this._accounts.get(key);\n\t\tif (cachedAccount == null) {\n\t\t\tconst api = await this.getProvidersApi();\n\t\t\tconst user = await api.getCurrentUser(toTokenWithInfo(this.id, session), {\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t});\n\t\t\tthis._accounts.set(\n\t\t\t\tkey,\n\t\t\t\tuser\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tprovider: this,\n\t\t\t\t\t\t\tid: user.id,\n\t\t\t\t\t\t\tname: user.name ?? undefined,\n\t\t\t\t\t\t\temail: user.email ?? undefined,\n\t\t\t\t\t\t\tavatarUrl: user.avatarUrl ?? undefined,\n\t\t\t\t\t\t\tusername: user.username ?? undefined,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\n\t\treturn this._accounts.get(key);\n\t}\n\n\tprotected override async getProviderOrganizationsForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t): Promise<ProviderHierarchyResult<ProviderOrganization>> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.getBitbucketServerProjects(\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t\tsession.id,\n\t\t);\n\t}\n\n\tprotected override async getProviderRepositoriesForOrg(\n\t\tsession: ProviderAuthenticationSession,\n\t\torg: string,\n\t\toptions?: { cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository>> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.getBitbucketServerRepositories(\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t\tsession.id,\n\t\t\t{\n\t\t\t\tproject: org,\n\t\t\t\tcursor: options?.cursor,\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderRepositoriesForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: { cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository>> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.getBitbucketServerRepositories(\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t\tsession.id,\n\t\t\toptions,\n\t\t);\n\t}\n\n\tprotected override async searchProviderMyPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: BitbucketRepositoryDescriptor[],\n\t\t_cancellation?: AbortSignal,\n\t\toptions?: SearchMyPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined> {\n\t\tif (repos != null) {\n\t\t\t// TODO: implement repos version\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst api = await this.getProvidersApi();\n\t\tif (!api) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst prs = await api.getBitbucketServerPullRequestsForCurrentUser(\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t\t{ states: toProviderPullRequestStates(options?.state) },\n\t\t);\n\t\treturn prs?.data.map(pr => fromProviderPullRequest(pr, this));\n\t}\n\n\tprotected override async getProviderMyPullRequestsForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: { state?: PullRequestStateFilter[]; cursor?: string; filters?: PullRequestFilter[] },\n\t): Promise<PagedResult<ProviderPullRequest> | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\tconst states = toProviderPullRequestStates(options?.state);\n\t\t// provider-apis translates the public 1-based `page` to Bitbucket Server's `start` offset and normalizes\n\t\t// `nextPageStart` back to the next page number. Thread that number inside our opaque cursor so the\n\t\t// ProviderBackend sweep drives the drain (bounded by its maxPages).\n\t\tconst page = parsePageCursor(options?.cursor);\n\t\tconst result = await api.getBitbucketServerPullRequestsForCurrentUser(\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t\t{ states: states, page: page },\n\t\t);\n\t\tif (result == null) return undefined;\n\n\t\tconst account = options?.filters?.length ? await this.getProviderCurrentAccount(session) : undefined;\n\t\tconst identifiers = new Set([account?.id, account?.username].filter((id): id is string => id != null));\n\t\tif (options?.filters?.length && identifiers.size === 0) {\n\t\t\tthrow new Error(\n\t\t\t\t'Unable to resolve the current Bitbucket Data Center account for the requested pull request filters.',\n\t\t\t);\n\t\t}\n\n\t\tconst values = options?.filters?.length\n\t\t\t? result.data.filter(pr => {\n\t\t\t\t\tconst isCurrentUser = (user: { id?: string | null; username?: string | null } | null | undefined) =>\n\t\t\t\t\t\tuser != null &&\n\t\t\t\t\t\t((user.id != null && identifiers.has(user.id)) ||\n\t\t\t\t\t\t\t(user.username != null && identifiers.has(user.username)));\n\t\t\t\t\tconst isAuthor = isCurrentUser(pr.author);\n\t\t\t\t\tconst isRequestedReviewer = pr.reviews?.some(\n\t\t\t\t\t\treview =>\n\t\t\t\t\t\t\tisCurrentUser(review.reviewer) &&\n\t\t\t\t\t\t\treview.state === ProviderPullRequestReviewState.ReviewRequested,\n\t\t\t\t\t);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t(options.filters!.includes(PullRequestFilter.Author) && isAuthor) ||\n\t\t\t\t\t\t(options.filters!.includes(PullRequestFilter.ReviewRequested) && isRequestedReviewer)\n\t\t\t\t\t);\n\t\t\t\t})\n\t\t\t: result.data;\n\n\t\treturn {\n\t\t\tvalues: values,\n\t\t\tpaging: {\n\t\t\t\tmore: result.hasMore,\n\t\t\t\tcursor: result.hasMore && result.nextPage != null ? toPageCursor(result.nextPage) : '{}',\n\t\t\t},\n\t\t};\n\t}\n\n\tprotected override async searchProviderPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\tsearchQuery: string,\n\t\trepos?: BitbucketRepositoryDescriptor[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined> {\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\tconst api = await this.getProvidersApi();\n\t\tif (!api) return undefined;\n\n\t\tconst repoInputs =\n\t\t\trepos != null\n\t\t\t\t? repos.map(r => ({ name: r.name, namespace: r.owner }))\n\t\t\t\t: await this.getWorkspaceRepoInputs();\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\t\t// An explicitly-empty `repos` means \"search these zero repos\" -> no results; reserve `undefined`\n\t\t// (\"scope couldn't be determined\") for when no repos were requested and none were discovered.\n\t\tif (repoInputs.length === 0) return repos != null ? [] : undefined;\n\n\t\tconst token = toTokenWithInfo(this.id, session);\n\t\tconst states = toProviderPullRequestStates(options?.include);\n\t\tconst providerPullRequests = await flatSettledOrThrow(\n\t\t\trepoInputs.map(async repo => {\n\t\t\t\tconst result = await collectProviderPagedResult(cursor => {\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\treturn api.getPullRequestsForRepo(token, repo, {\n\t\t\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t\t\tcursor: cursor,\n\t\t\t\t\t\tstates: states,\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t\treturn result.values;\n\t\t\t}),\n\t\t);\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\treturn providerPullRequests\n\t\t\t.filter(pr => providerPullRequestMatchesSearch(pr, searchQuery))\n\t\t\t.map(pr => fromProviderPullRequest(pr, this));\n\t}\n\n\t/**\n\t * The filtered pull-request search, read by this module's own requests rather than the SDK's: the SDK's list\n\t * reads carry no text, draft or participant-status filter and no per-facet continuation. Every request goes to\n\t * the session's own address, context path included, so one connection's cursor can't be replayed on another.\n\t */\n\tprotected override async searchProviderPullRequestsPage(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions: {\n\t\t\trepos?: ProviderRepoInput[];\n\t\t\torg?: string;\n\t\t\tcriteria?: PullRequestSearchCriteria;\n\t\t\tcursor?: string;\n\t\t\tpageSize?: number;\n\t\t\tsummary?: boolean;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderPullRequestSearchPage | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.searchBitbucketServerPullRequestsPage(\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\tconnectionId: session.id,\n\t\t\t\tprovider: this,\n\t\t\t\trepos: options.repos,\n\t\t\t\torg: options.org,\n\t\t\t\tcriteria: options.criteria,\n\t\t\t\tcurrentUser: await this.getSearchUser(session, options.criteria, cancellation),\n\t\t\t\tcursor: options.cursor,\n\t\t\t\tpageSize: options.pageSize,\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t/**\n\t * Counts each scope by reading it, since Bitbucket Data Center has neither a count query nor a total on its\n\t * pages. The facade hands over one scope per call and runs those calls concurrently (see `countPullRequests`),\n\t * so scopes here are counted one after another rather than multiplying that concurrency.\n\t */\n\tprotected override async countProviderPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: PullRequestSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderPullRequestCount[] | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\tconst token = toTokenWithInfo(this.id, session);\n\t\tconst counts: ProviderPullRequestCount[] = [];\n\t\tfor (const scope of scopes) {\n\t\t\tcounts.push(\n\t\t\t\tawait api.countBitbucketServerPullRequests(\n\t\t\t\t\ttoken,\n\t\t\t\t\t{\n\t\t\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t\t\trepos: scope.repos,\n\t\t\t\t\t\torg: scope.org,\n\t\t\t\t\t\tcriteria: scope.criteria,\n\t\t\t\t\t\tcurrentUser: await this.getSearchUser(session, scope.criteria, cancellation),\n\t\t\t\t\t},\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\treturn counts;\n\t}\n\n\t/**\n\t * The session's own user, which a relationship facet filters by. Resolved per session rather than from the\n\t * primary connection, so a read pinned to one account never filters by another's identity; an account that\n\t * can't be resolved refuses the read instead of widening it to everyone's pull requests.\n\t *\n\t * The lookup is raced against `cancellation` so a cancelled read settles at once. The SDK's current-user read\n\t * takes no signal, so the request itself runs on; its answer still lands in the per-token account cache, so a\n\t * cold lookup a cancellation abandoned isn't wasted on the next read.\n\t */\n\tprivate async getSearchUser(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcriteria: PullRequestSearchCriteria | undefined,\n\t\tcancellation: AbortSignal | undefined,\n\t): Promise<BitbucketServerSearchUser | undefined> {\n\t\tif (!criteria?.relationships?.length) return undefined;\n\n\t\tconst lookup = this.getProviderCurrentAccount(session);\n\t\tconst account = await (cancellation != null ? raceWithSignal(lookup, cancellation) : lookup);\n\t\tif (account?.id == null || account.username == null) {\n\t\t\tthrow new Error('Unable to resolve the current Bitbucket Data Center account for a relationship search.');\n\t\t}\n\n\t\treturn { id: account.id, username: account.username };\n\t}\n\n\tprivate async getWorkspaceRepoInputs(): Promise<{ name: string; namespace: string }[]> {\n\t\tconst remotes = await this.ctx.repositories.getOpenRemotes();\n\t\tconst inputs = await nonnullSettled(\n\t\t\tremotes.map(async (r: GitRemote) => {\n\t\t\t\tconst integration = await this.authenticationService.getByRemote(r);\n\t\t\t\tif (integration !== this) return undefined;\n\n\t\t\t\t// Use the remote provider's parsing so the Bitbucket Server `scm/<project>/<repo>` prefix is\n\t\t\t\t// stripped; a raw `path.split('/')` would yield namespace=`scm`, name=`<project>`.\n\t\t\t\tconst namespace = r.provider?.owner;\n\t\t\t\tconst name = r.provider?.repoName;\n\t\t\t\treturn namespace != null && name != null ? { name: name, namespace: namespace } : undefined;\n\t\t\t}),\n\t\t);\n\t\t// Dedupe: a repo with multiple remotes (e.g. `origin` + `upstream`) can map to the same input,\n\t\t// which would otherwise fetch and return the same PRs more than once.\n\t\treturn [...new Map(inputs.map(i => [`${i.namespace}/${i.name}`, i])).values()];\n\t}\n\n\tprotected override async searchProviderMyIssues(\n\t\t_session: AuthenticationSession,\n\t\t_repos?: BitbucketRepositoryDescriptor[],\n\t): Promise<IssueShape[] | undefined> {\n\t\treturn Promise.resolve(undefined);\n\t}\n\n\t/**\n\t * Bitbucket Data Center exposes no issue tracker at all (issues live in Jira), so — like Bitbucket Cloud,\n\t * whose own tracker is deprecated — it is not an issue provider on the ProviderBackend surface. Without this\n\t * the facade would take `supportsIssues`' default `true` and route the read to a provider that registers no\n\t * issue client: the repo-scoped path fails with the SDK's `does not support function: getIssuesForReposFn`\n\t * as an opaque `kind: 'other'` warning, and `broadenIssues` first drains every repo of the org before hitting\n\t * the same failure. Its metadata already declares no issue filters, so this keeps both halves of the\n\t * capability answer consistent.\n\t */\n\toverride get supportsIssues(): boolean {\n\t\treturn false;\n\t}\n\n\tprivate readonly storagePrefix = 'bitbucket-server';\n\tprotected override async providerOnConnect(): Promise<void> {\n\t\tif (this._session == null) return;\n\n\t\tconst accountKey = this.getAccountKey(this._session);\n\t\tconst accountStorageKey = md5(accountKey);\n\n\t\tconst storedAccount = this.ctx.storage.get(`${this.storagePrefix}:${accountStorageKey}:account`);\n\n\t\tlet account: Account | undefined = storedAccount?.data ? { ...storedAccount.data, provider: this } : undefined;\n\n\t\tif (storedAccount == null) {\n\t\t\taccount = await this.getProviderCurrentAccount(this._session);\n\t\t\tif (account != null) {\n\t\t\t\t// Clear all other stored workspaces and repositories and accounts when our session changes\n\t\t\t\tawait this.ctx.storage.deleteWithPrefix(this.storagePrefix);\n\t\t\t\tawait this.ctx.storage.store(`${this.storagePrefix}:${accountStorageKey}:account`, {\n\t\t\t\t\tv: 1,\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tid: account.id,\n\t\t\t\t\t\tname: account.name,\n\t\t\t\t\t\temail: account.email,\n\t\t\t\t\t\tavatarUrl: account.avatarUrl,\n\t\t\t\t\t\tusername: account.username,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis._accounts ??= new Map<string, Account | undefined>();\n\t\tthis._accounts.set(accountKey, account);\n\t}\n\n\tprotected override providerOnDisconnect(): void {\n\t\tthis._accounts = undefined;\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bitbucket-server.js","names":[],"sources":["../../../../../plus/integrations/src/providers/bitbucket-server.ts"],"sourcesContent":["import type { Account, UnidentifiedAuthor } from '@gitlens/git/models/author.js';\nimport type { DefaultBranch } from '@gitlens/git/models/defaultBranch.js';\nimport type { Issue, IssueShape } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequest, IssueOrPullRequestType } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type {\n\tPullRequest,\n\tPullRequestMergeMethod,\n\tPullRequestSearchCriteria,\n\tPullRequestShape,\n\tPullRequestState,\n\tPullRequestStateFilter,\n} from '@gitlens/git/models/pullRequest.js';\nimport type { GitRemote } from '@gitlens/git/models/remote.js';\nimport type { RepositoryMetadata } from '@gitlens/git/models/repositoryMetadata.js';\nimport type { PullRequestUrlIdentity } from '@gitlens/git/utils/pullRequest.utils.js';\nimport { CancellationError, raceWithSignal } from '@gitlens/utils/cancellation.js';\nimport { md5 } from '@gitlens/utils/crypto.js';\nimport type { Emitter } from '@gitlens/utils/event.js';\nimport type { PagedResult } from '@gitlens/utils/paging.js';\nimport { mapSettledBounded, nonnullSettled } from '@gitlens/utils/promise.js';\nimport type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider.js';\nimport type { IntegrationAuthenticationService } from '../authentication/integrationAuthenticationService.js';\nimport type {\n\tAuthenticationSessionLike as AuthenticationSession,\n\tProviderAuthenticationSession,\n} from '../authentication/models.js';\nimport { toTokenWithInfo } from '../authentication/models.js';\nimport { GitSelfManagedHostIntegrationId, providerFanOutConcurrency } from '../constants.js';\nimport type { IntegrationServiceContext } from '../context.js';\nimport type { ResponseHeaders } from '../errors.js';\nimport { AuthenticationError, getResponseHeader } from '../errors.js';\nimport type { IntegrationConnectionChangeEvent } from '../integrationService.js';\nimport type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';\nimport { GitHostIntegration } from '../models/gitHostIntegration.js';\nimport type { IntegrationKey, ProviderPullRequestCount, ProviderPullRequestSearchPage } from '../models/integration.js';\nimport type { BitbucketServerSearchUser } from './bitbucket-server/pullRequestSearch.js';\nimport { getBitbucketServerPullRequestIdentityFromMaybeUrl } from './bitbucket/bitbucket.utils.js';\nimport type { BitbucketRepositoryDescriptor } from './bitbucket/models.js';\nimport type {\n\tProviderHierarchyResult,\n\tProviderOrganization,\n\tProviderPullRequest,\n\tProviderRepoInput,\n\tProviderRepository,\n} from './models.js';\nimport {\n\tfromProviderPullRequest,\n\tproviderPullRequestMatchesSearch,\n\tProviderPullRequestReviewState,\n\tprovidersMetadata,\n\tPullRequestFilter,\n\ttoProviderPullRequestStates,\n} from './models.js';\nimport type { ProvidersApi } from './providersApi.js';\nimport {\n\tcollectProviderPagedResult,\n\tflatSettledOrThrow,\n\tparsePageCursor,\n\ttoPageCursor,\n} from './utils/providerPaging.js';\n\nconst metadata = providersMetadata[GitSelfManagedHostIntegrationId.BitbucketServer];\nconst authProvider = Object.freeze({ id: metadata.id, scopes: metadata.scopes });\n\nexport class BitbucketServerIntegration extends GitHostIntegration<\n\tGitSelfManagedHostIntegrationId.BitbucketServer,\n\tBitbucketRepositoryDescriptor\n> {\n\treadonly authProvider: IntegrationAuthenticationProviderDescriptor = authProvider;\n\treadonly id = GitSelfManagedHostIntegrationId.BitbucketServer;\n\tprotected readonly key =\n\t\t`${this.id}:${this.domain}` satisfies IntegrationKey<GitSelfManagedHostIntegrationId.BitbucketServer>;\n\treadonly name: string = 'Bitbucket Data Center';\n\n\tconstructor(\n\t\tctx: IntegrationServiceContext,\n\t\tauthenticationService: IntegrationAuthenticationService,\n\t\tgetProvidersApi: () => Promise<ProvidersApi>,\n\t\tdidChangeConnection: Emitter<IntegrationConnectionChangeEvent>,\n\t\tprivate readonly _domain: string,\n\t) {\n\t\tsuper(ctx, authenticationService, getProvidersApi, didChangeConnection);\n\t}\n\n\tget domain(): string {\n\t\treturn this._domain;\n\t}\n\n\tprotected apiBaseUrlFor(session: ProviderAuthenticationSession): string {\n\t\treturn this.getSelfManagedApiBaseUrl(session);\n\t}\n\n\tprotected override async mergeProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\tpr: PullRequest,\n\t\toptions?: {\n\t\t\tmergeMethod?: PullRequestMergeMethod;\n\t\t},\n\t): Promise<boolean> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.mergePullRequest(toTokenWithInfo(this.id, session), pr, {\n\t\t\tmergeMethod: options?.mergeMethod,\n\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t});\n\t}\n\n\tprotected override async getProviderAccountForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\trev: string,\n\t\toptions?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getServerAccountForCommit(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\trev,\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t\t{\n\t\t\t\tavatarSize: options?.avatarSize,\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderAccountForEmail(\n\t\t_session: AuthenticationSession,\n\t\t_repo: BitbucketRepositoryDescriptor,\n\t\t_email: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t): Promise<Account | undefined> {\n\t\treturn Promise.resolve(undefined);\n\t}\n\n\tprotected override async getProviderDefaultBranch(\n\t\t_session: AuthenticationSession,\n\t\t_repo: BitbucketRepositoryDescriptor,\n\t): Promise<DefaultBranch | undefined> {\n\t\treturn Promise.resolve(undefined);\n\t}\n\n\tprotected override async getProviderLinkedIssueOrPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\t{ id }: { id: string; key: string },\n\t\ttype: undefined | IssueOrPullRequestType,\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\tif (type === 'issue') {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getServerPullRequestById(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tid,\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t);\n\t}\n\n\t/**\n\t * One request per target, settled independently so one target's failure rejects only its own slot:\n\t * provider-apis has no single pull request read for Bitbucket, so this uses our own.\n\t */\n\tprotected override async getProviderPullRequestsBatch(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string } } | undefined,\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<PullRequestShape | undefined>[] | undefined> {\n\t\tconst api = await this.authenticationService.apis.bitbucket;\n\t\tif (api == null) return undefined;\n\n\t\tconst tokenWithInfo = toTokenWithInfo(this.id, session);\n\t\treturn mapSettledBounded(coordinates, providerFanOutConcurrency, c =>\n\t\t\tapi.getServerPullRequest(\n\t\t\t\tthis,\n\t\t\t\ttokenWithInfo,\n\t\t\t\tc.owner,\n\t\t\t\tc.repo,\n\t\t\t\tString(c.number),\n\t\t\t\tthis.apiBaseUrlFor(session),\n\t\t\t\t{\n\t\t\t\t\tcurrentAccount: options?.currentAccount,\n\t\t\t\t\tdeferFailure: true,\n\t\t\t\t\tprojection: 'batch',\n\t\t\t\t},\n\t\t\t),\n\t\t);\n\t}\n\n\t/**\n\t * One request per target, settled independently, through our own client: provider-apis' pull request list has\n\t * no source-branch filter. Serves only a branch in the base repository — the manager read refuses a `headOwner`\n\t * naming another owner here, since Bitbucket Data Center finds a branch's pull requests only through the\n\t * repository the branch lives in, and a fork's slug can't be derived from its owner.\n\t */\n\tprotected override async getProviderPullRequestsForBranches(\n\t\tsession: ProviderAuthenticationSession,\n\t\ttargets: readonly { owner: string; repo: string; project?: string; branch: string; headOwner?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string }; limit: number },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<{ pullRequests: PullRequestShape[]; truncated: boolean }>[] | undefined> {\n\t\tconst api = await this.authenticationService.apis.bitbucket;\n\t\tif (api == null) return undefined;\n\n\t\tconst tokenWithInfo = toTokenWithInfo(this.id, session);\n\t\treturn mapSettledBounded(targets, providerFanOutConcurrency, async t => {\n\t\t\tif (t.headOwner != null) {\n\t\t\t\tthrow new Error(`Bitbucket Data Center can't find ${t.branch}'s pull requests in a fork by its owner`);\n\t\t\t}\n\n\t\t\treturn api.getServerPullRequestsForBranch(\n\t\t\t\tthis,\n\t\t\t\ttokenWithInfo,\n\t\t\t\tt.owner,\n\t\t\t\tt.repo,\n\t\t\t\tt.branch,\n\t\t\t\tthis.apiBaseUrlFor(session),\n\t\t\t\t{\n\t\t\t\t\tlimit: options.limit,\n\t\t\t\t\tcurrentAccount: options.currentAccount,\n\t\t\t\t\tdeferFailure: true,\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tprotected override async getProviderIssue(\n\t\t_session: AuthenticationSession,\n\t\t_repo: BitbucketRepositoryDescriptor,\n\t\t_id: string,\n\t): Promise<Issue | undefined> {\n\t\treturn Promise.resolve(undefined);\n\t}\n\n\tprotected override async getProviderPullRequestForBranch(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\tbranch: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t\tinclude?: PullRequestState[];\n\t\t},\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getServerPullRequestForBranch(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tbranch,\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequestForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\trev: string,\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getServerPullRequestForCommit(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\trev,\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\tresource: BitbucketRepositoryDescriptor,\n\t\tid: string,\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getServerPullRequest(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tresource.owner,\n\t\t\tresource.name,\n\t\t\tid,\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t\t{ projection: 'point' },\n\t\t);\n\t}\n\n\tprotected override getProviderPullRequestIdentityFromMaybeUrl(search: string): PullRequestUrlIdentity | undefined {\n\t\treturn getBitbucketServerPullRequestIdentityFromMaybeUrl(search, this.id);\n\t}\n\n\tpublic override async getRepoInfo(repo: {\n\t\towner: string;\n\t\tname: string;\n\t\tproject?: string;\n\t\tconnectionId?: string;\n\t}): Promise<ProviderRepository | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(repo.connectionId, undefined);\n\t\tif (session == null) return undefined;\n\n\t\treturn api.getRepo(toTokenWithInfo(this.id, session), repo.owner, repo.name, repo.project, {\n\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t});\n\t}\n\n\tprotected override async getProviderRepositoryMetadata(\n\t\t_session: AuthenticationSession,\n\t\t_repo: BitbucketRepositoryDescriptor,\n\t\t_cancellation?: AbortSignal,\n\t): Promise<RepositoryMetadata | undefined> {\n\t\treturn Promise.resolve(undefined);\n\t}\n\n\t/**\n\t * Accounts by {@link getAccountKey}. One integration serves every installation on its host, and installations\n\t * mounted at different context paths are different servers whose users differ, even under the same token.\n\t */\n\tprivate _accounts: Map<string, Account | undefined> | undefined;\n\n\t/** The installation the session's reads address, plus the credential — what decides whose account it is. */\n\tprivate getAccountKey(session: ProviderAuthenticationSession): string {\n\t\treturn `${this.apiBaseUrlFor(session)}\\n${session.accessToken}`;\n\t}\n\n\t/**\n\t * The account request the account cache would otherwise answer; see `IntegrationBase.validateCredential`. Needed\n\t * without any discovery cache: a repo-scoped pull request read fans out across its repositories in the SDK with\n\t * no request to the connection first, so a dead token comes back as one refused repository per request.\n\t *\n\t * A project access token never confirms: its bot user authenticates, but `/users` does not list it, so the SDK\n\t * cannot find the current user and the check proves nothing.\n\t */\n\tprotected override async validateCredential(session: ProviderAuthenticationSession): Promise<void> {\n\t\tconst api = await this.getProvidersApi();\n\t\tconst user = await api\n\t\t\t.getCurrentUser(toTokenWithInfo(this.id, session), { baseUrl: this.apiBaseUrlFor(session) })\n\t\t\t.catch((ex: unknown) => {\n\t\t\t\tif (!(ex instanceof AuthenticationError)) throw ex;\n\n\t\t\t\t// Bitbucket Data Center names the user it authenticated in `X-AUSERNAME`, and answers a dead token\n\t\t\t\t// exactly as it answers no credential: the same 401 and body, without that header. So a refusal that\n\t\t\t\t// names a user, or says the user holds no license, came from a credential that authenticated, and\n\t\t\t\t// proves nothing about the scopes' refusals.\n\t\t\t\tconst response = (ex.original as { response?: { headers?: ResponseHeaders } } | undefined)?.response;\n\t\t\t\tif (\n\t\t\t\t\tgetResponseHeader(response?.headers, 'x-ausername') ||\n\t\t\t\t\t/not (?:a|currently) licensed/i.test(ex.original?.message ?? '')\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error('Bitbucket Data Center could not confirm the credential', { cause: ex });\n\t\t\t\t}\n\t\t\t\tthrow ex;\n\t\t\t});\n\t\tif (user == null) {\n\t\t\tthrow new Error('Bitbucket Data Center did not confirm the credential');\n\t\t}\n\t}\n\n\tprotected override async getProviderCurrentAccount(\n\t\tsession: ProviderAuthenticationSession,\n\t): Promise<Account | undefined> {\n\t\tconst key = this.getAccountKey(session);\n\t\tthis._accounts ??= new Map<string, Account | undefined>();\n\n\t\tconst cachedAccount = this._accounts.get(key);\n\t\tif (cachedAccount == null) {\n\t\t\tconst api = await this.getProvidersApi();\n\t\t\tconst user = await api.getCurrentUser(toTokenWithInfo(this.id, session), {\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t});\n\t\t\tthis._accounts.set(\n\t\t\t\tkey,\n\t\t\t\tuser\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tprovider: this,\n\t\t\t\t\t\t\tid: user.id,\n\t\t\t\t\t\t\tname: user.name ?? undefined,\n\t\t\t\t\t\t\temail: user.email ?? undefined,\n\t\t\t\t\t\t\tavatarUrl: user.avatarUrl ?? undefined,\n\t\t\t\t\t\t\tusername: user.username ?? undefined,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\n\t\treturn this._accounts.get(key);\n\t}\n\n\tprotected override async getProviderOrganizationsForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t): Promise<ProviderHierarchyResult<ProviderOrganization>> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.getBitbucketServerProjects(\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t\tsession.id,\n\t\t);\n\t}\n\n\tprotected override async getProviderRepositoriesForOrg(\n\t\tsession: ProviderAuthenticationSession,\n\t\torg: string,\n\t\toptions?: { cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository>> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.getBitbucketServerRepositories(\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t\tsession.id,\n\t\t\t{\n\t\t\t\tproject: org,\n\t\t\t\tcursor: options?.cursor,\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderRepositoriesForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: { cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository>> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.getBitbucketServerRepositories(\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t\tsession.id,\n\t\t\toptions,\n\t\t);\n\t}\n\n\tprotected override async searchProviderMyPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: BitbucketRepositoryDescriptor[],\n\t\t_cancellation?: AbortSignal,\n\t\toptions?: SearchMyPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined> {\n\t\tif (repos != null) {\n\t\t\t// TODO: implement repos version\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst api = await this.getProvidersApi();\n\t\tif (!api) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst prs = await api.getBitbucketServerPullRequestsForCurrentUser(\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t\t{ states: toProviderPullRequestStates(options?.state) },\n\t\t);\n\t\treturn prs?.data.map(pr => fromProviderPullRequest(pr, this, { projection: 'search' }));\n\t}\n\n\tprotected override async getProviderMyPullRequestsForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: { state?: PullRequestStateFilter[]; cursor?: string; filters?: PullRequestFilter[] },\n\t): Promise<PagedResult<ProviderPullRequest> | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\tconst states = toProviderPullRequestStates(options?.state);\n\t\t// provider-apis translates the public 1-based `page` to Bitbucket Server's `start` offset and normalizes\n\t\t// `nextPageStart` back to the next page number. Thread that number inside our opaque cursor so the\n\t\t// ProviderBackend sweep drives the drain (bounded by its maxPages).\n\t\tconst page = parsePageCursor(options?.cursor);\n\t\tconst result = await api.getBitbucketServerPullRequestsForCurrentUser(\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tthis.apiBaseUrlFor(session),\n\t\t\t{ states: states, page: page },\n\t\t);\n\t\tif (result == null) return undefined;\n\n\t\tconst account = options?.filters?.length ? await this.getProviderCurrentAccount(session) : undefined;\n\t\tconst identifiers = new Set([account?.id, account?.username].filter((id): id is string => id != null));\n\t\tif (options?.filters?.length && identifiers.size === 0) {\n\t\t\tthrow new Error(\n\t\t\t\t'Unable to resolve the current Bitbucket Data Center account for the requested pull request filters.',\n\t\t\t);\n\t\t}\n\n\t\tconst values = options?.filters?.length\n\t\t\t? result.data.filter(pr => {\n\t\t\t\t\tconst isCurrentUser = (user: { id?: string | null; username?: string | null } | null | undefined) =>\n\t\t\t\t\t\tuser != null &&\n\t\t\t\t\t\t((user.id != null && identifiers.has(user.id)) ||\n\t\t\t\t\t\t\t(user.username != null && identifiers.has(user.username)));\n\t\t\t\t\tconst isAuthor = isCurrentUser(pr.author);\n\t\t\t\t\tconst isRequestedReviewer = pr.reviews?.some(\n\t\t\t\t\t\treview =>\n\t\t\t\t\t\t\tisCurrentUser(review.reviewer) &&\n\t\t\t\t\t\t\treview.state === ProviderPullRequestReviewState.ReviewRequested,\n\t\t\t\t\t);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t(options.filters!.includes(PullRequestFilter.Author) && isAuthor) ||\n\t\t\t\t\t\t(options.filters!.includes(PullRequestFilter.ReviewRequested) && isRequestedReviewer)\n\t\t\t\t\t);\n\t\t\t\t})\n\t\t\t: result.data;\n\n\t\treturn {\n\t\t\tvalues: values,\n\t\t\tpaging: {\n\t\t\t\tmore: result.hasMore,\n\t\t\t\tcursor: result.hasMore && result.nextPage != null ? toPageCursor(result.nextPage) : '{}',\n\t\t\t},\n\t\t};\n\t}\n\n\tprotected override async searchProviderPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\tsearchQuery: string,\n\t\trepos?: BitbucketRepositoryDescriptor[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined> {\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\tconst api = await this.getProvidersApi();\n\t\tif (!api) return undefined;\n\n\t\tconst repoInputs =\n\t\t\trepos != null\n\t\t\t\t? repos.map(r => ({ name: r.name, namespace: r.owner }))\n\t\t\t\t: await this.getWorkspaceRepoInputs();\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\t\t// An explicitly-empty `repos` means \"search these zero repos\" -> no results; reserve `undefined`\n\t\t// (\"scope couldn't be determined\") for when no repos were requested and none were discovered.\n\t\tif (repoInputs.length === 0) return repos != null ? [] : undefined;\n\n\t\tconst token = toTokenWithInfo(this.id, session);\n\t\tconst states = toProviderPullRequestStates(options?.include);\n\t\tconst providerPullRequests = await flatSettledOrThrow(\n\t\t\trepoInputs.map(async repo => {\n\t\t\t\tconst result = await collectProviderPagedResult(cursor => {\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\treturn api.getPullRequestsForRepo(token, repo, {\n\t\t\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t\t\tcursor: cursor,\n\t\t\t\t\t\tstates: states,\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t\treturn result.values;\n\t\t\t}),\n\t\t);\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\treturn providerPullRequests\n\t\t\t.filter(pr => providerPullRequestMatchesSearch(pr, searchQuery))\n\t\t\t.map(pr => fromProviderPullRequest(pr, this, { projection: 'text-search' }));\n\t}\n\n\t/**\n\t * The filtered pull-request search, read by this module's own requests rather than the SDK's: the SDK's list\n\t * reads carry no text, draft or participant-status filter and no per-facet continuation. Every request goes to\n\t * the session's own address, context path included, so one connection's cursor can't be replayed on another.\n\t */\n\tprotected override async searchProviderPullRequestsPage(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions: {\n\t\t\trepos?: ProviderRepoInput[];\n\t\t\torg?: string;\n\t\t\tcriteria?: PullRequestSearchCriteria;\n\t\t\tcursor?: string;\n\t\t\tpageSize?: number;\n\t\t\tsummary?: boolean;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderPullRequestSearchPage | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.searchBitbucketServerPullRequestsPage(\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\tconnectionId: session.id,\n\t\t\t\tprovider: this,\n\t\t\t\trepos: options.repos,\n\t\t\t\torg: options.org,\n\t\t\t\tcriteria: options.criteria,\n\t\t\t\tcurrentUser: await this.getSearchUser(session, options.criteria, cancellation),\n\t\t\t\tcursor: options.cursor,\n\t\t\t\tpageSize: options.pageSize,\n\t\t\t\tprojection: options.summary ? 'search-summary' : 'search',\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t/**\n\t * Counts each scope by reading it, since Bitbucket Data Center has neither a count query nor a total on its\n\t * pages. The facade hands over one scope per call and runs those calls concurrently (see `countPullRequests`),\n\t * so scopes here are counted one after another rather than multiplying that concurrency.\n\t */\n\tprotected override async countProviderPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: PullRequestSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderPullRequestCount[] | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\tconst token = toTokenWithInfo(this.id, session);\n\t\tconst counts: ProviderPullRequestCount[] = [];\n\t\tfor (const scope of scopes) {\n\t\t\tcounts.push(\n\t\t\t\tawait api.countBitbucketServerPullRequests(\n\t\t\t\t\ttoken,\n\t\t\t\t\t{\n\t\t\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t\t\trepos: scope.repos,\n\t\t\t\t\t\torg: scope.org,\n\t\t\t\t\t\tcriteria: scope.criteria,\n\t\t\t\t\t\tcurrentUser: await this.getSearchUser(session, scope.criteria, cancellation),\n\t\t\t\t\t},\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\treturn counts;\n\t}\n\n\t/**\n\t * The session's own user, which a relationship facet filters by. Resolved per session rather than from the\n\t * primary connection, so a read pinned to one account never filters by another's identity; an account that\n\t * can't be resolved refuses the read instead of widening it to everyone's pull requests.\n\t *\n\t * The lookup is raced against `cancellation` so a cancelled read settles at once. The SDK's current-user read\n\t * takes no signal, so the request itself runs on; its answer still lands in the per-token account cache, so a\n\t * cold lookup a cancellation abandoned isn't wasted on the next read.\n\t */\n\tprivate async getSearchUser(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcriteria: PullRequestSearchCriteria | undefined,\n\t\tcancellation: AbortSignal | undefined,\n\t): Promise<BitbucketServerSearchUser | undefined> {\n\t\tif (!criteria?.relationships?.length) return undefined;\n\n\t\tconst lookup = this.getProviderCurrentAccount(session);\n\t\tconst account = await (cancellation != null ? raceWithSignal(lookup, cancellation) : lookup);\n\t\tif (account?.id == null || account.username == null) {\n\t\t\tthrow new Error('Unable to resolve the current Bitbucket Data Center account for a relationship search.');\n\t\t}\n\n\t\treturn { id: account.id, username: account.username };\n\t}\n\n\tprivate async getWorkspaceRepoInputs(): Promise<{ name: string; namespace: string }[]> {\n\t\tconst remotes = await this.ctx.repositories.getOpenRemotes();\n\t\tconst inputs = await nonnullSettled(\n\t\t\tremotes.map(async (r: GitRemote) => {\n\t\t\t\tconst integration = await this.authenticationService.getByRemote(r);\n\t\t\t\tif (integration !== this) return undefined;\n\n\t\t\t\t// Use the remote provider's parsing so the Bitbucket Server `scm/<project>/<repo>` prefix is\n\t\t\t\t// stripped; a raw `path.split('/')` would yield namespace=`scm`, name=`<project>`.\n\t\t\t\tconst namespace = r.provider?.owner;\n\t\t\t\tconst name = r.provider?.repoName;\n\t\t\t\treturn namespace != null && name != null ? { name: name, namespace: namespace } : undefined;\n\t\t\t}),\n\t\t);\n\t\t// Dedupe: a repo with multiple remotes (e.g. `origin` + `upstream`) can map to the same input,\n\t\t// which would otherwise fetch and return the same PRs more than once.\n\t\treturn [...new Map(inputs.map(i => [`${i.namespace}/${i.name}`, i])).values()];\n\t}\n\n\tprotected override async searchProviderMyIssues(\n\t\t_session: AuthenticationSession,\n\t\t_repos?: BitbucketRepositoryDescriptor[],\n\t): Promise<IssueShape[] | undefined> {\n\t\treturn Promise.resolve(undefined);\n\t}\n\n\t/**\n\t * Bitbucket Data Center exposes no issue tracker at all (issues live in Jira), so — like Bitbucket Cloud,\n\t * whose own tracker is deprecated — it is not an issue provider on the ProviderBackend surface. Without this\n\t * the facade would take `supportsIssues`' default `true` and route the read to a provider that registers no\n\t * issue client: the repo-scoped path fails with the SDK's `does not support function: getIssuesForReposFn`\n\t * as an opaque `kind: 'other'` warning, and `broadenIssues` first drains every repo of the org before hitting\n\t * the same failure. Its metadata already declares no issue filters, so this keeps both halves of the\n\t * capability answer consistent.\n\t */\n\toverride get supportsIssues(): boolean {\n\t\treturn false;\n\t}\n\n\tprivate readonly storagePrefix = 'bitbucket-server';\n\tprotected override async providerOnConnect(): Promise<void> {\n\t\tif (this._session == null) return;\n\n\t\tconst accountKey = this.getAccountKey(this._session);\n\t\tconst accountStorageKey = md5(accountKey);\n\n\t\tconst storedAccount = this.ctx.storage.get(`${this.storagePrefix}:${accountStorageKey}:account`);\n\n\t\tlet account: Account | undefined = storedAccount?.data ? { ...storedAccount.data, provider: this } : undefined;\n\n\t\tif (storedAccount == null) {\n\t\t\taccount = await this.getProviderCurrentAccount(this._session);\n\t\t\tif (account != null) {\n\t\t\t\t// Clear all other stored workspaces and repositories and accounts when our session changes\n\t\t\t\tawait this.ctx.storage.deleteWithPrefix(this.storagePrefix);\n\t\t\t\tawait this.ctx.storage.store(`${this.storagePrefix}:${accountStorageKey}:account`, {\n\t\t\t\t\tv: 1,\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tid: account.id,\n\t\t\t\t\t\tname: account.name,\n\t\t\t\t\t\temail: account.email,\n\t\t\t\t\t\tavatarUrl: account.avatarUrl,\n\t\t\t\t\t\tusername: account.username,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis._accounts ??= new Map<string, Account | undefined>();\n\t\tthis._accounts.set(accountKey, account);\n\t}\n\n\tprotected override providerOnDisconnect(): void {\n\t\tthis._accounts = undefined;\n\t}\n}\n"],"mappings":"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"}
@@ -9,10 +9,11 @@ import { AuthenticationSessionLike, ProviderAuthenticationSession } from "../aut
9
9
  import { GitCloudHostIntegrationId } from "../constants.js";
10
10
  import { ProviderOrganization } from "../results.js";
11
11
  import { ProviderRefusal } from "../collectionMetadata.js";
12
- import { GitHostIntegration, SearchMyPullRequestsOptions, SearchPullRequestsOptions } from "../models/gitHostIntegration.js";
13
12
  import { ProviderApiPagedResult, ProviderHierarchyResult, ProviderPullRequest, ProviderRepository } from "./models.js";
14
- import { IntegrationAuthenticationProviderDescriptor } from "../authentication/integrationAuthenticationProvider.js";
13
+ import { GitHostIntegration, SearchMyPullRequestsOptions, SearchPullRequestsOptions } from "../models/gitHostIntegration.js";
14
+ import { PullRequestEtagFields, PullRequestEtagInclude } from "../models/integration.js";
15
15
  import { BitbucketRepositoryDescriptor } from "./bitbucket/models.js";
16
+ import { IntegrationAuthenticationProviderDescriptor } from "../authentication/integrationAuthenticationProvider.js";
16
17
  //#region ../plus/integrations/src/providers/bitbucket.d.ts
17
18
  export declare class BitbucketIntegration extends GitHostIntegration<GitCloudHostIntegrationId.Bitbucket, BitbucketRepositoryDescriptor> {
18
19
  readonly authProvider: IntegrationAuthenticationProviderDescriptor;
@@ -56,6 +57,25 @@ export declare class BitbucketIntegration extends GitHostIntegration<GitCloudHos
56
57
  username?: string;
57
58
  };
58
59
  } | undefined, _cancellation?: AbortSignal): Promise<PromiseSettledResult<PullRequestShape | undefined>[] | undefined>;
60
+ /**
61
+ * The cheap check behind the batch pull request read's etags: GitLens' own client lists each repository's pull
62
+ * requests by id, up to {@link bitbucketEtagFieldsMaxIds} in ONE request, where
63
+ * {@link getProviderPullRequestsBatch} sends one per target, and selects only the fields its rows' etags read.
64
+ * Each is converted as {@link fromBitbucketPullRequest} converts the full one, so both reads compute the same
65
+ * etag. A request that throws rejects only its own targets' slots.
66
+ *
67
+ * The full row reads neither a mergeability nor a check rollup, so its etag sees a pull request's state, draft
68
+ * flag, update time and head commit, plus its participants' review decision when included; the `mergeable` and
69
+ * `checks` includes add nothing and cost nothing.
70
+ */
71
+ protected getProviderPullRequestsEtagFields(session: ProviderAuthenticationSession, coordinates: readonly {
72
+ owner: string;
73
+ repo: string;
74
+ number: number;
75
+ project?: string;
76
+ }[], options: {
77
+ etagIncludes?: readonly PullRequestEtagInclude[];
78
+ }, cancellation?: AbortSignal): Promise<PromiseSettledResult<PullRequestEtagFields | undefined>[] | undefined>;
59
79
  /**
60
80
  * One request per target, settled independently, through our own client: provider-apis' pull request list has
61
81
  * no source-branch filter.
@@ -6,8 +6,9 @@ import "../../../git/models/pullRequest.js";
6
6
  import "../constants.js";
7
7
  import { toCollectionScopeFailure } from "../collectionMetadata.js";
8
8
  import { toTokenWithInfo } from "../authentication/models.js";
9
- import { collectProviderPagedResult, flatSettledOrThrow, mergeCollectionMetadata, parsePageCursor, toPageCursor } from "./utils/providerPaging.js";
9
+ import { collectProviderPagedResult, flatSettledOrThrow, mergeCollectionMetadata, parsePageCursor, readEtagFieldsByRepository, toPageCursor } from "./utils/providerPaging.js";
10
10
  import { fromProviderPullRequest, getProviderPullRequestIdentity, providersMetadata, toProviderPullRequestStates } from "./models.js";
11
+ import { toBitbucketPullRequestEtagFields } from "./bitbucket/models.js";
11
12
  import { GitHostIntegration } from "../models/gitHostIntegration.js";
12
13
  import { getBitbucketPullRequestIdentityFromMaybeUrl } from "./bitbucket/bitbucket.utils.js";
13
14
  //#region ../plus/integrations/src/providers/bitbucket.ts
@@ -58,10 +59,32 @@ var BitbucketIntegration = class extends GitHostIntegration {
58
59
  const tokenWithInfo = toTokenWithInfo(this.id, session);
59
60
  return mapSettledBounded(coordinates, 6, (c) => api.getPullRequest(this, tokenWithInfo, c.owner, c.repo, String(c.number), this.apiBaseUrl, {
60
61
  currentAccount: options?.currentAccount,
61
- deferFailure: true
62
+ deferFailure: true,
63
+ projection: "batch"
62
64
  }));
63
65
  }
64
66
  /**
67
+ * The cheap check behind the batch pull request read's etags: GitLens' own client lists each repository's pull
68
+ * requests by id, up to {@link bitbucketEtagFieldsMaxIds} in ONE request, where
69
+ * {@link getProviderPullRequestsBatch} sends one per target, and selects only the fields its rows' etags read.
70
+ * Each is converted as {@link fromBitbucketPullRequest} converts the full one, so both reads compute the same
71
+ * etag. A request that throws rejects only its own targets' slots.
72
+ *
73
+ * The full row reads neither a mergeability nor a check rollup, so its etag sees a pull request's state, draft
74
+ * flag, update time and head commit, plus its participants' review decision when included; the `mergeable` and
75
+ * `checks` includes add nothing and cost nothing.
76
+ */
77
+ async getProviderPullRequestsEtagFields(session, coordinates, options, cancellation) {
78
+ const api = await this.authenticationService.apis.bitbucket;
79
+ if (api == null) return void 0;
80
+ const tokenWithInfo = toTokenWithInfo(this.id, session);
81
+ const etagIncludes = options.etagIncludes ?? [];
82
+ return readEtagFieldsByRepository(coordinates, 50, (owner, repo, ids) => api.getPullRequestsEtagFields(this, tokenWithInfo, owner, repo, ids, this.apiBaseUrl, {
83
+ etagIncludes,
84
+ deferFailure: true
85
+ }, cancellation), (node) => toBitbucketPullRequestEtagFields(node, etagIncludes));
86
+ }
87
+ /**
65
88
  * One request per target, settled independently, through our own client: provider-apis' pull request list has
66
89
  * no source-branch filter.
67
90
  */
@@ -86,7 +109,7 @@ var BitbucketIntegration = class extends GitHostIntegration {
86
109
  return (await this.authenticationService.apis.bitbucket)?.getPullRequestForCommit(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, rev, this.apiBaseUrl);
87
110
  }
88
111
  async getProviderPullRequest(session, resource, id) {
89
- return (await this.authenticationService.apis.bitbucket)?.getPullRequest(this, toTokenWithInfo(this.id, session), resource.owner, resource.name, id, this.apiBaseUrl);
112
+ return (await this.authenticationService.apis.bitbucket)?.getPullRequest(this, toTokenWithInfo(this.id, session), resource.owner, resource.name, id, this.apiBaseUrl, { projection: "point" });
90
113
  }
91
114
  getProviderPullRequestIdentityFromMaybeUrl(search) {
92
115
  return getBitbucketPullRequestIdentityFromMaybeUrl(search, this.id);
@@ -172,14 +195,14 @@ var BitbucketIntegration = class extends GitHostIntegration {
172
195
  const workspaces = workspacesResult.values;
173
196
  if (workspaces.length === 0) return [];
174
197
  const authoredPrs = workspaces.map(async (ws) => {
175
- return (await api.getBitbucketPullRequestsAuthoredByUserForWorkspace(toTokenWithInfo(this.id, session), user.id, ws.slug, { states }))?.data.map((pr) => fromProviderPullRequest(pr, this));
198
+ return (await api.getBitbucketPullRequestsAuthoredByUserForWorkspace(toTokenWithInfo(this.id, session), user.id, ws.slug, { states }))?.data.map((pr) => fromProviderPullRequest(pr, this, { projection: "search" }));
176
199
  });
177
200
  if (!options?.includeReviewRequested) return [...uniqueBy(await flatSettled(authoredPrs), (pr) => pr.url, (orig, _cur) => orig)];
178
201
  const stateClause = state === "closed" ? "(state=\"DECLINED\" OR state=\"SUPERSEDED\")" : state === "merged" ? "state=\"MERGED\"" : state === "all" ? void 0 : "state=\"OPEN\"";
179
202
  const workspaceRepos = await this.getWorkspaceRepoInputs();
180
203
  if (workspaceRepos.length === 0) return [...uniqueBy(await flatSettled(authoredPrs), (pr) => pr.url, (orig, _cur) => orig)];
181
204
  const reviewerClause = `reviewers.uuid="${user.id}"`;
182
- const reviewingPrs = api.getPullRequestsForRepos(toTokenWithInfo(this.id, session), workspaceRepos, { query: stateClause ? `${stateClause} AND ${reviewerClause}` : reviewerClause }).then((r) => r.values?.map((pr) => fromProviderPullRequest(pr, this)));
205
+ const reviewingPrs = api.getPullRequestsForRepos(toTokenWithInfo(this.id, session), workspaceRepos, { query: stateClause ? `${stateClause} AND ${reviewerClause}` : reviewerClause }).then((r) => r.values?.map((pr) => fromProviderPullRequest(pr, this, { projection: "search" })));
183
206
  return [...uniqueBy(await flatSettled([...authoredPrs, reviewingPrs]), (pr) => pr.url, (orig, _cur) => orig)];
184
207
  }
185
208
  async getProviderMyPullRequestsForUser(session, options) {
@@ -341,7 +364,7 @@ var BitbucketIntegration = class extends GitHostIntegration {
341
364
  })).values;
342
365
  }));
343
366
  if (cancellation?.aborted) throw new CancellationError();
344
- return providerPullRequests.map((pr) => fromProviderPullRequest(pr, this));
367
+ return providerPullRequests.map((pr) => fromProviderPullRequest(pr, this, { projection: "text-search" }));
345
368
  }
346
369
  async getWorkspaceRepoInputs() {
347
370
  const remotes = await this.ctx.repositories.getOpenRemotes();
@@ -1 +1 @@
1
- {"version":3,"file":"bitbucket.js","names":[],"sources":["../../../../../plus/integrations/src/providers/bitbucket.ts"],"sourcesContent":["import type { CollectionMetadata, CollectionScopeFailure } from '@gitkraken/provider-apis';\nimport type { Account, UnidentifiedAuthor } from '@gitlens/git/models/author.js';\nimport type { DefaultBranch } from '@gitlens/git/models/defaultBranch.js';\nimport type { Issue, IssueShape } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequest, IssueOrPullRequestType } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type {\n\tPullRequest,\n\tPullRequestMergeMethod,\n\tPullRequestShape,\n\tPullRequestState,\n\tPullRequestStateFilter,\n} from '@gitlens/git/models/pullRequest.js';\nimport type { GitRemote } from '@gitlens/git/models/remote.js';\nimport type { RepositoryMetadata } from '@gitlens/git/models/repositoryMetadata.js';\nimport type { PullRequestUrlIdentity } from '@gitlens/git/utils/pullRequest.utils.js';\nimport { CancellationError } from '@gitlens/utils/cancellation.js';\nimport { md5 } from '@gitlens/utils/crypto.js';\nimport { uniqueBy } from '@gitlens/utils/iterable.js';\nimport { batchResults, flatSettled, mapSettledBounded, nonnullSettled } from '@gitlens/utils/promise.js';\nimport type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider.js';\nimport type {\n\tAuthenticationSessionLike as AuthenticationSession,\n\tProviderAuthenticationSession,\n} from '../authentication/models.js';\nimport { toTokenWithInfo } from '../authentication/models.js';\nimport type { ProviderRefusal } from '../collectionMetadata.js';\nimport { toCollectionScopeFailure } from '../collectionMetadata.js';\nimport { GitCloudHostIntegrationId, providerFanOutConcurrency } from '../constants.js';\nimport type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';\nimport { GitHostIntegration } from '../models/gitHostIntegration.js';\nimport { getBitbucketPullRequestIdentityFromMaybeUrl } from './bitbucket/bitbucket.utils.js';\nimport type { BitbucketRepositoryDescriptor, BitbucketWorkspaceDescriptor } from './bitbucket/models.js';\nimport type {\n\tProviderApiCollectionResult,\n\tProviderApiPagedResult,\n\tProviderHierarchyResult,\n\tProviderOrganization,\n\tProviderPullRequest,\n\tProviderRepository,\n} from './models.js';\nimport {\n\tfromProviderPullRequest,\n\tgetProviderPullRequestIdentity,\n\tprovidersMetadata,\n\tPullRequestFilter,\n\ttoProviderPullRequestStates,\n} from './models.js';\nimport {\n\tcollectProviderPagedResult,\n\tflatSettledOrThrow,\n\tmergeCollectionMetadata,\n\tparsePageCursor,\n\ttoPageCursor,\n} from './utils/providerPaging.js';\n\nconst metadata = providersMetadata[GitCloudHostIntegrationId.Bitbucket];\nconst authProvider = Object.freeze({ id: metadata.id, scopes: metadata.scopes });\n\nexport class BitbucketIntegration extends GitHostIntegration<\n\tGitCloudHostIntegrationId.Bitbucket,\n\tBitbucketRepositoryDescriptor\n> {\n\treadonly authProvider: IntegrationAuthenticationProviderDescriptor = authProvider;\n\treadonly id = GitCloudHostIntegrationId.Bitbucket;\n\tprotected readonly key = this.id;\n\treadonly name: string = 'Bitbucket';\n\tget domain(): string {\n\t\treturn metadata.domain;\n\t}\n\n\tprotected get apiBaseUrl(): string {\n\t\treturn 'https://api.bitbucket.org/2.0';\n\t}\n\n\tprotected override async mergeProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\tpr: PullRequest,\n\t\toptions?: {\n\t\t\tmergeMethod?: PullRequestMergeMethod;\n\t\t},\n\t): Promise<boolean> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.mergePullRequest(toTokenWithInfo(this.id, session), pr, {\n\t\t\tmergeMethod: options?.mergeMethod,\n\t\t});\n\t}\n\n\tpublic override async getRepoInfo(repo: {\n\t\towner: string;\n\t\tname: string;\n\t\tproject?: string;\n\t\tconnectionId?: string;\n\t}): Promise<ProviderRepository | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(repo.connectionId, undefined);\n\t\tif (session == null) return undefined;\n\n\t\treturn api.getRepo(toTokenWithInfo(this.id, session), repo.owner, repo.name, repo.project, {\n\t\t\tbaseUrl: this.apiBaseUrl,\n\t\t});\n\t}\n\n\tprotected override async getProviderAccountForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\trev: string,\n\t\toptions?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getAccountForCommit(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\trev,\n\t\t\tthis.apiBaseUrl,\n\t\t\t{\n\t\t\t\tavatarSize: options?.avatarSize,\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderAccountForEmail(\n\t\t_session: AuthenticationSession,\n\t\t_repo: BitbucketRepositoryDescriptor,\n\t\t_email: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t): Promise<Account | undefined> {\n\t\treturn Promise.resolve(undefined);\n\t}\n\n\tprotected override async getProviderDefaultBranch(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\tcancellation?: AbortSignal,\n\t): Promise<DefaultBranch | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getDefaultBranch(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\t{ baseUrl: this.apiBaseUrl },\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprotected override async getProviderLinkedIssueOrPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\t{ id }: { id: string; key: string },\n\t\ttype: undefined | IssueOrPullRequestType,\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getIssueOrPullRequest(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tid,\n\t\t\tthis.apiBaseUrl,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * One request per target, settled independently so one target's failure rejects only its own slot:\n\t * provider-apis has no single pull request read for Bitbucket, so this uses our own.\n\t */\n\tprotected override async getProviderPullRequestsBatch(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string } } | undefined,\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<PullRequestShape | undefined>[] | undefined> {\n\t\tconst api = await this.authenticationService.apis.bitbucket;\n\t\tif (api == null) return undefined;\n\n\t\tconst tokenWithInfo = toTokenWithInfo(this.id, session);\n\t\treturn mapSettledBounded(coordinates, providerFanOutConcurrency, c =>\n\t\t\tapi.getPullRequest(this, tokenWithInfo, c.owner, c.repo, String(c.number), this.apiBaseUrl, {\n\t\t\t\tcurrentAccount: options?.currentAccount,\n\t\t\t\tdeferFailure: true,\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * One request per target, settled independently, through our own client: provider-apis' pull request list has\n\t * no source-branch filter.\n\t */\n\tprotected override async getProviderPullRequestsForBranches(\n\t\tsession: ProviderAuthenticationSession,\n\t\ttargets: readonly { owner: string; repo: string; project?: string; branch: string; headOwner?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string }; limit: number },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<{ pullRequests: PullRequestShape[]; truncated: boolean }>[] | undefined> {\n\t\tconst api = await this.authenticationService.apis.bitbucket;\n\t\tif (api == null) return undefined;\n\n\t\tconst tokenWithInfo = toTokenWithInfo(this.id, session);\n\t\treturn mapSettledBounded(targets, providerFanOutConcurrency, t =>\n\t\t\tapi.getPullRequestsForBranch(this, tokenWithInfo, t.owner, t.repo, t.branch, this.apiBaseUrl, {\n\t\t\t\theadOwner: t.headOwner,\n\t\t\t\tlimit: options.limit,\n\t\t\t\tcurrentAccount: options.currentAccount,\n\t\t\t\tdeferFailure: true,\n\t\t\t}),\n\t\t);\n\t}\n\n\tprotected override async getProviderIssue(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\tid: string,\n\t): Promise<Issue | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getIssue(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tid,\n\t\t\tthis.apiBaseUrl,\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequestForBranch(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\tbranch: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t\tinclude?: PullRequestState[];\n\t\t},\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getPullRequestForBranch(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tbranch,\n\t\t\tthis.apiBaseUrl,\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequestForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\trev: string,\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getPullRequestForCommit(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\trev,\n\t\t\tthis.apiBaseUrl,\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\tresource: BitbucketRepositoryDescriptor,\n\t\tid: string,\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getPullRequest(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tresource.owner,\n\t\t\tresource.name,\n\t\t\tid,\n\t\t\tthis.apiBaseUrl,\n\t\t);\n\t}\n\n\tprotected override getProviderPullRequestIdentityFromMaybeUrl(search: string): PullRequestUrlIdentity | undefined {\n\t\treturn getBitbucketPullRequestIdentityFromMaybeUrl(search, this.id);\n\t}\n\n\tprotected override async getProviderRepositoryMetadata(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\tcancellation?: AbortSignal,\n\t): Promise<RepositoryMetadata | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getRepositoryMetadata(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\t{ baseUrl: this.apiBaseUrl },\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprivate _accounts: Map<string, Account | undefined> | undefined;\n\tprotected override async getProviderCurrentAccount(\n\t\tsession: ProviderAuthenticationSession,\n\t): Promise<Account | undefined> {\n\t\tconst { accessToken } = session;\n\t\tthis._accounts ??= new Map<string, Account | undefined>();\n\n\t\tconst cachedAccount = this._accounts.get(accessToken);\n\t\tif (cachedAccount == null) {\n\t\t\tconst api = await this.getProvidersApi();\n\t\t\tconst user = await api.getCurrentUser(toTokenWithInfo(this.id, session));\n\t\t\tthis._accounts.set(\n\t\t\t\taccessToken,\n\t\t\t\tuser\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tprovider: this,\n\t\t\t\t\t\t\tid: user.id,\n\t\t\t\t\t\t\tname: user.name ?? undefined,\n\t\t\t\t\t\t\temail: user.email ?? undefined,\n\t\t\t\t\t\t\tavatarUrl: user.avatarUrl ?? undefined,\n\t\t\t\t\t\t\tusername: user.username ?? undefined,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\n\t\treturn this._accounts.get(accessToken);\n\t}\n\n\t/** The profile request the account cache would otherwise answer; see `IntegrationBase.validateCredential`. */\n\tprotected override async validateCredential(session: ProviderAuthenticationSession): Promise<void> {\n\t\tconst api = await this.getProvidersApi();\n\t\tif ((await api.getCurrentUser(toTokenWithInfo(this.id, session))) == null) {\n\t\t\tthrow new Error('Bitbucket did not confirm the credential');\n\t\t}\n\t}\n\n\t/**\n\t * Bitbucket's `403` for a token missing the OAuth scopes a request needs, which a reconnect fixes by consenting to\n\t * them again; see `IntegrationBase.isCredentialRefusal`.\n\t */\n\tprotected override isCredentialRefusal(refusal: ProviderRefusal): boolean {\n\t\treturn refusal.status === 403 && /required privilege scopes/i.test(refusal.detail ?? '');\n\t}\n\n\tprivate _workspaces: Map<string, ProviderApiCollectionResult<BitbucketWorkspaceDescriptor> | undefined> | undefined;\n\tprivate async getProviderResourcesForCurrentUser(\n\t\tsession: ProviderAuthenticationSession,\n\t\tforce: boolean = false,\n\t): Promise<ProviderApiCollectionResult<BitbucketWorkspaceDescriptor> | undefined> {\n\t\tthis._workspaces ??= new Map<string, ProviderApiCollectionResult<BitbucketWorkspaceDescriptor> | undefined>();\n\t\tconst { accessToken } = session;\n\t\tconst cachedResources = this._workspaces.get(accessToken);\n\t\tif (cachedResources != null && !force) return cachedResources;\n\n\t\tconst api = await this.getProvidersApi();\n\t\tconst resources = await api.getBitbucketResourcesForCurrentUser(toTokenWithInfo(this.id, session));\n\t\tif (resources == null) return undefined;\n\n\t\tconst values = resources.values.map(r => ({ ...r, key: r.id, name: r.name ?? r.slug }));\n\t\tconst metadata = mergeCollectionMetadata(\n\t\t\tresources.metadata,\n\t\t\tresources.paging?.truncated === true ? { completeness: 'partial' } : undefined,\n\t\t);\n\t\tconst result: ProviderApiCollectionResult<BitbucketWorkspaceDescriptor> = {\n\t\t\tvalues: values,\n\t\t\t...(metadata != null ? { metadata: metadata } : {}),\n\t\t};\n\n\t\t// A partial workspace prefix is useful to the current read but must not become authoritative cache state:\n\t\t// a transient page-2 failure must be retried on the next call rather than hiding every later workspace\n\t\t// until disconnect.\n\t\tif (metadata == null || metadata.completeness === 'complete') {\n\t\t\tthis._workspaces.set(accessToken, result);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprotected override async getProviderOrganizationsForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t): Promise<ProviderHierarchyResult<ProviderOrganization> | undefined> {\n\t\tconst workspaces = await this.getProviderResourcesForCurrentUser(session);\n\t\tif (workspaces == null) return undefined;\n\n\t\treturn {\n\t\t\tvalues: workspaces.values.map(w => ({\n\t\t\t\tid: w.id,\n\t\t\t\tproviderId: this.id,\n\t\t\t\tname: w.slug,\n\t\t\t\turl: `https://bitbucket.org/${w.slug}`,\n\t\t\t})),\n\t\t\t...(workspaces.metadata != null ? { metadata: workspaces.metadata } : {}),\n\t\t};\n\t}\n\n\tprotected override async getProviderRepositoriesForOrg(\n\t\tsession: ProviderAuthenticationSession,\n\t\torg: string,\n\t\toptions?: { cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository> | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.getReposForBitbucketWorkspace(toTokenWithInfo(this.id, session), org, {\n\t\t\tcursor: options?.cursor,\n\t\t});\n\t}\n\n\tprotected override async searchProviderMyPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: BitbucketRepositoryDescriptor[],\n\t\t_cancellation?: AbortSignal,\n\t\toptions?: SearchMyPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined> {\n\t\tif (repos != null) {\n\t\t\t// TODO: implement repos version\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst state = options?.state;\n\t\tconst states = toProviderPullRequestStates(state);\n\n\t\tconst api = await this.getProvidersApi();\n\t\tif (!api) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst user = await this.getProviderCurrentAccount(session);\n\t\t// `user.id` feeds both the authored workspace reads and the reviewer BBQL clause; guard on it so we\n\t\t// never issue requests/queries with an undefined uuid. `username` isn't used here, so don't gate on it.\n\t\tif (user?.id == null) return undefined;\n\n\t\tconst workspacesResult = await this.getProviderResourcesForCurrentUser(session);\n\t\tif (workspacesResult == null) return undefined;\n\n\t\tconst workspaces = workspacesResult.values;\n\t\tif (workspaces.length === 0) return [];\n\n\t\tconst authoredPrs = workspaces.map(async ws => {\n\t\t\tconst prs = await api.getBitbucketPullRequestsAuthoredByUserForWorkspace(\n\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\tuser.id,\n\t\t\t\tws.slug,\n\t\t\t\t{ states: states },\n\t\t\t);\n\t\t\treturn prs?.data.map(pr => fromProviderPullRequest(pr, this));\n\t\t});\n\n\t\tif (!options?.includeReviewRequested) {\n\t\t\treturn [\n\t\t\t\t...uniqueBy(\n\t\t\t\t\tawait flatSettled(authoredPrs),\n\t\t\t\t\tpr => pr.url,\n\t\t\t\t\t(orig, _cur) => orig,\n\t\t\t\t),\n\t\t\t];\n\t\t}\n\n\t\t// Bitbucket's reviewing PRs require a repo-scoped BBQL query; keep that sweep opt-in so the default\n\t\t// \"my pull requests\" feed stays aligned with backends that only expose authored PRs.\n\t\tconst stateClause =\n\t\t\tstate === 'closed'\n\t\t\t\t? '(state=\"DECLINED\" OR state=\"SUPERSEDED\")'\n\t\t\t\t: state === 'merged'\n\t\t\t\t\t? 'state=\"MERGED\"'\n\t\t\t\t\t: state === 'all'\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: 'state=\"OPEN\"';\n\n\t\tconst workspaceRepos = await this.getWorkspaceRepoInputs();\n\t\tif (workspaceRepos.length === 0) {\n\t\t\treturn [\n\t\t\t\t...uniqueBy(\n\t\t\t\t\tawait flatSettled(authoredPrs),\n\t\t\t\t\tpr => pr.url,\n\t\t\t\t\t(orig, _cur) => orig,\n\t\t\t\t),\n\t\t\t];\n\t\t}\n\n\t\tconst reviewerClause = `reviewers.uuid=\"${user.id}\"`;\n\t\tconst reviewingPrs = api\n\t\t\t.getPullRequestsForRepos(toTokenWithInfo(this.id, session), workspaceRepos, {\n\t\t\t\tquery: stateClause ? `${stateClause} AND ${reviewerClause}` : reviewerClause,\n\t\t\t})\n\t\t\t.then(r => r.values?.map(pr => fromProviderPullRequest(pr, this)));\n\n\t\treturn [\n\t\t\t...uniqueBy(\n\t\t\t\tawait flatSettled([...authoredPrs, reviewingPrs]),\n\t\t\t\tpr => pr.url,\n\t\t\t\t(orig, _cur) => orig,\n\t\t\t),\n\t\t];\n\t}\n\n\tprotected override async getProviderMyPullRequestsForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: {\n\t\t\tstate?: PullRequestStateFilter[];\n\t\t\tcursor?: string;\n\t\t\tincludeReviewRequested?: boolean;\n\t\t\tfilters?: PullRequestFilter[];\n\t\t},\n\t): Promise<ProviderApiPagedResult<ProviderPullRequest> | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\tconst user = await this.getProviderCurrentAccount(session);\n\t\tif (user?.id == null) return undefined;\n\n\t\tconst workspacesResult = await this.getProviderResourcesForCurrentUser(session);\n\t\tif (workspacesResult == null) return undefined;\n\n\t\tconst workspaces = workspacesResult.values;\n\t\tif (workspaces.length === 0) {\n\t\t\tconst incomplete =\n\t\t\t\tworkspacesResult.metadata != null && workspacesResult.metadata.completeness !== 'complete';\n\t\t\treturn {\n\t\t\t\tvalues: [],\n\t\t\t\tpaging: { cursor: '{}', more: false, truncated: incomplete || undefined },\n\t\t\t\t...(workspacesResult.metadata != null ? { metadata: workspacesResult.metadata } : {}),\n\t\t\t};\n\t\t}\n\n\t\t// Account-wide \"my PRs\" for Bitbucket = the user's authored PRs across every workspace they belong to,\n\t\t// plus the PRs they've been requested to review. Bitbucket's cross-workspace read is per-workspace and\n\t\t// numbered-page, so drain each workspace fully (bounded by a defensive backstop) and concatenate.\n\t\t// There's no single cross-workspace cursor, so the aggregate is one page; `truncated` is set when a\n\t\t// workspace hit the backstop with more pages left, or when a workspace's read was dropped by a failure.\n\t\tconst states = toProviderPullRequestStates(options?.state);\n\t\tconst requested = options?.filters?.length ? new Set(options.filters) : undefined;\n\t\tconst wantAuthored = requested == null || requested.has(PullRequestFilter.Author);\n\t\tconst wantReviewRequested =\n\t\t\trequested?.has(PullRequestFilter.ReviewRequested) ?? options?.includeReviewRequested === true;\n\t\tconst maxPagesPerWorkspace = 20;\n\t\tlet truncated = workspacesResult.metadata != null && workspacesResult.metadata.completeness !== 'complete';\n\t\t// Structured per-scope failures from BOTH the authored and reviewer slices. A rejected scope is recorded\n\t\t// here (never re-thrown) so successful sibling workspaces/repos survive and the ProviderBackend facade\n\t\t// maps each failure to an actionable warning + `fetchFailed` (auth/rate-limit failures still drive\n\t\t// recovery through their warning kind, matching the SDK's own collect-across-scopes model).\n\t\tconst failures: CollectionScopeFailure[] = [];\n\t\tlet aggregateMetadata = workspacesResult.metadata;\n\t\tconst absorbCollectionResult = (result: ProviderHierarchyResult<unknown>): void => {\n\t\t\taggregateMetadata = mergeCollectionMetadata(aggregateMetadata, result.metadata);\n\t\t\tif (result.truncated || (result.metadata != null && result.metadata.completeness !== 'complete')) {\n\t\t\t\ttruncated = true;\n\t\t\t}\n\t\t};\n\t\tconst settled = wantAuthored\n\t\t\t? await Promise.allSettled(\n\t\t\t\t\tworkspaces.map(async ws => {\n\t\t\t\t\t\treturn collectProviderPagedResult(\n\t\t\t\t\t\t\tasync cursor => {\n\t\t\t\t\t\t\t\tconst result = await api.getBitbucketPullRequestsAuthoredByUserForWorkspace(\n\t\t\t\t\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\t\t\t\t\tuser.id,\n\t\t\t\t\t\t\t\t\tws.slug,\n\t\t\t\t\t\t\t\t\t{ states: states, page: parsePageCursor(cursor) },\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tif (result == null) return undefined;\n\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tvalues: result.data,\n\t\t\t\t\t\t\t\t\tpaging: {\n\t\t\t\t\t\t\t\t\t\tmore: result.hasMore,\n\t\t\t\t\t\t\t\t\t\tcursor:\n\t\t\t\t\t\t\t\t\t\t\tresult.hasMore && result.nextPage != null\n\t\t\t\t\t\t\t\t\t\t\t\t? toPageCursor(result.nextPage)\n\t\t\t\t\t\t\t\t\t\t\t\t: '{}',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tmaxPagesPerWorkspace,\n\t\t\t\t\t\t\t{ providerId: this.id, resourceId: ws.slug },\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t: [];\n\n\t\tconst prsByIdentity = new Map<string, ProviderPullRequest>();\n\t\tlet unkeyedPullRequest = 0;\n\t\tconst addPullRequest = (pr: ProviderPullRequest): void => {\n\t\t\tconst key = getProviderPullRequestIdentity(pr) ?? `unkeyed:${unkeyedPullRequest++}`;\n\t\t\tif (!prsByIdentity.has(key)) {\n\t\t\t\tprsByIdentity.set(key, pr);\n\t\t\t}\n\t\t};\n\t\t// `allSettled` preserves order, so `settled[i]` is `workspaces[i]`. A rejected workspace becomes a\n\t\t// structured failure (attributed to its slug) instead of a generic truncation or a re-throw, preserving\n\t\t// every sibling workspace's authored PRs.\n\t\tsettled.forEach((outcome, i) => {\n\t\t\tif (outcome.status !== 'fulfilled') {\n\t\t\t\tfailures.push(this.toWorkspaceFailure(workspaces[i].slug, outcome.reason));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tabsorbCollectionResult(outcome.value);\n\t\t\tfor (const pr of outcome.value.values) {\n\t\t\t\taddPullRequest(pr);\n\t\t\t}\n\t\t});\n\n\t\t// Bitbucket's account-wide (per-workspace) endpoint returns authored PRs only, and the SDK exposes no\n\t\t// workspace-level reviewer query — only a repo-scoped one. Adding the reviewer slice therefore requires\n\t\t// draining every workspace's full repo list and then a per-repo `getPullRequestsForRepo` with `reviewerId`\n\t\t// (O(workspaces × repos) requests), so keep it opt-in: gate it on `includeReviewRequested` so the default\n\t\t// sweep matches the gkcli baseline (authored PRs only, no reviewer fan-out) and a caller pays that cost\n\t\t// only when it deliberately asks for review-requested PRs.\n\t\tif (wantReviewRequested) {\n\t\t\t// Enumerate the account's repos by draining each resolved workspace's repository list, then drain the\n\t\t\t// real per-repo paged `getPullRequestsForRepo` for each repo with `reviewerId`, so review-requested PRs\n\t\t\t// aren't bounded to the currently-open remotes and a reviewer PR past the first page isn't dropped.\n\t\t\t// Structured per-scope failures are collected as CollectionScopeFailure so the ProviderBackend facade\n\t\t\t// maps them to actionable warnings (Step 3).\n\t\t\tconst maxReposPagesPerWorkspace = 20;\n\t\t\tconst maxPrPagesPerRepo = 20;\n\t\t\t// Bound concurrency: workspaces are few, so process them concurrently, but drain each workspace's repos\n\t\t\t// in a bounded batch rather than an unbounded Promise.all over every repo in every workspace.\n\t\t\tconst repoBatchSize = 5;\n\n\t\t\tawait Promise.all(\n\t\t\t\tworkspaces.map(async ws => {\n\t\t\t\t\tlet repos: ProviderRepository[];\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst discovered = await collectProviderPagedResult(\n\t\t\t\t\t\t\tcursor =>\n\t\t\t\t\t\t\t\tapi.getReposForBitbucketWorkspace(toTokenWithInfo(this.id, session), ws.slug, {\n\t\t\t\t\t\t\t\t\tcursor: cursor,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tmaxReposPagesPerWorkspace,\n\t\t\t\t\t\t\t{ providerId: this.id, resourceId: ws.slug },\n\t\t\t\t\t\t);\n\t\t\t\t\t\trepos = discovered.values;\n\t\t\t\t\t\tabsorbCollectionResult(discovered);\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t// Record the workspace as a structured failure and keep going: the failure metadata drives\n\t\t\t\t\t\t// the warning + `fetchFailed` + incompleteness for every kind (auth/rate-limit stay\n\t\t\t\t\t\t// actionable via their warning kind), so sibling workspaces' repos are still drained.\n\t\t\t\t\t\tfailures.push(this.toWorkspaceFailure(ws.slug, ex));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst drained = await batchResults(repos, repoBatchSize, async repo => {\n\t\t\t\t\t\tconst reviewing = await collectProviderPagedResult(\n\t\t\t\t\t\t\tcursor =>\n\t\t\t\t\t\t\t\tapi.getPullRequestsForRepo(\n\t\t\t\t\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\t\t\t\t\t{ namespace: repo.namespace, name: repo.name },\n\t\t\t\t\t\t\t\t\t{ reviewerId: user.id, states: states, cursor: cursor },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tmaxPrPagesPerRepo,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tproviderId: this.id,\n\t\t\t\t\t\t\t\tresourceId: ws.slug,\n\t\t\t\t\t\t\t\trepositoryId: `${repo.namespace}/${repo.name}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { repo: repo, reviewing: reviewing };\n\t\t\t\t\t});\n\n\t\t\t\t\tfor (let i = 0; i < drained.length; i++) {\n\t\t\t\t\t\tconst outcome = drained[i];\n\t\t\t\t\t\tif (outcome.status !== 'fulfilled') {\n\t\t\t\t\t\t\tconst repo = repos[i];\n\t\t\t\t\t\t\tfailures.push(\n\t\t\t\t\t\t\t\tthis.toRepositoryFailure(\n\t\t\t\t\t\t\t\t\t`${repo?.namespace ?? ws.slug}/${repo?.name ?? 'unknown'}`,\n\t\t\t\t\t\t\t\t\toutcome.reason,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { reviewing } = outcome.value;\n\t\t\t\t\t\tabsorbCollectionResult(reviewing);\n\t\t\t\t\t\tfor (const pr of reviewing.values) {\n\t\t\t\t\t\t\taddPullRequest(pr);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\t// Every slice that ran (authored workspaces always, reviewer workspaces/repos when opted in) records its\n\t\t// per-scope rejections as structured failures instead of re-throwing: re-throwing would discard every\n\t\t// successful sibling's PRs. Auth/rate-limit failures stay actionable through the metadata (the facade maps\n\t\t// kind `authentication` → an `auth` warning, `rate-limit` → a `rate-limit` warning) while the survivors are\n\t\t// returned with `fetchFailed`.\n\t\tconst metadata: CollectionMetadata | undefined = mergeCollectionMetadata(\n\t\t\tfailures.length > 0 ? { completeness: 'partial', failures: failures } : undefined,\n\t\t\taggregateMetadata,\n\t\t);\n\n\t\treturn {\n\t\t\tvalues: [...prsByIdentity.values()],\n\t\t\tpaging: { cursor: '{}', more: false, truncated: truncated || undefined },\n\t\t\tmetadata: metadata,\n\t\t};\n\t}\n\n\t/** Classifies a caught workspace-scope error into a structured {@link CollectionScopeFailure}. */\n\tprivate toWorkspaceFailure(workspaceSlug: string, ex: unknown): CollectionScopeFailure {\n\t\treturn toCollectionScopeFailure({ providerId: this.id, resourceId: workspaceSlug }, ex);\n\t}\n\n\t/** Classifies a caught repository-scope error into a structured {@link CollectionScopeFailure}. */\n\tprivate toRepositoryFailure(repositoryId: string, ex: unknown): CollectionScopeFailure {\n\t\treturn toCollectionScopeFailure({ providerId: this.id, repositoryId: repositoryId }, ex);\n\t}\n\n\tprotected override async searchProviderPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\tsearchQuery: string,\n\t\trepos?: BitbucketRepositoryDescriptor[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined> {\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\tconst api = await this.getProvidersApi();\n\t\tif (!api) return undefined;\n\n\t\tconst workspaceRepos =\n\t\t\trepos != null\n\t\t\t\t? repos.map(r => ({ name: r.name, namespace: r.owner }))\n\t\t\t\t: await this.getWorkspaceRepoInputs();\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\t\t// An explicitly-empty `repos` means \"search these zero repos\" -> no results; reserve `undefined`\n\t\t// (\"scope couldn't be determined\") for when no repos were requested and none were discovered.\n\t\tif (workspaceRepos.length === 0) return repos != null ? [] : undefined;\n\n\t\tconst token = toTokenWithInfo(this.id, session);\n\t\tconst states = toProviderPullRequestStates(options?.include);\n\t\tconst providerPullRequests = await flatSettledOrThrow(\n\t\t\tworkspaceRepos.map(async repo => {\n\t\t\t\tconst result = await collectProviderPagedResult(cursor => {\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\treturn api.getPullRequestsForRepo(token, repo, {\n\t\t\t\t\t\tcursor: cursor,\n\t\t\t\t\t\tquery: searchQuery,\n\t\t\t\t\t\tstates: states,\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t\treturn result.values;\n\t\t\t}),\n\t\t);\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\treturn providerPullRequests.map(pr => fromProviderPullRequest(pr, this));\n\t}\n\n\tprivate async getWorkspaceRepoInputs(): Promise<{ name: string; namespace: string }[]> {\n\t\tconst remotes = await this.ctx.repositories.getOpenRemotes();\n\t\tconst inputs = await nonnullSettled(\n\t\t\tremotes.map(async (r: GitRemote) => {\n\t\t\t\tconst integration = await this.authenticationService.getByRemote(r);\n\t\t\t\tif (integration !== this) return undefined;\n\n\t\t\t\t// Use the remote provider's parsing rather than splitting `r.path`, so adornments like a\n\t\t\t\t// trailing `.git` or extra path segments don't leak into the namespace/name.\n\t\t\t\tconst namespace = r.provider?.owner;\n\t\t\t\tconst name = r.provider?.repoName;\n\t\t\t\treturn namespace != null && name != null ? { name: name, namespace: namespace } : undefined;\n\t\t\t}),\n\t\t);\n\t\t// Dedupe: a repo with multiple remotes (e.g. `origin` + `upstream`) can map to the same input,\n\t\t// which would otherwise fetch and return the same PRs more than once.\n\t\treturn [...new Map(inputs.map(i => [`${i.namespace}/${i.name}`, i])).values()];\n\t}\n\n\tprotected override async searchProviderMyIssues(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: BitbucketRepositoryDescriptor[],\n\t): Promise<IssueShape[] | undefined> {\n\t\tif (repos == null || repos.length === 0) return undefined;\n\n\t\tconst user = await this.getProviderCurrentAccount(session);\n\t\tif (user?.username == null) return undefined;\n\n\t\tconst api = await this.authenticationService.apis.bitbucket;\n\t\tif (!api) return undefined;\n\n\t\tconst issueResult = await flatSettled(\n\t\t\trepos.map(repo => {\n\t\t\t\treturn api.getUsersIssuesForRepo(\n\t\t\t\t\tthis,\n\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\tuser.id,\n\t\t\t\t\trepo.owner,\n\t\t\t\t\trepo.name,\n\t\t\t\t\tthis.apiBaseUrl,\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\t\treturn issueResult;\n\t}\n\n\t/**\n\t * Bitbucket is not an issue provider on the ProviderBackend surface: Bitbucket Cloud deprecated its issue\n\t * tracker in favor of dedicated issue integrations (e.g. Jira). The legacy per-repo `getUsersIssuesForRepo`\n\t * client is retained only for autolink/hover enrichment, not for the ProviderBackend issue reads, so the\n\t * facade reports issues as unsupported rather than serving a deprecated, partial source.\n\t */\n\toverride get supportsIssues(): boolean {\n\t\treturn false;\n\t}\n\n\tprivate readonly storagePrefix = 'bitbucket';\n\tprotected override async providerOnConnect(): Promise<void> {\n\t\tif (this._session == null) return;\n\n\t\tconst accountStorageKey = md5(this._session.accessToken);\n\n\t\tconst storedAccount = this.ctx.storage.get(`${this.storagePrefix}:${accountStorageKey}:account`);\n\t\tconst storedWorkspaces = this.ctx.storage.get(`${this.storagePrefix}:${accountStorageKey}:workspaces`);\n\n\t\tlet account: Account | undefined = storedAccount?.data ? { ...storedAccount.data, provider: this } : undefined;\n\n\t\tconst storedWorkspacesData = storedWorkspaces?.data as\n\t\t\t| ProviderApiCollectionResult<BitbucketWorkspaceDescriptor>\n\t\t\t| BitbucketWorkspaceDescriptor[]\n\t\t\t| undefined;\n\t\tlet workspaces: ProviderApiCollectionResult<BitbucketWorkspaceDescriptor> | undefined;\n\t\tif (\n\t\t\t!Array.isArray(storedWorkspacesData) &&\n\t\t\tArray.isArray(storedWorkspacesData?.values) &&\n\t\t\t(storedWorkspacesData.metadata == null || storedWorkspacesData.metadata.completeness === 'complete')\n\t\t) {\n\t\t\tworkspaces = {\n\t\t\t\tvalues: storedWorkspacesData.values.map((o: BitbucketWorkspaceDescriptor) => ({ ...o })),\n\t\t\t\t...(storedWorkspacesData.metadata != null ? { metadata: storedWorkspacesData.metadata } : {}),\n\t\t\t};\n\t\t}\n\n\t\tif (storedAccount == null) {\n\t\t\taccount = await this.getProviderCurrentAccount(this._session);\n\t\t\tif (account != null) {\n\t\t\t\t// Clear all other stored workspaces and repositories and accounts when our session changes\n\t\t\t\tawait this.ctx.storage.deleteWithPrefix(this.storagePrefix);\n\t\t\t\tawait this.ctx.storage.store(`${this.storagePrefix}:${accountStorageKey}:account`, {\n\t\t\t\t\tv: 1,\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tid: account.id,\n\t\t\t\t\t\tname: account.name,\n\t\t\t\t\t\temail: account.email,\n\t\t\t\t\t\tavatarUrl: account.avatarUrl,\n\t\t\t\t\t\tusername: account.username,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis._accounts ??= new Map<string, Account | undefined>();\n\t\tthis._accounts.set(this._session.accessToken, account);\n\n\t\tif (workspaces == null) {\n\t\t\tconst discovered = await this.getProviderResourcesForCurrentUser(this._session, true);\n\t\t\tif (discovered?.metadata == null || discovered.metadata.completeness === 'complete') {\n\t\t\t\tworkspaces = discovered;\n\t\t\t\tif (workspaces != null) {\n\t\t\t\t\tawait this.ctx.storage.store(`${this.storagePrefix}:${accountStorageKey}:workspaces`, {\n\t\t\t\t\t\tv: 2,\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\tdata: workspaces,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (workspaces != null) {\n\t\t\tthis._workspaces ??= new Map<\n\t\t\t\tstring,\n\t\t\t\tProviderApiCollectionResult<BitbucketWorkspaceDescriptor> | undefined\n\t\t\t>();\n\t\t\tthis._workspaces.set(this._session.accessToken, workspaces);\n\t\t}\n\t}\n\n\tprotected override providerOnDisconnect(): void {\n\t\tthis._accounts = undefined;\n\t\tthis._workspaces = undefined;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;AAuDA,MAAM,WAAW,kBAAA;AACjB,MAAM,eAAe,OAAO,OAAO;CAAE,IAAI,SAAS;CAAI,QAAQ,SAAS;AAAO,CAAC;AAE/E,IAAa,uBAAb,cAA0C,mBAGxC;CACD,eAAqE;CACrE,KAAS;CACT,MAAyB,KAAK;CAC9B,OAAwB;CACxB,IAAI,SAAiB;EACpB,OAAO,SAAS;CACjB;CAEA,IAAc,aAAqB;EAClC,OAAO;CACR;CAEA,MAAyB,yBACxB,SACA,IACA,SAGmB;EAEnB,QAAO,MADW,KAAK,gBAAgB,EAAA,CAC5B,iBAAiB,gBAAgB,KAAK,IAAI,OAAO,GAAG,IAAI,EAClE,aAAa,SAAS,YACvB,CAAC;CACF;CAEA,MAAsB,YAAY,MAKU;EAC3C,MAAM,MAAM,MAAM,KAAK,gBAAgB;EAEvC,MAAM,UAAU,MAAM,KAAK,mBAAmB,KAAK,cAAc,KAAA,CAAS;EAC1E,IAAI,WAAW,MAAM,OAAO,KAAA;EAE5B,OAAO,IAAI,QAAQ,gBAAgB,KAAK,IAAI,OAAO,GAAG,KAAK,OAAO,KAAK,MAAM,KAAK,SAAS,EAC1F,SAAS,KAAK,WACf,CAAC;CACF;CAEA,MAAyB,4BACxB,SACA,MACA,KACA,SAGoD;EACpD,QAAQ,MAAM,KAAK,sBAAsB,KAAK,UAAA,EAAY,oBACzD,MACA,gBAAgB,KAAK,IAAI,OAAO,GAChC,KAAK,OACL,KAAK,MACL,KACA,KAAK,YACL,EACC,YAAY,SAAS,WACtB,CACD;CACD;CAEA,MAAyB,2BACxB,UACA,OACA,QACA,UAG+B;EAC/B,OAAO,QAAQ,QAAQ,KAAA,CAAS;CACjC;CAEA,MAAyB,yBACxB,SACA,MACA,cACqC;EACrC,QAAQ,MAAM,KAAK,sBAAsB,KAAK,UAAA,EAAY,iBACzD,MACA,gBAAgB,KAAK,IAAI,OAAO,GAChC,KAAK,OACL,KAAK,MACL,EAAE,SAAS,KAAK,WAAW,GAC3B,YACD;CACD;CAEA,MAAyB,oCACxB,SACA,MACA,EAAE,MACF,MAC0C;EAC1C,QAAQ,MAAM,KAAK,sBAAsB,KAAK,UAAA,EAAY,sBACzD,MACA,gBAAgB,KAAK,IAAI,OAAO,GAChC,KAAK,OACL,KAAK,MACL,IACA,KAAK,YACL,EACO,KACP,CACD;CACD;;;;;CAMA,MAAyB,6BACxB,SACA,aACA,SACA,eAC4E;EAC5E,MAAM,MAAM,MAAM,KAAK,sBAAsB,KAAK;EAClD,IAAI,OAAO,MAAM,OAAO,KAAA;EAExB,MAAM,gBAAgB,gBAAgB,KAAK,IAAI,OAAO;EACtD,OAAO,kBAAkB,aAAA,IAAwC,MAChE,IAAI,eAAe,MAAM,eAAe,EAAE,OAAO,EAAE,MAAM,OAAO,EAAE,MAAM,GAAG,KAAK,YAAY;GAC3F,gBAAgB,SAAS;GACzB,cAAc;EACf,CAAC,CACF;CACD;;;;;CAMA,MAAyB,mCACxB,SACA,SACA,SACA,eACwG;EACxG,MAAM,MAAM,MAAM,KAAK,sBAAsB,KAAK;EAClD,IAAI,OAAO,MAAM,OAAO,KAAA;EAExB,MAAM,gBAAgB,gBAAgB,KAAK,IAAI,OAAO;EACtD,OAAO,kBAAkB,SAAA,IAAoC,MAC5D,IAAI,yBAAyB,MAAM,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,KAAK,YAAY;GAC7F,WAAW,EAAE;GACb,OAAO,QAAQ;GACf,gBAAgB,QAAQ;GACxB,cAAc;EACf,CAAC,CACF;CACD;CAEA,MAAyB,iBACxB,SACA,MACA,IAC6B;EAC7B,QAAQ,MAAM,KAAK,sBAAsB,KAAK,UAAA,EAAY,SACzD,MACA,gBAAgB,KAAK,IAAI,OAAO,GAChC,KAAK,OACL,KAAK,MACL,IACA,KAAK,UACN;CACD;CAEA,MAAyB,gCACxB,SACA,MACA,QACA,UAImC;EACnC,QAAQ,MAAM,KAAK,sBAAsB,KAAK,UAAA,EAAY,wBACzD,MACA,gBAAgB,KAAK,IAAI,OAAO,GAChC,KAAK,OACL,KAAK,MACL,QACA,KAAK,UACN;CACD;CAEA,MAAyB,gCACxB,SACA,MACA,KACmC;EACnC,QAAQ,MAAM,KAAK,sBAAsB,KAAK,UAAA,EAAY,wBACzD,MACA,gBAAgB,KAAK,IAAI,OAAO,GAChC,KAAK,OACL,KAAK,MACL,KACA,KAAK,UACN;CACD;CAEA,MAAyB,uBACxB,SACA,UACA,IACmC;EACnC,QAAQ,MAAM,KAAK,sBAAsB,KAAK,UAAA,EAAY,eACzD,MACA,gBAAgB,KAAK,IAAI,OAAO,GAChC,SAAS,OACT,SAAS,MACT,IACA,KAAK,UACN;CACD;CAEA,2CAA8D,QAAoD;EACjH,OAAO,4CAA4C,QAAQ,KAAK,EAAE;CACnE;CAEA,MAAyB,8BACxB,SACA,MACA,cAC0C;EAC1C,QAAQ,MAAM,KAAK,sBAAsB,KAAK,UAAA,EAAY,sBACzD,MACA,gBAAgB,KAAK,IAAI,OAAO,GAChC,KAAK,OACL,KAAK,MACL,EAAE,SAAS,KAAK,WAAW,GAC3B,YACD;CACD;CAEA;CACA,MAAyB,0BACxB,SAC+B;EAC/B,MAAM,EAAE,gBAAgB;EACxB,KAAK,8BAAc,IAAI,IAAiC;EAGxD,IADsB,KAAK,UAAU,IAAI,WACzB,KAAK,MAAM;GAE1B,MAAM,OAAO,OAAM,MADD,KAAK,gBAAgB,EAAA,CAChB,eAAe,gBAAgB,KAAK,IAAI,OAAO,CAAC;GACvE,KAAK,UAAU,IACd,aACA,OACG;IACA,UAAU;IACV,IAAI,KAAK;IACT,MAAM,KAAK,QAAQ,KAAA;IACnB,OAAO,KAAK,SAAS,KAAA;IACrB,WAAW,KAAK,aAAa,KAAA;IAC7B,UAAU,KAAK,YAAY,KAAA;GAC5B,IACC,KAAA,CACJ;EACD;EAEA,OAAO,KAAK,UAAU,IAAI,WAAW;CACtC;;CAGA,MAAyB,mBAAmB,SAAuD;EAElG,IAAK,OAAM,MADO,KAAK,gBAAgB,EAAA,CACxB,eAAe,gBAAgB,KAAK,IAAI,OAAO,CAAC,KAAM,MACpE,MAAM,IAAI,MAAM,0CAA0C;CAE5D;;;;;CAMA,oBAAuC,SAAmC;EACzE,OAAO,QAAQ,WAAW,OAAO,6BAA6B,KAAK,QAAQ,UAAU,EAAE;CACxF;CAEA;CACA,MAAc,mCACb,SACA,QAAiB,OACgE;EACjF,KAAK,gCAAgB,IAAI,IAAmF;EAC5G,MAAM,EAAE,gBAAgB;EACxB,MAAM,kBAAkB,KAAK,YAAY,IAAI,WAAW;EACxD,IAAI,mBAAmB,QAAQ,CAAC,OAAO,OAAO;EAG9C,MAAM,YAAY,OAAM,MADN,KAAK,gBAAgB,EAAA,CACX,oCAAoC,gBAAgB,KAAK,IAAI,OAAO,CAAC;EACjG,IAAI,aAAa,MAAM,OAAO,KAAA;EAE9B,MAAM,SAAS,UAAU,OAAO,KAAI,OAAM;GAAE,GAAG;GAAG,KAAK,EAAE;GAAI,MAAM,EAAE,QAAQ,EAAE;EAAK,EAAE;EACtF,MAAM,WAAW,wBAChB,UAAU,UACV,UAAU,QAAQ,cAAc,OAAO,EAAE,cAAc,UAAU,IAAI,KAAA,CACtE;EACA,MAAM,SAAoE;GACjE;GACR,GAAI,YAAY,OAAO,EAAY,SAAS,IAAI,CAAC;EAClD;EAKA,IAAI,YAAY,QAAQ,SAAS,iBAAiB,YACjD,KAAK,YAAY,IAAI,aAAa,MAAM;EAEzC,OAAO;CACR;CAEA,MAAyB,gCACxB,SACqE;EACrE,MAAM,aAAa,MAAM,KAAK,mCAAmC,OAAO;EACxE,IAAI,cAAc,MAAM,OAAO,KAAA;EAE/B,OAAO;GACN,QAAQ,WAAW,OAAO,KAAI,OAAM;IACnC,IAAI,EAAE;IACN,YAAY,KAAK;IACjB,MAAM,EAAE;IACR,KAAK,yBAAyB,EAAE;GACjC,EAAE;GACF,GAAI,WAAW,YAAY,OAAO,EAAE,UAAU,WAAW,SAAS,IAAI,CAAC;EACxE;CACD;CAEA,MAAyB,8BACxB,SACA,KACA,SACmE;EAEnE,QAAO,MADW,KAAK,gBAAgB,EAAA,CAC5B,8BAA8B,gBAAgB,KAAK,IAAI,OAAO,GAAG,KAAK,EAChF,QAAQ,SAAS,OAClB,CAAC;CACF;CAEA,MAAyB,6BACxB,SACA,OACA,eACA,SACqC;EACrC,IAAI,SAAS,MAEZ;EAGD,MAAM,QAAQ,SAAS;EACvB,MAAM,SAAS,4BAA4B,KAAK;EAEhD,MAAM,MAAM,MAAM,KAAK,gBAAgB;EACvC,IAAI,CAAC,KACJ;EAGD,MAAM,OAAO,MAAM,KAAK,0BAA0B,OAAO;EAGzD,IAAI,MAAM,MAAM,MAAM,OAAO,KAAA;EAE7B,MAAM,mBAAmB,MAAM,KAAK,mCAAmC,OAAO;EAC9E,IAAI,oBAAoB,MAAM,OAAO,KAAA;EAErC,MAAM,aAAa,iBAAiB;EACpC,IAAI,WAAW,WAAW,GAAG,OAAO,CAAC;EAErC,MAAM,cAAc,WAAW,IAAI,OAAM,OAAM;GAO9C,QAAO,MANW,IAAI,mDACrB,gBAAgB,KAAK,IAAI,OAAO,GAChC,KAAK,IACL,GAAG,MACH,EAAU,OAAO,CAClB,EAAA,EACY,KAAK,KAAI,OAAM,wBAAwB,IAAI,IAAI,CAAC;EAC7D,CAAC;EAED,IAAI,CAAC,SAAS,wBACb,OAAO,CACN,GAAG,SACF,MAAM,YAAY,WAAW,IAC7B,OAAM,GAAG,MACR,MAAM,SAAS,IACjB,CACD;EAKD,MAAM,cACL,UAAU,WACP,iDACA,UAAU,WACT,qBACA,UAAU,QACT,KAAA,IACA;EAEN,MAAM,iBAAiB,MAAM,KAAK,uBAAuB;EACzD,IAAI,eAAe,WAAW,GAC7B,OAAO,CACN,GAAG,SACF,MAAM,YAAY,WAAW,IAC7B,OAAM,GAAG,MACR,MAAM,SAAS,IACjB,CACD;EAGD,MAAM,iBAAiB,mBAAmB,KAAK,GAAG;EAClD,MAAM,eAAe,IACnB,wBAAwB,gBAAgB,KAAK,IAAI,OAAO,GAAG,gBAAgB,EAC3E,OAAO,cAAc,GAAG,YAAY,OAAO,mBAAmB,eAC/D,CAAC,CAAC,CACD,MAAK,MAAK,EAAE,QAAQ,KAAI,OAAM,wBAAwB,IAAI,IAAI,CAAC,CAAC;EAElE,OAAO,CACN,GAAG,SACF,MAAM,YAAY,CAAC,GAAG,aAAa,YAAY,CAAC,IAChD,OAAM,GAAG,MACR,MAAM,SAAS,IACjB,CACD;CACD;CAEA,MAAyB,iCACxB,SACA,SAMmE;EACnE,MAAM,MAAM,MAAM,KAAK,gBAAgB;EACvC,MAAM,OAAO,MAAM,KAAK,0BAA0B,OAAO;EACzD,IAAI,MAAM,MAAM,MAAM,OAAO,KAAA;EAE7B,MAAM,mBAAmB,MAAM,KAAK,mCAAmC,OAAO;EAC9E,IAAI,oBAAoB,MAAM,OAAO,KAAA;EAErC,MAAM,aAAa,iBAAiB;EACpC,IAAI,WAAW,WAAW,GAGzB,OAAO;GACN,QAAQ,CAAC;GACT,QAAQ;IAAE,QAAQ;IAAM,MAAM;IAAO,WAHrC,iBAAiB,YAAY,QAAQ,iBAAiB,SAAS,iBAAiB,cAGlB,KAAA;GAAU;GACxE,GAAI,iBAAiB,YAAY,OAAO,EAAE,UAAU,iBAAiB,SAAS,IAAI,CAAC;EACpF;EAQD,MAAM,SAAS,4BAA4B,SAAS,KAAK;EACzD,MAAM,YAAY,SAAS,SAAS,SAAS,IAAI,IAAI,QAAQ,OAAO,IAAI,KAAA;EACxE,MAAM,eAAe,aAAa,QAAQ,UAAU,IAAA,QAA4B;EAChF,MAAM,sBACL,WAAW,IAAA,kBAAqC,KAAK,SAAS,2BAA2B;EAC1F,MAAM,uBAAuB;EAC7B,IAAI,YAAY,iBAAiB,YAAY,QAAQ,iBAAiB,SAAS,iBAAiB;EAKhG,MAAM,WAAqC,CAAC;EAC5C,IAAI,oBAAoB,iBAAiB;EACzC,MAAM,0BAA0B,WAAmD;GAClF,oBAAoB,wBAAwB,mBAAmB,OAAO,QAAQ;GAC9E,IAAI,OAAO,aAAc,OAAO,YAAY,QAAQ,OAAO,SAAS,iBAAiB,YACpF,YAAY;EAEd;EACA,MAAM,UAAU,eACb,MAAM,QAAQ,WACd,WAAW,IAAI,OAAM,OAAM;GAC1B,OAAO,2BACN,OAAM,WAAU;IACf,MAAM,SAAS,MAAM,IAAI,mDACxB,gBAAgB,KAAK,IAAI,OAAO,GAChC,KAAK,IACL,GAAG,MACH;KAAU;KAAQ,MAAM,gBAAgB,MAAM;IAAE,CACjD;IACA,IAAI,UAAU,MAAM,OAAO,KAAA;IAE3B,OAAO;KACN,QAAQ,OAAO;KACf,QAAQ;MACP,MAAM,OAAO;MACb,QACC,OAAO,WAAW,OAAO,YAAY,OAClC,aAAa,OAAO,QAAQ,IAC5B;KACL;IACD;GACD,GACA,sBACA;IAAE,YAAY,KAAK;IAAI,YAAY,GAAG;GAAK,CAC5C;EACD,CAAC,CACF,IACC,CAAC;EAEJ,MAAM,gCAAgB,IAAI,IAAiC;EAC3D,IAAI,qBAAqB;EACzB,MAAM,kBAAkB,OAAkC;GACzD,MAAM,MAAM,+BAA+B,EAAE,KAAK,WAAW;GAC7D,IAAI,CAAC,cAAc,IAAI,GAAG,GACzB,cAAc,IAAI,KAAK,EAAE;EAE3B;EAIA,QAAQ,SAAS,SAAS,MAAM;GAC/B,IAAI,QAAQ,WAAW,aAAa;IACnC,SAAS,KAAK,KAAK,mBAAmB,WAAW,EAAE,CAAC,MAAM,QAAQ,MAAM,CAAC;IACzE;GACD;GAEA,uBAAuB,QAAQ,KAAK;GACpC,KAAK,MAAM,MAAM,QAAQ,MAAM,QAC9B,eAAe,EAAE;EAEnB,CAAC;EAQD,IAAI,qBAAqB;GAMxB,MAAM,4BAA4B;GAClC,MAAM,oBAAoB;GAG1B,MAAM,gBAAgB;GAEtB,MAAM,QAAQ,IACb,WAAW,IAAI,OAAM,OAAM;IAC1B,IAAI;IACJ,IAAI;KACH,MAAM,aAAa,MAAM,4BACxB,WACC,IAAI,8BAA8B,gBAAgB,KAAK,IAAI,OAAO,GAAG,GAAG,MAAM,EACrE,OACT,CAAC,GACF,2BACA;MAAE,YAAY,KAAK;MAAI,YAAY,GAAG;KAAK,CAC5C;KACA,QAAQ,WAAW;KACnB,uBAAuB,UAAU;IAClC,SAAS,IAAI;KAIZ,SAAS,KAAK,KAAK,mBAAmB,GAAG,MAAM,EAAE,CAAC;KAClD;IACD;IAEA,MAAM,UAAU,MAAM,aAAa,OAAO,eAAe,OAAM,SAAQ;KAetE,OAAO;MAAQ;MAAM,WAAW,MAdR,4BACvB,WACC,IAAI,uBACH,gBAAgB,KAAK,IAAI,OAAO,GAChC;OAAE,WAAW,KAAK;OAAW,MAAM,KAAK;MAAK,GAC7C;OAAE,YAAY,KAAK;OAAY;OAAgB;MAAO,CACvD,GACD,mBACA;OACC,YAAY,KAAK;OACjB,YAAY,GAAG;OACf,cAAc,GAAG,KAAK,UAAU,GAAG,KAAK;MACzC,CACD;KAC0C;IAC3C,CAAC;IAED,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;KACxC,MAAM,UAAU,QAAQ;KACxB,IAAI,QAAQ,WAAW,aAAa;MACnC,MAAM,OAAO,MAAM;MACnB,SAAS,KACR,KAAK,oBACJ,GAAG,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,QAAQ,aAC/C,QAAQ,MACT,CACD;MACA;KACD;KAEA,MAAM,EAAE,cAAc,QAAQ;KAC9B,uBAAuB,SAAS;KAChC,KAAK,MAAM,MAAM,UAAU,QAC1B,eAAe,EAAE;IAEnB;GACD,CAAC,CACF;EACD;EAOA,MAAM,WAA2C,wBAChD,SAAS,SAAS,IAAI;GAAE,cAAc;GAAqB;EAAS,IAAI,KAAA,GACxE,iBACD;EAEA,OAAO;GACN,QAAQ,CAAC,GAAG,cAAc,OAAO,CAAC;GAClC,QAAQ;IAAE,QAAQ;IAAM,MAAM;IAAO,WAAW,aAAa,KAAA;GAAU;GAC7D;EACX;CACD;;CAGA,mBAA2B,eAAuB,IAAqC;EACtF,OAAO,yBAAyB;GAAE,YAAY,KAAK;GAAI,YAAY;EAAc,GAAG,EAAE;CACvF;;CAGA,oBAA4B,cAAsB,IAAqC;EACtF,OAAO,yBAAyB;GAAE,YAAY,KAAK;GAAkB;EAAa,GAAG,EAAE;CACxF;CAEA,MAAyB,2BACxB,SACA,aACA,OACA,cACA,SACqC;EACrC,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;EAEvD,MAAM,MAAM,MAAM,KAAK,gBAAgB;EACvC,IAAI,CAAC,KAAK,OAAO,KAAA;EAEjB,MAAM,iBACL,SAAS,OACN,MAAM,KAAI,OAAM;GAAE,MAAM,EAAE;GAAM,WAAW,EAAE;EAAM,EAAE,IACrD,MAAM,KAAK,uBAAuB;EACtC,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;EAGvD,IAAI,eAAe,WAAW,GAAG,OAAO,SAAS,OAAO,CAAC,IAAI,KAAA;EAE7D,MAAM,QAAQ,gBAAgB,KAAK,IAAI,OAAO;EAC9C,MAAM,SAAS,4BAA4B,SAAS,OAAO;EAC3D,MAAM,uBAAuB,MAAM,mBAClC,eAAe,IAAI,OAAM,SAAQ;GAUhC,QAAO,MATc,4BAA2B,WAAU;IACzD,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;IAEvD,OAAO,IAAI,uBAAuB,OAAO,MAAM;KACtC;KACR,OAAO;KACC;IACT,CAAC;GACF,CAAC,EAAA,CACa;EACf,CAAC,CACF;EACA,IAAI,cAAc,SAAS,MAAM,IAAI,kBAAkB;EAEvD,OAAO,qBAAqB,KAAI,OAAM,wBAAwB,IAAI,IAAI,CAAC;CACxE;CAEA,MAAc,yBAAyE;EACtF,MAAM,UAAU,MAAM,KAAK,IAAI,aAAa,eAAe;EAC3D,MAAM,SAAS,MAAM,eACpB,QAAQ,IAAI,OAAO,MAAiB;GAEnC,IAAI,MADsB,KAAK,sBAAsB,YAAY,CAAC,MAC9C,MAAM,OAAO,KAAA;GAIjC,MAAM,YAAY,EAAE,UAAU;GAC9B,MAAM,OAAO,EAAE,UAAU;GACzB,OAAO,aAAa,QAAQ,QAAQ,OAAO;IAAQ;IAAiB;GAAU,IAAI,KAAA;EACnF,CAAC,CACF;EAGA,OAAO,CAAC,GAAG,IAAI,IAAI,OAAO,KAAI,MAAK,CAAC,GAAG,EAAE,UAAU,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;CAC9E;CAEA,MAAyB,uBACxB,SACA,OACoC;EACpC,IAAI,SAAS,QAAQ,MAAM,WAAW,GAAG,OAAO,KAAA;EAEhD,MAAM,OAAO,MAAM,KAAK,0BAA0B,OAAO;EACzD,IAAI,MAAM,YAAY,MAAM,OAAO,KAAA;EAEnC,MAAM,MAAM,MAAM,KAAK,sBAAsB,KAAK;EAClD,IAAI,CAAC,KAAK,OAAO,KAAA;EAcjB,OAAO,MAZmB,YACzB,MAAM,KAAI,SAAQ;GACjB,OAAO,IAAI,sBACV,MACA,gBAAgB,KAAK,IAAI,OAAO,GAChC,KAAK,IACL,KAAK,OACL,KAAK,MACL,KAAK,UACN;EACD,CAAC,CACF;CAED;;;;;;;CAQA,IAAa,iBAA0B;EACtC,OAAO;CACR;CAEA,gBAAiC;CACjC,MAAyB,oBAAmC;EAC3D,IAAI,KAAK,YAAY,MAAM;EAE3B,MAAM,oBAAoB,IAAI,KAAK,SAAS,WAAW;EAEvD,MAAM,gBAAgB,KAAK,IAAI,QAAQ,IAAI,GAAG,KAAK,cAAc,GAAG,kBAAkB,SAAS;EAC/F,MAAM,mBAAmB,KAAK,IAAI,QAAQ,IAAI,GAAG,KAAK,cAAc,GAAG,kBAAkB,YAAY;EAErG,IAAI,UAA+B,eAAe,OAAO;GAAE,GAAG,cAAc;GAAM,UAAU;EAAK,IAAI,KAAA;EAErG,MAAM,uBAAuB,kBAAkB;EAI/C,IAAI;EACJ,IACC,CAAC,MAAM,QAAQ,oBAAoB,KACnC,MAAM,QAAQ,sBAAsB,MAAM,MACzC,qBAAqB,YAAY,QAAQ,qBAAqB,SAAS,iBAAiB,aAEzF,aAAa;GACZ,QAAQ,qBAAqB,OAAO,KAAK,OAAqC,EAAE,GAAG,EAAE,EAAE;GACvF,GAAI,qBAAqB,YAAY,OAAO,EAAE,UAAU,qBAAqB,SAAS,IAAI,CAAC;EAC5F;EAGD,IAAI,iBAAiB,MAAM;GAC1B,UAAU,MAAM,KAAK,0BAA0B,KAAK,QAAQ;GAC5D,IAAI,WAAW,MAAM;IAEpB,MAAM,KAAK,IAAI,QAAQ,iBAAiB,KAAK,aAAa;IAC1D,MAAM,KAAK,IAAI,QAAQ,MAAM,GAAG,KAAK,cAAc,GAAG,kBAAkB,WAAW;KAClF,GAAG;KACH,WAAW,KAAK,IAAI;KACpB,MAAM;MACL,IAAI,QAAQ;MACZ,MAAM,QAAQ;MACd,OAAO,QAAQ;MACf,WAAW,QAAQ;MACnB,UAAU,QAAQ;KACnB;IACD,CAAC;GACF;EACD;EACA,KAAK,8BAAc,IAAI,IAAiC;EACxD,KAAK,UAAU,IAAI,KAAK,SAAS,aAAa,OAAO;EAErD,IAAI,cAAc,MAAM;GACvB,MAAM,aAAa,MAAM,KAAK,mCAAmC,KAAK,UAAU,IAAI;GACpF,IAAI,YAAY,YAAY,QAAQ,WAAW,SAAS,iBAAiB,YAAY;IACpF,aAAa;IACb,IAAI,cAAc,MACjB,MAAM,KAAK,IAAI,QAAQ,MAAM,GAAG,KAAK,cAAc,GAAG,kBAAkB,cAAc;KACrF,GAAG;KACH,WAAW,KAAK,IAAI;KACpB,MAAM;IACP,CAAC;GAEH;EACD;EACA,IAAI,cAAc,MAAM;GACvB,KAAK,gCAAgB,IAAI,IAGvB;GACF,KAAK,YAAY,IAAI,KAAK,SAAS,aAAa,UAAU;EAC3D;CACD;CAEA,uBAAgD;EAC/C,KAAK,YAAY,KAAA;EACjB,KAAK,cAAc,KAAA;CACpB;AACD"}
1
+ {"version":3,"file":"bitbucket.js","names":[],"sources":["../../../../../plus/integrations/src/providers/bitbucket.ts"],"sourcesContent":["import type { CollectionMetadata, CollectionScopeFailure } from '@gitkraken/provider-apis';\nimport type { Account, UnidentifiedAuthor } from '@gitlens/git/models/author.js';\nimport type { DefaultBranch } from '@gitlens/git/models/defaultBranch.js';\nimport type { Issue, IssueShape } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequest, IssueOrPullRequestType } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type {\n\tPullRequest,\n\tPullRequestMergeMethod,\n\tPullRequestShape,\n\tPullRequestState,\n\tPullRequestStateFilter,\n} from '@gitlens/git/models/pullRequest.js';\nimport type { GitRemote } from '@gitlens/git/models/remote.js';\nimport type { RepositoryMetadata } from '@gitlens/git/models/repositoryMetadata.js';\nimport type { PullRequestUrlIdentity } from '@gitlens/git/utils/pullRequest.utils.js';\nimport { CancellationError } from '@gitlens/utils/cancellation.js';\nimport { md5 } from '@gitlens/utils/crypto.js';\nimport { uniqueBy } from '@gitlens/utils/iterable.js';\nimport { batchResults, flatSettled, mapSettledBounded, nonnullSettled } from '@gitlens/utils/promise.js';\nimport type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider.js';\nimport type {\n\tAuthenticationSessionLike as AuthenticationSession,\n\tProviderAuthenticationSession,\n} from '../authentication/models.js';\nimport { toTokenWithInfo } from '../authentication/models.js';\nimport type { ProviderRefusal } from '../collectionMetadata.js';\nimport { toCollectionScopeFailure } from '../collectionMetadata.js';\nimport { GitCloudHostIntegrationId, providerFanOutConcurrency } from '../constants.js';\nimport type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';\nimport { GitHostIntegration } from '../models/gitHostIntegration.js';\nimport type { PullRequestEtagFields, PullRequestEtagInclude } from '../models/integration.js';\nimport { getBitbucketPullRequestIdentityFromMaybeUrl } from './bitbucket/bitbucket.utils.js';\nimport type { BitbucketRepositoryDescriptor, BitbucketWorkspaceDescriptor } from './bitbucket/models.js';\nimport { bitbucketEtagFieldsMaxIds, toBitbucketPullRequestEtagFields } from './bitbucket/models.js';\nimport type {\n\tProviderApiCollectionResult,\n\tProviderApiPagedResult,\n\tProviderHierarchyResult,\n\tProviderOrganization,\n\tProviderPullRequest,\n\tProviderRepository,\n} from './models.js';\nimport {\n\tfromProviderPullRequest,\n\tgetProviderPullRequestIdentity,\n\tprovidersMetadata,\n\tPullRequestFilter,\n\ttoProviderPullRequestStates,\n} from './models.js';\nimport {\n\tcollectProviderPagedResult,\n\tflatSettledOrThrow,\n\tmergeCollectionMetadata,\n\tparsePageCursor,\n\treadEtagFieldsByRepository,\n\ttoPageCursor,\n} from './utils/providerPaging.js';\n\nconst metadata = providersMetadata[GitCloudHostIntegrationId.Bitbucket];\nconst authProvider = Object.freeze({ id: metadata.id, scopes: metadata.scopes });\n\nexport class BitbucketIntegration extends GitHostIntegration<\n\tGitCloudHostIntegrationId.Bitbucket,\n\tBitbucketRepositoryDescriptor\n> {\n\treadonly authProvider: IntegrationAuthenticationProviderDescriptor = authProvider;\n\treadonly id = GitCloudHostIntegrationId.Bitbucket;\n\tprotected readonly key = this.id;\n\treadonly name: string = 'Bitbucket';\n\tget domain(): string {\n\t\treturn metadata.domain;\n\t}\n\n\tprotected get apiBaseUrl(): string {\n\t\treturn 'https://api.bitbucket.org/2.0';\n\t}\n\n\tprotected override async mergeProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\tpr: PullRequest,\n\t\toptions?: {\n\t\t\tmergeMethod?: PullRequestMergeMethod;\n\t\t},\n\t): Promise<boolean> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.mergePullRequest(toTokenWithInfo(this.id, session), pr, {\n\t\t\tmergeMethod: options?.mergeMethod,\n\t\t});\n\t}\n\n\tpublic override async getRepoInfo(repo: {\n\t\towner: string;\n\t\tname: string;\n\t\tproject?: string;\n\t\tconnectionId?: string;\n\t}): Promise<ProviderRepository | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(repo.connectionId, undefined);\n\t\tif (session == null) return undefined;\n\n\t\treturn api.getRepo(toTokenWithInfo(this.id, session), repo.owner, repo.name, repo.project, {\n\t\t\tbaseUrl: this.apiBaseUrl,\n\t\t});\n\t}\n\n\tprotected override async getProviderAccountForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\trev: string,\n\t\toptions?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getAccountForCommit(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\trev,\n\t\t\tthis.apiBaseUrl,\n\t\t\t{\n\t\t\t\tavatarSize: options?.avatarSize,\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderAccountForEmail(\n\t\t_session: AuthenticationSession,\n\t\t_repo: BitbucketRepositoryDescriptor,\n\t\t_email: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t): Promise<Account | undefined> {\n\t\treturn Promise.resolve(undefined);\n\t}\n\n\tprotected override async getProviderDefaultBranch(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\tcancellation?: AbortSignal,\n\t): Promise<DefaultBranch | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getDefaultBranch(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\t{ baseUrl: this.apiBaseUrl },\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprotected override async getProviderLinkedIssueOrPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\t{ id }: { id: string; key: string },\n\t\ttype: undefined | IssueOrPullRequestType,\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getIssueOrPullRequest(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tid,\n\t\t\tthis.apiBaseUrl,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * One request per target, settled independently so one target's failure rejects only its own slot:\n\t * provider-apis has no single pull request read for Bitbucket, so this uses our own.\n\t */\n\tprotected override async getProviderPullRequestsBatch(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string } } | undefined,\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<PullRequestShape | undefined>[] | undefined> {\n\t\tconst api = await this.authenticationService.apis.bitbucket;\n\t\tif (api == null) return undefined;\n\n\t\tconst tokenWithInfo = toTokenWithInfo(this.id, session);\n\t\treturn mapSettledBounded(coordinates, providerFanOutConcurrency, c =>\n\t\t\tapi.getPullRequest(this, tokenWithInfo, c.owner, c.repo, String(c.number), this.apiBaseUrl, {\n\t\t\t\tcurrentAccount: options?.currentAccount,\n\t\t\t\tdeferFailure: true,\n\t\t\t\tprojection: 'batch',\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * The cheap check behind the batch pull request read's etags: GitLens' own client lists each repository's pull\n\t * requests by id, up to {@link bitbucketEtagFieldsMaxIds} in ONE request, where\n\t * {@link getProviderPullRequestsBatch} sends one per target, and selects only the fields its rows' etags read.\n\t * Each is converted as {@link fromBitbucketPullRequest} converts the full one, so both reads compute the same\n\t * etag. A request that throws rejects only its own targets' slots.\n\t *\n\t * The full row reads neither a mergeability nor a check rollup, so its etag sees a pull request's state, draft\n\t * flag, update time and head commit, plus its participants' review decision when included; the `mergeable` and\n\t * `checks` includes add nothing and cost nothing.\n\t */\n\tprotected override async getProviderPullRequestsEtagFields(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { etagIncludes?: readonly PullRequestEtagInclude[] },\n\t\tcancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<PullRequestEtagFields | undefined>[] | undefined> {\n\t\tconst api = await this.authenticationService.apis.bitbucket;\n\t\tif (api == null) return undefined;\n\n\t\tconst tokenWithInfo = toTokenWithInfo(this.id, session);\n\t\tconst etagIncludes = options.etagIncludes ?? [];\n\n\t\treturn readEtagFieldsByRepository(\n\t\t\tcoordinates,\n\t\t\tbitbucketEtagFieldsMaxIds,\n\t\t\t(owner, repo, ids) =>\n\t\t\t\tapi.getPullRequestsEtagFields(\n\t\t\t\t\tthis,\n\t\t\t\t\ttokenWithInfo,\n\t\t\t\t\towner,\n\t\t\t\t\trepo,\n\t\t\t\t\tids,\n\t\t\t\t\tthis.apiBaseUrl,\n\t\t\t\t\t{ etagIncludes: etagIncludes, deferFailure: true },\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t\tnode => toBitbucketPullRequestEtagFields(node, etagIncludes),\n\t\t);\n\t}\n\n\t/**\n\t * One request per target, settled independently, through our own client: provider-apis' pull request list has\n\t * no source-branch filter.\n\t */\n\tprotected override async getProviderPullRequestsForBranches(\n\t\tsession: ProviderAuthenticationSession,\n\t\ttargets: readonly { owner: string; repo: string; project?: string; branch: string; headOwner?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string }; limit: number },\n\t\t_cancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<{ pullRequests: PullRequestShape[]; truncated: boolean }>[] | undefined> {\n\t\tconst api = await this.authenticationService.apis.bitbucket;\n\t\tif (api == null) return undefined;\n\n\t\tconst tokenWithInfo = toTokenWithInfo(this.id, session);\n\t\treturn mapSettledBounded(targets, providerFanOutConcurrency, t =>\n\t\t\tapi.getPullRequestsForBranch(this, tokenWithInfo, t.owner, t.repo, t.branch, this.apiBaseUrl, {\n\t\t\t\theadOwner: t.headOwner,\n\t\t\t\tlimit: options.limit,\n\t\t\t\tcurrentAccount: options.currentAccount,\n\t\t\t\tdeferFailure: true,\n\t\t\t}),\n\t\t);\n\t}\n\n\tprotected override async getProviderIssue(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\tid: string,\n\t): Promise<Issue | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getIssue(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tid,\n\t\t\tthis.apiBaseUrl,\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequestForBranch(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\tbranch: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t\tinclude?: PullRequestState[];\n\t\t},\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getPullRequestForBranch(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tbranch,\n\t\t\tthis.apiBaseUrl,\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequestForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\trev: string,\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getPullRequestForCommit(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\trev,\n\t\t\tthis.apiBaseUrl,\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\tresource: BitbucketRepositoryDescriptor,\n\t\tid: string,\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getPullRequest(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tresource.owner,\n\t\t\tresource.name,\n\t\t\tid,\n\t\t\tthis.apiBaseUrl,\n\t\t\t{ projection: 'point' },\n\t\t);\n\t}\n\n\tprotected override getProviderPullRequestIdentityFromMaybeUrl(search: string): PullRequestUrlIdentity | undefined {\n\t\treturn getBitbucketPullRequestIdentityFromMaybeUrl(search, this.id);\n\t}\n\n\tprotected override async getProviderRepositoryMetadata(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: BitbucketRepositoryDescriptor,\n\t\tcancellation?: AbortSignal,\n\t): Promise<RepositoryMetadata | undefined> {\n\t\treturn (await this.authenticationService.apis.bitbucket)?.getRepositoryMetadata(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\t{ baseUrl: this.apiBaseUrl },\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprivate _accounts: Map<string, Account | undefined> | undefined;\n\tprotected override async getProviderCurrentAccount(\n\t\tsession: ProviderAuthenticationSession,\n\t): Promise<Account | undefined> {\n\t\tconst { accessToken } = session;\n\t\tthis._accounts ??= new Map<string, Account | undefined>();\n\n\t\tconst cachedAccount = this._accounts.get(accessToken);\n\t\tif (cachedAccount == null) {\n\t\t\tconst api = await this.getProvidersApi();\n\t\t\tconst user = await api.getCurrentUser(toTokenWithInfo(this.id, session));\n\t\t\tthis._accounts.set(\n\t\t\t\taccessToken,\n\t\t\t\tuser\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tprovider: this,\n\t\t\t\t\t\t\tid: user.id,\n\t\t\t\t\t\t\tname: user.name ?? undefined,\n\t\t\t\t\t\t\temail: user.email ?? undefined,\n\t\t\t\t\t\t\tavatarUrl: user.avatarUrl ?? undefined,\n\t\t\t\t\t\t\tusername: user.username ?? undefined,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\n\t\treturn this._accounts.get(accessToken);\n\t}\n\n\t/** The profile request the account cache would otherwise answer; see `IntegrationBase.validateCredential`. */\n\tprotected override async validateCredential(session: ProviderAuthenticationSession): Promise<void> {\n\t\tconst api = await this.getProvidersApi();\n\t\tif ((await api.getCurrentUser(toTokenWithInfo(this.id, session))) == null) {\n\t\t\tthrow new Error('Bitbucket did not confirm the credential');\n\t\t}\n\t}\n\n\t/**\n\t * Bitbucket's `403` for a token missing the OAuth scopes a request needs, which a reconnect fixes by consenting to\n\t * them again; see `IntegrationBase.isCredentialRefusal`.\n\t */\n\tprotected override isCredentialRefusal(refusal: ProviderRefusal): boolean {\n\t\treturn refusal.status === 403 && /required privilege scopes/i.test(refusal.detail ?? '');\n\t}\n\n\tprivate _workspaces: Map<string, ProviderApiCollectionResult<BitbucketWorkspaceDescriptor> | undefined> | undefined;\n\tprivate async getProviderResourcesForCurrentUser(\n\t\tsession: ProviderAuthenticationSession,\n\t\tforce: boolean = false,\n\t): Promise<ProviderApiCollectionResult<BitbucketWorkspaceDescriptor> | undefined> {\n\t\tthis._workspaces ??= new Map<string, ProviderApiCollectionResult<BitbucketWorkspaceDescriptor> | undefined>();\n\t\tconst { accessToken } = session;\n\t\tconst cachedResources = this._workspaces.get(accessToken);\n\t\tif (cachedResources != null && !force) return cachedResources;\n\n\t\tconst api = await this.getProvidersApi();\n\t\tconst resources = await api.getBitbucketResourcesForCurrentUser(toTokenWithInfo(this.id, session));\n\t\tif (resources == null) return undefined;\n\n\t\tconst values = resources.values.map(r => ({ ...r, key: r.id, name: r.name ?? r.slug }));\n\t\tconst metadata = mergeCollectionMetadata(\n\t\t\tresources.metadata,\n\t\t\tresources.paging?.truncated === true ? { completeness: 'partial' } : undefined,\n\t\t);\n\t\tconst result: ProviderApiCollectionResult<BitbucketWorkspaceDescriptor> = {\n\t\t\tvalues: values,\n\t\t\t...(metadata != null ? { metadata: metadata } : {}),\n\t\t};\n\n\t\t// A partial workspace prefix is useful to the current read but must not become authoritative cache state:\n\t\t// a transient page-2 failure must be retried on the next call rather than hiding every later workspace\n\t\t// until disconnect.\n\t\tif (metadata == null || metadata.completeness === 'complete') {\n\t\t\tthis._workspaces.set(accessToken, result);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprotected override async getProviderOrganizationsForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t): Promise<ProviderHierarchyResult<ProviderOrganization> | undefined> {\n\t\tconst workspaces = await this.getProviderResourcesForCurrentUser(session);\n\t\tif (workspaces == null) return undefined;\n\n\t\treturn {\n\t\t\tvalues: workspaces.values.map(w => ({\n\t\t\t\tid: w.id,\n\t\t\t\tproviderId: this.id,\n\t\t\t\tname: w.slug,\n\t\t\t\turl: `https://bitbucket.org/${w.slug}`,\n\t\t\t})),\n\t\t\t...(workspaces.metadata != null ? { metadata: workspaces.metadata } : {}),\n\t\t};\n\t}\n\n\tprotected override async getProviderRepositoriesForOrg(\n\t\tsession: ProviderAuthenticationSession,\n\t\torg: string,\n\t\toptions?: { cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository> | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.getReposForBitbucketWorkspace(toTokenWithInfo(this.id, session), org, {\n\t\t\tcursor: options?.cursor,\n\t\t});\n\t}\n\n\tprotected override async searchProviderMyPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: BitbucketRepositoryDescriptor[],\n\t\t_cancellation?: AbortSignal,\n\t\toptions?: SearchMyPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined> {\n\t\tif (repos != null) {\n\t\t\t// TODO: implement repos version\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst state = options?.state;\n\t\tconst states = toProviderPullRequestStates(state);\n\n\t\tconst api = await this.getProvidersApi();\n\t\tif (!api) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst user = await this.getProviderCurrentAccount(session);\n\t\t// `user.id` feeds both the authored workspace reads and the reviewer BBQL clause; guard on it so we\n\t\t// never issue requests/queries with an undefined uuid. `username` isn't used here, so don't gate on it.\n\t\tif (user?.id == null) return undefined;\n\n\t\tconst workspacesResult = await this.getProviderResourcesForCurrentUser(session);\n\t\tif (workspacesResult == null) return undefined;\n\n\t\tconst workspaces = workspacesResult.values;\n\t\tif (workspaces.length === 0) return [];\n\n\t\tconst authoredPrs = workspaces.map(async ws => {\n\t\t\tconst prs = await api.getBitbucketPullRequestsAuthoredByUserForWorkspace(\n\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\tuser.id,\n\t\t\t\tws.slug,\n\t\t\t\t{ states: states },\n\t\t\t);\n\t\t\treturn prs?.data.map(pr => fromProviderPullRequest(pr, this, { projection: 'search' }));\n\t\t});\n\n\t\tif (!options?.includeReviewRequested) {\n\t\t\treturn [\n\t\t\t\t...uniqueBy(\n\t\t\t\t\tawait flatSettled(authoredPrs),\n\t\t\t\t\tpr => pr.url,\n\t\t\t\t\t(orig, _cur) => orig,\n\t\t\t\t),\n\t\t\t];\n\t\t}\n\n\t\t// Bitbucket's reviewing PRs require a repo-scoped BBQL query; keep that sweep opt-in so the default\n\t\t// \"my pull requests\" feed stays aligned with backends that only expose authored PRs.\n\t\tconst stateClause =\n\t\t\tstate === 'closed'\n\t\t\t\t? '(state=\"DECLINED\" OR state=\"SUPERSEDED\")'\n\t\t\t\t: state === 'merged'\n\t\t\t\t\t? 'state=\"MERGED\"'\n\t\t\t\t\t: state === 'all'\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: 'state=\"OPEN\"';\n\n\t\tconst workspaceRepos = await this.getWorkspaceRepoInputs();\n\t\tif (workspaceRepos.length === 0) {\n\t\t\treturn [\n\t\t\t\t...uniqueBy(\n\t\t\t\t\tawait flatSettled(authoredPrs),\n\t\t\t\t\tpr => pr.url,\n\t\t\t\t\t(orig, _cur) => orig,\n\t\t\t\t),\n\t\t\t];\n\t\t}\n\n\t\tconst reviewerClause = `reviewers.uuid=\"${user.id}\"`;\n\t\tconst reviewingPrs = api\n\t\t\t.getPullRequestsForRepos(toTokenWithInfo(this.id, session), workspaceRepos, {\n\t\t\t\tquery: stateClause ? `${stateClause} AND ${reviewerClause}` : reviewerClause,\n\t\t\t})\n\t\t\t.then(r => r.values?.map(pr => fromProviderPullRequest(pr, this, { projection: 'search' })));\n\n\t\treturn [\n\t\t\t...uniqueBy(\n\t\t\t\tawait flatSettled([...authoredPrs, reviewingPrs]),\n\t\t\t\tpr => pr.url,\n\t\t\t\t(orig, _cur) => orig,\n\t\t\t),\n\t\t];\n\t}\n\n\tprotected override async getProviderMyPullRequestsForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: {\n\t\t\tstate?: PullRequestStateFilter[];\n\t\t\tcursor?: string;\n\t\t\tincludeReviewRequested?: boolean;\n\t\t\tfilters?: PullRequestFilter[];\n\t\t},\n\t): Promise<ProviderApiPagedResult<ProviderPullRequest> | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\tconst user = await this.getProviderCurrentAccount(session);\n\t\tif (user?.id == null) return undefined;\n\n\t\tconst workspacesResult = await this.getProviderResourcesForCurrentUser(session);\n\t\tif (workspacesResult == null) return undefined;\n\n\t\tconst workspaces = workspacesResult.values;\n\t\tif (workspaces.length === 0) {\n\t\t\tconst incomplete =\n\t\t\t\tworkspacesResult.metadata != null && workspacesResult.metadata.completeness !== 'complete';\n\t\t\treturn {\n\t\t\t\tvalues: [],\n\t\t\t\tpaging: { cursor: '{}', more: false, truncated: incomplete || undefined },\n\t\t\t\t...(workspacesResult.metadata != null ? { metadata: workspacesResult.metadata } : {}),\n\t\t\t};\n\t\t}\n\n\t\t// Account-wide \"my PRs\" for Bitbucket = the user's authored PRs across every workspace they belong to,\n\t\t// plus the PRs they've been requested to review. Bitbucket's cross-workspace read is per-workspace and\n\t\t// numbered-page, so drain each workspace fully (bounded by a defensive backstop) and concatenate.\n\t\t// There's no single cross-workspace cursor, so the aggregate is one page; `truncated` is set when a\n\t\t// workspace hit the backstop with more pages left, or when a workspace's read was dropped by a failure.\n\t\tconst states = toProviderPullRequestStates(options?.state);\n\t\tconst requested = options?.filters?.length ? new Set(options.filters) : undefined;\n\t\tconst wantAuthored = requested == null || requested.has(PullRequestFilter.Author);\n\t\tconst wantReviewRequested =\n\t\t\trequested?.has(PullRequestFilter.ReviewRequested) ?? options?.includeReviewRequested === true;\n\t\tconst maxPagesPerWorkspace = 20;\n\t\tlet truncated = workspacesResult.metadata != null && workspacesResult.metadata.completeness !== 'complete';\n\t\t// Structured per-scope failures from BOTH the authored and reviewer slices. A rejected scope is recorded\n\t\t// here (never re-thrown) so successful sibling workspaces/repos survive and the ProviderBackend facade\n\t\t// maps each failure to an actionable warning + `fetchFailed` (auth/rate-limit failures still drive\n\t\t// recovery through their warning kind, matching the SDK's own collect-across-scopes model).\n\t\tconst failures: CollectionScopeFailure[] = [];\n\t\tlet aggregateMetadata = workspacesResult.metadata;\n\t\tconst absorbCollectionResult = (result: ProviderHierarchyResult<unknown>): void => {\n\t\t\taggregateMetadata = mergeCollectionMetadata(aggregateMetadata, result.metadata);\n\t\t\tif (result.truncated || (result.metadata != null && result.metadata.completeness !== 'complete')) {\n\t\t\t\ttruncated = true;\n\t\t\t}\n\t\t};\n\t\tconst settled = wantAuthored\n\t\t\t? await Promise.allSettled(\n\t\t\t\t\tworkspaces.map(async ws => {\n\t\t\t\t\t\treturn collectProviderPagedResult(\n\t\t\t\t\t\t\tasync cursor => {\n\t\t\t\t\t\t\t\tconst result = await api.getBitbucketPullRequestsAuthoredByUserForWorkspace(\n\t\t\t\t\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\t\t\t\t\tuser.id,\n\t\t\t\t\t\t\t\t\tws.slug,\n\t\t\t\t\t\t\t\t\t{ states: states, page: parsePageCursor(cursor) },\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tif (result == null) return undefined;\n\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tvalues: result.data,\n\t\t\t\t\t\t\t\t\tpaging: {\n\t\t\t\t\t\t\t\t\t\tmore: result.hasMore,\n\t\t\t\t\t\t\t\t\t\tcursor:\n\t\t\t\t\t\t\t\t\t\t\tresult.hasMore && result.nextPage != null\n\t\t\t\t\t\t\t\t\t\t\t\t? toPageCursor(result.nextPage)\n\t\t\t\t\t\t\t\t\t\t\t\t: '{}',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tmaxPagesPerWorkspace,\n\t\t\t\t\t\t\t{ providerId: this.id, resourceId: ws.slug },\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t: [];\n\n\t\tconst prsByIdentity = new Map<string, ProviderPullRequest>();\n\t\tlet unkeyedPullRequest = 0;\n\t\tconst addPullRequest = (pr: ProviderPullRequest): void => {\n\t\t\tconst key = getProviderPullRequestIdentity(pr) ?? `unkeyed:${unkeyedPullRequest++}`;\n\t\t\tif (!prsByIdentity.has(key)) {\n\t\t\t\tprsByIdentity.set(key, pr);\n\t\t\t}\n\t\t};\n\t\t// `allSettled` preserves order, so `settled[i]` is `workspaces[i]`. A rejected workspace becomes a\n\t\t// structured failure (attributed to its slug) instead of a generic truncation or a re-throw, preserving\n\t\t// every sibling workspace's authored PRs.\n\t\tsettled.forEach((outcome, i) => {\n\t\t\tif (outcome.status !== 'fulfilled') {\n\t\t\t\tfailures.push(this.toWorkspaceFailure(workspaces[i].slug, outcome.reason));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tabsorbCollectionResult(outcome.value);\n\t\t\tfor (const pr of outcome.value.values) {\n\t\t\t\taddPullRequest(pr);\n\t\t\t}\n\t\t});\n\n\t\t// Bitbucket's account-wide (per-workspace) endpoint returns authored PRs only, and the SDK exposes no\n\t\t// workspace-level reviewer query — only a repo-scoped one. Adding the reviewer slice therefore requires\n\t\t// draining every workspace's full repo list and then a per-repo `getPullRequestsForRepo` with `reviewerId`\n\t\t// (O(workspaces × repos) requests), so keep it opt-in: gate it on `includeReviewRequested` so the default\n\t\t// sweep matches the gkcli baseline (authored PRs only, no reviewer fan-out) and a caller pays that cost\n\t\t// only when it deliberately asks for review-requested PRs.\n\t\tif (wantReviewRequested) {\n\t\t\t// Enumerate the account's repos by draining each resolved workspace's repository list, then drain the\n\t\t\t// real per-repo paged `getPullRequestsForRepo` for each repo with `reviewerId`, so review-requested PRs\n\t\t\t// aren't bounded to the currently-open remotes and a reviewer PR past the first page isn't dropped.\n\t\t\t// Structured per-scope failures are collected as CollectionScopeFailure so the ProviderBackend facade\n\t\t\t// maps them to actionable warnings (Step 3).\n\t\t\tconst maxReposPagesPerWorkspace = 20;\n\t\t\tconst maxPrPagesPerRepo = 20;\n\t\t\t// Bound concurrency: workspaces are few, so process them concurrently, but drain each workspace's repos\n\t\t\t// in a bounded batch rather than an unbounded Promise.all over every repo in every workspace.\n\t\t\tconst repoBatchSize = 5;\n\n\t\t\tawait Promise.all(\n\t\t\t\tworkspaces.map(async ws => {\n\t\t\t\t\tlet repos: ProviderRepository[];\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst discovered = await collectProviderPagedResult(\n\t\t\t\t\t\t\tcursor =>\n\t\t\t\t\t\t\t\tapi.getReposForBitbucketWorkspace(toTokenWithInfo(this.id, session), ws.slug, {\n\t\t\t\t\t\t\t\t\tcursor: cursor,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tmaxReposPagesPerWorkspace,\n\t\t\t\t\t\t\t{ providerId: this.id, resourceId: ws.slug },\n\t\t\t\t\t\t);\n\t\t\t\t\t\trepos = discovered.values;\n\t\t\t\t\t\tabsorbCollectionResult(discovered);\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t// Record the workspace as a structured failure and keep going: the failure metadata drives\n\t\t\t\t\t\t// the warning + `fetchFailed` + incompleteness for every kind (auth/rate-limit stay\n\t\t\t\t\t\t// actionable via their warning kind), so sibling workspaces' repos are still drained.\n\t\t\t\t\t\tfailures.push(this.toWorkspaceFailure(ws.slug, ex));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst drained = await batchResults(repos, repoBatchSize, async repo => {\n\t\t\t\t\t\tconst reviewing = await collectProviderPagedResult(\n\t\t\t\t\t\t\tcursor =>\n\t\t\t\t\t\t\t\tapi.getPullRequestsForRepo(\n\t\t\t\t\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\t\t\t\t\t{ namespace: repo.namespace, name: repo.name },\n\t\t\t\t\t\t\t\t\t{ reviewerId: user.id, states: states, cursor: cursor },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tmaxPrPagesPerRepo,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tproviderId: this.id,\n\t\t\t\t\t\t\t\tresourceId: ws.slug,\n\t\t\t\t\t\t\t\trepositoryId: `${repo.namespace}/${repo.name}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { repo: repo, reviewing: reviewing };\n\t\t\t\t\t});\n\n\t\t\t\t\tfor (let i = 0; i < drained.length; i++) {\n\t\t\t\t\t\tconst outcome = drained[i];\n\t\t\t\t\t\tif (outcome.status !== 'fulfilled') {\n\t\t\t\t\t\t\tconst repo = repos[i];\n\t\t\t\t\t\t\tfailures.push(\n\t\t\t\t\t\t\t\tthis.toRepositoryFailure(\n\t\t\t\t\t\t\t\t\t`${repo?.namespace ?? ws.slug}/${repo?.name ?? 'unknown'}`,\n\t\t\t\t\t\t\t\t\toutcome.reason,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { reviewing } = outcome.value;\n\t\t\t\t\t\tabsorbCollectionResult(reviewing);\n\t\t\t\t\t\tfor (const pr of reviewing.values) {\n\t\t\t\t\t\t\taddPullRequest(pr);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\t// Every slice that ran (authored workspaces always, reviewer workspaces/repos when opted in) records its\n\t\t// per-scope rejections as structured failures instead of re-throwing: re-throwing would discard every\n\t\t// successful sibling's PRs. Auth/rate-limit failures stay actionable through the metadata (the facade maps\n\t\t// kind `authentication` → an `auth` warning, `rate-limit` → a `rate-limit` warning) while the survivors are\n\t\t// returned with `fetchFailed`.\n\t\tconst metadata: CollectionMetadata | undefined = mergeCollectionMetadata(\n\t\t\tfailures.length > 0 ? { completeness: 'partial', failures: failures } : undefined,\n\t\t\taggregateMetadata,\n\t\t);\n\n\t\treturn {\n\t\t\tvalues: [...prsByIdentity.values()],\n\t\t\tpaging: { cursor: '{}', more: false, truncated: truncated || undefined },\n\t\t\tmetadata: metadata,\n\t\t};\n\t}\n\n\t/** Classifies a caught workspace-scope error into a structured {@link CollectionScopeFailure}. */\n\tprivate toWorkspaceFailure(workspaceSlug: string, ex: unknown): CollectionScopeFailure {\n\t\treturn toCollectionScopeFailure({ providerId: this.id, resourceId: workspaceSlug }, ex);\n\t}\n\n\t/** Classifies a caught repository-scope error into a structured {@link CollectionScopeFailure}. */\n\tprivate toRepositoryFailure(repositoryId: string, ex: unknown): CollectionScopeFailure {\n\t\treturn toCollectionScopeFailure({ providerId: this.id, repositoryId: repositoryId }, ex);\n\t}\n\n\tprotected override async searchProviderPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\tsearchQuery: string,\n\t\trepos?: BitbucketRepositoryDescriptor[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined> {\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\tconst api = await this.getProvidersApi();\n\t\tif (!api) return undefined;\n\n\t\tconst workspaceRepos =\n\t\t\trepos != null\n\t\t\t\t? repos.map(r => ({ name: r.name, namespace: r.owner }))\n\t\t\t\t: await this.getWorkspaceRepoInputs();\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\t\t// An explicitly-empty `repos` means \"search these zero repos\" -> no results; reserve `undefined`\n\t\t// (\"scope couldn't be determined\") for when no repos were requested and none were discovered.\n\t\tif (workspaceRepos.length === 0) return repos != null ? [] : undefined;\n\n\t\tconst token = toTokenWithInfo(this.id, session);\n\t\tconst states = toProviderPullRequestStates(options?.include);\n\t\tconst providerPullRequests = await flatSettledOrThrow(\n\t\t\tworkspaceRepos.map(async repo => {\n\t\t\t\tconst result = await collectProviderPagedResult(cursor => {\n\t\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\t\treturn api.getPullRequestsForRepo(token, repo, {\n\t\t\t\t\t\tcursor: cursor,\n\t\t\t\t\t\tquery: searchQuery,\n\t\t\t\t\t\tstates: states,\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t\treturn result.values;\n\t\t\t}),\n\t\t);\n\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\treturn providerPullRequests.map(pr => fromProviderPullRequest(pr, this, { projection: 'text-search' }));\n\t}\n\n\tprivate async getWorkspaceRepoInputs(): Promise<{ name: string; namespace: string }[]> {\n\t\tconst remotes = await this.ctx.repositories.getOpenRemotes();\n\t\tconst inputs = await nonnullSettled(\n\t\t\tremotes.map(async (r: GitRemote) => {\n\t\t\t\tconst integration = await this.authenticationService.getByRemote(r);\n\t\t\t\tif (integration !== this) return undefined;\n\n\t\t\t\t// Use the remote provider's parsing rather than splitting `r.path`, so adornments like a\n\t\t\t\t// trailing `.git` or extra path segments don't leak into the namespace/name.\n\t\t\t\tconst namespace = r.provider?.owner;\n\t\t\t\tconst name = r.provider?.repoName;\n\t\t\t\treturn namespace != null && name != null ? { name: name, namespace: namespace } : undefined;\n\t\t\t}),\n\t\t);\n\t\t// Dedupe: a repo with multiple remotes (e.g. `origin` + `upstream`) can map to the same input,\n\t\t// which would otherwise fetch and return the same PRs more than once.\n\t\treturn [...new Map(inputs.map(i => [`${i.namespace}/${i.name}`, i])).values()];\n\t}\n\n\tprotected override async searchProviderMyIssues(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: BitbucketRepositoryDescriptor[],\n\t): Promise<IssueShape[] | undefined> {\n\t\tif (repos == null || repos.length === 0) return undefined;\n\n\t\tconst user = await this.getProviderCurrentAccount(session);\n\t\tif (user?.username == null) return undefined;\n\n\t\tconst api = await this.authenticationService.apis.bitbucket;\n\t\tif (!api) return undefined;\n\n\t\tconst issueResult = await flatSettled(\n\t\t\trepos.map(repo => {\n\t\t\t\treturn api.getUsersIssuesForRepo(\n\t\t\t\t\tthis,\n\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\tuser.id,\n\t\t\t\t\trepo.owner,\n\t\t\t\t\trepo.name,\n\t\t\t\t\tthis.apiBaseUrl,\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\t\treturn issueResult;\n\t}\n\n\t/**\n\t * Bitbucket is not an issue provider on the ProviderBackend surface: Bitbucket Cloud deprecated its issue\n\t * tracker in favor of dedicated issue integrations (e.g. Jira). The legacy per-repo `getUsersIssuesForRepo`\n\t * client is retained only for autolink/hover enrichment, not for the ProviderBackend issue reads, so the\n\t * facade reports issues as unsupported rather than serving a deprecated, partial source.\n\t */\n\toverride get supportsIssues(): boolean {\n\t\treturn false;\n\t}\n\n\tprivate readonly storagePrefix = 'bitbucket';\n\tprotected override async providerOnConnect(): Promise<void> {\n\t\tif (this._session == null) return;\n\n\t\tconst accountStorageKey = md5(this._session.accessToken);\n\n\t\tconst storedAccount = this.ctx.storage.get(`${this.storagePrefix}:${accountStorageKey}:account`);\n\t\tconst storedWorkspaces = this.ctx.storage.get(`${this.storagePrefix}:${accountStorageKey}:workspaces`);\n\n\t\tlet account: Account | undefined = storedAccount?.data ? { ...storedAccount.data, provider: this } : undefined;\n\n\t\tconst storedWorkspacesData = storedWorkspaces?.data as\n\t\t\t| ProviderApiCollectionResult<BitbucketWorkspaceDescriptor>\n\t\t\t| BitbucketWorkspaceDescriptor[]\n\t\t\t| undefined;\n\t\tlet workspaces: ProviderApiCollectionResult<BitbucketWorkspaceDescriptor> | undefined;\n\t\tif (\n\t\t\t!Array.isArray(storedWorkspacesData) &&\n\t\t\tArray.isArray(storedWorkspacesData?.values) &&\n\t\t\t(storedWorkspacesData.metadata == null || storedWorkspacesData.metadata.completeness === 'complete')\n\t\t) {\n\t\t\tworkspaces = {\n\t\t\t\tvalues: storedWorkspacesData.values.map((o: BitbucketWorkspaceDescriptor) => ({ ...o })),\n\t\t\t\t...(storedWorkspacesData.metadata != null ? { metadata: storedWorkspacesData.metadata } : {}),\n\t\t\t};\n\t\t}\n\n\t\tif (storedAccount == null) {\n\t\t\taccount = await this.getProviderCurrentAccount(this._session);\n\t\t\tif (account != null) {\n\t\t\t\t// Clear all other stored workspaces and repositories and accounts when our session changes\n\t\t\t\tawait this.ctx.storage.deleteWithPrefix(this.storagePrefix);\n\t\t\t\tawait this.ctx.storage.store(`${this.storagePrefix}:${accountStorageKey}:account`, {\n\t\t\t\t\tv: 1,\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tid: account.id,\n\t\t\t\t\t\tname: account.name,\n\t\t\t\t\t\temail: account.email,\n\t\t\t\t\t\tavatarUrl: account.avatarUrl,\n\t\t\t\t\t\tusername: account.username,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis._accounts ??= new Map<string, Account | undefined>();\n\t\tthis._accounts.set(this._session.accessToken, account);\n\n\t\tif (workspaces == null) {\n\t\t\tconst discovered = await this.getProviderResourcesForCurrentUser(this._session, true);\n\t\t\tif (discovered?.metadata == null || discovered.metadata.completeness === 'complete') {\n\t\t\t\tworkspaces = discovered;\n\t\t\t\tif (workspaces != null) {\n\t\t\t\t\tawait this.ctx.storage.store(`${this.storagePrefix}:${accountStorageKey}:workspaces`, {\n\t\t\t\t\t\tv: 2,\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\tdata: workspaces,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (workspaces != null) {\n\t\t\tthis._workspaces ??= new Map<\n\t\t\t\tstring,\n\t\t\t\tProviderApiCollectionResult<BitbucketWorkspaceDescriptor> | undefined\n\t\t\t>();\n\t\t\tthis._workspaces.set(this._session.accessToken, workspaces);\n\t\t}\n\t}\n\n\tprotected override providerOnDisconnect(): void {\n\t\tthis._accounts = undefined;\n\t\tthis._workspaces = undefined;\n\t}\n}\n"],"mappings":"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"}