@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.
Files changed (230) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/README.md +13 -10
  3. package/dist/git/context.d.ts +4 -3
  4. package/dist/git/context.d.ts.map +1 -1
  5. package/dist/git/context.js.map +1 -1
  6. package/dist/git/providers/operations.d.ts +1 -0
  7. package/dist/git/providers/operations.d.ts.map +1 -1
  8. package/dist/git/providers/worktrees.d.ts +2 -0
  9. package/dist/git/providers/worktrees.d.ts.map +1 -1
  10. package/dist/git/utils/conflictResolution.utils.d.ts +32 -0
  11. package/dist/git/utils/conflictResolution.utils.d.ts.map +1 -1
  12. package/dist/git/utils/conflictResolution.utils.js +95 -0
  13. package/dist/git/utils/conflictResolution.utils.js.map +1 -1
  14. package/dist/git-cli/providers/operations.d.ts +1 -0
  15. package/dist/git-cli/providers/operations.d.ts.map +1 -1
  16. package/dist/git-cli/providers/operations.js +22 -1
  17. package/dist/git-cli/providers/operations.js.map +1 -1
  18. package/dist/git-cli/providers/worktrees.d.ts +2 -0
  19. package/dist/git-cli/providers/worktrees.d.ts.map +1 -1
  20. package/dist/git-cli/providers/worktrees.js +3 -0
  21. package/dist/git-cli/providers/worktrees.js.map +1 -1
  22. package/dist/plus/ai/utils/ai.utils.js +5 -5
  23. package/dist/plus/ai/utils/ai.utils.js.map +1 -1
  24. package/dist/plus/git-github/api/github.d.ts +6 -13
  25. package/dist/plus/git-github/api/github.d.ts.map +1 -1
  26. package/dist/plus/git-github/api/github.js +5 -10
  27. package/dist/plus/git-github/api/github.js.map +1 -1
  28. package/dist/plus/integrations/authentication/cloudIntegrationService.d.ts +11 -0
  29. package/dist/plus/integrations/authentication/cloudIntegrationService.d.ts.map +1 -0
  30. package/dist/plus/integrations/authentication/cloudIntegrationService.js +90 -0
  31. package/dist/plus/integrations/authentication/cloudIntegrationService.js.map +1 -0
  32. package/dist/plus/integrations/authentication/configuredIntegrationService.d.ts +67 -0
  33. package/dist/plus/integrations/authentication/configuredIntegrationService.d.ts.map +1 -0
  34. package/dist/plus/integrations/authentication/configuredIntegrationService.js +295 -0
  35. package/dist/plus/integrations/authentication/configuredIntegrationService.js.map +1 -0
  36. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.d.ts +92 -0
  37. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.d.ts.map +1 -0
  38. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +185 -0
  39. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js.map +1 -0
  40. package/dist/plus/integrations/authentication/integrationAuthenticationService.d.ts +62 -0
  41. package/dist/plus/integrations/authentication/integrationAuthenticationService.d.ts.map +1 -0
  42. package/dist/plus/integrations/authentication/integrationAuthenticationService.js +122 -0
  43. package/dist/plus/integrations/authentication/integrationAuthenticationService.js.map +1 -0
  44. package/dist/plus/integrations/authentication/manualTokenProvider.d.ts +15 -0
  45. package/dist/plus/integrations/authentication/manualTokenProvider.d.ts.map +1 -0
  46. package/dist/plus/integrations/authentication/manualTokenProvider.js +49 -0
  47. package/dist/plus/integrations/authentication/manualTokenProvider.js.map +1 -0
  48. package/dist/plus/integrations/authentication/models.d.ts +87 -0
  49. package/dist/plus/integrations/authentication/models.d.ts.map +1 -0
  50. package/dist/plus/integrations/authentication/models.js +64 -0
  51. package/dist/plus/integrations/authentication/models.js.map +1 -0
  52. package/dist/plus/integrations/constants.d.ts +47 -0
  53. package/dist/plus/integrations/constants.d.ts.map +1 -0
  54. package/dist/plus/integrations/constants.js +128 -0
  55. package/dist/plus/integrations/constants.js.map +1 -0
  56. package/dist/plus/integrations/context.d.ts +354 -0
  57. package/dist/plus/integrations/context.d.ts.map +1 -0
  58. package/dist/plus/integrations/context.js +2 -0
  59. package/dist/plus/integrations/context.js.map +1 -0
  60. package/dist/plus/integrations/errors.d.ts +14 -0
  61. package/dist/plus/integrations/errors.d.ts.map +1 -0
  62. package/dist/plus/integrations/errors.js +19 -0
  63. package/dist/plus/integrations/errors.js.map +1 -0
  64. package/dist/plus/integrations/index.d.ts +32 -0
  65. package/dist/plus/integrations/index.d.ts.map +1 -0
  66. package/dist/plus/integrations/index.js +62 -0
  67. package/dist/plus/integrations/index.js.map +1 -0
  68. package/dist/plus/integrations/integrationService.d.ts +98 -0
  69. package/dist/plus/integrations/integrationService.d.ts.map +1 -0
  70. package/dist/plus/integrations/integrationService.js +627 -0
  71. package/dist/plus/integrations/integrationService.js.map +1 -0
  72. package/dist/plus/integrations/models/gitHostIntegration.d.ts +82 -0
  73. package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -0
  74. package/dist/plus/integrations/models/gitHostIntegration.js +522 -0
  75. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -0
  76. package/dist/plus/integrations/models/integration.d.ts +127 -0
  77. package/dist/plus/integrations/models/integration.d.ts.map +1 -0
  78. package/dist/plus/integrations/models/integration.js +456 -0
  79. package/dist/plus/integrations/models/integration.js.map +1 -0
  80. package/dist/plus/integrations/models/issuesIntegration.d.ts +28 -0
  81. package/dist/plus/integrations/models/issuesIntegration.d.ts.map +1 -0
  82. package/dist/plus/integrations/models/issuesIntegration.js +101 -0
  83. package/dist/plus/integrations/models/issuesIntegration.js.map +1 -0
  84. package/dist/plus/integrations/providers/apiClients.d.ts +25 -0
  85. package/dist/plus/integrations/providers/apiClients.d.ts.map +1 -0
  86. package/dist/plus/integrations/providers/apiClients.js +39 -0
  87. package/dist/plus/integrations/providers/apiClients.js.map +1 -0
  88. package/dist/plus/integrations/providers/azure/azure.d.ts +47 -0
  89. package/dist/plus/integrations/providers/azure/azure.d.ts.map +1 -0
  90. package/dist/plus/integrations/providers/azure/azure.js +444 -0
  91. package/dist/plus/integrations/providers/azure/azure.js.map +1 -0
  92. package/dist/plus/integrations/providers/azure/models.d.ts +286 -0
  93. package/dist/plus/integrations/providers/azure/models.d.ts.map +1 -0
  94. package/dist/plus/integrations/providers/azure/models.js +203 -0
  95. package/dist/plus/integrations/providers/azure/models.js.map +1 -0
  96. package/dist/plus/integrations/providers/azureDevOps.d.ts +95 -0
  97. package/dist/plus/integrations/providers/azureDevOps.d.ts.map +1 -0
  98. package/dist/plus/integrations/providers/azureDevOps.js +432 -0
  99. package/dist/plus/integrations/providers/azureDevOps.js.map +1 -0
  100. package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts +42 -0
  101. package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts.map +1 -0
  102. package/dist/plus/integrations/providers/bitbucket/bitbucket.js +513 -0
  103. package/dist/plus/integrations/providers/bitbucket/bitbucket.js.map +1 -0
  104. package/dist/plus/integrations/providers/bitbucket/models.d.ts +222 -0
  105. package/dist/plus/integrations/providers/bitbucket/models.d.ts.map +1 -0
  106. package/dist/plus/integrations/providers/bitbucket/models.js +158 -0
  107. package/dist/plus/integrations/providers/bitbucket/models.js.map +1 -0
  108. package/dist/plus/integrations/providers/bitbucket-server/models.d.ts +120 -0
  109. package/dist/plus/integrations/providers/bitbucket-server/models.d.ts.map +1 -0
  110. package/dist/plus/integrations/providers/bitbucket-server/models.js +111 -0
  111. package/dist/plus/integrations/providers/bitbucket-server/models.js.map +1 -0
  112. package/dist/plus/integrations/providers/bitbucket-server.d.ts +60 -0
  113. package/dist/plus/integrations/providers/bitbucket-server.d.ts.map +1 -0
  114. package/dist/plus/integrations/providers/bitbucket-server.js +138 -0
  115. package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -0
  116. package/dist/plus/integrations/providers/bitbucket.d.ts +50 -0
  117. package/dist/plus/integrations/providers/bitbucket.d.ts.map +1 -0
  118. package/dist/plus/integrations/providers/bitbucket.js +181 -0
  119. package/dist/plus/integrations/providers/bitbucket.js.map +1 -0
  120. package/dist/plus/integrations/providers/github/github.d.ts +5 -0
  121. package/dist/plus/integrations/providers/github/github.d.ts.map +1 -0
  122. package/dist/plus/integrations/providers/github/github.js +47 -0
  123. package/dist/plus/integrations/providers/github/github.js.map +1 -0
  124. package/dist/plus/integrations/providers/github/github.utils.d.ts +11 -0
  125. package/dist/plus/integrations/providers/github/github.utils.d.ts.map +1 -0
  126. package/dist/plus/integrations/providers/github/github.utils.js +6 -0
  127. package/dist/plus/integrations/providers/github/github.utils.js.map +1 -0
  128. package/dist/plus/integrations/providers/github/models.d.ts +3 -0
  129. package/dist/plus/integrations/providers/github/models.d.ts.map +1 -0
  130. package/dist/plus/integrations/providers/github/models.js +2 -0
  131. package/dist/plus/integrations/providers/github/models.js.map +1 -0
  132. package/dist/plus/integrations/providers/github.d.ts +73 -0
  133. package/dist/plus/integrations/providers/github.d.ts.map +1 -0
  134. package/dist/plus/integrations/providers/github.js +160 -0
  135. package/dist/plus/integrations/providers/github.js.map +1 -0
  136. package/dist/plus/integrations/providers/gitlab/gitlab.d.ts +63 -0
  137. package/dist/plus/integrations/providers/gitlab/gitlab.d.ts.map +1 -0
  138. package/dist/plus/integrations/providers/gitlab/gitlab.js +828 -0
  139. package/dist/plus/integrations/providers/gitlab/gitlab.js.map +1 -0
  140. package/dist/plus/integrations/providers/gitlab/gitlab.utils.d.ts +21 -0
  141. package/dist/plus/integrations/providers/gitlab/gitlab.utils.d.ts.map +1 -0
  142. package/dist/plus/integrations/providers/gitlab/gitlab.utils.js +45 -0
  143. package/dist/plus/integrations/providers/gitlab/gitlab.utils.js.map +1 -0
  144. package/dist/plus/integrations/providers/gitlab/models.d.ts +128 -0
  145. package/dist/plus/integrations/providers/gitlab/models.d.ts.map +1 -0
  146. package/dist/plus/integrations/providers/gitlab/models.js +96 -0
  147. package/dist/plus/integrations/providers/gitlab/models.js.map +1 -0
  148. package/dist/plus/integrations/providers/gitlab.d.ts +79 -0
  149. package/dist/plus/integrations/providers/gitlab.d.ts.map +1 -0
  150. package/dist/plus/integrations/providers/gitlab.js +253 -0
  151. package/dist/plus/integrations/providers/gitlab.js.map +1 -0
  152. package/dist/plus/integrations/providers/jira.d.ts +46 -0
  153. package/dist/plus/integrations/providers/jira.d.ts.map +1 -0
  154. package/dist/plus/integrations/providers/jira.js +255 -0
  155. package/dist/plus/integrations/providers/jira.js.map +1 -0
  156. package/dist/plus/integrations/providers/linear.d.ts +47 -0
  157. package/dist/plus/integrations/providers/linear.d.ts.map +1 -0
  158. package/dist/plus/integrations/providers/linear.js +198 -0
  159. package/dist/plus/integrations/providers/linear.js.map +1 -0
  160. package/dist/plus/integrations/providers/models.d.ts +433 -0
  161. package/dist/plus/integrations/providers/models.d.ts.map +1 -0
  162. package/dist/plus/integrations/providers/models.js +602 -0
  163. package/dist/plus/integrations/providers/models.js.map +1 -0
  164. package/dist/plus/integrations/providers/providersApi.d.ts +129 -0
  165. package/dist/plus/integrations/providers/providersApi.d.ts.map +1 -0
  166. package/dist/plus/integrations/providers/providersApi.js +602 -0
  167. package/dist/plus/integrations/providers/providersApi.js.map +1 -0
  168. package/dist/plus/integrations/providers/utils.d.ts +54 -0
  169. package/dist/plus/integrations/providers/utils.d.ts.map +1 -0
  170. package/dist/plus/integrations/providers/utils.js +262 -0
  171. package/dist/plus/integrations/providers/utils.js.map +1 -0
  172. package/dist/plus/integrations/telemetry.d.ts +26 -0
  173. package/dist/plus/integrations/telemetry.d.ts.map +1 -0
  174. package/dist/plus/integrations/telemetry.js +11 -0
  175. package/dist/plus/integrations/telemetry.js.map +1 -0
  176. package/dist/plus/integrations/utils/integration.utils.d.ts +14 -0
  177. package/dist/plus/integrations/utils/integration.utils.d.ts.map +1 -0
  178. package/dist/plus/integrations/utils/integration.utils.js +111 -0
  179. package/dist/plus/integrations/utils/integration.utils.js.map +1 -0
  180. package/dist/utils/disposable.d.ts +15 -2
  181. package/dist/utils/disposable.d.ts.map +1 -1
  182. package/dist/utils/disposable.js.map +1 -1
  183. package/package.json +43 -2
  184. package/src/git/context.ts +4 -3
  185. package/src/git/providers/operations.ts +1 -1
  186. package/src/git/providers/worktrees.ts +14 -2
  187. package/src/git/utils/conflictResolution.utils.ts +126 -0
  188. package/src/git-cli/providers/operations.ts +22 -2
  189. package/src/git-cli/providers/worktrees.ts +17 -2
  190. package/src/plus/ai/utils/ai.utils.ts +5 -5
  191. package/src/plus/git-github/api/github.ts +13 -25
  192. package/src/plus/integrations/authentication/cloudIntegrationService.ts +120 -0
  193. package/src/plus/integrations/authentication/configuredIntegrationService.ts +414 -0
  194. package/src/plus/integrations/authentication/integrationAuthenticationProvider.ts +289 -0
  195. package/src/plus/integrations/authentication/integrationAuthenticationService.ts +144 -0
  196. package/src/plus/integrations/authentication/manualTokenProvider.ts +72 -0
  197. package/src/plus/integrations/authentication/models.ts +168 -0
  198. package/src/plus/integrations/constants.ts +169 -0
  199. package/src/plus/integrations/context.ts +383 -0
  200. package/src/plus/integrations/errors.ts +35 -0
  201. package/src/plus/integrations/index.ts +119 -0
  202. package/src/plus/integrations/integrationService.ts +924 -0
  203. package/src/plus/integrations/models/gitHostIntegration.ts +738 -0
  204. package/src/plus/integrations/models/integration.ts +657 -0
  205. package/src/plus/integrations/models/issuesIntegration.ts +124 -0
  206. package/src/plus/integrations/providers/apiClients.ts +72 -0
  207. package/src/plus/integrations/providers/azure/azure.ts +691 -0
  208. package/src/plus/integrations/providers/azure/models.ts +605 -0
  209. package/src/plus/integrations/providers/azureDevOps.ts +677 -0
  210. package/src/plus/integrations/providers/bitbucket/bitbucket.ts +774 -0
  211. package/src/plus/integrations/providers/bitbucket/models.ts +445 -0
  212. package/src/plus/integrations/providers/bitbucket-server/models.ts +252 -0
  213. package/src/plus/integrations/providers/bitbucket-server.ts +282 -0
  214. package/src/plus/integrations/providers/bitbucket.ts +350 -0
  215. package/src/plus/integrations/providers/github/github.ts +64 -0
  216. package/src/plus/integrations/providers/github/github.utils.ts +23 -0
  217. package/src/plus/integrations/providers/github/models.ts +29 -0
  218. package/src/plus/integrations/providers/github.ts +366 -0
  219. package/src/plus/integrations/providers/gitlab/gitlab.ts +1210 -0
  220. package/src/plus/integrations/providers/gitlab/gitlab.utils.ts +71 -0
  221. package/src/plus/integrations/providers/gitlab/models.ts +257 -0
  222. package/src/plus/integrations/providers/gitlab.ts +473 -0
  223. package/src/plus/integrations/providers/jira.ts +359 -0
  224. package/src/plus/integrations/providers/linear.ts +275 -0
  225. package/src/plus/integrations/providers/models.ts +1114 -0
  226. package/src/plus/integrations/providers/providersApi.ts +1126 -0
  227. package/src/plus/integrations/providers/utils.ts +359 -0
  228. package/src/plus/integrations/telemetry.ts +29 -0
  229. package/src/plus/integrations/utils/integration.utils.ts +138 -0
  230. package/src/utils/disposable.ts +15 -2
@@ -0,0 +1,71 @@
1
+ import type { PullRequestUrlIdentity } from '../../../../git/utils/pullRequest.utils.js';
2
+ import { equalsIgnoreCase } from '../../../../utils/string.js';
3
+ import type { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId } from '../../constants.js';
4
+ import type { GitLabUser } from './models.js';
5
+
6
+ export type GitLabIntegrationIds =
7
+ | GitCloudHostIntegrationId.GitLab
8
+ | GitSelfManagedHostIntegrationId.CloudGitLabSelfHosted;
9
+
10
+ export function isMaybeGitLabPullRequestUrl(url: string): boolean {
11
+ return getGitLabPullRequestIdentityFromMaybeUrl(url) != null;
12
+ }
13
+
14
+ export function getGitLabPullRequestIdentityFromMaybeUrl(
15
+ search: string,
16
+ ): (PullRequestUrlIdentity & { provider: undefined }) | undefined;
17
+ export function getGitLabPullRequestIdentityFromMaybeUrl(
18
+ search: string,
19
+ id: GitLabIntegrationIds,
20
+ ): (PullRequestUrlIdentity & { provider: GitLabIntegrationIds }) | undefined;
21
+ export function getGitLabPullRequestIdentityFromMaybeUrl(
22
+ search: string,
23
+ id?: GitLabIntegrationIds,
24
+ ): (PullRequestUrlIdentity & { provider: GitLabIntegrationIds | undefined }) | undefined {
25
+ let ownerAndRepo: string | undefined = undefined;
26
+ let prNumber: string | undefined = undefined;
27
+
28
+ let match = search.match(/([^/]+\/[^/]+)\/(?:-\/merge_requests)\/(\d+)/); // with org and rep name
29
+ if (match != null) {
30
+ ownerAndRepo = match[1];
31
+ prNumber = match[2];
32
+ }
33
+
34
+ if (prNumber == null) {
35
+ match = search.match(/(?:\/|^)(?:-\/merge_requests)\/(\d+)/); // without repo name
36
+ if (match != null) {
37
+ prNumber = match[1];
38
+ }
39
+ }
40
+
41
+ return prNumber != null ? { ownerAndRepo: ownerAndRepo, prNumber: prNumber, provider: id } : undefined;
42
+ }
43
+
44
+ /**
45
+ * Selects the GitLab user that authored a commit from a set of search results.
46
+ *
47
+ * GitLab has no way to resolve a commit's author to a user directly, so we search users by name/email and
48
+ * disambiguate here. To avoid showing a stranger's avatar when multiple users share a name (see #2205), we only
49
+ * return a user when we can identify them confidently — a matching public email, or a single exact name match.
50
+ * Otherwise we return `undefined` so avatar resolution falls back to the commit email's Gravatar.
51
+ */
52
+ export function selectGitLabUserForCommit(
53
+ users: GitLabUser[],
54
+ authorName: string,
55
+ authorEmail: string | undefined,
56
+ ): GitLabUser | undefined {
57
+ if (users.length === 0) return undefined;
58
+
59
+ // Strongest signal: a public email that matches the commit email — unambiguous identity
60
+ if (authorEmail) {
61
+ const byEmail = users.find(u => u.publicEmail && equalsIgnoreCase(u.publicEmail, authorEmail));
62
+ if (byEmail != null) return byEmail;
63
+ }
64
+
65
+ // Otherwise fall back to an exact name match — but only when it's unambiguous
66
+ const nameMatches = users.filter(u => equalsIgnoreCase(u.name, authorName));
67
+ if (nameMatches.length === 1) return nameMatches[0];
68
+
69
+ // No matches, or multiple name matches we can't disambiguate by email — don't guess
70
+ return undefined;
71
+ }
@@ -0,0 +1,257 @@
1
+ import type { PullRequestRefs, PullRequestState } from '../../../../git/models/pullRequest.js';
2
+ import { PullRequest, PullRequestMergeableState } from '../../../../git/models/pullRequest.js';
3
+ import type { Provider } from '../../../../git/models/remoteProvider.js';
4
+ import type { Integration } from '../../models/integration.js';
5
+ import type { ProviderPullRequest } from '../models.js';
6
+ import { fromProviderPullRequest } from '../models.js';
7
+
8
+ export interface GitLabUser {
9
+ id: number;
10
+ name: string;
11
+ username: string;
12
+ publicEmail: string | undefined;
13
+ state: string;
14
+ avatarUrl: string | undefined;
15
+ webUrl: string;
16
+ }
17
+
18
+ export interface GitLabCommit {
19
+ id: string;
20
+ short_id: string;
21
+ created_at: Date;
22
+ parent_ids: string[];
23
+ title: string;
24
+ message: string;
25
+ author_name: string;
26
+ author_email: string;
27
+ authored_date: Date;
28
+ committer_name: string;
29
+ committer_email: string;
30
+ committed_date: Date;
31
+ status: string;
32
+ project_id: number;
33
+ }
34
+
35
+ export interface GitLabIssue {
36
+ iid: string;
37
+ author: {
38
+ name: string;
39
+ avatarUrl: string | null;
40
+ webUrl: string;
41
+ } | null;
42
+ title: string;
43
+ description: string;
44
+ createdAt: string;
45
+ updatedAt: string;
46
+ closedAt: string;
47
+ webUrl: string;
48
+ state: 'opened' | 'closed' | 'locked';
49
+ }
50
+
51
+ export interface GitLabMergeRequest {
52
+ iid: string;
53
+ author: {
54
+ id: string;
55
+ name: string;
56
+ avatarUrl: string | null;
57
+ webUrl: string;
58
+ } | null;
59
+ title: string;
60
+ description: string | null;
61
+ state: GitLabMergeRequestState;
62
+ createdAt: string;
63
+ updatedAt: string;
64
+ mergedAt: string | null;
65
+ webUrl: string;
66
+ }
67
+
68
+ export interface GitLabRepositoryStub {
69
+ id: string;
70
+ fullPath: string;
71
+ webUrl: string;
72
+ }
73
+
74
+ export interface GitLabMergeRequestFull extends GitLabMergeRequest {
75
+ id: string;
76
+ targetBranch: string;
77
+ sourceBranch: string;
78
+ diffRefs: {
79
+ baseSha: string | null;
80
+ headSha: string;
81
+ } | null;
82
+ project: GitLabRepositoryStub;
83
+ sourceProject: GitLabRepositoryStub | null;
84
+ }
85
+
86
+ export type GitLabMergeRequestState = 'opened' | 'closed' | 'locked' | 'merged';
87
+
88
+ export function fromGitLabMergeRequestState(state: GitLabMergeRequestState): PullRequestState {
89
+ return state === 'locked' ? 'closed' : state;
90
+ }
91
+
92
+ export function toGitLabMergeRequestState(state: PullRequestState): GitLabMergeRequestState {
93
+ return state;
94
+ }
95
+
96
+ export interface GitLabMergeRequestREST {
97
+ id: number;
98
+ iid: number;
99
+ author: {
100
+ id: string;
101
+ name: string;
102
+ avatar_url?: string;
103
+ web_url: string;
104
+ } | null;
105
+ title: string;
106
+ description: string;
107
+ state: GitLabMergeRequestState;
108
+ created_at: string;
109
+ updated_at: string;
110
+ closed_at: string | null;
111
+ merged_at: string | null;
112
+ diff_refs: {
113
+ base_sha: string;
114
+ head_sha: string;
115
+ start_sha: string;
116
+ };
117
+ source_branch: string;
118
+ source_project_id: number;
119
+ target_branch: string;
120
+ target_project_id: number;
121
+ web_url: string;
122
+ }
123
+
124
+ export function fromGitLabMergeRequestREST(
125
+ pr: GitLabMergeRequestREST,
126
+ provider: Provider,
127
+ repo: { owner: string; repo: string },
128
+ ): PullRequest {
129
+ return new PullRequest(
130
+ provider,
131
+ {
132
+ id: pr.author?.id ?? '',
133
+ name: pr.author?.name ?? 'Unknown',
134
+ avatarUrl: pr.author?.avatar_url ?? '',
135
+ url: pr.author?.web_url ?? '',
136
+ },
137
+ String(pr.iid),
138
+ undefined,
139
+ pr.title,
140
+ pr.web_url,
141
+ repo,
142
+ fromGitLabMergeRequestState(pr.state),
143
+ new Date(pr.created_at),
144
+ new Date(pr.updated_at),
145
+ pr.closed_at == null ? undefined : new Date(pr.closed_at),
146
+ pr.merged_at == null ? undefined : new Date(pr.merged_at),
147
+ );
148
+ }
149
+
150
+ export interface GitLabProjectREST {
151
+ namespace: {
152
+ path: string;
153
+ full_path: string;
154
+ };
155
+ path: string;
156
+
157
+ forked_from_project?: {
158
+ namespace: {
159
+ path: string;
160
+ full_path: string;
161
+ };
162
+ path: string;
163
+ };
164
+ }
165
+
166
+ export function fromGitLabMergeRequestProvidersApi(pr: ProviderPullRequest, provider: Integration): PullRequest {
167
+ const wrappedPr: ProviderPullRequest = {
168
+ ...pr,
169
+ // @gitkraken/providers-api returns global ID as id, while allover GitLens we use internal ID (iid) that is returned as `number`:
170
+ id: String(pr.number),
171
+ // Substitute some defaults that are needed to enable PRs because @gitkraken/providers-api always returns null here:
172
+ // Discussed: https://github.com/gitkraken/provider-apis-package-js/blob/6ee521eb6b46bbb759d9c68646979c3b25681d90/src/providers/gitlab/gitlab.ts#L597
173
+ permissions: pr.permissions ?? {
174
+ canMerge: true,
175
+ canMergeAndBypassProtections: false,
176
+ },
177
+ };
178
+ return fromProviderPullRequest(wrappedPr, provider);
179
+ }
180
+
181
+ export function fromGitLabMergeRequest(pr: GitLabMergeRequestFull, provider: Provider): PullRequest {
182
+ let avatarUrl: string | undefined;
183
+ try {
184
+ avatarUrl = new URL(pr.author?.avatarUrl ?? '').toString();
185
+ } catch {
186
+ try {
187
+ const authorUrl = new URL(pr.author?.webUrl ?? '');
188
+ authorUrl.pathname = '';
189
+ authorUrl.search = '';
190
+ authorUrl.hash = '';
191
+ avatarUrl = pr.author?.avatarUrl ? authorUrl.toString() + pr.author?.avatarUrl : undefined;
192
+ } catch {
193
+ avatarUrl = undefined;
194
+ }
195
+ }
196
+ const [owner, repo] = pr.project.fullPath.split('/');
197
+
198
+ return new PullRequest(
199
+ provider,
200
+ {
201
+ // author
202
+ id: pr.author?.id ?? '',
203
+ name: pr.author?.name ?? 'Unknown',
204
+ avatarUrl: avatarUrl,
205
+ url: pr.author?.webUrl ?? '',
206
+ },
207
+ pr.iid, // id
208
+ pr.id, // nodeId
209
+ pr.title,
210
+ pr.webUrl || '',
211
+ {
212
+ // IssueRepository
213
+ owner: owner,
214
+ repo: repo,
215
+ url: pr.project.webUrl,
216
+ },
217
+ fromGitLabMergeRequestState(pr.state), // PullRequestState
218
+ new Date(pr.createdAt),
219
+ new Date(pr.updatedAt),
220
+ // TODO@eamodio this isn't right, but GitLab doesn't seem to provide a closedAt on merge requests in GraphQL
221
+ pr.state !== 'closed' ? undefined : new Date(pr.updatedAt),
222
+ pr.mergedAt == null ? undefined : new Date(pr.mergedAt),
223
+ PullRequestMergeableState.Unknown,
224
+ undefined, // viewerCanUpdate
225
+ fromGitLabMergeRequestRefs(pr), // PullRequestRefs
226
+ );
227
+ }
228
+
229
+ function fromGitLabMergeRequestRefs(pr: GitLabMergeRequestFull): PullRequestRefs | undefined {
230
+ if (pr.sourceProject == null) {
231
+ return undefined;
232
+ }
233
+ // GitLab terminology: sourceBranch = branch with changes (head), targetBranch = merge target (base)
234
+ return {
235
+ head: {
236
+ owner: getRepoNamespace(pr.sourceProject.fullPath),
237
+ branch: pr.sourceBranch,
238
+ exists: true,
239
+ url: pr.sourceProject.webUrl,
240
+ repo: pr.sourceProject.fullPath,
241
+ sha: pr.diffRefs?.headSha || '',
242
+ },
243
+ base: {
244
+ owner: getRepoNamespace(pr.project.fullPath),
245
+ branch: pr.targetBranch,
246
+ exists: true,
247
+ url: pr.project.webUrl,
248
+ repo: pr.project.fullPath,
249
+ sha: pr.diffRefs?.baseSha || '',
250
+ },
251
+ isCrossRepository: pr.sourceProject.id !== pr.project.id,
252
+ };
253
+ }
254
+
255
+ function getRepoNamespace(projectFullPath: string) {
256
+ return projectFullPath.split('/').slice(0, -1).join('/');
257
+ }