@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,473 @@
|
|
|
1
|
+
import type { Account } 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 } 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 type { RepositoryDescriptor } from '../../../git/models/resourceDescriptor.js';
|
|
8
|
+
import type { PullRequestUrlIdentity } from '../../../git/utils/pullRequest.utils.js';
|
|
9
|
+
import type { Emitter } from '../../../utils/event.js';
|
|
10
|
+
import { uniqueBy } from '../../../utils/iterable.js';
|
|
11
|
+
import type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider.js';
|
|
12
|
+
import type { IntegrationAuthenticationService } from '../authentication/integrationAuthenticationService.js';
|
|
13
|
+
import type { IntegrationServiceContext } from '../context.js';
|
|
14
|
+
import type { ProviderAuthenticationSession } from '../authentication/models.js';
|
|
15
|
+
import { toTokenWithInfo } from '../authentication/models.js';
|
|
16
|
+
import { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId } from '../constants.js';
|
|
17
|
+
import type { IntegrationConnectionChangeEvent } from '../integrationService.js';
|
|
18
|
+
import { GitHostIntegration } from '../models/gitHostIntegration.js';
|
|
19
|
+
import type { GitLabIntegrationIds } from './gitlab/gitlab.utils.js';
|
|
20
|
+
import { getGitLabPullRequestIdentityFromMaybeUrl } from './gitlab/gitlab.utils.js';
|
|
21
|
+
import { fromGitLabMergeRequestProvidersApi } from './gitlab/models.js';
|
|
22
|
+
import type { ProviderRepository } from './models.js';
|
|
23
|
+
import { ProviderPullRequestReviewState, providersMetadata, toIssueShape } from './models.js';
|
|
24
|
+
import type { ProvidersApi } from './providersApi.js';
|
|
25
|
+
|
|
26
|
+
const metadata = providersMetadata[GitCloudHostIntegrationId.GitLab];
|
|
27
|
+
const authProvider: IntegrationAuthenticationProviderDescriptor = Object.freeze({
|
|
28
|
+
id: metadata.id,
|
|
29
|
+
scopes: metadata.scopes,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const cloudEnterpriseMetadata = providersMetadata[GitSelfManagedHostIntegrationId.CloudGitLabSelfHosted];
|
|
33
|
+
const cloudEnterpriseAuthProvider: IntegrationAuthenticationProviderDescriptor = Object.freeze({
|
|
34
|
+
id: cloudEnterpriseMetadata.id,
|
|
35
|
+
scopes: cloudEnterpriseMetadata.scopes,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export type GitLabRepositoryDescriptor = RepositoryDescriptor;
|
|
39
|
+
|
|
40
|
+
abstract class GitLabIntegrationBase<ID extends GitLabIntegrationIds> extends GitHostIntegration<
|
|
41
|
+
ID,
|
|
42
|
+
GitLabRepositoryDescriptor
|
|
43
|
+
> {
|
|
44
|
+
protected abstract get apiBaseUrl(): string;
|
|
45
|
+
|
|
46
|
+
/** Self-hosted GitLab uses PAT semantics and a domain-based API base; gitlab.com does not. */
|
|
47
|
+
protected get isEnterprise(): boolean {
|
|
48
|
+
return this.id === GitSelfManagedHostIntegrationId.CloudGitLabSelfHosted;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
protected override async getProviderAccountForCommit(
|
|
52
|
+
session: ProviderAuthenticationSession,
|
|
53
|
+
repo: GitLabRepositoryDescriptor,
|
|
54
|
+
rev: string,
|
|
55
|
+
options?: {
|
|
56
|
+
avatarSize?: number;
|
|
57
|
+
},
|
|
58
|
+
): Promise<Account | undefined> {
|
|
59
|
+
return (await this.authenticationService.apis.gitlab)?.getAccountForCommit(
|
|
60
|
+
this,
|
|
61
|
+
toTokenWithInfo(this.id, session),
|
|
62
|
+
repo.owner,
|
|
63
|
+
repo.name,
|
|
64
|
+
rev,
|
|
65
|
+
{
|
|
66
|
+
...options,
|
|
67
|
+
baseUrl: this.apiBaseUrl,
|
|
68
|
+
},
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
protected override async getProviderAccountForEmail(
|
|
73
|
+
session: ProviderAuthenticationSession,
|
|
74
|
+
repo: GitLabRepositoryDescriptor,
|
|
75
|
+
email: string,
|
|
76
|
+
options?: {
|
|
77
|
+
avatarSize?: number;
|
|
78
|
+
},
|
|
79
|
+
): Promise<Account | undefined> {
|
|
80
|
+
return (await this.authenticationService.apis.gitlab)?.getAccountForEmail(
|
|
81
|
+
this,
|
|
82
|
+
toTokenWithInfo(this.id, session),
|
|
83
|
+
repo.owner,
|
|
84
|
+
repo.name,
|
|
85
|
+
email,
|
|
86
|
+
{
|
|
87
|
+
...options,
|
|
88
|
+
baseUrl: this.apiBaseUrl,
|
|
89
|
+
},
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
protected override async getProviderDefaultBranch(
|
|
94
|
+
session: ProviderAuthenticationSession,
|
|
95
|
+
repo: GitLabRepositoryDescriptor,
|
|
96
|
+
): Promise<DefaultBranch | undefined> {
|
|
97
|
+
return (await this.authenticationService.apis.gitlab)?.getDefaultBranch(
|
|
98
|
+
this,
|
|
99
|
+
toTokenWithInfo(this.id, session),
|
|
100
|
+
repo.owner,
|
|
101
|
+
repo.name,
|
|
102
|
+
{
|
|
103
|
+
baseUrl: this.apiBaseUrl,
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
protected override async getProviderLinkedIssueOrPullRequest(
|
|
109
|
+
session: ProviderAuthenticationSession,
|
|
110
|
+
repo: GitLabRepositoryDescriptor,
|
|
111
|
+
{ id }: { id: string; key: string },
|
|
112
|
+
): Promise<IssueOrPullRequest | undefined> {
|
|
113
|
+
return (await this.authenticationService.apis.gitlab)?.getIssueOrPullRequest(
|
|
114
|
+
this,
|
|
115
|
+
toTokenWithInfo(this.id, session),
|
|
116
|
+
repo.owner,
|
|
117
|
+
repo.name,
|
|
118
|
+
Number(id),
|
|
119
|
+
{
|
|
120
|
+
baseUrl: this.apiBaseUrl,
|
|
121
|
+
},
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
protected override async getProviderIssue(
|
|
126
|
+
session: ProviderAuthenticationSession,
|
|
127
|
+
repo: GitLabRepositoryDescriptor,
|
|
128
|
+
id: string,
|
|
129
|
+
): Promise<Issue | undefined> {
|
|
130
|
+
const api = await this.authenticationService.apis.gitlab;
|
|
131
|
+
const providerApi = await this.getProvidersApi();
|
|
132
|
+
if (!api || !repo || !id) {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const repoId = await api.getProjectId(
|
|
137
|
+
this,
|
|
138
|
+
toTokenWithInfo(this.id, session),
|
|
139
|
+
repo.owner,
|
|
140
|
+
repo.name,
|
|
141
|
+
this.apiBaseUrl,
|
|
142
|
+
undefined,
|
|
143
|
+
);
|
|
144
|
+
if (!repoId) {
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const apiResult = await providerApi.getIssue(
|
|
149
|
+
toTokenWithInfo(this.id, session),
|
|
150
|
+
{ namespace: repo.owner, name: repo.name, number: id },
|
|
151
|
+
{
|
|
152
|
+
isPAT: this.isEnterprise,
|
|
153
|
+
baseUrl: this.isEnterprise ? `https://${this.domain}` : undefined,
|
|
154
|
+
},
|
|
155
|
+
);
|
|
156
|
+
const issue = apiResult != null ? toIssueShape(apiResult, this) : undefined;
|
|
157
|
+
return issue != null ? { ...issue, type: 'issue' } : undefined;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
protected override async getProviderPullRequestForBranch(
|
|
161
|
+
session: ProviderAuthenticationSession,
|
|
162
|
+
repo: GitLabRepositoryDescriptor,
|
|
163
|
+
branch: string,
|
|
164
|
+
options?: {
|
|
165
|
+
avatarSize?: number;
|
|
166
|
+
include?: PullRequestState[];
|
|
167
|
+
},
|
|
168
|
+
): Promise<PullRequest | undefined> {
|
|
169
|
+
const { include, ...opts } = options ?? {};
|
|
170
|
+
|
|
171
|
+
const toGitLabMergeRequestState = (await import(/* webpackChunkName: "integrations" */ './gitlab/models.js'))
|
|
172
|
+
.toGitLabMergeRequestState;
|
|
173
|
+
return (await this.authenticationService.apis.gitlab)?.getPullRequestForBranch(
|
|
174
|
+
this,
|
|
175
|
+
toTokenWithInfo(this.id, session),
|
|
176
|
+
repo.owner,
|
|
177
|
+
repo.name,
|
|
178
|
+
branch,
|
|
179
|
+
{
|
|
180
|
+
...opts,
|
|
181
|
+
include: include?.map(s => toGitLabMergeRequestState(s)),
|
|
182
|
+
baseUrl: this.apiBaseUrl,
|
|
183
|
+
},
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
protected override async getProviderPullRequestForCommit(
|
|
188
|
+
session: ProviderAuthenticationSession,
|
|
189
|
+
repo: GitLabRepositoryDescriptor,
|
|
190
|
+
rev: string,
|
|
191
|
+
): Promise<PullRequest | undefined> {
|
|
192
|
+
return (await this.authenticationService.apis.gitlab)?.getPullRequestForCommit(
|
|
193
|
+
this,
|
|
194
|
+
toTokenWithInfo(this.id, session),
|
|
195
|
+
repo.owner,
|
|
196
|
+
repo.name,
|
|
197
|
+
rev,
|
|
198
|
+
{
|
|
199
|
+
baseUrl: this.apiBaseUrl,
|
|
200
|
+
},
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
protected override async getProviderPullRequest(
|
|
205
|
+
session: ProviderAuthenticationSession,
|
|
206
|
+
resource: GitLabRepositoryDescriptor,
|
|
207
|
+
id: string,
|
|
208
|
+
): Promise<PullRequest | undefined> {
|
|
209
|
+
return (await this.authenticationService.apis.gitlab)?.getPullRequest(
|
|
210
|
+
this,
|
|
211
|
+
toTokenWithInfo(this.id, session),
|
|
212
|
+
resource.owner,
|
|
213
|
+
resource.name,
|
|
214
|
+
parseInt(id, 10),
|
|
215
|
+
{
|
|
216
|
+
baseUrl: this.apiBaseUrl,
|
|
217
|
+
},
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
public override async getRepoInfo(repo: { owner: string; name: string }): Promise<ProviderRepository | undefined> {
|
|
222
|
+
const api = await this.getProvidersApi();
|
|
223
|
+
const tokenOptInfo = this._session ? toTokenWithInfo(this.id, this._session) : { providerId: this.id };
|
|
224
|
+
return api.getRepo(tokenOptInfo, repo.owner, repo.name, undefined);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
protected override async getProviderRepositoryMetadata(
|
|
228
|
+
session: ProviderAuthenticationSession,
|
|
229
|
+
repo: GitLabRepositoryDescriptor,
|
|
230
|
+
cancellation?: AbortSignal,
|
|
231
|
+
): Promise<RepositoryMetadata | undefined> {
|
|
232
|
+
return (await this.authenticationService.apis.gitlab)?.getRepositoryMetadata(
|
|
233
|
+
this,
|
|
234
|
+
toTokenWithInfo(this.id, session),
|
|
235
|
+
repo.owner,
|
|
236
|
+
repo.name,
|
|
237
|
+
{
|
|
238
|
+
baseUrl: this.apiBaseUrl,
|
|
239
|
+
},
|
|
240
|
+
cancellation,
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
protected override async searchProviderMyPullRequests(
|
|
245
|
+
session: ProviderAuthenticationSession,
|
|
246
|
+
repos?: GitLabRepositoryDescriptor[],
|
|
247
|
+
): Promise<PullRequest[] | undefined> {
|
|
248
|
+
const api = await this.getProvidersApi();
|
|
249
|
+
const username = (await this.getCurrentAccount())?.username;
|
|
250
|
+
if (!username) {
|
|
251
|
+
return Promise.resolve([]);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const apiResult = await api.getPullRequestsForUser(toTokenWithInfo(this.id, session), username, {
|
|
255
|
+
isPAT: this.isEnterprise,
|
|
256
|
+
baseUrl: this.isEnterprise ? `https://${this.domain}` : undefined,
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
if (apiResult == null) {
|
|
260
|
+
return Promise.resolve([]);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// now I'm going to filter prs from the result according to the repos parameter
|
|
264
|
+
let prs;
|
|
265
|
+
if (repos != null) {
|
|
266
|
+
const repoMap = new Map<string, GitLabRepositoryDescriptor>();
|
|
267
|
+
for (const repo of repos) {
|
|
268
|
+
repoMap.set(`${repo.owner}/${repo.name}`, repo);
|
|
269
|
+
}
|
|
270
|
+
prs = apiResult.values.filter(pr => {
|
|
271
|
+
const repo = repoMap.get(`${pr.repository.owner.login}/${pr.repository.name}`);
|
|
272
|
+
return repo != null;
|
|
273
|
+
});
|
|
274
|
+
} else {
|
|
275
|
+
prs = apiResult.values;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const results: IterableIterator<PullRequest> = uniqueBy(
|
|
279
|
+
[
|
|
280
|
+
...prs
|
|
281
|
+
.filter(pr => {
|
|
282
|
+
const isAssignee = pr.assignees?.some(a => a.username === username);
|
|
283
|
+
const isRequestedReviewer = pr.reviews?.some(
|
|
284
|
+
review =>
|
|
285
|
+
review.reviewer?.username === username ||
|
|
286
|
+
review.state === ProviderPullRequestReviewState.ReviewRequested,
|
|
287
|
+
);
|
|
288
|
+
const isAuthor = pr.author?.username === username;
|
|
289
|
+
// It seems like GitLab doesn't give us mentioned PRs.
|
|
290
|
+
// const isMentioned = ???;
|
|
291
|
+
|
|
292
|
+
return isAssignee || isRequestedReviewer || isAuthor;
|
|
293
|
+
})
|
|
294
|
+
.map(pr => fromGitLabMergeRequestProvidersApi(pr, this)),
|
|
295
|
+
],
|
|
296
|
+
r => r.url,
|
|
297
|
+
(original, _current) => original,
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
return [...results];
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
protected override async searchProviderMyIssues(
|
|
304
|
+
session: ProviderAuthenticationSession,
|
|
305
|
+
repos?: GitLabRepositoryDescriptor[],
|
|
306
|
+
): Promise<IssueShape[] | undefined> {
|
|
307
|
+
const api = await this.authenticationService.apis.gitlab;
|
|
308
|
+
const providerApi = await this.getProvidersApi();
|
|
309
|
+
if (!api || !repos) {
|
|
310
|
+
return undefined;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const repoIdsResult = await Promise.allSettled(
|
|
314
|
+
repos.map(
|
|
315
|
+
(r: GitLabRepositoryDescriptor): Promise<string | undefined> =>
|
|
316
|
+
api.getProjectId(
|
|
317
|
+
this,
|
|
318
|
+
toTokenWithInfo(this.id, session),
|
|
319
|
+
r.owner,
|
|
320
|
+
r.name,
|
|
321
|
+
this.apiBaseUrl,
|
|
322
|
+
undefined,
|
|
323
|
+
),
|
|
324
|
+
) ?? [],
|
|
325
|
+
);
|
|
326
|
+
const repoInput = repoIdsResult
|
|
327
|
+
.map(result => (result.status === 'fulfilled' ? result.value : undefined))
|
|
328
|
+
.filter((r): r is string => r != null);
|
|
329
|
+
const apiResult = await providerApi.getIssuesForRepos(toTokenWithInfo(this.id, session), repoInput, {
|
|
330
|
+
isPAT: this.isEnterprise,
|
|
331
|
+
baseUrl: this.isEnterprise ? `https://${this.domain}` : undefined,
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
return apiResult.values
|
|
335
|
+
.map(issue => toIssueShape(issue, this))
|
|
336
|
+
.filter((result): result is IssueShape => result != null);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
protected override async searchProviderPullRequests(
|
|
340
|
+
session: ProviderAuthenticationSession,
|
|
341
|
+
searchQuery: string,
|
|
342
|
+
repos?: GitLabRepositoryDescriptor[],
|
|
343
|
+
cancellation?: AbortSignal,
|
|
344
|
+
): Promise<PullRequest[] | undefined> {
|
|
345
|
+
const api = await this.authenticationService.apis.gitlab;
|
|
346
|
+
if (!api) {
|
|
347
|
+
return undefined;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return api.searchPullRequests(
|
|
351
|
+
this,
|
|
352
|
+
toTokenWithInfo(this.id, session),
|
|
353
|
+
{
|
|
354
|
+
search: searchQuery,
|
|
355
|
+
repos: repos?.map(r => `${r.owner}/${r.name}`),
|
|
356
|
+
baseUrl: this.apiBaseUrl,
|
|
357
|
+
},
|
|
358
|
+
cancellation,
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
protected override async mergeProviderPullRequest(
|
|
363
|
+
session: ProviderAuthenticationSession,
|
|
364
|
+
pr: PullRequest,
|
|
365
|
+
options?: {
|
|
366
|
+
mergeMethod?: PullRequestMergeMethod;
|
|
367
|
+
},
|
|
368
|
+
): Promise<boolean> {
|
|
369
|
+
if (!this.isPullRequest(pr)) return false;
|
|
370
|
+
|
|
371
|
+
const api = await this.getProvidersApi();
|
|
372
|
+
try {
|
|
373
|
+
const res = await api.mergePullRequest(toTokenWithInfo(this.id, session), pr, {
|
|
374
|
+
...options,
|
|
375
|
+
isPAT: this.isEnterprise,
|
|
376
|
+
baseUrl: this.isEnterprise ? `https://${this.domain}` : undefined,
|
|
377
|
+
});
|
|
378
|
+
return res;
|
|
379
|
+
} catch (ex) {
|
|
380
|
+
void this.showMergeErrorMessage(ex);
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
private async showMergeErrorMessage(ex: Error) {
|
|
386
|
+
// Unfortunately, providers-api does not let us know the exact reason for the error,
|
|
387
|
+
// so we show the same message to everything.
|
|
388
|
+
// When we update the library, we can improve the error handling here.
|
|
389
|
+
const reauthenticate = await this.ctx.hooks?.onReauthenticationRequired?.(
|
|
390
|
+
`${ex.message}. Would you like to try reauthenticating to provide additional access? Your token needs to have the 'api' scope to perform merge.`,
|
|
391
|
+
);
|
|
392
|
+
|
|
393
|
+
if (reauthenticate) {
|
|
394
|
+
await this.reauthenticate();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
private isPullRequest(pr: PullRequest | { id: string; headRefSha: string }): pr is PullRequest {
|
|
399
|
+
return (pr as PullRequest).refs != null;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
protected override async getProviderCurrentAccount(
|
|
403
|
+
session: ProviderAuthenticationSession,
|
|
404
|
+
): Promise<Account | undefined> {
|
|
405
|
+
const api = await this.getProvidersApi();
|
|
406
|
+
const currentUser = await api.getCurrentUser(toTokenWithInfo(this.id, session), {
|
|
407
|
+
isPAT: this.isEnterprise,
|
|
408
|
+
baseUrl: this.isEnterprise ? `https://${this.domain}` : undefined,
|
|
409
|
+
});
|
|
410
|
+
if (currentUser == null) return undefined;
|
|
411
|
+
|
|
412
|
+
return {
|
|
413
|
+
provider: {
|
|
414
|
+
id: this.id,
|
|
415
|
+
name: this.name,
|
|
416
|
+
domain: this.domain,
|
|
417
|
+
icon: this.icon,
|
|
418
|
+
},
|
|
419
|
+
id: currentUser.id,
|
|
420
|
+
name: currentUser.name || undefined,
|
|
421
|
+
email: currentUser.email || undefined,
|
|
422
|
+
avatarUrl: currentUser.avatarUrl || undefined,
|
|
423
|
+
username: currentUser.username || undefined,
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
protected override getProviderPullRequestIdentityFromMaybeUrl(search: string): PullRequestUrlIdentity | undefined {
|
|
428
|
+
return getGitLabPullRequestIdentityFromMaybeUrl(search, this.id);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
export class GitLabIntegration extends GitLabIntegrationBase<GitCloudHostIntegrationId.GitLab> {
|
|
433
|
+
readonly authProvider = authProvider;
|
|
434
|
+
readonly id = GitCloudHostIntegrationId.GitLab;
|
|
435
|
+
protected readonly key = this.id;
|
|
436
|
+
readonly name: string = 'GitLab';
|
|
437
|
+
get domain(): string {
|
|
438
|
+
return metadata.domain;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
protected get apiBaseUrl(): string {
|
|
442
|
+
return 'https://gitlab.com/api';
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
override access(): Promise<boolean> {
|
|
446
|
+
// Always allow GitHub cloud integration access
|
|
447
|
+
return Promise.resolve(true);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export class GitLabSelfHostedIntegration extends GitLabIntegrationBase<GitSelfManagedHostIntegrationId.CloudGitLabSelfHosted> {
|
|
452
|
+
readonly authProvider = cloudEnterpriseAuthProvider;
|
|
453
|
+
readonly id = GitSelfManagedHostIntegrationId.CloudGitLabSelfHosted;
|
|
454
|
+
protected readonly key;
|
|
455
|
+
readonly name = 'GitLab Self-Hosted';
|
|
456
|
+
get domain(): string {
|
|
457
|
+
return this._domain;
|
|
458
|
+
}
|
|
459
|
+
protected override get apiBaseUrl(): string {
|
|
460
|
+
return `https://${this._domain}/api`;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
constructor(
|
|
464
|
+
ctx: IntegrationServiceContext,
|
|
465
|
+
authenticationService: IntegrationAuthenticationService,
|
|
466
|
+
getProvidersApi: () => Promise<ProvidersApi>,
|
|
467
|
+
didChangeConnection: Emitter<IntegrationConnectionChangeEvent>,
|
|
468
|
+
private readonly _domain: string,
|
|
469
|
+
) {
|
|
470
|
+
super(ctx, authenticationService, getProvidersApi, didChangeConnection);
|
|
471
|
+
this.key = `${this.id}:${this.domain}` as const;
|
|
472
|
+
}
|
|
473
|
+
}
|