@gitkraken/core-gitlens 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -1
- package/README.md +13 -10
- package/dist/git/context.d.ts +4 -3
- package/dist/git/context.d.ts.map +1 -1
- package/dist/git/context.js.map +1 -1
- package/dist/git/providers/operations.d.ts +1 -0
- package/dist/git/providers/operations.d.ts.map +1 -1
- package/dist/git/providers/worktrees.d.ts +2 -0
- package/dist/git/providers/worktrees.d.ts.map +1 -1
- package/dist/git/utils/conflictResolution.utils.d.ts +32 -0
- package/dist/git/utils/conflictResolution.utils.d.ts.map +1 -1
- package/dist/git/utils/conflictResolution.utils.js +95 -0
- package/dist/git/utils/conflictResolution.utils.js.map +1 -1
- package/dist/git-cli/providers/operations.d.ts +1 -0
- package/dist/git-cli/providers/operations.d.ts.map +1 -1
- package/dist/git-cli/providers/operations.js +22 -1
- package/dist/git-cli/providers/operations.js.map +1 -1
- package/dist/git-cli/providers/worktrees.d.ts +2 -0
- package/dist/git-cli/providers/worktrees.d.ts.map +1 -1
- package/dist/git-cli/providers/worktrees.js +3 -0
- package/dist/git-cli/providers/worktrees.js.map +1 -1
- package/dist/plus/ai/utils/ai.utils.js +5 -5
- package/dist/plus/ai/utils/ai.utils.js.map +1 -1
- package/dist/plus/git-github/api/github.d.ts +6 -13
- package/dist/plus/git-github/api/github.d.ts.map +1 -1
- package/dist/plus/git-github/api/github.js +5 -10
- package/dist/plus/git-github/api/github.js.map +1 -1
- package/dist/plus/integrations/authentication/cloudIntegrationService.d.ts +11 -0
- package/dist/plus/integrations/authentication/cloudIntegrationService.d.ts.map +1 -0
- package/dist/plus/integrations/authentication/cloudIntegrationService.js +90 -0
- package/dist/plus/integrations/authentication/cloudIntegrationService.js.map +1 -0
- package/dist/plus/integrations/authentication/configuredIntegrationService.d.ts +67 -0
- package/dist/plus/integrations/authentication/configuredIntegrationService.d.ts.map +1 -0
- package/dist/plus/integrations/authentication/configuredIntegrationService.js +295 -0
- package/dist/plus/integrations/authentication/configuredIntegrationService.js.map +1 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.d.ts +92 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.d.ts.map +1 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +185 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js.map +1 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationService.d.ts +62 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationService.d.ts.map +1 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationService.js +122 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationService.js.map +1 -0
- package/dist/plus/integrations/authentication/manualTokenProvider.d.ts +15 -0
- package/dist/plus/integrations/authentication/manualTokenProvider.d.ts.map +1 -0
- package/dist/plus/integrations/authentication/manualTokenProvider.js +49 -0
- package/dist/plus/integrations/authentication/manualTokenProvider.js.map +1 -0
- package/dist/plus/integrations/authentication/models.d.ts +87 -0
- package/dist/plus/integrations/authentication/models.d.ts.map +1 -0
- package/dist/plus/integrations/authentication/models.js +64 -0
- package/dist/plus/integrations/authentication/models.js.map +1 -0
- package/dist/plus/integrations/constants.d.ts +47 -0
- package/dist/plus/integrations/constants.d.ts.map +1 -0
- package/dist/plus/integrations/constants.js +128 -0
- package/dist/plus/integrations/constants.js.map +1 -0
- package/dist/plus/integrations/context.d.ts +354 -0
- package/dist/plus/integrations/context.d.ts.map +1 -0
- package/dist/plus/integrations/context.js +2 -0
- package/dist/plus/integrations/context.js.map +1 -0
- package/dist/plus/integrations/errors.d.ts +14 -0
- package/dist/plus/integrations/errors.d.ts.map +1 -0
- package/dist/plus/integrations/errors.js +19 -0
- package/dist/plus/integrations/errors.js.map +1 -0
- package/dist/plus/integrations/index.d.ts +32 -0
- package/dist/plus/integrations/index.d.ts.map +1 -0
- package/dist/plus/integrations/index.js +62 -0
- package/dist/plus/integrations/index.js.map +1 -0
- package/dist/plus/integrations/integrationService.d.ts +98 -0
- package/dist/plus/integrations/integrationService.d.ts.map +1 -0
- package/dist/plus/integrations/integrationService.js +627 -0
- package/dist/plus/integrations/integrationService.js.map +1 -0
- package/dist/plus/integrations/models/gitHostIntegration.d.ts +82 -0
- package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -0
- package/dist/plus/integrations/models/gitHostIntegration.js +522 -0
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -0
- package/dist/plus/integrations/models/integration.d.ts +127 -0
- package/dist/plus/integrations/models/integration.d.ts.map +1 -0
- package/dist/plus/integrations/models/integration.js +456 -0
- package/dist/plus/integrations/models/integration.js.map +1 -0
- package/dist/plus/integrations/models/issuesIntegration.d.ts +28 -0
- package/dist/plus/integrations/models/issuesIntegration.d.ts.map +1 -0
- package/dist/plus/integrations/models/issuesIntegration.js +101 -0
- package/dist/plus/integrations/models/issuesIntegration.js.map +1 -0
- package/dist/plus/integrations/providers/apiClients.d.ts +25 -0
- package/dist/plus/integrations/providers/apiClients.d.ts.map +1 -0
- package/dist/plus/integrations/providers/apiClients.js +39 -0
- package/dist/plus/integrations/providers/apiClients.js.map +1 -0
- package/dist/plus/integrations/providers/azure/azure.d.ts +47 -0
- package/dist/plus/integrations/providers/azure/azure.d.ts.map +1 -0
- package/dist/plus/integrations/providers/azure/azure.js +444 -0
- package/dist/plus/integrations/providers/azure/azure.js.map +1 -0
- package/dist/plus/integrations/providers/azure/models.d.ts +286 -0
- package/dist/plus/integrations/providers/azure/models.d.ts.map +1 -0
- package/dist/plus/integrations/providers/azure/models.js +203 -0
- package/dist/plus/integrations/providers/azure/models.js.map +1 -0
- package/dist/plus/integrations/providers/azureDevOps.d.ts +95 -0
- package/dist/plus/integrations/providers/azureDevOps.d.ts.map +1 -0
- package/dist/plus/integrations/providers/azureDevOps.js +432 -0
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts +42 -0
- package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts.map +1 -0
- package/dist/plus/integrations/providers/bitbucket/bitbucket.js +513 -0
- package/dist/plus/integrations/providers/bitbucket/bitbucket.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket/models.d.ts +222 -0
- package/dist/plus/integrations/providers/bitbucket/models.d.ts.map +1 -0
- package/dist/plus/integrations/providers/bitbucket/models.js +158 -0
- package/dist/plus/integrations/providers/bitbucket/models.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server/models.d.ts +120 -0
- package/dist/plus/integrations/providers/bitbucket-server/models.d.ts.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server/models.js +111 -0
- package/dist/plus/integrations/providers/bitbucket-server/models.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server.d.ts +60 -0
- package/dist/plus/integrations/providers/bitbucket-server.d.ts.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server.js +138 -0
- package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket.d.ts +50 -0
- package/dist/plus/integrations/providers/bitbucket.d.ts.map +1 -0
- package/dist/plus/integrations/providers/bitbucket.js +181 -0
- package/dist/plus/integrations/providers/bitbucket.js.map +1 -0
- package/dist/plus/integrations/providers/github/github.d.ts +5 -0
- package/dist/plus/integrations/providers/github/github.d.ts.map +1 -0
- package/dist/plus/integrations/providers/github/github.js +47 -0
- package/dist/plus/integrations/providers/github/github.js.map +1 -0
- package/dist/plus/integrations/providers/github/github.utils.d.ts +11 -0
- package/dist/plus/integrations/providers/github/github.utils.d.ts.map +1 -0
- package/dist/plus/integrations/providers/github/github.utils.js +6 -0
- package/dist/plus/integrations/providers/github/github.utils.js.map +1 -0
- package/dist/plus/integrations/providers/github/models.d.ts +3 -0
- package/dist/plus/integrations/providers/github/models.d.ts.map +1 -0
- package/dist/plus/integrations/providers/github/models.js +2 -0
- package/dist/plus/integrations/providers/github/models.js.map +1 -0
- package/dist/plus/integrations/providers/github.d.ts +73 -0
- package/dist/plus/integrations/providers/github.d.ts.map +1 -0
- package/dist/plus/integrations/providers/github.js +160 -0
- package/dist/plus/integrations/providers/github.js.map +1 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.d.ts +63 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.d.ts.map +1 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.js +828 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.js.map +1 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.utils.d.ts +21 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.utils.d.ts.map +1 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.utils.js +45 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.utils.js.map +1 -0
- package/dist/plus/integrations/providers/gitlab/models.d.ts +128 -0
- package/dist/plus/integrations/providers/gitlab/models.d.ts.map +1 -0
- package/dist/plus/integrations/providers/gitlab/models.js +96 -0
- package/dist/plus/integrations/providers/gitlab/models.js.map +1 -0
- package/dist/plus/integrations/providers/gitlab.d.ts +79 -0
- package/dist/plus/integrations/providers/gitlab.d.ts.map +1 -0
- package/dist/plus/integrations/providers/gitlab.js +253 -0
- package/dist/plus/integrations/providers/gitlab.js.map +1 -0
- package/dist/plus/integrations/providers/jira.d.ts +46 -0
- package/dist/plus/integrations/providers/jira.d.ts.map +1 -0
- package/dist/plus/integrations/providers/jira.js +255 -0
- package/dist/plus/integrations/providers/jira.js.map +1 -0
- package/dist/plus/integrations/providers/linear.d.ts +47 -0
- package/dist/plus/integrations/providers/linear.d.ts.map +1 -0
- package/dist/plus/integrations/providers/linear.js +198 -0
- package/dist/plus/integrations/providers/linear.js.map +1 -0
- package/dist/plus/integrations/providers/models.d.ts +433 -0
- package/dist/plus/integrations/providers/models.d.ts.map +1 -0
- package/dist/plus/integrations/providers/models.js +602 -0
- package/dist/plus/integrations/providers/models.js.map +1 -0
- package/dist/plus/integrations/providers/providersApi.d.ts +129 -0
- package/dist/plus/integrations/providers/providersApi.d.ts.map +1 -0
- package/dist/plus/integrations/providers/providersApi.js +602 -0
- package/dist/plus/integrations/providers/providersApi.js.map +1 -0
- package/dist/plus/integrations/providers/utils.d.ts +54 -0
- package/dist/plus/integrations/providers/utils.d.ts.map +1 -0
- package/dist/plus/integrations/providers/utils.js +262 -0
- package/dist/plus/integrations/providers/utils.js.map +1 -0
- package/dist/plus/integrations/telemetry.d.ts +26 -0
- package/dist/plus/integrations/telemetry.d.ts.map +1 -0
- package/dist/plus/integrations/telemetry.js +11 -0
- package/dist/plus/integrations/telemetry.js.map +1 -0
- package/dist/plus/integrations/utils/integration.utils.d.ts +14 -0
- package/dist/plus/integrations/utils/integration.utils.d.ts.map +1 -0
- package/dist/plus/integrations/utils/integration.utils.js +111 -0
- package/dist/plus/integrations/utils/integration.utils.js.map +1 -0
- package/dist/utils/disposable.d.ts +15 -2
- package/dist/utils/disposable.d.ts.map +1 -1
- package/dist/utils/disposable.js.map +1 -1
- package/package.json +43 -2
- package/src/git/context.ts +4 -3
- package/src/git/providers/operations.ts +1 -1
- package/src/git/providers/worktrees.ts +14 -2
- package/src/git/utils/conflictResolution.utils.ts +126 -0
- package/src/git-cli/providers/operations.ts +22 -2
- package/src/git-cli/providers/worktrees.ts +17 -2
- package/src/plus/ai/utils/ai.utils.ts +5 -5
- package/src/plus/git-github/api/github.ts +13 -25
- package/src/plus/integrations/authentication/cloudIntegrationService.ts +120 -0
- package/src/plus/integrations/authentication/configuredIntegrationService.ts +414 -0
- package/src/plus/integrations/authentication/integrationAuthenticationProvider.ts +289 -0
- package/src/plus/integrations/authentication/integrationAuthenticationService.ts +144 -0
- package/src/plus/integrations/authentication/manualTokenProvider.ts +72 -0
- package/src/plus/integrations/authentication/models.ts +168 -0
- package/src/plus/integrations/constants.ts +169 -0
- package/src/plus/integrations/context.ts +383 -0
- package/src/plus/integrations/errors.ts +35 -0
- package/src/plus/integrations/index.ts +119 -0
- package/src/plus/integrations/integrationService.ts +924 -0
- package/src/plus/integrations/models/gitHostIntegration.ts +738 -0
- package/src/plus/integrations/models/integration.ts +657 -0
- package/src/plus/integrations/models/issuesIntegration.ts +124 -0
- package/src/plus/integrations/providers/apiClients.ts +72 -0
- package/src/plus/integrations/providers/azure/azure.ts +691 -0
- package/src/plus/integrations/providers/azure/models.ts +605 -0
- package/src/plus/integrations/providers/azureDevOps.ts +677 -0
- package/src/plus/integrations/providers/bitbucket/bitbucket.ts +774 -0
- package/src/plus/integrations/providers/bitbucket/models.ts +445 -0
- package/src/plus/integrations/providers/bitbucket-server/models.ts +252 -0
- package/src/plus/integrations/providers/bitbucket-server.ts +282 -0
- package/src/plus/integrations/providers/bitbucket.ts +350 -0
- package/src/plus/integrations/providers/github/github.ts +64 -0
- package/src/plus/integrations/providers/github/github.utils.ts +23 -0
- package/src/plus/integrations/providers/github/models.ts +29 -0
- package/src/plus/integrations/providers/github.ts +366 -0
- package/src/plus/integrations/providers/gitlab/gitlab.ts +1210 -0
- package/src/plus/integrations/providers/gitlab/gitlab.utils.ts +71 -0
- package/src/plus/integrations/providers/gitlab/models.ts +257 -0
- package/src/plus/integrations/providers/gitlab.ts +473 -0
- package/src/plus/integrations/providers/jira.ts +359 -0
- package/src/plus/integrations/providers/linear.ts +275 -0
- package/src/plus/integrations/providers/models.ts +1114 -0
- package/src/plus/integrations/providers/providersApi.ts +1126 -0
- package/src/plus/integrations/providers/utils.ts +359 -0
- package/src/plus/integrations/telemetry.ts +29 -0
- package/src/plus/integrations/utils/integration.utils.ts +138 -0
- package/src/utils/disposable.ts +15 -2
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import type { Account, UnidentifiedAuthor } from '../../../git/models/author.js';
|
|
2
|
+
import type { DefaultBranch } from '../../../git/models/defaultBranch.js';
|
|
3
|
+
import type { Issue, IssueShape } from '../../../git/models/issue.js';
|
|
4
|
+
import type { IssueOrPullRequest, IssueOrPullRequestType } from '../../../git/models/issueOrPullRequest.js';
|
|
5
|
+
import type { PullRequest, PullRequestMergeMethod, PullRequestState } from '../../../git/models/pullRequest.js';
|
|
6
|
+
import type { RepositoryMetadata } from '../../../git/models/repositoryMetadata.js';
|
|
7
|
+
import { md5 } from '../../../utils/crypto.js';
|
|
8
|
+
import type { Emitter } from '../../../utils/event.js';
|
|
9
|
+
import type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider.js';
|
|
10
|
+
import type { IntegrationAuthenticationService } from '../authentication/integrationAuthenticationService.js';
|
|
11
|
+
import type { IntegrationServiceContext } from '../context.js';
|
|
12
|
+
import type {
|
|
13
|
+
AuthenticationSessionLike as AuthenticationSession,
|
|
14
|
+
ProviderAuthenticationSession,
|
|
15
|
+
} from '../authentication/models.js';
|
|
16
|
+
import { toTokenWithInfo } from '../authentication/models.js';
|
|
17
|
+
import { GitSelfManagedHostIntegrationId } from '../constants.js';
|
|
18
|
+
import type { IntegrationConnectionChangeEvent } from '../integrationService.js';
|
|
19
|
+
import { GitHostIntegration } from '../models/gitHostIntegration.js';
|
|
20
|
+
import type { IntegrationKey } from '../models/integration.js';
|
|
21
|
+
import type { BitbucketRepositoryDescriptor } from './bitbucket/models.js';
|
|
22
|
+
import type { ProviderRepository } from './models.js';
|
|
23
|
+
import { fromProviderPullRequest, providersMetadata } from './models.js';
|
|
24
|
+
import type { ProvidersApi } from './providersApi.js';
|
|
25
|
+
|
|
26
|
+
const metadata = providersMetadata[GitSelfManagedHostIntegrationId.BitbucketServer];
|
|
27
|
+
const authProvider = Object.freeze({ id: metadata.id, scopes: metadata.scopes });
|
|
28
|
+
|
|
29
|
+
export class BitbucketServerIntegration extends GitHostIntegration<
|
|
30
|
+
GitSelfManagedHostIntegrationId.BitbucketServer,
|
|
31
|
+
BitbucketRepositoryDescriptor
|
|
32
|
+
> {
|
|
33
|
+
readonly authProvider: IntegrationAuthenticationProviderDescriptor = authProvider;
|
|
34
|
+
readonly id = GitSelfManagedHostIntegrationId.BitbucketServer;
|
|
35
|
+
protected readonly key =
|
|
36
|
+
`${this.id}:${this.domain}` satisfies IntegrationKey<GitSelfManagedHostIntegrationId.BitbucketServer>;
|
|
37
|
+
readonly name: string = 'Bitbucket Data Center';
|
|
38
|
+
|
|
39
|
+
constructor(
|
|
40
|
+
ctx: IntegrationServiceContext,
|
|
41
|
+
authenticationService: IntegrationAuthenticationService,
|
|
42
|
+
getProvidersApi: () => Promise<ProvidersApi>,
|
|
43
|
+
didChangeConnection: Emitter<IntegrationConnectionChangeEvent>,
|
|
44
|
+
private readonly _domain: string,
|
|
45
|
+
) {
|
|
46
|
+
super(ctx, authenticationService, getProvidersApi, didChangeConnection);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get domain(): string {
|
|
50
|
+
return this._domain;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
protected get apiBaseUrl(): string {
|
|
54
|
+
const protocol = this._session?.protocol ?? 'https:';
|
|
55
|
+
return `${protocol}//${this.domain}/rest/api/1.0`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
protected override async mergeProviderPullRequest(
|
|
59
|
+
session: ProviderAuthenticationSession,
|
|
60
|
+
pr: PullRequest,
|
|
61
|
+
options?: {
|
|
62
|
+
mergeMethod?: PullRequestMergeMethod;
|
|
63
|
+
},
|
|
64
|
+
): Promise<boolean> {
|
|
65
|
+
const api = await this.getProvidersApi();
|
|
66
|
+
return api.mergePullRequest(toTokenWithInfo(this.id, session), pr, {
|
|
67
|
+
mergeMethod: options?.mergeMethod,
|
|
68
|
+
baseUrl: this.apiBaseUrl,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
protected override async getProviderAccountForCommit(
|
|
73
|
+
session: ProviderAuthenticationSession,
|
|
74
|
+
repo: BitbucketRepositoryDescriptor,
|
|
75
|
+
rev: string,
|
|
76
|
+
options?: {
|
|
77
|
+
avatarSize?: number;
|
|
78
|
+
},
|
|
79
|
+
): Promise<Account | UnidentifiedAuthor | undefined> {
|
|
80
|
+
return (await this.authenticationService.apis.bitbucket)?.getServerAccountForCommit(
|
|
81
|
+
this,
|
|
82
|
+
toTokenWithInfo(this.id, session),
|
|
83
|
+
repo.owner,
|
|
84
|
+
repo.name,
|
|
85
|
+
rev,
|
|
86
|
+
this.apiBaseUrl,
|
|
87
|
+
{
|
|
88
|
+
avatarSize: options?.avatarSize,
|
|
89
|
+
},
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
protected override async getProviderAccountForEmail(
|
|
94
|
+
_session: AuthenticationSession,
|
|
95
|
+
_repo: BitbucketRepositoryDescriptor,
|
|
96
|
+
_email: string,
|
|
97
|
+
_options?: {
|
|
98
|
+
avatarSize?: number;
|
|
99
|
+
},
|
|
100
|
+
): Promise<Account | undefined> {
|
|
101
|
+
return Promise.resolve(undefined);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
protected override async getProviderDefaultBranch(
|
|
105
|
+
_session: AuthenticationSession,
|
|
106
|
+
_repo: BitbucketRepositoryDescriptor,
|
|
107
|
+
): Promise<DefaultBranch | undefined> {
|
|
108
|
+
return Promise.resolve(undefined);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
protected override async getProviderLinkedIssueOrPullRequest(
|
|
112
|
+
session: ProviderAuthenticationSession,
|
|
113
|
+
repo: BitbucketRepositoryDescriptor,
|
|
114
|
+
{ id }: { id: string; key: string },
|
|
115
|
+
type: undefined | IssueOrPullRequestType,
|
|
116
|
+
): Promise<IssueOrPullRequest | undefined> {
|
|
117
|
+
if (type === 'issue') {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
return (await this.authenticationService.apis.bitbucket)?.getServerPullRequestById(
|
|
121
|
+
this,
|
|
122
|
+
toTokenWithInfo(this.id, session),
|
|
123
|
+
repo.owner,
|
|
124
|
+
repo.name,
|
|
125
|
+
id,
|
|
126
|
+
this.apiBaseUrl,
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
protected override async getProviderIssue(
|
|
131
|
+
_session: AuthenticationSession,
|
|
132
|
+
_repo: BitbucketRepositoryDescriptor,
|
|
133
|
+
_id: string,
|
|
134
|
+
): Promise<Issue | undefined> {
|
|
135
|
+
return Promise.resolve(undefined);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
protected override async getProviderPullRequestForBranch(
|
|
139
|
+
session: ProviderAuthenticationSession,
|
|
140
|
+
repo: BitbucketRepositoryDescriptor,
|
|
141
|
+
branch: string,
|
|
142
|
+
_options?: {
|
|
143
|
+
avatarSize?: number;
|
|
144
|
+
include?: PullRequestState[];
|
|
145
|
+
},
|
|
146
|
+
): Promise<PullRequest | undefined> {
|
|
147
|
+
return (await this.authenticationService.apis.bitbucket)?.getServerPullRequestForBranch(
|
|
148
|
+
this,
|
|
149
|
+
toTokenWithInfo(this.id, session),
|
|
150
|
+
repo.owner,
|
|
151
|
+
repo.name,
|
|
152
|
+
branch,
|
|
153
|
+
this.apiBaseUrl,
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
protected override async getProviderPullRequestForCommit(
|
|
158
|
+
session: ProviderAuthenticationSession,
|
|
159
|
+
repo: BitbucketRepositoryDescriptor,
|
|
160
|
+
rev: string,
|
|
161
|
+
): Promise<PullRequest | undefined> {
|
|
162
|
+
return (await this.authenticationService.apis.bitbucket)?.getServerPullRequestForCommit(
|
|
163
|
+
this,
|
|
164
|
+
toTokenWithInfo(this.id, session),
|
|
165
|
+
repo.owner,
|
|
166
|
+
repo.name,
|
|
167
|
+
rev,
|
|
168
|
+
this.apiBaseUrl,
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
public override async getRepoInfo(repo: { owner: string; name: string }): Promise<ProviderRepository | undefined> {
|
|
173
|
+
const api = await this.getProvidersApi();
|
|
174
|
+
const tokenOptInfo = this._session ? toTokenWithInfo(this.id, this._session) : { providerId: this.id };
|
|
175
|
+
return api.getRepo(tokenOptInfo, repo.owner, repo.name, undefined, {
|
|
176
|
+
baseUrl: this.apiBaseUrl,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
protected override async getProviderRepositoryMetadata(
|
|
181
|
+
_session: AuthenticationSession,
|
|
182
|
+
_repo: BitbucketRepositoryDescriptor,
|
|
183
|
+
_cancellation?: AbortSignal,
|
|
184
|
+
): Promise<RepositoryMetadata | undefined> {
|
|
185
|
+
return Promise.resolve(undefined);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
private _accounts: Map<string, Account | undefined> | undefined;
|
|
189
|
+
protected override async getProviderCurrentAccount(
|
|
190
|
+
session: ProviderAuthenticationSession,
|
|
191
|
+
): Promise<Account | undefined> {
|
|
192
|
+
const { accessToken } = session;
|
|
193
|
+
this._accounts ??= new Map<string, Account | undefined>();
|
|
194
|
+
|
|
195
|
+
const cachedAccount = this._accounts.get(accessToken);
|
|
196
|
+
if (cachedAccount == null) {
|
|
197
|
+
const api = await this.getProvidersApi();
|
|
198
|
+
const user = await api.getCurrentUser(toTokenWithInfo(this.id, session), {
|
|
199
|
+
baseUrl: this.apiBaseUrl,
|
|
200
|
+
});
|
|
201
|
+
this._accounts.set(
|
|
202
|
+
accessToken,
|
|
203
|
+
user
|
|
204
|
+
? {
|
|
205
|
+
provider: this,
|
|
206
|
+
id: user.id,
|
|
207
|
+
name: user.name ?? undefined,
|
|
208
|
+
email: user.email ?? undefined,
|
|
209
|
+
avatarUrl: user.avatarUrl ?? undefined,
|
|
210
|
+
username: user.username ?? undefined,
|
|
211
|
+
}
|
|
212
|
+
: undefined,
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return this._accounts.get(accessToken);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
protected override async searchProviderMyPullRequests(
|
|
220
|
+
session: ProviderAuthenticationSession,
|
|
221
|
+
repos?: BitbucketRepositoryDescriptor[],
|
|
222
|
+
): Promise<PullRequest[] | undefined> {
|
|
223
|
+
if (repos != null) {
|
|
224
|
+
// TODO: implement repos version
|
|
225
|
+
return undefined;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const api = await this.getProvidersApi();
|
|
229
|
+
if (!api) {
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const prs = await api.getBitbucketServerPullRequestsForCurrentUser(
|
|
234
|
+
toTokenWithInfo(this.id, session),
|
|
235
|
+
this.apiBaseUrl,
|
|
236
|
+
);
|
|
237
|
+
return prs?.map(pr => fromProviderPullRequest(pr, this));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
protected override async searchProviderMyIssues(
|
|
241
|
+
_session: AuthenticationSession,
|
|
242
|
+
_repos?: BitbucketRepositoryDescriptor[],
|
|
243
|
+
): Promise<IssueShape[] | undefined> {
|
|
244
|
+
return Promise.resolve(undefined);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
private readonly storagePrefix = 'bitbucket-server';
|
|
248
|
+
protected override async providerOnConnect(): Promise<void> {
|
|
249
|
+
if (this._session == null) return;
|
|
250
|
+
|
|
251
|
+
const accountStorageKey = md5(this._session.accessToken);
|
|
252
|
+
|
|
253
|
+
const storedAccount = this.ctx.storage.get(`${this.storagePrefix}:${accountStorageKey}:account`);
|
|
254
|
+
|
|
255
|
+
let account: Account | undefined = storedAccount?.data ? { ...storedAccount.data, provider: this } : undefined;
|
|
256
|
+
|
|
257
|
+
if (storedAccount == null) {
|
|
258
|
+
account = await this.getProviderCurrentAccount(this._session);
|
|
259
|
+
if (account != null) {
|
|
260
|
+
// Clear all other stored workspaces and repositories and accounts when our session changes
|
|
261
|
+
await this.ctx.storage.deleteWithPrefix(this.storagePrefix);
|
|
262
|
+
await this.ctx.storage.store(`${this.storagePrefix}:${accountStorageKey}:account`, {
|
|
263
|
+
v: 1,
|
|
264
|
+
timestamp: Date.now(),
|
|
265
|
+
data: {
|
|
266
|
+
id: account.id,
|
|
267
|
+
name: account.name,
|
|
268
|
+
email: account.email,
|
|
269
|
+
avatarUrl: account.avatarUrl,
|
|
270
|
+
username: account.username,
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
this._accounts ??= new Map<string, Account | undefined>();
|
|
276
|
+
this._accounts.set(this._session.accessToken, account);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
protected override providerOnDisconnect(): void {
|
|
280
|
+
this._accounts = undefined;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import type { Account, UnidentifiedAuthor } from '../../../git/models/author.js';
|
|
2
|
+
import type { DefaultBranch } from '../../../git/models/defaultBranch.js';
|
|
3
|
+
import type { Issue, IssueShape } from '../../../git/models/issue.js';
|
|
4
|
+
import type { IssueOrPullRequest, IssueOrPullRequestType } from '../../../git/models/issueOrPullRequest.js';
|
|
5
|
+
import type { PullRequest, PullRequestMergeMethod, PullRequestState } from '../../../git/models/pullRequest.js';
|
|
6
|
+
import type { GitRemote } from '../../../git/models/remote.js';
|
|
7
|
+
import type { RepositoryMetadata } from '../../../git/models/repositoryMetadata.js';
|
|
8
|
+
import { md5 } from '../../../utils/crypto.js';
|
|
9
|
+
import { uniqueBy } from '../../../utils/iterable.js';
|
|
10
|
+
import { flatSettled, nonnullSettled } from '../../../utils/promise.js';
|
|
11
|
+
import type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider.js';
|
|
12
|
+
import type {
|
|
13
|
+
AuthenticationSessionLike as AuthenticationSession,
|
|
14
|
+
ProviderAuthenticationSession,
|
|
15
|
+
} from '../authentication/models.js';
|
|
16
|
+
import { toTokenWithInfo } from '../authentication/models.js';
|
|
17
|
+
import { GitCloudHostIntegrationId } from '../constants.js';
|
|
18
|
+
import { GitHostIntegration } from '../models/gitHostIntegration.js';
|
|
19
|
+
import type { BitbucketRepositoryDescriptor, BitbucketWorkspaceDescriptor } from './bitbucket/models.js';
|
|
20
|
+
import { fromProviderPullRequest, providersMetadata } from './models.js';
|
|
21
|
+
|
|
22
|
+
const metadata = providersMetadata[GitCloudHostIntegrationId.Bitbucket];
|
|
23
|
+
const authProvider = Object.freeze({ id: metadata.id, scopes: metadata.scopes });
|
|
24
|
+
|
|
25
|
+
export class BitbucketIntegration extends GitHostIntegration<
|
|
26
|
+
GitCloudHostIntegrationId.Bitbucket,
|
|
27
|
+
BitbucketRepositoryDescriptor
|
|
28
|
+
> {
|
|
29
|
+
readonly authProvider: IntegrationAuthenticationProviderDescriptor = authProvider;
|
|
30
|
+
readonly id = GitCloudHostIntegrationId.Bitbucket;
|
|
31
|
+
protected readonly key = this.id;
|
|
32
|
+
readonly name: string = 'Bitbucket';
|
|
33
|
+
get domain(): string {
|
|
34
|
+
return metadata.domain;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected get apiBaseUrl(): string {
|
|
38
|
+
return 'https://api.bitbucket.org/2.0';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
protected override async mergeProviderPullRequest(
|
|
42
|
+
session: ProviderAuthenticationSession,
|
|
43
|
+
pr: PullRequest,
|
|
44
|
+
options?: {
|
|
45
|
+
mergeMethod?: PullRequestMergeMethod;
|
|
46
|
+
},
|
|
47
|
+
): Promise<boolean> {
|
|
48
|
+
const api = await this.getProvidersApi();
|
|
49
|
+
return api.mergePullRequest(toTokenWithInfo(this.id, session), pr, {
|
|
50
|
+
mergeMethod: options?.mergeMethod,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
protected override async getProviderAccountForCommit(
|
|
55
|
+
session: ProviderAuthenticationSession,
|
|
56
|
+
repo: BitbucketRepositoryDescriptor,
|
|
57
|
+
rev: string,
|
|
58
|
+
options?: {
|
|
59
|
+
avatarSize?: number;
|
|
60
|
+
},
|
|
61
|
+
): Promise<Account | UnidentifiedAuthor | undefined> {
|
|
62
|
+
return (await this.authenticationService.apis.bitbucket)?.getAccountForCommit(
|
|
63
|
+
this,
|
|
64
|
+
toTokenWithInfo(this.id, session),
|
|
65
|
+
repo.owner,
|
|
66
|
+
repo.name,
|
|
67
|
+
rev,
|
|
68
|
+
this.apiBaseUrl,
|
|
69
|
+
{
|
|
70
|
+
avatarSize: options?.avatarSize,
|
|
71
|
+
},
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
protected override async getProviderAccountForEmail(
|
|
76
|
+
_session: AuthenticationSession,
|
|
77
|
+
_repo: BitbucketRepositoryDescriptor,
|
|
78
|
+
_email: string,
|
|
79
|
+
_options?: {
|
|
80
|
+
avatarSize?: number;
|
|
81
|
+
},
|
|
82
|
+
): Promise<Account | undefined> {
|
|
83
|
+
return Promise.resolve(undefined);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
protected override async getProviderDefaultBranch(
|
|
87
|
+
_session: AuthenticationSession,
|
|
88
|
+
_repo: BitbucketRepositoryDescriptor,
|
|
89
|
+
): Promise<DefaultBranch | undefined> {
|
|
90
|
+
return Promise.resolve(undefined);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
protected override async getProviderLinkedIssueOrPullRequest(
|
|
94
|
+
session: ProviderAuthenticationSession,
|
|
95
|
+
repo: BitbucketRepositoryDescriptor,
|
|
96
|
+
{ id }: { id: string; key: string },
|
|
97
|
+
type: undefined | IssueOrPullRequestType,
|
|
98
|
+
): Promise<IssueOrPullRequest | undefined> {
|
|
99
|
+
return (await this.authenticationService.apis.bitbucket)?.getIssueOrPullRequest(
|
|
100
|
+
this,
|
|
101
|
+
toTokenWithInfo(this.id, session),
|
|
102
|
+
repo.owner,
|
|
103
|
+
repo.name,
|
|
104
|
+
id,
|
|
105
|
+
this.apiBaseUrl,
|
|
106
|
+
{
|
|
107
|
+
type: type,
|
|
108
|
+
},
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
protected override async getProviderIssue(
|
|
113
|
+
session: ProviderAuthenticationSession,
|
|
114
|
+
repo: BitbucketRepositoryDescriptor,
|
|
115
|
+
id: string,
|
|
116
|
+
): Promise<Issue | undefined> {
|
|
117
|
+
return (await this.authenticationService.apis.bitbucket)?.getIssue(
|
|
118
|
+
this,
|
|
119
|
+
toTokenWithInfo(this.id, session),
|
|
120
|
+
repo.owner,
|
|
121
|
+
repo.name,
|
|
122
|
+
id,
|
|
123
|
+
this.apiBaseUrl,
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
protected override async getProviderPullRequestForBranch(
|
|
128
|
+
session: ProviderAuthenticationSession,
|
|
129
|
+
repo: BitbucketRepositoryDescriptor,
|
|
130
|
+
branch: string,
|
|
131
|
+
_options?: {
|
|
132
|
+
avatarSize?: number;
|
|
133
|
+
include?: PullRequestState[];
|
|
134
|
+
},
|
|
135
|
+
): Promise<PullRequest | undefined> {
|
|
136
|
+
return (await this.authenticationService.apis.bitbucket)?.getPullRequestForBranch(
|
|
137
|
+
this,
|
|
138
|
+
toTokenWithInfo(this.id, session),
|
|
139
|
+
repo.owner,
|
|
140
|
+
repo.name,
|
|
141
|
+
branch,
|
|
142
|
+
this.apiBaseUrl,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
protected override async getProviderPullRequestForCommit(
|
|
147
|
+
session: ProviderAuthenticationSession,
|
|
148
|
+
repo: BitbucketRepositoryDescriptor,
|
|
149
|
+
rev: string,
|
|
150
|
+
): Promise<PullRequest | undefined> {
|
|
151
|
+
return (await this.authenticationService.apis.bitbucket)?.getPullRequestForCommit(
|
|
152
|
+
this,
|
|
153
|
+
toTokenWithInfo(this.id, session),
|
|
154
|
+
repo.owner,
|
|
155
|
+
repo.name,
|
|
156
|
+
rev,
|
|
157
|
+
this.apiBaseUrl,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
protected override async getProviderRepositoryMetadata(
|
|
162
|
+
_session: AuthenticationSession,
|
|
163
|
+
_repo: BitbucketRepositoryDescriptor,
|
|
164
|
+
_cancellation?: AbortSignal,
|
|
165
|
+
): Promise<RepositoryMetadata | undefined> {
|
|
166
|
+
return Promise.resolve(undefined);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private _accounts: Map<string, Account | undefined> | undefined;
|
|
170
|
+
protected override async getProviderCurrentAccount(
|
|
171
|
+
session: ProviderAuthenticationSession,
|
|
172
|
+
): Promise<Account | undefined> {
|
|
173
|
+
const { accessToken } = session;
|
|
174
|
+
this._accounts ??= new Map<string, Account | undefined>();
|
|
175
|
+
|
|
176
|
+
const cachedAccount = this._accounts.get(accessToken);
|
|
177
|
+
if (cachedAccount == null) {
|
|
178
|
+
const api = await this.getProvidersApi();
|
|
179
|
+
const user = await api.getCurrentUser(toTokenWithInfo(this.id, session));
|
|
180
|
+
this._accounts.set(
|
|
181
|
+
accessToken,
|
|
182
|
+
user
|
|
183
|
+
? {
|
|
184
|
+
provider: this,
|
|
185
|
+
id: user.id,
|
|
186
|
+
name: user.name ?? undefined,
|
|
187
|
+
email: user.email ?? undefined,
|
|
188
|
+
avatarUrl: user.avatarUrl ?? undefined,
|
|
189
|
+
username: user.username ?? undefined,
|
|
190
|
+
}
|
|
191
|
+
: undefined,
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return this._accounts.get(accessToken);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private _workspaces: Map<string, BitbucketWorkspaceDescriptor[] | undefined> | undefined;
|
|
199
|
+
private async getProviderResourcesForCurrentUser(
|
|
200
|
+
session: ProviderAuthenticationSession,
|
|
201
|
+
force: boolean = false,
|
|
202
|
+
): Promise<BitbucketWorkspaceDescriptor[] | undefined> {
|
|
203
|
+
this._workspaces ??= new Map<string, BitbucketWorkspaceDescriptor[] | undefined>();
|
|
204
|
+
const { accessToken } = session;
|
|
205
|
+
const cachedResources = this._workspaces.get(accessToken);
|
|
206
|
+
|
|
207
|
+
if (cachedResources == null || force) {
|
|
208
|
+
const api = await this.getProvidersApi();
|
|
209
|
+
|
|
210
|
+
const resources = await api.getBitbucketResourcesForCurrentUser(toTokenWithInfo(this.id, session));
|
|
211
|
+
this._workspaces.set(
|
|
212
|
+
accessToken,
|
|
213
|
+
resources != null ? resources.map(r => ({ ...r, key: r.id, name: r.name ?? r.slug })) : undefined,
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return this._workspaces.get(accessToken);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
protected override async searchProviderMyPullRequests(
|
|
221
|
+
session: ProviderAuthenticationSession,
|
|
222
|
+
repos?: BitbucketRepositoryDescriptor[],
|
|
223
|
+
): Promise<PullRequest[] | undefined> {
|
|
224
|
+
if (repos != null) {
|
|
225
|
+
// TODO: implement repos version
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const api = await this.getProvidersApi();
|
|
230
|
+
if (!api) {
|
|
231
|
+
return undefined;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const remotes = await this.ctx.repositories.getOpenRemotes();
|
|
235
|
+
const workspaceRepos = await nonnullSettled(
|
|
236
|
+
remotes.map(async (r: GitRemote) => {
|
|
237
|
+
const integration = await this.authenticationService.getByRemote(r);
|
|
238
|
+
const [namespace, name] = r.path.split('/');
|
|
239
|
+
return integration?.id === this.id ? { name: name, namespace: namespace } : undefined;
|
|
240
|
+
}),
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
const user = await this.getProviderCurrentAccount(session);
|
|
244
|
+
if (user?.username == null) return undefined;
|
|
245
|
+
|
|
246
|
+
const workspaces = await this.getProviderResourcesForCurrentUser(session);
|
|
247
|
+
if (workspaces == null || workspaces.length === 0) return undefined;
|
|
248
|
+
|
|
249
|
+
const authoredPrs = workspaces.map(async ws => {
|
|
250
|
+
const prs = await api.getBitbucketPullRequestsAuthoredByUserForWorkspace(
|
|
251
|
+
toTokenWithInfo(this.id, session),
|
|
252
|
+
user.id,
|
|
253
|
+
ws.slug,
|
|
254
|
+
);
|
|
255
|
+
return prs?.map(pr => fromProviderPullRequest(pr, this));
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
const reviewingPrs = api
|
|
259
|
+
.getPullRequestsForRepos(toTokenWithInfo(this.id, session), workspaceRepos, {
|
|
260
|
+
query: `state="OPEN" AND reviewers.uuid="${user.id}"`,
|
|
261
|
+
})
|
|
262
|
+
.then(r => r.values?.map(pr => fromProviderPullRequest(pr, this)));
|
|
263
|
+
|
|
264
|
+
return [
|
|
265
|
+
...uniqueBy(
|
|
266
|
+
await flatSettled([...authoredPrs, reviewingPrs]),
|
|
267
|
+
pr => pr.url,
|
|
268
|
+
(orig, _cur) => orig,
|
|
269
|
+
),
|
|
270
|
+
];
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
protected override async searchProviderMyIssues(
|
|
274
|
+
session: ProviderAuthenticationSession,
|
|
275
|
+
repos?: BitbucketRepositoryDescriptor[],
|
|
276
|
+
): Promise<IssueShape[] | undefined> {
|
|
277
|
+
if (repos == null || repos.length === 0) return undefined;
|
|
278
|
+
|
|
279
|
+
const user = await this.getProviderCurrentAccount(session);
|
|
280
|
+
if (user?.username == null) return undefined;
|
|
281
|
+
|
|
282
|
+
const api = await this.authenticationService.apis.bitbucket;
|
|
283
|
+
if (!api) return undefined;
|
|
284
|
+
|
|
285
|
+
const issueResult = await flatSettled(
|
|
286
|
+
repos.map(repo => {
|
|
287
|
+
return api.getUsersIssuesForRepo(
|
|
288
|
+
this,
|
|
289
|
+
toTokenWithInfo(this.id, session),
|
|
290
|
+
user.id,
|
|
291
|
+
repo.owner,
|
|
292
|
+
repo.name,
|
|
293
|
+
this.apiBaseUrl,
|
|
294
|
+
);
|
|
295
|
+
}),
|
|
296
|
+
);
|
|
297
|
+
return issueResult;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
private readonly storagePrefix = 'bitbucket';
|
|
301
|
+
protected override async providerOnConnect(): Promise<void> {
|
|
302
|
+
if (this._session == null) return;
|
|
303
|
+
|
|
304
|
+
const accountStorageKey = md5(this._session.accessToken);
|
|
305
|
+
|
|
306
|
+
const storedAccount = this.ctx.storage.get(`${this.storagePrefix}:${accountStorageKey}:account`);
|
|
307
|
+
const storedWorkspaces = this.ctx.storage.get(`${this.storagePrefix}:${accountStorageKey}:workspaces`);
|
|
308
|
+
|
|
309
|
+
let account: Account | undefined = storedAccount?.data ? { ...storedAccount.data, provider: this } : undefined;
|
|
310
|
+
|
|
311
|
+
let workspaces = storedWorkspaces?.data?.map((o: BitbucketWorkspaceDescriptor) => ({ ...o }));
|
|
312
|
+
|
|
313
|
+
if (storedAccount == null) {
|
|
314
|
+
account = await this.getProviderCurrentAccount(this._session);
|
|
315
|
+
if (account != null) {
|
|
316
|
+
// Clear all other stored workspaces and repositories and accounts when our session changes
|
|
317
|
+
await this.ctx.storage.deleteWithPrefix(this.storagePrefix);
|
|
318
|
+
await this.ctx.storage.store(`${this.storagePrefix}:${accountStorageKey}:account`, {
|
|
319
|
+
v: 1,
|
|
320
|
+
timestamp: Date.now(),
|
|
321
|
+
data: {
|
|
322
|
+
id: account.id,
|
|
323
|
+
name: account.name,
|
|
324
|
+
email: account.email,
|
|
325
|
+
avatarUrl: account.avatarUrl,
|
|
326
|
+
username: account.username,
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
this._accounts ??= new Map<string, Account | undefined>();
|
|
332
|
+
this._accounts.set(this._session.accessToken, account);
|
|
333
|
+
|
|
334
|
+
if (storedWorkspaces == null) {
|
|
335
|
+
workspaces = await this.getProviderResourcesForCurrentUser(this._session, true);
|
|
336
|
+
await this.ctx.storage.store(`${this.storagePrefix}:${accountStorageKey}:workspaces`, {
|
|
337
|
+
v: 1,
|
|
338
|
+
timestamp: Date.now(),
|
|
339
|
+
data: workspaces,
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
this._workspaces ??= new Map<string, BitbucketWorkspaceDescriptor[] | undefined>();
|
|
343
|
+
this._workspaces.set(this._session.accessToken, workspaces);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
protected override providerOnDisconnect(): void {
|
|
347
|
+
this._accounts = undefined;
|
|
348
|
+
this._workspaces = undefined;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { AuthenticationErrorReason } from '../../../../git/errors.js';
|
|
2
|
+
import type { Provider } from '../../../../git/models/remoteProvider.js';
|
|
3
|
+
import type { GitHubApiConfig } from '../../../git-github/api/config.js';
|
|
4
|
+
import { GitHubApi } from '../../../git-github/api/github.js';
|
|
5
|
+
import type { IntegrationServiceContext } from '../../context.js';
|
|
6
|
+
|
|
7
|
+
export { GitHubApi } from '../../../git-github/api/github.js';
|
|
8
|
+
|
|
9
|
+
export function createGitHubApi(ctx: IntegrationServiceContext): GitHubApi {
|
|
10
|
+
const launchpad = () => ctx.config.getLaunchpadOptions();
|
|
11
|
+
|
|
12
|
+
const config: GitHubApiConfig = {
|
|
13
|
+
isWeb: ctx.http.isWeb,
|
|
14
|
+
fetch: ctx.http.fetch.bind(ctx.http),
|
|
15
|
+
wrapForForcedInsecureSSL: ctx.http.wrapForForcedInsecureSSL.bind(ctx.http),
|
|
16
|
+
|
|
17
|
+
onConfigChanged: (listener: () => void) =>
|
|
18
|
+
ctx.config.onDidChange(e => {
|
|
19
|
+
if (e.httpProxy) {
|
|
20
|
+
listener();
|
|
21
|
+
}
|
|
22
|
+
}),
|
|
23
|
+
|
|
24
|
+
onAuthenticationFailure: async (error, provider: Provider | undefined) => {
|
|
25
|
+
if (
|
|
26
|
+
error.reason === AuthenticationErrorReason.Unauthorized ||
|
|
27
|
+
error.reason === AuthenticationErrorReason.Forbidden
|
|
28
|
+
) {
|
|
29
|
+
const reauthenticate = await ctx.hooks?.onReauthenticationRequired?.(
|
|
30
|
+
`${error.message}. Would you like to try reauthenticating${
|
|
31
|
+
error.reason === AuthenticationErrorReason.Forbidden ? ' to provide additional access' : ''
|
|
32
|
+
}?`,
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
if (reauthenticate) {
|
|
36
|
+
await provider?.reauthenticate();
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
ctx.hooks?.ui?.onError?.(error.message);
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
onRequestError: (provider: Provider | undefined, message: string) => {
|
|
46
|
+
if (message.includes('timeout')) {
|
|
47
|
+
ctx.hooks?.ui?.onRequestTimedOut?.(provider?.name ?? 'GitHub');
|
|
48
|
+
} else {
|
|
49
|
+
ctx.hooks?.ui?.onRequestFailed?.(message);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
onDebugError: (message: string) => {
|
|
54
|
+
ctx.hooks?.ui?.onError?.(message);
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
getLaunchpadQueryLimit: () => launchpad().queryLimit ?? 100,
|
|
58
|
+
getLaunchpadIgnoredRepositories: () => [...(launchpad().ignoredRepositories ?? [])],
|
|
59
|
+
getLaunchpadIncludedOrganizations: () => [...(launchpad().includedOrganizations ?? [])],
|
|
60
|
+
getLaunchpadIgnoredOrganizations: () => [...(launchpad().ignoredOrganizations ?? [])],
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return new GitHubApi(config);
|
|
64
|
+
}
|