|
1 | 1 | import type { AuthenticationSession, CancellationToken } from 'vscode';
|
| 2 | +import { md5 } from '@env/crypto'; |
2 | 3 | import { HostingIntegrationId } from '../../../constants.integrations';
|
3 | 4 | import type { Account } from '../../../git/models/author';
|
4 | 5 | import type { DefaultBranch } from '../../../git/models/defaultBranch';
|
@@ -33,6 +34,7 @@ interface BitbucketWorkspaceDescriptor extends ResourceDescriptor {
|
33 | 34 | }
|
34 | 35 |
|
35 | 36 | interface BitbucketRemoteRepositoryDescriptor extends ResourceDescriptor {
|
| 37 | + resourceId: string; |
36 | 38 | owner: string;
|
37 | 39 | name: string;
|
38 | 40 | cloneUrlHttps?: string;
|
@@ -238,6 +240,7 @@ export class BitbucketIntegration extends HostingIntegration<
|
238 | 240 | `${accessToken}:${resource.id}`,
|
239 | 241 | resourceRepos.map(r => ({
|
240 | 242 | id: `${r.owner}/${r.name}`,
|
| 243 | + resourceId: r.owner, |
241 | 244 | owner: r.owner,
|
242 | 245 | name: r.name,
|
243 | 246 | key: `${r.owner}/${r.name}`,
|
@@ -302,6 +305,77 @@ export class BitbucketIntegration extends HostingIntegration<
|
302 | 305 | remotePullRequest.graphQLId = remotePullRequest.id;
|
303 | 306 | return fromProviderPullRequest(remotePullRequest, this);
|
304 | 307 | }
|
| 308 | + |
| 309 | + protected override async providerOnConnect(): Promise<void> { |
| 310 | + if (this._session == null) return; |
| 311 | + |
| 312 | + const accountStorageKey = md5(this._session.accessToken); |
| 313 | + |
| 314 | + const storedAccount = this.container.storage.get(`bitbucket:${accountStorageKey}:account`); |
| 315 | + const storedWorkspaces = this.container.storage.get(`bitbucket:${accountStorageKey}:workspaces`); |
| 316 | + const storedRepositories = this.container.storage.get(`bitbucket:${accountStorageKey}:repositories`); |
| 317 | + |
| 318 | + let account: Account | undefined = storedAccount?.data ? { ...storedAccount.data, provider: this } : undefined; |
| 319 | + let workspaces = storedWorkspaces?.data?.map(o => ({ ...o })); |
| 320 | + let repositories = storedRepositories?.data?.map(p => ({ ...p })); |
| 321 | + |
| 322 | + if (storedAccount == null) { |
| 323 | + account = await this.getProviderCurrentAccount(this._session); |
| 324 | + if (account != null) { |
| 325 | + // Clear all other stored workspaces and repositories and accounts when our session changes |
| 326 | + await this.container.storage.deleteWithPrefix('bitbucket'); |
| 327 | + await this.container.storage.store(`bitbucket:${accountStorageKey}:account`, { |
| 328 | + v: 1, |
| 329 | + timestamp: Date.now(), |
| 330 | + data: { |
| 331 | + id: account.id, |
| 332 | + name: account.name, |
| 333 | + email: account.email, |
| 334 | + avatarUrl: account.avatarUrl, |
| 335 | + username: account.username, |
| 336 | + }, |
| 337 | + }); |
| 338 | + } |
| 339 | + } |
| 340 | + this._accounts ??= new Map<string, Account | undefined>(); |
| 341 | + this._accounts.set(this._session.accessToken, account); |
| 342 | + |
| 343 | + if (storedWorkspaces == null) { |
| 344 | + workspaces = await this.getProviderResourcesForUser(this._session, true); |
| 345 | + await this.container.storage.store(`bitbucket:${accountStorageKey}:workspaces`, { |
| 346 | + v: 1, |
| 347 | + timestamp: Date.now(), |
| 348 | + data: workspaces, |
| 349 | + }); |
| 350 | + } |
| 351 | + this._workspaces ??= new Map<string, BitbucketWorkspaceDescriptor[] | undefined>(); |
| 352 | + this._workspaces.set(this._session.accessToken, workspaces); |
| 353 | + |
| 354 | + if (storedRepositories == null && workspaces?.length) { |
| 355 | + repositories = await this.getProviderProjectsForResources(this._session, workspaces); |
| 356 | + await this.container.storage.store(`bitbucket:${accountStorageKey}:repositories`, { |
| 357 | + v: 1, |
| 358 | + timestamp: Date.now(), |
| 359 | + data: repositories, |
| 360 | + }); |
| 361 | + } |
| 362 | + this._repositories ??= new Map<string, BitbucketRemoteRepositoryDescriptor[] | undefined>(); |
| 363 | + for (const repository of repositories ?? []) { |
| 364 | + const resourceKey = `${this._session.accessToken}:${repository.resourceId}`; |
| 365 | + const repos = this._repositories.get(resourceKey); |
| 366 | + if (repos == null) { |
| 367 | + this._repositories.set(resourceKey, [repository]); |
| 368 | + } else if (!repos.some(r => r.key === repository.key)) { |
| 369 | + repos.push(repository); |
| 370 | + } |
| 371 | + } |
| 372 | + } |
| 373 | + |
| 374 | + protected override providerOnDisconnect(): void { |
| 375 | + this._accounts = undefined; |
| 376 | + this._workspaces = undefined; |
| 377 | + this._repositories = undefined; |
| 378 | + } |
305 | 379 | }
|
306 | 380 |
|
307 | 381 | const bitbucketCloudDomainRegex = /^bitbucket\.org$/i;
|
|
0 commit comments