@gitkraken/core-gitlens 0.10.0 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -1
- package/dist/plus/integrations/authentication/cloudIntegrationService.js +24 -7
- package/dist/plus/integrations/authentication/cloudIntegrationService.js.map +1 -1
- package/dist/plus/integrations/authentication/configuredIntegrationService.d.ts +40 -27
- package/dist/plus/integrations/authentication/configuredIntegrationService.js +92 -22
- package/dist/plus/integrations/authentication/configuredIntegrationService.js.map +1 -1
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.d.ts +7 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +22 -8
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js.map +1 -1
- package/dist/plus/integrations/integrationService.js +6 -3
- package/dist/plus/integrations/integrationService.js.map +1 -1
- package/dist/plus/integrations/models/gitHostIntegration.js +38 -36
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
- package/dist/plus/integrations/models/integration.d.ts +71 -7
- package/dist/plus/integrations/models/integration.js +201 -55
- package/dist/plus/integrations/models/integration.js.map +1 -1
- package/dist/plus/integrations/models/issuesIntegration.js +9 -9
- package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOps.js +1 -1
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOpsServer.js +1 -1
- package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server.js +1 -1
- package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket.js +1 -1
- package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
- package/dist/plus/integrations/providers/github.js +3 -6
- package/dist/plus/integrations/providers/github.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab.js +1 -1
- package/dist/plus/integrations/providers/gitlab.js.map +1 -1
- package/dist/plus/integrations/providers/jira.js +1 -0
- package/dist/plus/integrations/providers/jira.js.map +1 -1
- package/dist/plus/integrations/providers/linear.js +1 -0
- package/dist/plus/integrations/providers/linear.js.map +1 -1
- package/package.json +1 -1
|
@@ -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 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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"}
|
|
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.resolveReadSessionOrThrow(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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"}
|
|
@@ -217,7 +217,7 @@ var GitHubIntegrationBase = class extends GitHostIntegration {
|
|
|
217
217
|
}
|
|
218
218
|
async getRepoInfo(repo) {
|
|
219
219
|
const api = await this.getProvidersApi();
|
|
220
|
-
const session = await this.
|
|
220
|
+
const session = await this.resolveReadSessionOrThrow(repo.connectionId, void 0);
|
|
221
221
|
if (session == null) return void 0;
|
|
222
222
|
try {
|
|
223
223
|
return await api.getRepo(toTokenWithInfo(this.id, session), repo.owner, repo.name, repo.project, { baseUrl: this.apiBaseUrlFor(session) });
|
|
@@ -608,7 +608,7 @@ var GitHubIntegrationBase = class extends GitHostIntegration {
|
|
|
608
608
|
* empty map, which means the repository genuinely has no stacks.
|
|
609
609
|
*/
|
|
610
610
|
async getStacksByPullRequestNumber(owner, repo, cancellation) {
|
|
611
|
-
const session = await this.
|
|
611
|
+
const session = await this.resolveReadSessionOrThrow(void 0, void 0);
|
|
612
612
|
if (session == null) return void 0;
|
|
613
613
|
const stacks = await (await this.authenticationService.apis.github)?.getRepositoryStacks(this, toTokenWithInfo(this.id, session), owner, repo, { baseUrl: this.apiBaseUrlFor(session) }, cancellation);
|
|
614
614
|
if (stacks == null) return void 0;
|
|
@@ -668,10 +668,7 @@ var GitHubIntegration = class extends GitHubIntegrationBase {
|
|
|
668
668
|
async refresh() {
|
|
669
669
|
const session = await (await this.authenticationService.get(this.authProvider.id)).getSession(this.authProviderDescriptor);
|
|
670
670
|
if (session == null && this.maybeConnected) this.disconnect({ silent: true });
|
|
671
|
-
else
|
|
672
|
-
if (session?.accessToken !== this._session?.accessToken) this._session = void 0;
|
|
673
|
-
super.refresh();
|
|
674
|
-
}
|
|
671
|
+
else this.resyncSessionIfTokenChanged(session?.accessToken);
|
|
675
672
|
}
|
|
676
673
|
};
|
|
677
674
|
var GitHubEnterpriseIntegration = class extends GitHubIntegrationBase {
|