@gitkraken/core-gitlens 0.7.0 → 0.7.1
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 +21 -2
- package/dist/git/remotes/azure-devops.js +3 -3
- package/dist/git/remotes/azure-devops.js.map +1 -1
- package/dist/git-cli/exec/git.js +1 -1
- package/dist/git-cli/providers/config.js +2 -2
- package/dist/git-cli/providers/pausedOperations.js +2 -2
- package/dist/git-cli/providers/pausedOperations.js.map +1 -1
- package/dist/git-cli/providers/staging.js +1 -1
- package/dist/ipc/discovery.js +1 -1
- package/dist/plus/agents/providers/claudeCodeTranscript.js +6 -6
- package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -1
- package/dist/plus/ai/providers/openAICompatibleProviderBase.js +1 -1
- package/dist/plus/integrations/authentication/configuredIntegrationService.js +9 -2
- package/dist/plus/integrations/authentication/configuredIntegrationService.js.map +1 -1
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +1 -1
- package/dist/plus/integrations/index.d.ts +2 -2
- package/dist/plus/integrations/index.js.map +1 -1
- package/dist/plus/integrations/integrationService.d.ts +34 -0
- package/dist/plus/integrations/integrationService.js +90 -43
- package/dist/plus/integrations/integrationService.js.map +1 -1
- package/dist/plus/integrations/lite.js +5 -4
- package/dist/plus/integrations/lite.js.map +1 -1
- package/dist/plus/integrations/manager.d.ts +68 -23
- package/dist/plus/integrations/models/gitHostIntegration.d.ts +30 -14
- package/dist/plus/integrations/models/gitHostIntegration.js +59 -21
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
- package/dist/plus/integrations/models/integration.d.ts +3 -3
- package/dist/plus/integrations/models/integration.js +1 -1
- package/dist/plus/integrations/models/integration.js.map +1 -1
- package/dist/plus/integrations/models/issueReads.d.ts +17 -0
- package/dist/plus/integrations/models/pullRequestReads.d.ts +26 -0
- package/dist/plus/integrations/providers/azure/azure.d.ts +66 -1
- package/dist/plus/integrations/providers/azure/azure.js +192 -12
- package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
- package/dist/plus/integrations/providers/azure/search.d.ts +144 -0
- package/dist/plus/integrations/providers/azure/search.js +250 -0
- package/dist/plus/integrations/providers/azure/search.js.map +1 -0
- package/dist/plus/integrations/providers/azureDevOps.d.ts +54 -35
- package/dist/plus/integrations/providers/azureDevOps.js +154 -121
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOpsServer.d.ts +176 -0
- package/dist/plus/integrations/providers/azureDevOpsServer.js +560 -0
- package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server/discovery.d.ts +12 -0
- package/dist/plus/integrations/providers/bitbucket-server/discovery.js +128 -0
- package/dist/plus/integrations/providers/bitbucket-server/discovery.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server/models.d.ts +10 -1
- package/dist/plus/integrations/providers/bitbucket-server/models.js +3 -2
- package/dist/plus/integrations/providers/bitbucket-server/models.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.d.ts +58 -0
- package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js +485 -0
- package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server.d.ts +52 -3
- package/dist/plus/integrations/providers/bitbucket-server.js +96 -20
- package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket.js +1 -1
- package/dist/plus/integrations/providers/github.d.ts +5 -5
- package/dist/plus/integrations/providers/github.js +34 -33
- package/dist/plus/integrations/providers/github.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab.d.ts +5 -3
- package/dist/plus/integrations/providers/gitlab.js +31 -27
- package/dist/plus/integrations/providers/gitlab.js.map +1 -1
- package/dist/plus/integrations/providers/issueSorts.d.ts +1 -0
- package/dist/plus/integrations/providers/jira-server.d.ts +9 -0
- package/dist/plus/integrations/providers/jira-server.js +13 -2
- package/dist/plus/integrations/providers/jira-server.js.map +1 -1
- package/dist/plus/integrations/providers/jira.js +1 -1
- package/dist/plus/integrations/providers/linear.js +1 -1
- package/dist/plus/integrations/providers/models.d.ts +9 -0
- package/dist/plus/integrations/providers/models.js +86 -0
- package/dist/plus/integrations/providers/models.js.map +1 -1
- package/dist/plus/integrations/providers/providersApi.d.ts +10 -0
- package/dist/plus/integrations/providers/providersApi.js +16 -1
- package/dist/plus/integrations/providers/providersApi.js.map +1 -1
- package/dist/plus/integrations/providers/utils.d.ts +12 -1
- package/dist/plus/integrations/providers/utils.js +36 -6
- package/dist/plus/integrations/providers/utils.js.map +1 -1
- package/dist/plus/integrations/reads/broaden.js +5 -5
- package/dist/plus/integrations/reads/broaden.js.map +1 -1
- package/dist/plus/integrations/reads/counts.d.ts +18 -4
- package/dist/plus/integrations/reads/counts.js +66 -15
- package/dist/plus/integrations/reads/counts.js.map +1 -1
- package/dist/plus/integrations/reads/cursors.js +1 -1
- package/dist/plus/integrations/reads/drains.d.ts +1 -0
- package/dist/plus/integrations/reads/filters.d.ts +1 -1
- package/dist/plus/integrations/reads/filters.js +17 -12
- package/dist/plus/integrations/reads/filters.js.map +1 -1
- package/dist/plus/integrations/reads/hierarchy.js +1 -1
- package/dist/plus/integrations/reads/hierarchy.js.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.js +1 -1
- package/dist/plus/integrations/reads/issues.js +1 -1
- package/dist/plus/integrations/reads/paging.js +1 -1
- package/dist/plus/integrations/reads/resolveRepository.d.ts +12 -11
- package/dist/plus/integrations/reads/resolveRepository.js +109 -18
- package/dist/plus/integrations/reads/resolveRepository.js.map +1 -1
- package/dist/plus/integrations/reads/searchIssues.js +4 -2
- package/dist/plus/integrations/reads/searchIssues.js.map +1 -1
- package/dist/plus/integrations/reads/searchPullRequests.js +9 -3
- package/dist/plus/integrations/reads/searchPullRequests.js.map +1 -1
- package/dist/plus/integrations/reads/trackerIssue.d.ts +9 -5
- package/dist/plus/integrations/reads/trackerIssue.js +15 -9
- package/dist/plus/integrations/reads/trackerIssue.js.map +1 -1
- package/dist/plus/integrations/reads/warnings.d.ts +6 -2
- package/dist/plus/integrations/reads/warnings.js +15 -19
- package/dist/plus/integrations/reads/warnings.js.map +1 -1
- package/dist/plus/integrations/utils/domain.utils.d.ts +19 -0
- package/dist/plus/integrations/utils/domain.utils.js +36 -1
- package/dist/plus/integrations/utils/domain.utils.js.map +1 -1
- package/dist/plus/integrations/utils/integration.utils.d.ts +1 -0
- package/dist/plus/integrations/utils/integration.utils.js +12 -1
- package/dist/plus/integrations/utils/integration.utils.js.map +1 -1
- package/dist/utils/env/node/exec.js +2 -2
- package/docs/integrations.md +176 -73
- package/docs/kepler-read-api-parity.md +19 -6
- package/package.json +1 -1
|
@@ -5,8 +5,9 @@ import { toCollectionScopeFailure } from "../collectionMetadata.js";
|
|
|
5
5
|
import "../constants.js";
|
|
6
6
|
import { toTokenWithInfo } from "../authentication/models.js";
|
|
7
7
|
import "../providerFilters.js";
|
|
8
|
-
import { fromProviderIssue, fromProviderPullRequest, getProviderPullRequestIdentity, providerPullRequestMatchesSearch, providersMetadata, toProviderPullRequestStates } from "./models.js";
|
|
9
8
|
import { collectProviderPagedResult, flatSettledResultsOrThrow, mergeCollectionMetadata } from "./utils/providerPaging.js";
|
|
9
|
+
import { decodePathSegment } from "../utils/domain.utils.js";
|
|
10
|
+
import { fromProviderIssue, fromProviderPullRequest, getProviderPullRequestIdentity, providerPullRequestMatchesSearch, providersMetadata, toProviderPullRequestStates } from "./models.js";
|
|
10
11
|
import { GitHostIntegration } from "../models/gitHostIntegration.js";
|
|
11
12
|
//#region ../plus/integrations/src/providers/azureDevOps.ts
|
|
12
13
|
function getAzureRepositoryIdentity(repo) {
|
|
@@ -18,10 +19,33 @@ function getAzureRepositoryIdentity(repo) {
|
|
|
18
19
|
};
|
|
19
20
|
}
|
|
20
21
|
function getAzureRepositoryApiBaseUrl(baseUrl, repo) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
const directory = repo.virtualDirectory?.split("/");
|
|
23
|
+
if (directory?.some((segment) => !segment || segment === "." || segment === "..")) throw new Error(`Invalid Azure virtual directory '${repo.virtualDirectory}'.`);
|
|
24
|
+
const url = new URL(baseUrl);
|
|
25
|
+
const toUrl = (segments) => `${url.protocol}//${url.host}${segments.map((s) => `/${s}`).join("")}`;
|
|
26
|
+
const configured = url.pathname.split("/").filter(Boolean);
|
|
27
|
+
if (!configured.length) return toUrl(directory?.map(encodeURIComponent) ?? []);
|
|
28
|
+
const namesCollection = sameAzurePathSegment(configured.at(-1), repo.owner);
|
|
29
|
+
const installation = namesCollection ? configured.slice(0, -1) : configured;
|
|
30
|
+
if (directory == null) return toUrl(installation);
|
|
31
|
+
for (const candidate of namesCollection ? [configured, installation] : [configured]) if (candidate.length === directory.length && candidate.every((s, i) => sameAzurePathSegment(s, directory[i]))) return toUrl(candidate);
|
|
32
|
+
throw new Error("Azure repository virtual directory does not match the configured installation");
|
|
33
|
+
}
|
|
34
|
+
function sameAzurePathSegment(encoded, value) {
|
|
35
|
+
return decodePathSegment(encoded).toLowerCase() === value.toLowerCase();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Whether two collection or project names name the same scope. Azure DevOps treats them case-insensitively, so a
|
|
39
|
+
* name typed by hand must still select the collection or project discovery reported.
|
|
40
|
+
*/
|
|
41
|
+
function sameAzureName(a, b) {
|
|
42
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
43
|
+
}
|
|
44
|
+
/** The distinct names in `names`, compared as Azure compares them, keeping the first spelling of each. */
|
|
45
|
+
function uniqueAzureNames(names) {
|
|
46
|
+
const unique = [];
|
|
47
|
+
for (const name of names) if (!unique.some((n) => sameAzureName(n, name))) unique.push(name);
|
|
48
|
+
return unique;
|
|
25
49
|
}
|
|
26
50
|
/**
|
|
27
51
|
* Matches an org/project descriptor against a caller-supplied name, mirroring the facade's own
|
|
@@ -39,15 +63,51 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
39
63
|
options: { isPAT: usePat }
|
|
40
64
|
};
|
|
41
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* The options for a request addressed below one collection (an Azure DevOps Services organization).
|
|
68
|
+
*
|
|
69
|
+
* The same as {@link getApiOptions} unless a self-managed address already names the collection, which requests
|
|
70
|
+
* append themselves: see the server override, which keeps it from being applied twice.
|
|
71
|
+
*/
|
|
72
|
+
getCollectionApiOptions(session, _collection) {
|
|
73
|
+
return this.getApiOptions(session).options;
|
|
74
|
+
}
|
|
75
|
+
/** The base a request or link below `collection` appends the collection to; see {@link getCollectionApiOptions}. */
|
|
76
|
+
collectionApiBaseUrl(session, _collection) {
|
|
77
|
+
return this.apiBaseUrlFor(session);
|
|
78
|
+
}
|
|
79
|
+
/** Reads the organizations (Azure DevOps Server: the collections) the account can see. */
|
|
80
|
+
async requestResourcesForUser(session, userId) {
|
|
81
|
+
const api = await this.getProvidersApi();
|
|
82
|
+
const { tokenWithInfo, options } = this.getApiOptions(session);
|
|
83
|
+
return api.getAzureResourcesForUser(tokenWithInfo, userId, options);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The identity id a pull-request creator/reviewer filter must carry for `collection`.
|
|
87
|
+
*
|
|
88
|
+
* On Azure DevOps Services that is the account id, one per user. The server override resolves it per collection,
|
|
89
|
+
* since Azure DevOps Server gives one person a different id in each collection than at the server level.
|
|
90
|
+
*/
|
|
91
|
+
async getFilterUserId(session, _collection) {
|
|
92
|
+
return (await this.getProviderCurrentAccount(session))?.id;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* What the discovery caches (account, organizations, projects, and their stored copies) are keyed by. Azure DevOps
|
|
96
|
+
* Services has a single address, so the credential alone identifies what it discovers; the server override adds
|
|
97
|
+
* the installation address.
|
|
98
|
+
*/
|
|
99
|
+
discoveryKey(session) {
|
|
100
|
+
return session.accessToken;
|
|
101
|
+
}
|
|
42
102
|
_accounts;
|
|
43
103
|
async getProviderCurrentAccount(session) {
|
|
44
|
-
const
|
|
104
|
+
const key = this.discoveryKey(session);
|
|
45
105
|
this._accounts ??= /* @__PURE__ */ new Map();
|
|
46
|
-
if (this._accounts.get(
|
|
106
|
+
if (this._accounts.get(key) == null) {
|
|
47
107
|
const user = await this._requestForCurrentUser(session);
|
|
48
|
-
this._accounts.set(
|
|
108
|
+
this._accounts.set(key, user);
|
|
49
109
|
}
|
|
50
|
-
return this._accounts.get(
|
|
110
|
+
return this._accounts.get(key);
|
|
51
111
|
}
|
|
52
112
|
async _requestForCurrentUser(session) {
|
|
53
113
|
const api = await this.getProvidersApi();
|
|
@@ -65,19 +125,17 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
65
125
|
_organizations;
|
|
66
126
|
async getProviderResourcesForUser(session, force = false) {
|
|
67
127
|
this._organizations ??= /* @__PURE__ */ new Map();
|
|
68
|
-
const
|
|
69
|
-
if (this._organizations.get(
|
|
70
|
-
const api = await this.getProvidersApi();
|
|
128
|
+
const key = this.discoveryKey(session);
|
|
129
|
+
if (this._organizations.get(key) == null || force) {
|
|
71
130
|
const account = await this.getProviderCurrentAccount(session);
|
|
72
131
|
if (account?.id == null) return void 0;
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
this._organizations.set(accessToken, resources != null ? resources.map((r) => ({
|
|
132
|
+
const resources = await this.requestResourcesForUser(session, account.id);
|
|
133
|
+
this._organizations.set(key, resources != null ? resources.map((r) => ({
|
|
76
134
|
...r,
|
|
77
135
|
key: r.id
|
|
78
136
|
})) : void 0);
|
|
79
137
|
}
|
|
80
|
-
return this._organizations.get(
|
|
138
|
+
return this._organizations.get(key);
|
|
81
139
|
}
|
|
82
140
|
_projects;
|
|
83
141
|
/**
|
|
@@ -89,22 +147,22 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
89
147
|
*/
|
|
90
148
|
async getProviderProjectsForResources(session, resources, force = false, failures) {
|
|
91
149
|
this._projects ??= /* @__PURE__ */ new Map();
|
|
92
|
-
const
|
|
150
|
+
const discoveryKey = this.discoveryKey(session);
|
|
93
151
|
let resourcesWithoutProjects = [];
|
|
94
152
|
if (force) resourcesWithoutProjects = resources;
|
|
95
153
|
else for (const resource of resources) {
|
|
96
|
-
const resourceKey = `${
|
|
154
|
+
const resourceKey = `${discoveryKey}:${resource.id}`;
|
|
97
155
|
if (this._projects.get(resourceKey) == null) resourcesWithoutProjects.push(resource);
|
|
98
156
|
}
|
|
99
157
|
const allProjects = [];
|
|
100
158
|
let resultMetadata;
|
|
101
159
|
if (resourcesWithoutProjects.length > 0) {
|
|
102
160
|
const api = await this.getProvidersApi();
|
|
103
|
-
const { tokenWithInfo
|
|
161
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
104
162
|
(await Promise.allSettled(resourcesWithoutProjects.map(async (resource) => ({
|
|
105
163
|
resource,
|
|
106
164
|
result: await collectProviderPagedResult((cursor) => api.getAzureProjectsForResource(tokenWithInfo, resource.name, {
|
|
107
|
-
...
|
|
165
|
+
...this.getCollectionApiOptions(session, resource.name),
|
|
108
166
|
cursor
|
|
109
167
|
}), 20, {
|
|
110
168
|
providerId: this.id,
|
|
@@ -149,11 +207,11 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
149
207
|
allProjects.push(...projects);
|
|
150
208
|
return;
|
|
151
209
|
}
|
|
152
|
-
this._projects.set(`${
|
|
210
|
+
this._projects.set(`${discoveryKey}:${resource.id}`, projects);
|
|
153
211
|
});
|
|
154
212
|
}
|
|
155
213
|
const cachedProjects = resources.reduce((projects, resource) => {
|
|
156
|
-
const resourceProjects = this._projects.get(`${
|
|
214
|
+
const resourceProjects = this._projects.get(`${discoveryKey}:${resource.id}`);
|
|
157
215
|
if (resourceProjects != null) projects.push(...resourceProjects);
|
|
158
216
|
return projects;
|
|
159
217
|
}, []);
|
|
@@ -173,9 +231,9 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
173
231
|
const descriptors = /* @__PURE__ */ new Map();
|
|
174
232
|
if (projects.length === 0) return descriptors;
|
|
175
233
|
const api = await this.getProvidersApi();
|
|
176
|
-
const { tokenWithInfo
|
|
234
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
177
235
|
await Promise.all(projects.map(async (project) => {
|
|
178
|
-
const repos = (await api.getReposForAzureProject(tokenWithInfo, project.resourceName, project.name,
|
|
236
|
+
const repos = (await api.getReposForAzureProject(tokenWithInfo, project.resourceName, project.name, this.getCollectionApiOptions(session, project.resourceName)))?.values;
|
|
179
237
|
if (repos != null && repos.length > 0) descriptors.set(project.id, repos.map((r) => ({
|
|
180
238
|
id: r.id,
|
|
181
239
|
nodeId: r.graphQLId ?? void 0,
|
|
@@ -197,7 +255,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
197
255
|
id: o.id,
|
|
198
256
|
providerId: this.id,
|
|
199
257
|
name: o.name,
|
|
200
|
-
url: `${this.
|
|
258
|
+
url: `${this.collectionApiBaseUrl(session, o.name)}/${o.name}`
|
|
201
259
|
})) };
|
|
202
260
|
}
|
|
203
261
|
async getProviderProjectsForOrg(session, org) {
|
|
@@ -220,7 +278,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
220
278
|
providerId: this.id,
|
|
221
279
|
name: p.name,
|
|
222
280
|
org: p.resourceName,
|
|
223
|
-
url: `${this.
|
|
281
|
+
url: `${this.collectionApiBaseUrl(session, p.resourceName)}/${p.resourceName}/${p.name}`
|
|
224
282
|
})),
|
|
225
283
|
...projects.metadata != null ? { metadata: projects.metadata } : {}
|
|
226
284
|
};
|
|
@@ -234,7 +292,8 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
234
292
|
*/
|
|
235
293
|
async getProviderRepositoriesForOrg(session, org, options) {
|
|
236
294
|
const api = await this.getProvidersApi();
|
|
237
|
-
const { tokenWithInfo
|
|
295
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
296
|
+
const apiOptions = this.getCollectionApiOptions(session, org);
|
|
238
297
|
if (options?.project) return api.getReposForAzureProject(tokenWithInfo, org, options.project, {
|
|
239
298
|
...apiOptions,
|
|
240
299
|
cursor: options.cursor
|
|
@@ -276,7 +335,8 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
276
335
|
async mergeProviderPullRequest(session, pr, options) {
|
|
277
336
|
const api = await this.getProvidersApi();
|
|
278
337
|
if (pr.refs == null || pr.project == null) return false;
|
|
279
|
-
const { tokenWithInfo
|
|
338
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
339
|
+
const apiOptions = this.getCollectionApiOptions(session, pr.repository.owner);
|
|
280
340
|
try {
|
|
281
341
|
return await api.mergePullRequest(tokenWithInfo, pr, {
|
|
282
342
|
...options,
|
|
@@ -291,17 +351,17 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
291
351
|
this.ctx.hooks?.ui?.onError?.(`${ex.message}. Check branch policies, and ensure you have the necessary permissions to merge the pull request.`);
|
|
292
352
|
}
|
|
293
353
|
async getProviderAccountForCommit(session, repo, rev, options) {
|
|
294
|
-
return (await this.authenticationService.apis.azure)?.getAccountForCommit(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, rev, getAzureRepositoryApiBaseUrl(this.
|
|
354
|
+
return (await this.authenticationService.apis.azure)?.getAccountForCommit(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, rev, getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo), options);
|
|
295
355
|
}
|
|
296
356
|
async getProviderAccountForEmail(_session, _repo, _email, _options) {
|
|
297
357
|
return Promise.resolve(void 0);
|
|
298
358
|
}
|
|
299
359
|
async getProviderDefaultBranch(session, repo, cancellation) {
|
|
300
|
-
return (await this.authenticationService.apis.azure)?.getDefaultBranch(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, { baseUrl: getAzureRepositoryApiBaseUrl(this.
|
|
360
|
+
return (await this.authenticationService.apis.azure)?.getDefaultBranch(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, { baseUrl: getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo) }, cancellation);
|
|
301
361
|
}
|
|
302
362
|
async getProviderLinkedIssueOrPullRequest(session, repo, { id }, type) {
|
|
303
363
|
return (await this.authenticationService.apis.azure)?.getIssueOrPullRequest(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, id, {
|
|
304
|
-
baseUrl: getAzureRepositoryApiBaseUrl(this.
|
|
364
|
+
baseUrl: getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo),
|
|
305
365
|
type
|
|
306
366
|
});
|
|
307
367
|
}
|
|
@@ -313,13 +373,13 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
313
373
|
if (projects.values.length === 0) return void 0;
|
|
314
374
|
const matchingProject = projects.values.find((p) => p.resourceName === project.owner && p.name === project.name);
|
|
315
375
|
if (matchingProject == null) return void 0;
|
|
316
|
-
return (await this.authenticationService.apis.azure)?.getIssue(this, toTokenWithInfo(this.id, session), matchingProject, id, { baseUrl: this.
|
|
376
|
+
return (await this.authenticationService.apis.azure)?.getIssue(this, toTokenWithInfo(this.id, session), matchingProject, id, { baseUrl: this.collectionApiBaseUrl(session, matchingProject.resourceName) });
|
|
317
377
|
}
|
|
318
378
|
async getProviderPullRequestForBranch(session, repo, branch, _options) {
|
|
319
|
-
return (await this.authenticationService.apis.azure)?.getPullRequestForBranch(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, branch, { baseUrl: getAzureRepositoryApiBaseUrl(this.
|
|
379
|
+
return (await this.authenticationService.apis.azure)?.getPullRequestForBranch(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, branch, { baseUrl: getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo) });
|
|
320
380
|
}
|
|
321
381
|
async getProviderPullRequestForCommit(session, repo, rev) {
|
|
322
|
-
return (await this.authenticationService.apis.azure)?.getPullRequestForCommit(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, rev, getAzureRepositoryApiBaseUrl(this.
|
|
382
|
+
return (await this.authenticationService.apis.azure)?.getPullRequestForCommit(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, rev, getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo));
|
|
323
383
|
}
|
|
324
384
|
async getRepoInfo(repo) {
|
|
325
385
|
const identity = getAzureRepositoryIdentity(repo);
|
|
@@ -330,47 +390,53 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
330
390
|
const { tokenWithInfo, options } = this.getApiOptions(session);
|
|
331
391
|
return api.getRepo(tokenWithInfo, identity.resourceName, identity.repositoryName, identity.projectName, {
|
|
332
392
|
...options,
|
|
333
|
-
baseUrl: getAzureRepositoryApiBaseUrl(this.
|
|
393
|
+
baseUrl: getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo)
|
|
334
394
|
});
|
|
335
395
|
}
|
|
336
396
|
async getProviderRepositoryMetadata(session, repo, cancellation) {
|
|
337
|
-
return (await this.authenticationService.apis.azure)?.getRepositoryMetadata(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, { baseUrl: getAzureRepositoryApiBaseUrl(this.
|
|
397
|
+
return (await this.authenticationService.apis.azure)?.getRepositoryMetadata(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, { baseUrl: getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo) }, cancellation);
|
|
338
398
|
}
|
|
339
399
|
async searchProviderMyPullRequests(session, repos, _cancellation, options) {
|
|
340
400
|
const api = await this.getProvidersApi();
|
|
341
401
|
if (repos != null) return;
|
|
342
402
|
const states = toProviderPullRequestStates(options?.state);
|
|
343
|
-
|
|
344
|
-
if (user?.id == null) return void 0;
|
|
403
|
+
if ((await this.getProviderCurrentAccount(session))?.id == null) return void 0;
|
|
345
404
|
const orgs = await this.getProviderResourcesForUser(session);
|
|
346
405
|
if (orgs == null || orgs.length === 0) return void 0;
|
|
347
406
|
const projects = await this.getProviderProjectsForResources(session, orgs);
|
|
348
407
|
if (projects.values.length === 0) return void 0;
|
|
349
408
|
const repoDescriptors = [...(await this.getRepoDescriptorsForProjects(session, projects.values) ?? /* @__PURE__ */ new Map()).values()].filter((r) => r != null).flat();
|
|
350
|
-
const { tokenWithInfo
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
409
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
410
|
+
const assignedPrs = [];
|
|
411
|
+
const authoredPrs = [];
|
|
412
|
+
for (const org of uniqueAzureNames(projects.values.map((p) => p.resourceName))) {
|
|
413
|
+
const userId = await this.getFilterUserId(session, org);
|
|
414
|
+
if (userId == null) continue;
|
|
415
|
+
const projectInputs = projects.values.filter((p) => sameAzureName(p.resourceName, org)).map((p) => ({
|
|
416
|
+
namespace: p.resourceName,
|
|
417
|
+
project: p.name
|
|
418
|
+
}));
|
|
419
|
+
const orgOptions = this.getCollectionApiOptions(session, org);
|
|
420
|
+
const reads = [[{ assigneeLogins: [userId] }, assignedPrs], [{ authorLogin: userId }, authoredPrs]];
|
|
421
|
+
for (const [filter, into] of reads) {
|
|
422
|
+
const result = await api.getPullRequestsForAzureProjects(tokenWithInfo, projectInputs, {
|
|
423
|
+
...orgOptions,
|
|
424
|
+
...filter,
|
|
425
|
+
states
|
|
426
|
+
});
|
|
427
|
+
into.push(...result.values.map((pr) => this.fromAzureProviderPullRequest(pr, repoDescriptors, projects.values)));
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
const prsByIdentity = /* @__PURE__ */ new Map();
|
|
431
|
+
for (const pr of [...authoredPrs, ...assignedPrs]) {
|
|
432
|
+
const identity = `${pr.repository.owner}/${pr.repository.id || pr.repository.repo}#${pr.id}`;
|
|
433
|
+
if (!prsByIdentity.has(identity)) prsByIdentity.set(identity, pr);
|
|
434
|
+
}
|
|
435
|
+
return [...prsByIdentity.values()];
|
|
369
436
|
}
|
|
370
437
|
async getProviderMyPullRequestsForUser(session, options) {
|
|
371
438
|
const api = await this.getProvidersApi();
|
|
372
|
-
|
|
373
|
-
if (user?.id == null) return void 0;
|
|
439
|
+
if ((await this.getProviderCurrentAccount(session))?.id == null) return void 0;
|
|
374
440
|
const orgs = await this.getProviderResourcesForUser(session);
|
|
375
441
|
if (orgs == null || orgs.length === 0) return void 0;
|
|
376
442
|
const failures = [];
|
|
@@ -384,7 +450,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
384
450
|
},
|
|
385
451
|
...projects.metadata != null ? { metadata: projects.metadata } : {}
|
|
386
452
|
};
|
|
387
|
-
const { tokenWithInfo
|
|
453
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
388
454
|
const states = toProviderPullRequestStates(options?.state);
|
|
389
455
|
const maxPagesPerProject = 20;
|
|
390
456
|
let truncated = projects.metadata != null && projects.metadata.completeness !== "complete";
|
|
@@ -394,7 +460,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
394
460
|
let page;
|
|
395
461
|
for (let i = 0; i < maxPagesPerProject; i++) try {
|
|
396
462
|
const result = await api.getPullRequestsForAzureProject(tokenWithInfo, project, {
|
|
397
|
-
...
|
|
463
|
+
...this.getCollectionApiOptions(session, project.namespace),
|
|
398
464
|
...filter,
|
|
399
465
|
states,
|
|
400
466
|
page
|
|
@@ -436,6 +502,8 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
436
502
|
const requested = options?.filters?.length ? new Set(options.filters) : void 0;
|
|
437
503
|
const wantAuthored = requested == null || requested.has("author");
|
|
438
504
|
const wantReviewed = requested == null || requested.has("assignee") || requested.has("review-requested");
|
|
505
|
+
const userIds = /* @__PURE__ */ new Map();
|
|
506
|
+
for (const org of uniqueAzureNames(projects.values.map((p) => p.resourceName))) userIds.set(org.toLowerCase(), await this.getFilterUserId(session, org));
|
|
439
507
|
const outcomes = await Promise.all(projects.values.flatMap((p) => {
|
|
440
508
|
const project = {
|
|
441
509
|
namespace: p.resourceName,
|
|
@@ -446,9 +514,15 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
446
514
|
resourceId: p.resourceId,
|
|
447
515
|
projectId: p.name
|
|
448
516
|
};
|
|
517
|
+
const userId = userIds.get(p.resourceName.toLowerCase());
|
|
518
|
+
if (userId == null) {
|
|
519
|
+
failures.push(toCollectionScopeFailure(scope, /* @__PURE__ */ new Error("The current user could not be resolved here")));
|
|
520
|
+
truncated = true;
|
|
521
|
+
return [];
|
|
522
|
+
}
|
|
449
523
|
const drains = [];
|
|
450
|
-
if (wantAuthored) drains.push(drainProject(project, scope, { authorLogin:
|
|
451
|
-
if (wantReviewed) drains.push(drainProject(project, scope, { reviewerId:
|
|
524
|
+
if (wantAuthored) drains.push(drainProject(project, scope, { authorLogin: userId }));
|
|
525
|
+
if (wantReviewed) drains.push(drainProject(project, scope, { reviewerId: userId }));
|
|
452
526
|
return drains;
|
|
453
527
|
}));
|
|
454
528
|
const prsByIdentity = /* @__PURE__ */ new Map();
|
|
@@ -488,7 +562,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
488
562
|
const repoInputs = requestedRepos == null ? void 0 : repoDescriptors.filter((r) => requestedRepos.some((repo) => repo.resourceName === r.resourceName && repo.repositoryName === r.name && (repo.projectName == null || repo.projectName === r.projectName)));
|
|
489
563
|
if (repoInputs?.length === 0) return [];
|
|
490
564
|
const api = await this.getProvidersApi();
|
|
491
|
-
const { tokenWithInfo
|
|
565
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
492
566
|
const states = toProviderPullRequestStates(options?.include);
|
|
493
567
|
const searchScopes = repoInputs != null ? repoInputs.flatMap((repo) => repo.projectName == null ? [] : [{
|
|
494
568
|
project: {
|
|
@@ -511,7 +585,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
511
585
|
for (let i = 0; i < 20; i++) {
|
|
512
586
|
if (cancellation?.aborted) throw new CancellationError();
|
|
513
587
|
const result = await api.getPullRequestsForAzureProject(tokenWithInfo, scope.project, {
|
|
514
|
-
...
|
|
588
|
+
...this.getCollectionApiOptions(session, scope.project.namespace),
|
|
515
589
|
page,
|
|
516
590
|
repo: scope.repo,
|
|
517
591
|
states
|
|
@@ -571,10 +645,10 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
571
645
|
values: [],
|
|
572
646
|
truncated: false
|
|
573
647
|
};
|
|
574
|
-
const { tokenWithInfo
|
|
648
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
575
649
|
const drain = async (p, filter) => {
|
|
576
650
|
const result = await collectProviderPagedResult((cursor) => api.getIssuesForAzureProject(tokenWithInfo, p.resourceName, p.name, {
|
|
577
|
-
...
|
|
651
|
+
...this.getCollectionApiOptions(session, p.resourceName),
|
|
578
652
|
...filter,
|
|
579
653
|
cursor,
|
|
580
654
|
sort: searchOptions?.sort
|
|
@@ -623,10 +697,11 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
623
697
|
}
|
|
624
698
|
async providerOnConnect() {
|
|
625
699
|
if (this._session == null) return;
|
|
700
|
+
const discoveryKey = this.discoveryKey(this._session);
|
|
626
701
|
const canHydrateStoredProjects = (metadata) => metadata == null || metadata.completeness === "complete";
|
|
627
|
-
const storedAccount = this.ctx.storage.get(`azure:${
|
|
628
|
-
const storedOrganizations = this.ctx.storage.get(`azure:${
|
|
629
|
-
const storedProjects = this.ctx.storage.get(`azure:${
|
|
702
|
+
const storedAccount = this.ctx.storage.get(`azure:${discoveryKey}:account`);
|
|
703
|
+
const storedOrganizations = this.ctx.storage.get(`azure:${discoveryKey}:organizations`);
|
|
704
|
+
const storedProjects = this.ctx.storage.get(`azure:${discoveryKey}:projects`);
|
|
630
705
|
let account = storedAccount?.data ? {
|
|
631
706
|
...storedAccount.data,
|
|
632
707
|
provider: this
|
|
@@ -645,7 +720,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
645
720
|
account = await this.getProviderCurrentAccount(this._session);
|
|
646
721
|
if (account != null) {
|
|
647
722
|
await this.ctx.storage.deleteWithPrefix("azure");
|
|
648
|
-
await this.ctx.storage.store(`azure:${
|
|
723
|
+
await this.ctx.storage.store(`azure:${discoveryKey}:account`, {
|
|
649
724
|
v: 1,
|
|
650
725
|
timestamp: Date.now(),
|
|
651
726
|
data: {
|
|
@@ -659,29 +734,29 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
659
734
|
}
|
|
660
735
|
}
|
|
661
736
|
this._accounts ??= /* @__PURE__ */ new Map();
|
|
662
|
-
this._accounts.set(
|
|
737
|
+
this._accounts.set(discoveryKey, account);
|
|
663
738
|
if (storedOrganizations == null) {
|
|
664
739
|
organizations = await this.getProviderResourcesForUser(this._session, true);
|
|
665
|
-
await this.ctx.storage.store(`azure:${
|
|
740
|
+
await this.ctx.storage.store(`azure:${discoveryKey}:organizations`, {
|
|
666
741
|
v: 1,
|
|
667
742
|
timestamp: Date.now(),
|
|
668
743
|
data: organizations
|
|
669
744
|
});
|
|
670
745
|
}
|
|
671
746
|
this._organizations ??= /* @__PURE__ */ new Map();
|
|
672
|
-
this._organizations.set(
|
|
747
|
+
this._organizations.set(discoveryKey, organizations);
|
|
673
748
|
if (projects == null && organizations?.length) {
|
|
674
749
|
projects = await this.getProviderProjectsForResources(this._session, organizations);
|
|
675
|
-
if (projects != null && canHydrateStoredProjects(projects.metadata)) await this.ctx.storage.store(`azure:${
|
|
750
|
+
if (projects != null && canHydrateStoredProjects(projects.metadata)) await this.ctx.storage.store(`azure:${discoveryKey}:projects`, {
|
|
676
751
|
v: 2,
|
|
677
752
|
timestamp: Date.now(),
|
|
678
753
|
data: projects
|
|
679
754
|
});
|
|
680
|
-
else await this.ctx.storage.delete(`azure:${
|
|
755
|
+
else await this.ctx.storage.delete(`azure:${discoveryKey}:projects`);
|
|
681
756
|
}
|
|
682
757
|
this._projects ??= /* @__PURE__ */ new Map();
|
|
683
758
|
if (projects != null && canHydrateStoredProjects(projects.metadata)) for (const project of projects.values) {
|
|
684
|
-
const projectKey = `${
|
|
759
|
+
const projectKey = `${discoveryKey}:${project.resourceId}`;
|
|
685
760
|
const projects = this._projects.get(projectKey);
|
|
686
761
|
if (projects == null) this._projects.set(projectKey, [project]);
|
|
687
762
|
else if (!projects.some((p) => p.id === project.id)) projects.push(project);
|
|
@@ -729,53 +804,11 @@ var AzureDevOpsIntegration = class extends AzureDevOpsIntegrationBase {
|
|
|
729
804
|
get domain() {
|
|
730
805
|
return cloudMetadata.domain;
|
|
731
806
|
}
|
|
732
|
-
|
|
807
|
+
apiBaseUrlFor(_session) {
|
|
733
808
|
return "https://dev.azure.com";
|
|
734
809
|
}
|
|
735
810
|
};
|
|
736
|
-
const serverMetadata = providersMetadata["azure-devops-server"];
|
|
737
|
-
const serverAuthProvider = Object.freeze({
|
|
738
|
-
id: serverMetadata.id,
|
|
739
|
-
scopes: serverMetadata.scopes
|
|
740
|
-
});
|
|
741
|
-
var AzureDevOpsServerIntegration = class extends AzureDevOpsIntegrationBase {
|
|
742
|
-
domain;
|
|
743
|
-
authProvider = serverAuthProvider;
|
|
744
|
-
id = "azure-devops-server";
|
|
745
|
-
key;
|
|
746
|
-
name = "Azure DevOps Server";
|
|
747
|
-
constructor(ctx, authenticationService, getProvidersApi, didChangeConnection, domain) {
|
|
748
|
-
super(ctx, authenticationService, getProvidersApi, didChangeConnection);
|
|
749
|
-
this.domain = domain;
|
|
750
|
-
this.key = `${this.id}:${this.domain}`;
|
|
751
|
-
}
|
|
752
|
-
get apiBaseUrl() {
|
|
753
|
-
return `${this._session?.protocol ?? "https:"}//${this.domain}`;
|
|
754
|
-
}
|
|
755
|
-
getApiOptions(session, doNotConvertToPat = false) {
|
|
756
|
-
const { options, ...rest } = super.getApiOptions(session, doNotConvertToPat);
|
|
757
|
-
return {
|
|
758
|
-
...rest,
|
|
759
|
-
options: {
|
|
760
|
-
...options,
|
|
761
|
-
baseUrl: this.apiBaseUrl
|
|
762
|
-
}
|
|
763
|
-
};
|
|
764
|
-
}
|
|
765
|
-
async _requestForCurrentUser(session) {
|
|
766
|
-
const azure = await this.authenticationService.apis.azure;
|
|
767
|
-
const user = azure ? await azure.getCurrentUserOnServer(this, toTokenWithInfo(this.id, session), this.apiBaseUrl) : void 0;
|
|
768
|
-
return user ? {
|
|
769
|
-
provider: this,
|
|
770
|
-
id: user.id,
|
|
771
|
-
name: user.name ?? void 0,
|
|
772
|
-
email: user.email ?? void 0,
|
|
773
|
-
avatarUrl: user.avatarUrl ?? void 0,
|
|
774
|
-
username: user.username ?? void 0
|
|
775
|
-
} : void 0;
|
|
776
|
-
}
|
|
777
|
-
};
|
|
778
811
|
//#endregion
|
|
779
|
-
export { AzureDevOpsIntegration, AzureDevOpsIntegrationBase,
|
|
812
|
+
export { AzureDevOpsIntegration, AzureDevOpsIntegrationBase, getAzureRepositoryApiBaseUrl, getAzureRepositoryIdentity, sameAzureName, uniqueAzureNames };
|
|
780
813
|
|
|
781
814
|
//# sourceMappingURL=azureDevOps.js.map
|