@gitkraken/core-gitlens 0.7.0 → 0.7.2
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 +28 -2
- package/dist/git/remotes/azure-devops.js +3 -3
- package/dist/git/remotes/azure-devops.js.map +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/collectionMetadata.d.ts +48 -3
- package/dist/plus/integrations/collectionMetadata.js +138 -8
- package/dist/plus/integrations/collectionMetadata.js.map +1 -1
- package/dist/plus/integrations/errors.d.ts +3 -1
- package/dist/plus/integrations/errors.js +7 -3
- package/dist/plus/integrations/errors.js.map +1 -1
- package/dist/plus/integrations/index.d.ts +3 -3
- package/dist/plus/integrations/index.js.map +1 -1
- package/dist/plus/integrations/integrationService.d.ts +35 -1
- 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 +31 -15
- package/dist/plus/integrations/models/gitHostIntegration.js +71 -22
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
- package/dist/plus/integrations/models/integration.d.ts +70 -12
- package/dist/plus/integrations/models/integration.js +56 -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/issuesIntegration.js +2 -0
- package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
- 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 +73 -36
- package/dist/plus/integrations/providers/azureDevOps.js +191 -122
- 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 +61 -3
- package/dist/plus/integrations/providers/bitbucket-server.js +114 -20
- package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket.d.ts +9 -1
- package/dist/plus/integrations/providers/bitbucket.js +13 -2
- package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
- package/dist/plus/integrations/providers/github.d.ts +6 -6
- package/dist/plus/integrations/providers/github.js +35 -34
- package/dist/plus/integrations/providers/github.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab.d.ts +6 -4
- package/dist/plus/integrations/providers/gitlab.js +32 -28
- 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 +15 -7
- package/dist/plus/integrations/providers/jira-server.js.map +1 -1
- package/dist/plus/integrations/providers/jira.d.ts +9 -0
- package/dist/plus/integrations/providers/jira.js +14 -2
- package/dist/plus/integrations/providers/jira.js.map +1 -1
- package/dist/plus/integrations/providers/linear.js +2 -2
- package/dist/plus/integrations/providers/models.d.ts +10 -1
- 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 +18 -3
- 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 +6 -6
- package/dist/plus/integrations/reads/broaden.js.map +1 -1
- package/dist/plus/integrations/reads/context.d.ts +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 +2 -1
- package/dist/plus/integrations/reads/drains.js +1 -1
- 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 +2 -2
- package/dist/plus/integrations/reads/hierarchy.js.map +1 -1
- package/dist/plus/integrations/reads/hierarchy.utils.js +1 -1
- package/dist/plus/integrations/reads/issueBatch.js +1 -1
- package/dist/plus/integrations/reads/issueTracker.js +2 -2
- package/dist/plus/integrations/reads/issues.js +2 -2
- 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 +110 -19
- 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/sweeps.js +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/results.d.ts +84 -6
- package/dist/plus/integrations/results.js +9 -2
- package/dist/plus/integrations/results.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/docs/integrations.md +263 -74
- package/docs/kepler-read-api-parity.md +19 -6
- package/package.json +1 -1
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { CancellationError } from "../../../utils/cancellation.js";
|
|
2
2
|
import { mapSettledBounded } from "../../../utils/promise.js";
|
|
3
3
|
import "../../../git/models/pullRequest.js";
|
|
4
|
-
import { toCollectionScopeFailure } from "../collectionMetadata.js";
|
|
5
4
|
import "../constants.js";
|
|
5
|
+
import { toCollectionScopeFailure } from "../collectionMetadata.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();
|
|
@@ -62,22 +122,56 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
62
122
|
username: user.username ?? void 0
|
|
63
123
|
} : void 0;
|
|
64
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* The profile request the account cache would otherwise answer; see `IntegrationBase.validateCredential`. No
|
|
127
|
+
* account proves nothing, since Azure DevOps Server's request answers every failure but a refusal that way.
|
|
128
|
+
*/
|
|
129
|
+
async validateCredential(session) {
|
|
130
|
+
if (await this._requestForCurrentUser(session) == null) throw new Error("Azure DevOps did not confirm the credential");
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Names a confirmed credential's refusal from the answers Azure DevOps gives, captured live (#5890):
|
|
134
|
+
* - `VS403463` in the explanation is a Conditional Access policy;
|
|
135
|
+
* - a typed `UnauthorizedRequestException` body is an organization or project the account has no access to;
|
|
136
|
+
* - a `401` to an OAuth token that explains nothing (sent as Basic), or only `TF400813` (sent as Bearer), is an
|
|
137
|
+
* organization whose "Third-party application access via OAuth" policy is off. It is the same answer an
|
|
138
|
+
* expired token gets, which is why this is only asked once the credential passed. The policy does not govern
|
|
139
|
+
* personal access tokens, so a PAT is never given it.
|
|
140
|
+
*
|
|
141
|
+
* Any other explanation is left unnamed, so the warning keeps Azure's own words rather than a guess.
|
|
142
|
+
*/
|
|
143
|
+
describeRefusal(session, refusal, scope) {
|
|
144
|
+
const code = /\b(?:TF|VS)\d{6}\b/.exec(refusal.detail ?? "")?.[0];
|
|
145
|
+
if (code === "VS403463") return {
|
|
146
|
+
reason: "conditional-access",
|
|
147
|
+
code
|
|
148
|
+
};
|
|
149
|
+
if (refusal.typeKey === "UnauthorizedRequestException") return {
|
|
150
|
+
reason: "access-denied",
|
|
151
|
+
...code != null ? { code } : {}
|
|
152
|
+
};
|
|
153
|
+
if (this.id !== "azureDevOps" || session.type !== "oauth" || refusal.status !== 401 || refusal.typeKey != null || refusal.detail != null && code !== "TF400813") return;
|
|
154
|
+
const org = scope.resourceId != null ? this._organizations?.get(this.discoveryKey(session))?.find((o) => o.id === scope.resourceId || o.name === scope.resourceId)?.name : void 0;
|
|
155
|
+
return {
|
|
156
|
+
reason: "oauth-app-not-allowed",
|
|
157
|
+
...code != null ? { code } : {},
|
|
158
|
+
...org != null ? { remedyUrl: `${this.apiBaseUrlFor(session)}/${encodeURIComponent(org)}/_settings/organizationPolicy` } : {}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
65
161
|
_organizations;
|
|
66
162
|
async getProviderResourcesForUser(session, force = false) {
|
|
67
163
|
this._organizations ??= /* @__PURE__ */ new Map();
|
|
68
|
-
const
|
|
69
|
-
if (this._organizations.get(
|
|
70
|
-
const api = await this.getProvidersApi();
|
|
164
|
+
const key = this.discoveryKey(session);
|
|
165
|
+
if (this._organizations.get(key) == null || force) {
|
|
71
166
|
const account = await this.getProviderCurrentAccount(session);
|
|
72
167
|
if (account?.id == null) return void 0;
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
this._organizations.set(accessToken, resources != null ? resources.map((r) => ({
|
|
168
|
+
const resources = await this.requestResourcesForUser(session, account.id);
|
|
169
|
+
this._organizations.set(key, resources != null ? resources.map((r) => ({
|
|
76
170
|
...r,
|
|
77
171
|
key: r.id
|
|
78
172
|
})) : void 0);
|
|
79
173
|
}
|
|
80
|
-
return this._organizations.get(
|
|
174
|
+
return this._organizations.get(key);
|
|
81
175
|
}
|
|
82
176
|
_projects;
|
|
83
177
|
/**
|
|
@@ -89,22 +183,22 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
89
183
|
*/
|
|
90
184
|
async getProviderProjectsForResources(session, resources, force = false, failures) {
|
|
91
185
|
this._projects ??= /* @__PURE__ */ new Map();
|
|
92
|
-
const
|
|
186
|
+
const discoveryKey = this.discoveryKey(session);
|
|
93
187
|
let resourcesWithoutProjects = [];
|
|
94
188
|
if (force) resourcesWithoutProjects = resources;
|
|
95
189
|
else for (const resource of resources) {
|
|
96
|
-
const resourceKey = `${
|
|
190
|
+
const resourceKey = `${discoveryKey}:${resource.id}`;
|
|
97
191
|
if (this._projects.get(resourceKey) == null) resourcesWithoutProjects.push(resource);
|
|
98
192
|
}
|
|
99
193
|
const allProjects = [];
|
|
100
194
|
let resultMetadata;
|
|
101
195
|
if (resourcesWithoutProjects.length > 0) {
|
|
102
196
|
const api = await this.getProvidersApi();
|
|
103
|
-
const { tokenWithInfo
|
|
197
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
104
198
|
(await Promise.allSettled(resourcesWithoutProjects.map(async (resource) => ({
|
|
105
199
|
resource,
|
|
106
200
|
result: await collectProviderPagedResult((cursor) => api.getAzureProjectsForResource(tokenWithInfo, resource.name, {
|
|
107
|
-
...
|
|
201
|
+
...this.getCollectionApiOptions(session, resource.name),
|
|
108
202
|
cursor
|
|
109
203
|
}), 20, {
|
|
110
204
|
providerId: this.id,
|
|
@@ -149,11 +243,11 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
149
243
|
allProjects.push(...projects);
|
|
150
244
|
return;
|
|
151
245
|
}
|
|
152
|
-
this._projects.set(`${
|
|
246
|
+
this._projects.set(`${discoveryKey}:${resource.id}`, projects);
|
|
153
247
|
});
|
|
154
248
|
}
|
|
155
249
|
const cachedProjects = resources.reduce((projects, resource) => {
|
|
156
|
-
const resourceProjects = this._projects.get(`${
|
|
250
|
+
const resourceProjects = this._projects.get(`${discoveryKey}:${resource.id}`);
|
|
157
251
|
if (resourceProjects != null) projects.push(...resourceProjects);
|
|
158
252
|
return projects;
|
|
159
253
|
}, []);
|
|
@@ -173,9 +267,9 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
173
267
|
const descriptors = /* @__PURE__ */ new Map();
|
|
174
268
|
if (projects.length === 0) return descriptors;
|
|
175
269
|
const api = await this.getProvidersApi();
|
|
176
|
-
const { tokenWithInfo
|
|
270
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
177
271
|
await Promise.all(projects.map(async (project) => {
|
|
178
|
-
const repos = (await api.getReposForAzureProject(tokenWithInfo, project.resourceName, project.name,
|
|
272
|
+
const repos = (await api.getReposForAzureProject(tokenWithInfo, project.resourceName, project.name, this.getCollectionApiOptions(session, project.resourceName)))?.values;
|
|
179
273
|
if (repos != null && repos.length > 0) descriptors.set(project.id, repos.map((r) => ({
|
|
180
274
|
id: r.id,
|
|
181
275
|
nodeId: r.graphQLId ?? void 0,
|
|
@@ -197,7 +291,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
197
291
|
id: o.id,
|
|
198
292
|
providerId: this.id,
|
|
199
293
|
name: o.name,
|
|
200
|
-
url: `${this.
|
|
294
|
+
url: `${this.collectionApiBaseUrl(session, o.name)}/${o.name}`
|
|
201
295
|
})) };
|
|
202
296
|
}
|
|
203
297
|
async getProviderProjectsForOrg(session, org) {
|
|
@@ -220,7 +314,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
220
314
|
providerId: this.id,
|
|
221
315
|
name: p.name,
|
|
222
316
|
org: p.resourceName,
|
|
223
|
-
url: `${this.
|
|
317
|
+
url: `${this.collectionApiBaseUrl(session, p.resourceName)}/${p.resourceName}/${p.name}`
|
|
224
318
|
})),
|
|
225
319
|
...projects.metadata != null ? { metadata: projects.metadata } : {}
|
|
226
320
|
};
|
|
@@ -234,7 +328,8 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
234
328
|
*/
|
|
235
329
|
async getProviderRepositoriesForOrg(session, org, options) {
|
|
236
330
|
const api = await this.getProvidersApi();
|
|
237
|
-
const { tokenWithInfo
|
|
331
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
332
|
+
const apiOptions = this.getCollectionApiOptions(session, org);
|
|
238
333
|
if (options?.project) return api.getReposForAzureProject(tokenWithInfo, org, options.project, {
|
|
239
334
|
...apiOptions,
|
|
240
335
|
cursor: options.cursor
|
|
@@ -276,7 +371,8 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
276
371
|
async mergeProviderPullRequest(session, pr, options) {
|
|
277
372
|
const api = await this.getProvidersApi();
|
|
278
373
|
if (pr.refs == null || pr.project == null) return false;
|
|
279
|
-
const { tokenWithInfo
|
|
374
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
375
|
+
const apiOptions = this.getCollectionApiOptions(session, pr.repository.owner);
|
|
280
376
|
try {
|
|
281
377
|
return await api.mergePullRequest(tokenWithInfo, pr, {
|
|
282
378
|
...options,
|
|
@@ -291,17 +387,17 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
291
387
|
this.ctx.hooks?.ui?.onError?.(`${ex.message}. Check branch policies, and ensure you have the necessary permissions to merge the pull request.`);
|
|
292
388
|
}
|
|
293
389
|
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.
|
|
390
|
+
return (await this.authenticationService.apis.azure)?.getAccountForCommit(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, rev, getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo), options);
|
|
295
391
|
}
|
|
296
392
|
async getProviderAccountForEmail(_session, _repo, _email, _options) {
|
|
297
393
|
return Promise.resolve(void 0);
|
|
298
394
|
}
|
|
299
395
|
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.
|
|
396
|
+
return (await this.authenticationService.apis.azure)?.getDefaultBranch(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, { baseUrl: getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo) }, cancellation);
|
|
301
397
|
}
|
|
302
398
|
async getProviderLinkedIssueOrPullRequest(session, repo, { id }, type) {
|
|
303
399
|
return (await this.authenticationService.apis.azure)?.getIssueOrPullRequest(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, id, {
|
|
304
|
-
baseUrl: getAzureRepositoryApiBaseUrl(this.
|
|
400
|
+
baseUrl: getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo),
|
|
305
401
|
type
|
|
306
402
|
});
|
|
307
403
|
}
|
|
@@ -313,13 +409,13 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
313
409
|
if (projects.values.length === 0) return void 0;
|
|
314
410
|
const matchingProject = projects.values.find((p) => p.resourceName === project.owner && p.name === project.name);
|
|
315
411
|
if (matchingProject == null) return void 0;
|
|
316
|
-
return (await this.authenticationService.apis.azure)?.getIssue(this, toTokenWithInfo(this.id, session), matchingProject, id, { baseUrl: this.
|
|
412
|
+
return (await this.authenticationService.apis.azure)?.getIssue(this, toTokenWithInfo(this.id, session), matchingProject, id, { baseUrl: this.collectionApiBaseUrl(session, matchingProject.resourceName) });
|
|
317
413
|
}
|
|
318
414
|
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.
|
|
415
|
+
return (await this.authenticationService.apis.azure)?.getPullRequestForBranch(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, branch, { baseUrl: getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo) });
|
|
320
416
|
}
|
|
321
417
|
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.
|
|
418
|
+
return (await this.authenticationService.apis.azure)?.getPullRequestForCommit(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, rev, getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo));
|
|
323
419
|
}
|
|
324
420
|
async getRepoInfo(repo) {
|
|
325
421
|
const identity = getAzureRepositoryIdentity(repo);
|
|
@@ -330,47 +426,53 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
330
426
|
const { tokenWithInfo, options } = this.getApiOptions(session);
|
|
331
427
|
return api.getRepo(tokenWithInfo, identity.resourceName, identity.repositoryName, identity.projectName, {
|
|
332
428
|
...options,
|
|
333
|
-
baseUrl: getAzureRepositoryApiBaseUrl(this.
|
|
429
|
+
baseUrl: getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo)
|
|
334
430
|
});
|
|
335
431
|
}
|
|
336
432
|
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.
|
|
433
|
+
return (await this.authenticationService.apis.azure)?.getRepositoryMetadata(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, { baseUrl: getAzureRepositoryApiBaseUrl(this.apiBaseUrlFor(session), repo) }, cancellation);
|
|
338
434
|
}
|
|
339
435
|
async searchProviderMyPullRequests(session, repos, _cancellation, options) {
|
|
340
436
|
const api = await this.getProvidersApi();
|
|
341
437
|
if (repos != null) return;
|
|
342
438
|
const states = toProviderPullRequestStates(options?.state);
|
|
343
|
-
|
|
344
|
-
if (user?.id == null) return void 0;
|
|
439
|
+
if ((await this.getProviderCurrentAccount(session))?.id == null) return void 0;
|
|
345
440
|
const orgs = await this.getProviderResourcesForUser(session);
|
|
346
441
|
if (orgs == null || orgs.length === 0) return void 0;
|
|
347
442
|
const projects = await this.getProviderProjectsForResources(session, orgs);
|
|
348
443
|
if (projects.values.length === 0) return void 0;
|
|
349
444
|
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
|
-
|
|
445
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
446
|
+
const assignedPrs = [];
|
|
447
|
+
const authoredPrs = [];
|
|
448
|
+
for (const org of uniqueAzureNames(projects.values.map((p) => p.resourceName))) {
|
|
449
|
+
const userId = await this.getFilterUserId(session, org);
|
|
450
|
+
if (userId == null) continue;
|
|
451
|
+
const projectInputs = projects.values.filter((p) => sameAzureName(p.resourceName, org)).map((p) => ({
|
|
452
|
+
namespace: p.resourceName,
|
|
453
|
+
project: p.name
|
|
454
|
+
}));
|
|
455
|
+
const orgOptions = this.getCollectionApiOptions(session, org);
|
|
456
|
+
const reads = [[{ assigneeLogins: [userId] }, assignedPrs], [{ authorLogin: userId }, authoredPrs]];
|
|
457
|
+
for (const [filter, into] of reads) {
|
|
458
|
+
const result = await api.getPullRequestsForAzureProjects(tokenWithInfo, projectInputs, {
|
|
459
|
+
...orgOptions,
|
|
460
|
+
...filter,
|
|
461
|
+
states
|
|
462
|
+
});
|
|
463
|
+
into.push(...result.values.map((pr) => this.fromAzureProviderPullRequest(pr, repoDescriptors, projects.values)));
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
const prsByIdentity = /* @__PURE__ */ new Map();
|
|
467
|
+
for (const pr of [...authoredPrs, ...assignedPrs]) {
|
|
468
|
+
const identity = `${pr.repository.owner}/${pr.repository.id || pr.repository.repo}#${pr.id}`;
|
|
469
|
+
if (!prsByIdentity.has(identity)) prsByIdentity.set(identity, pr);
|
|
470
|
+
}
|
|
471
|
+
return [...prsByIdentity.values()];
|
|
369
472
|
}
|
|
370
473
|
async getProviderMyPullRequestsForUser(session, options) {
|
|
371
474
|
const api = await this.getProvidersApi();
|
|
372
|
-
|
|
373
|
-
if (user?.id == null) return void 0;
|
|
475
|
+
if ((await this.getProviderCurrentAccount(session))?.id == null) return void 0;
|
|
374
476
|
const orgs = await this.getProviderResourcesForUser(session);
|
|
375
477
|
if (orgs == null || orgs.length === 0) return void 0;
|
|
376
478
|
const failures = [];
|
|
@@ -384,7 +486,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
384
486
|
},
|
|
385
487
|
...projects.metadata != null ? { metadata: projects.metadata } : {}
|
|
386
488
|
};
|
|
387
|
-
const { tokenWithInfo
|
|
489
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
388
490
|
const states = toProviderPullRequestStates(options?.state);
|
|
389
491
|
const maxPagesPerProject = 20;
|
|
390
492
|
let truncated = projects.metadata != null && projects.metadata.completeness !== "complete";
|
|
@@ -394,7 +496,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
394
496
|
let page;
|
|
395
497
|
for (let i = 0; i < maxPagesPerProject; i++) try {
|
|
396
498
|
const result = await api.getPullRequestsForAzureProject(tokenWithInfo, project, {
|
|
397
|
-
...
|
|
499
|
+
...this.getCollectionApiOptions(session, project.namespace),
|
|
398
500
|
...filter,
|
|
399
501
|
states,
|
|
400
502
|
page
|
|
@@ -436,6 +538,8 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
436
538
|
const requested = options?.filters?.length ? new Set(options.filters) : void 0;
|
|
437
539
|
const wantAuthored = requested == null || requested.has("author");
|
|
438
540
|
const wantReviewed = requested == null || requested.has("assignee") || requested.has("review-requested");
|
|
541
|
+
const userIds = /* @__PURE__ */ new Map();
|
|
542
|
+
for (const org of uniqueAzureNames(projects.values.map((p) => p.resourceName))) userIds.set(org.toLowerCase(), await this.getFilterUserId(session, org));
|
|
439
543
|
const outcomes = await Promise.all(projects.values.flatMap((p) => {
|
|
440
544
|
const project = {
|
|
441
545
|
namespace: p.resourceName,
|
|
@@ -446,9 +550,15 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
446
550
|
resourceId: p.resourceId,
|
|
447
551
|
projectId: p.name
|
|
448
552
|
};
|
|
553
|
+
const userId = userIds.get(p.resourceName.toLowerCase());
|
|
554
|
+
if (userId == null) {
|
|
555
|
+
failures.push(toCollectionScopeFailure(scope, /* @__PURE__ */ new Error("The current user could not be resolved here")));
|
|
556
|
+
truncated = true;
|
|
557
|
+
return [];
|
|
558
|
+
}
|
|
449
559
|
const drains = [];
|
|
450
|
-
if (wantAuthored) drains.push(drainProject(project, scope, { authorLogin:
|
|
451
|
-
if (wantReviewed) drains.push(drainProject(project, scope, { reviewerId:
|
|
560
|
+
if (wantAuthored) drains.push(drainProject(project, scope, { authorLogin: userId }));
|
|
561
|
+
if (wantReviewed) drains.push(drainProject(project, scope, { reviewerId: userId }));
|
|
452
562
|
return drains;
|
|
453
563
|
}));
|
|
454
564
|
const prsByIdentity = /* @__PURE__ */ new Map();
|
|
@@ -488,7 +598,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
488
598
|
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
599
|
if (repoInputs?.length === 0) return [];
|
|
490
600
|
const api = await this.getProvidersApi();
|
|
491
|
-
const { tokenWithInfo
|
|
601
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
492
602
|
const states = toProviderPullRequestStates(options?.include);
|
|
493
603
|
const searchScopes = repoInputs != null ? repoInputs.flatMap((repo) => repo.projectName == null ? [] : [{
|
|
494
604
|
project: {
|
|
@@ -511,7 +621,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
511
621
|
for (let i = 0; i < 20; i++) {
|
|
512
622
|
if (cancellation?.aborted) throw new CancellationError();
|
|
513
623
|
const result = await api.getPullRequestsForAzureProject(tokenWithInfo, scope.project, {
|
|
514
|
-
...
|
|
624
|
+
...this.getCollectionApiOptions(session, scope.project.namespace),
|
|
515
625
|
page,
|
|
516
626
|
repo: scope.repo,
|
|
517
627
|
states
|
|
@@ -571,10 +681,10 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
571
681
|
values: [],
|
|
572
682
|
truncated: false
|
|
573
683
|
};
|
|
574
|
-
const { tokenWithInfo
|
|
684
|
+
const { tokenWithInfo } = this.getApiOptions(session);
|
|
575
685
|
const drain = async (p, filter) => {
|
|
576
686
|
const result = await collectProviderPagedResult((cursor) => api.getIssuesForAzureProject(tokenWithInfo, p.resourceName, p.name, {
|
|
577
|
-
...
|
|
687
|
+
...this.getCollectionApiOptions(session, p.resourceName),
|
|
578
688
|
...filter,
|
|
579
689
|
cursor,
|
|
580
690
|
sort: searchOptions?.sort
|
|
@@ -623,10 +733,11 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
623
733
|
}
|
|
624
734
|
async providerOnConnect() {
|
|
625
735
|
if (this._session == null) return;
|
|
736
|
+
const discoveryKey = this.discoveryKey(this._session);
|
|
626
737
|
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:${
|
|
738
|
+
const storedAccount = this.ctx.storage.get(`azure:${discoveryKey}:account`);
|
|
739
|
+
const storedOrganizations = this.ctx.storage.get(`azure:${discoveryKey}:organizations`);
|
|
740
|
+
const storedProjects = this.ctx.storage.get(`azure:${discoveryKey}:projects`);
|
|
630
741
|
let account = storedAccount?.data ? {
|
|
631
742
|
...storedAccount.data,
|
|
632
743
|
provider: this
|
|
@@ -645,7 +756,7 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
645
756
|
account = await this.getProviderCurrentAccount(this._session);
|
|
646
757
|
if (account != null) {
|
|
647
758
|
await this.ctx.storage.deleteWithPrefix("azure");
|
|
648
|
-
await this.ctx.storage.store(`azure:${
|
|
759
|
+
await this.ctx.storage.store(`azure:${discoveryKey}:account`, {
|
|
649
760
|
v: 1,
|
|
650
761
|
timestamp: Date.now(),
|
|
651
762
|
data: {
|
|
@@ -659,29 +770,29 @@ var AzureDevOpsIntegrationBase = class extends GitHostIntegration {
|
|
|
659
770
|
}
|
|
660
771
|
}
|
|
661
772
|
this._accounts ??= /* @__PURE__ */ new Map();
|
|
662
|
-
this._accounts.set(
|
|
773
|
+
this._accounts.set(discoveryKey, account);
|
|
663
774
|
if (storedOrganizations == null) {
|
|
664
775
|
organizations = await this.getProviderResourcesForUser(this._session, true);
|
|
665
|
-
await this.ctx.storage.store(`azure:${
|
|
776
|
+
await this.ctx.storage.store(`azure:${discoveryKey}:organizations`, {
|
|
666
777
|
v: 1,
|
|
667
778
|
timestamp: Date.now(),
|
|
668
779
|
data: organizations
|
|
669
780
|
});
|
|
670
781
|
}
|
|
671
782
|
this._organizations ??= /* @__PURE__ */ new Map();
|
|
672
|
-
this._organizations.set(
|
|
783
|
+
this._organizations.set(discoveryKey, organizations);
|
|
673
784
|
if (projects == null && organizations?.length) {
|
|
674
785
|
projects = await this.getProviderProjectsForResources(this._session, organizations);
|
|
675
|
-
if (projects != null && canHydrateStoredProjects(projects.metadata)) await this.ctx.storage.store(`azure:${
|
|
786
|
+
if (projects != null && canHydrateStoredProjects(projects.metadata)) await this.ctx.storage.store(`azure:${discoveryKey}:projects`, {
|
|
676
787
|
v: 2,
|
|
677
788
|
timestamp: Date.now(),
|
|
678
789
|
data: projects
|
|
679
790
|
});
|
|
680
|
-
else await this.ctx.storage.delete(`azure:${
|
|
791
|
+
else await this.ctx.storage.delete(`azure:${discoveryKey}:projects`);
|
|
681
792
|
}
|
|
682
793
|
this._projects ??= /* @__PURE__ */ new Map();
|
|
683
794
|
if (projects != null && canHydrateStoredProjects(projects.metadata)) for (const project of projects.values) {
|
|
684
|
-
const projectKey = `${
|
|
795
|
+
const projectKey = `${discoveryKey}:${project.resourceId}`;
|
|
685
796
|
const projects = this._projects.get(projectKey);
|
|
686
797
|
if (projects == null) this._projects.set(projectKey, [project]);
|
|
687
798
|
else if (!projects.some((p) => p.id === project.id)) projects.push(project);
|
|
@@ -729,53 +840,11 @@ var AzureDevOpsIntegration = class extends AzureDevOpsIntegrationBase {
|
|
|
729
840
|
get domain() {
|
|
730
841
|
return cloudMetadata.domain;
|
|
731
842
|
}
|
|
732
|
-
|
|
843
|
+
apiBaseUrlFor(_session) {
|
|
733
844
|
return "https://dev.azure.com";
|
|
734
845
|
}
|
|
735
846
|
};
|
|
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
847
|
//#endregion
|
|
779
|
-
export { AzureDevOpsIntegration, AzureDevOpsIntegrationBase,
|
|
848
|
+
export { AzureDevOpsIntegration, AzureDevOpsIntegrationBase, getAzureRepositoryApiBaseUrl, getAzureRepositoryIdentity, sameAzureName, uniqueAzureNames };
|
|
780
849
|
|
|
781
850
|
//# sourceMappingURL=azureDevOps.js.map
|