@gitkraken/core-gitlens 0.9.4 → 0.9.5
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 +22 -1
- package/dist/git/models/issue.d.ts +25 -2
- package/dist/git/models/issue.js +3 -1
- package/dist/git/models/issue.js.map +1 -1
- package/dist/git/models/pullRequest.d.ts +55 -5
- package/dist/git/models/pullRequest.js +5 -1
- package/dist/git/models/pullRequest.js.map +1 -1
- package/dist/git/utils/issue.utils.d.ts +4 -0
- package/dist/git/utils/issue.utils.js +4 -0
- package/dist/git/utils/issue.utils.js.map +1 -1
- package/dist/git/utils/pullRequest.utils.d.ts +4 -0
- package/dist/git/utils/pullRequest.utils.js +8 -0
- package/dist/git/utils/pullRequest.utils.js.map +1 -1
- package/dist/plus/git-github/api/github.d.ts +64 -4
- package/dist/plus/git-github/api/github.js +232 -15
- package/dist/plus/git-github/api/github.js.map +1 -1
- package/dist/plus/git-github/models.d.ts +48 -6
- package/dist/plus/git-github/models.js +11 -10
- package/dist/plus/git-github/models.js.map +1 -1
- package/dist/plus/integrations/fieldPresence.d.ts +75 -0
- package/dist/plus/integrations/fieldPresence.js +381 -0
- package/dist/plus/integrations/fieldPresence.js.map +1 -0
- package/dist/plus/integrations/index.d.ts +6 -4
- package/dist/plus/integrations/index.js +2 -1
- package/dist/plus/integrations/index.js.map +1 -1
- package/dist/plus/integrations/integrationService.d.ts +7 -3
- package/dist/plus/integrations/integrationService.js.map +1 -1
- package/dist/plus/integrations/manager.d.ts +56 -6
- package/dist/plus/integrations/models/gitHostIntegration.d.ts +103 -9
- package/dist/plus/integrations/models/gitHostIntegration.js +116 -5
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
- package/dist/plus/integrations/models/integration.d.ts +91 -4
- package/dist/plus/integrations/models/integration.js +56 -7
- package/dist/plus/integrations/models/integration.js.map +1 -1
- package/dist/plus/integrations/models/issuesIntegration.d.ts +44 -3
- package/dist/plus/integrations/models/issuesIntegration.js +51 -1
- package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
- package/dist/plus/integrations/providers/azure/azure.js +3 -3
- package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
- package/dist/plus/integrations/providers/azure/models.d.ts +36 -4
- package/dist/plus/integrations/providers/azure/models.js +118 -8
- package/dist/plus/integrations/providers/azure/models.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOps.d.ts +102 -5
- package/dist/plus/integrations/providers/azureDevOps.js +264 -45
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOpsServer.d.ts +30 -6
- package/dist/plus/integrations/providers/azureDevOpsServer.js +82 -21
- package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts +21 -1
- package/dist/plus/integrations/providers/bitbucket/bitbucket.js +74 -10
- package/dist/plus/integrations/providers/bitbucket/bitbucket.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket/models.d.ts +40 -3
- package/dist/plus/integrations/providers/bitbucket/models.js +30 -7
- package/dist/plus/integrations/providers/bitbucket/models.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server/models.d.ts +2 -6
- package/dist/plus/integrations/providers/bitbucket-server/models.js +1 -3
- package/dist/plus/integrations/providers/bitbucket-server/models.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.d.ts +3 -1
- package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js +4 -1
- package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server.d.ts +2 -2
- package/dist/plus/integrations/providers/bitbucket-server.js +7 -5
- package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket.d.ts +22 -2
- package/dist/plus/integrations/providers/bitbucket.js +29 -6
- package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
- package/dist/plus/integrations/providers/github.d.ts +40 -3
- package/dist/plus/integrations/providers/github.js +133 -11
- package/dist/plus/integrations/providers/github.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab/gitlab.d.ts +34 -1
- package/dist/plus/integrations/providers/gitlab/gitlab.js +118 -4
- package/dist/plus/integrations/providers/gitlab/gitlab.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab/models.d.ts +70 -5
- package/dist/plus/integrations/providers/gitlab/models.js +106 -13
- package/dist/plus/integrations/providers/gitlab/models.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab.d.ts +31 -2
- package/dist/plus/integrations/providers/gitlab.js +48 -8
- 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 +1 -0
- package/dist/plus/integrations/providers/jira-server.js +9 -6
- package/dist/plus/integrations/providers/jira-server.js.map +1 -1
- package/dist/plus/integrations/providers/jira.d.ts +20 -1
- package/dist/plus/integrations/providers/jira.js +101 -6
- package/dist/plus/integrations/providers/jira.js.map +1 -1
- package/dist/plus/integrations/providers/jiraIssueByKey.d.ts +79 -0
- package/dist/plus/integrations/providers/jiraIssueByKey.js +58 -7
- package/dist/plus/integrations/providers/jiraIssueByKey.js.map +1 -1
- package/dist/plus/integrations/providers/linear.d.ts +19 -1
- package/dist/plus/integrations/providers/linear.js +97 -5
- package/dist/plus/integrations/providers/linear.js.map +1 -1
- package/dist/plus/integrations/providers/linearIssuesEtag.d.ts +42 -0
- package/dist/plus/integrations/providers/linearIssuesEtag.js +94 -0
- package/dist/plus/integrations/providers/linearIssuesEtag.js.map +1 -0
- package/dist/plus/integrations/providers/models.d.ts +51 -7
- package/dist/plus/integrations/providers/models.js +45 -16
- package/dist/plus/integrations/providers/models.js.map +1 -1
- package/dist/plus/integrations/providers/providerErrors.js +8 -1
- package/dist/plus/integrations/providers/providerErrors.js.map +1 -1
- package/dist/plus/integrations/providers/providersApi.d.ts +62 -3
- package/dist/plus/integrations/providers/providersApi.js +145 -4
- package/dist/plus/integrations/providers/providersApi.js.map +1 -1
- package/dist/plus/integrations/providers/pullRequestReviews.d.ts +13 -0
- package/dist/plus/integrations/providers/pullRequestReviews.js +30 -6
- package/dist/plus/integrations/providers/pullRequestReviews.js.map +1 -1
- package/dist/plus/integrations/providers/trello.js +10 -7
- package/dist/plus/integrations/providers/trello.js.map +1 -1
- package/dist/plus/integrations/providers/utils/providerPaging.d.ts +11 -0
- package/dist/plus/integrations/providers/utils/providerPaging.js +47 -1
- package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
- package/dist/plus/integrations/providers/utils.d.ts +1 -1
- package/dist/plus/integrations/reads/batchEtags.d.ts +69 -0
- package/dist/plus/integrations/reads/batchEtags.js +114 -0
- package/dist/plus/integrations/reads/batchEtags.js.map +1 -0
- package/dist/plus/integrations/reads/counts.js +2 -2
- package/dist/plus/integrations/reads/counts.js.map +1 -1
- package/dist/plus/integrations/reads/currentAccount.js +2 -2
- package/dist/plus/integrations/reads/currentAccount.js.map +1 -1
- package/dist/plus/integrations/reads/drains.d.ts +13 -3
- package/dist/plus/integrations/reads/drains.js +29 -5
- package/dist/plus/integrations/reads/drains.js.map +1 -1
- package/dist/plus/integrations/reads/etag.d.ts +26 -0
- package/dist/plus/integrations/reads/etag.js +108 -0
- package/dist/plus/integrations/reads/etag.js.map +1 -0
- package/dist/plus/integrations/reads/hierarchy.js +3 -3
- package/dist/plus/integrations/reads/hierarchy.js.map +1 -1
- package/dist/plus/integrations/reads/issueBatch.d.ts +47 -16
- package/dist/plus/integrations/reads/issueBatch.js +55 -87
- package/dist/plus/integrations/reads/issueBatch.js.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.d.ts +1 -1
- package/dist/plus/integrations/reads/issueTracker.js +4 -4
- package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
- package/dist/plus/integrations/reads/issues.d.ts +1 -1
- package/dist/plus/integrations/reads/issues.js +4 -4
- package/dist/plus/integrations/reads/issues.js.map +1 -1
- package/dist/plus/integrations/reads/pullRequestBatch.d.ts +44 -6
- package/dist/plus/integrations/reads/pullRequestBatch.js +31 -34
- package/dist/plus/integrations/reads/pullRequestBatch.js.map +1 -1
- package/dist/plus/integrations/reads/pullRequestBranches.d.ts +5 -2
- package/dist/plus/integrations/reads/pullRequestBranches.js +4 -3
- package/dist/plus/integrations/reads/pullRequestBranches.js.map +1 -1
- package/dist/plus/integrations/reads/pullRequests.js +8 -4
- package/dist/plus/integrations/reads/pullRequests.js.map +1 -1
- package/dist/plus/integrations/reads/sweeps.js +8 -4
- package/dist/plus/integrations/reads/sweeps.js.map +1 -1
- package/dist/plus/integrations/reads/warnings.d.ts +23 -8
- package/dist/plus/integrations/reads/warnings.js +43 -19
- package/dist/plus/integrations/reads/warnings.js.map +1 -1
- package/dist/plus/integrations/results.d.ts +12 -4
- package/dist/plus/integrations/results.js +2 -0
- package/dist/plus/integrations/results.js.map +1 -1
- package/docs/integrations.md +385 -23
- package/docs/kepler-read-api-parity.md +16 -2
- package/package.json +1 -1
|
@@ -33,27 +33,27 @@ var BitbucketApi = class {
|
|
|
33
33
|
const scope = getScopedLogger();
|
|
34
34
|
const response = await this.request(provider, token, baseUrl, `repositories/${owner}/${repo}/pullrequests?q=source.branch.name="${branch}"&fields=%2Bvalues.reviewers,%2Bvalues.participants`, { method: "GET" }, scope);
|
|
35
35
|
if (!response?.values?.length) return;
|
|
36
|
-
return fromBitbucketPullRequest(response.values[0], provider);
|
|
36
|
+
return fromBitbucketPullRequest(response.values[0], provider, { projection: "point" });
|
|
37
37
|
}
|
|
38
38
|
async getServerPullRequestForBranch(provider, token, owner, repo, branch, baseUrl) {
|
|
39
39
|
const scope = getScopedLogger();
|
|
40
40
|
const response = await this.request(provider, token, baseUrl, `projects/${owner}/repos/${repo}/pull-requests?at=refs/heads/${branch}&direction=OUTGOING&state=ALL`, { method: "GET" }, scope);
|
|
41
41
|
if (!response?.values?.length) return;
|
|
42
42
|
const providersPr = normalizeBitbucketServerPullRequest(response.values[0]);
|
|
43
|
-
return fromProviderPullRequest(providersPr, provider);
|
|
43
|
+
return fromProviderPullRequest(providersPr, provider, { projection: "point" });
|
|
44
44
|
}
|
|
45
45
|
async getUsersIssuesForRepo(provider, token, userUuid, owner, repo, baseUrl) {
|
|
46
46
|
const scope = getScopedLogger();
|
|
47
47
|
const query = encodeURIComponent(`assignee.uuid="${userUuid}" OR reporter.uuid="${userUuid}"`);
|
|
48
48
|
const response = await this.request(provider, token, baseUrl, `repositories/${owner}/${repo}/issues?q=${query}`, { method: "GET" }, scope);
|
|
49
49
|
if (!response?.values?.length) return;
|
|
50
|
-
return response.values.map((issue) => fromBitbucketIssue(issue, provider));
|
|
50
|
+
return response.values.map((issue) => fromBitbucketIssue(issue, provider, "account"));
|
|
51
51
|
}
|
|
52
52
|
async getIssue(provider, token, owner, repo, id, baseUrl) {
|
|
53
53
|
const scope = getScopedLogger();
|
|
54
54
|
try {
|
|
55
55
|
const response = await this.request(provider, token, baseUrl, `repositories/${owner}/${repo}/issues/${id}`, { method: "GET" }, scope);
|
|
56
|
-
if (response) return fromBitbucketIssue(response, provider);
|
|
56
|
+
if (response) return fromBitbucketIssue(response, provider, "point");
|
|
57
57
|
return;
|
|
58
58
|
} catch (ex) {
|
|
59
59
|
scope?.error(ex);
|
|
@@ -106,13 +106,61 @@ var BitbucketApi = class {
|
|
|
106
106
|
try {
|
|
107
107
|
const pr = await this.request(provider, token, baseUrl, `repositories/${owner}/${repo}/pullrequests/${id}?fields=%2Bvalues.reviewers,%2Bvalues.participants`, { method: "GET" }, scope, void 0, options?.deferFailure);
|
|
108
108
|
if (pr == null) throw new Error(`Bitbucket returned no pull request for ${owner}/${repo}#${id}`);
|
|
109
|
-
return fromBitbucketPullRequest(pr, provider, {
|
|
109
|
+
return fromBitbucketPullRequest(pr, provider, {
|
|
110
|
+
currentAccount: options?.currentAccount,
|
|
111
|
+
projection: options?.projection
|
|
112
|
+
});
|
|
110
113
|
} catch (ex) {
|
|
111
114
|
if (isNotFoundResponse(ex)) return void 0;
|
|
112
115
|
throw ex;
|
|
113
116
|
}
|
|
114
117
|
}
|
|
115
118
|
/**
|
|
119
|
+
* The change state of pull requests `ids` in `owner/repo` — the cheap check behind the batch read's etags — in ONE
|
|
120
|
+
* request for up to {@link bitbucketEtagFieldsMaxIds} ids, selecting only what {@link getPullRequest}'s row reads
|
|
121
|
+
* into its etag (plus the participants and reviewers for the `reviewDecision` include). One entry per input id, in
|
|
122
|
+
* order.
|
|
123
|
+
*
|
|
124
|
+
* Strict like {@link getPullRequest}: `undefined` is a PROVEN ABSENCE, for an id missing from a complete page, or
|
|
125
|
+
* for every id when the repository is a 404, as each id's own read would be. A page with more (`next`) and every
|
|
126
|
+
* other failure throw. Every state is asked for, since the list answers only open pull requests by default.
|
|
127
|
+
*/
|
|
128
|
+
async getPullRequestsEtagFields(provider, token, owner, repo, ids, baseUrl, options, cancellation) {
|
|
129
|
+
const scope = getScopedLogger();
|
|
130
|
+
if (!ids.length) return [];
|
|
131
|
+
if (ids.length > 50) throw new Error(`Cannot read more than 50 Bitbucket pull requests in one request`);
|
|
132
|
+
const fields = [
|
|
133
|
+
"values.id",
|
|
134
|
+
"values.state",
|
|
135
|
+
"values.draft",
|
|
136
|
+
"values.updated_on",
|
|
137
|
+
"values.source.commit.hash",
|
|
138
|
+
"next"
|
|
139
|
+
];
|
|
140
|
+
if (options.etagIncludes.includes("reviewDecision")) fields.push("values.participants.approved", "values.participants.state", "values.participants.participated_on", "values.reviewers.uuid");
|
|
141
|
+
const params = new URLSearchParams({
|
|
142
|
+
q: `id IN (${ids.join(",")})`,
|
|
143
|
+
fields: fields.join(","),
|
|
144
|
+
pagelen: String(ids.length)
|
|
145
|
+
});
|
|
146
|
+
for (const state of [
|
|
147
|
+
"OPEN",
|
|
148
|
+
"MERGED",
|
|
149
|
+
"DECLINED",
|
|
150
|
+
"SUPERSEDED"
|
|
151
|
+
]) params.append("state", state);
|
|
152
|
+
try {
|
|
153
|
+
const response = await this.request(provider, token, baseUrl, `repositories/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pullrequests?${params.toString()}`, { method: "GET" }, scope, cancellation, options.deferFailure);
|
|
154
|
+
if (response?.values == null) throw new Error(`Bitbucket returned no pull requests for ${owner}/${repo}`);
|
|
155
|
+
if (response.next != null) throw new Error(`Bitbucket returned a partial page of ${owner}/${repo}`);
|
|
156
|
+
const byId = new Map(response.values.map((pr) => [pr.id, pr]));
|
|
157
|
+
return ids.map((id) => byId.get(id));
|
|
158
|
+
} catch (ex) {
|
|
159
|
+
if (isNotFoundResponse(ex)) return ids.map(() => void 0);
|
|
160
|
+
throw ex;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
116
164
|
* A Bitbucket Data Center pull request by id. Strict, unlike {@link getServerPullRequestById}: `undefined` means
|
|
117
165
|
* a 404, and every other failure throws, so the answer can be cached as a proven absence.
|
|
118
166
|
*/
|
|
@@ -121,7 +169,10 @@ var BitbucketApi = class {
|
|
|
121
169
|
try {
|
|
122
170
|
const pr = await this.request(provider, token, baseUrl, `projects/${owner}/repos/${repo}/pull-requests/${id}`, { method: "GET" }, scope, void 0, options?.deferFailure);
|
|
123
171
|
if (pr == null) throw new Error(`Bitbucket returned no pull request for ${owner}/${repo}#${id}`);
|
|
124
|
-
return fromProviderPullRequest(normalizeBitbucketServerPullRequest(pr), provider, {
|
|
172
|
+
return fromProviderPullRequest(normalizeBitbucketServerPullRequest(pr), provider, {
|
|
173
|
+
currentAccount: options?.currentAccount,
|
|
174
|
+
projection: options?.projection
|
|
175
|
+
});
|
|
125
176
|
} catch (ex) {
|
|
126
177
|
if (isNotFoundResponse(ex)) return void 0;
|
|
127
178
|
throw ex;
|
|
@@ -156,7 +207,10 @@ var BitbucketApi = class {
|
|
|
156
207
|
return source.uuid !== pr.destination.repository.uuid && equalsIgnoreCase(source.full_name.split("/")[0], headOwner);
|
|
157
208
|
},
|
|
158
209
|
updatedAt: (pr) => Date.parse(pr.updated_on),
|
|
159
|
-
map: (pr) => fromBitbucketPullRequest(pr, provider, {
|
|
210
|
+
map: (pr) => fromBitbucketPullRequest(pr, provider, {
|
|
211
|
+
currentAccount: options.currentAccount,
|
|
212
|
+
projection: "batch"
|
|
213
|
+
}),
|
|
160
214
|
limit: options.limit,
|
|
161
215
|
more: response.next != null
|
|
162
216
|
});
|
|
@@ -196,7 +250,10 @@ var BitbucketApi = class {
|
|
|
196
250
|
const { values, truncated } = selectBranchPullRequests(response.values, {
|
|
197
251
|
matchesHead: (pr) => pr.fromRef.id === ref && pr.fromRef.repository.id === pr.toRef.repository.id,
|
|
198
252
|
updatedAt: (pr) => pr.updatedDate,
|
|
199
|
-
map: (pr) => fromProviderPullRequest(normalizeBitbucketServerPullRequest(pr), provider, {
|
|
253
|
+
map: (pr) => fromProviderPullRequest(normalizeBitbucketServerPullRequest(pr), provider, {
|
|
254
|
+
currentAccount: options.currentAccount,
|
|
255
|
+
projection: "batch"
|
|
256
|
+
}),
|
|
200
257
|
limit: options.limit,
|
|
201
258
|
more: response.isLastPage !== true
|
|
202
259
|
});
|
|
@@ -282,7 +339,7 @@ var BitbucketApi = class {
|
|
|
282
339
|
const prResponse = (await this.request(provider, token, baseUrl, `projects/${owner}/repos/${repo}/commits/${rev}/pull-requests`, { method: "GET" }, scope, cancellation))?.values?.reduce((acc, pr) => !acc || pr.updatedDate > acc.updatedDate ? pr : acc, void 0);
|
|
283
340
|
if (!prResponse) return void 0;
|
|
284
341
|
const providersPr = normalizeBitbucketServerPullRequest(prResponse);
|
|
285
|
-
return fromProviderPullRequest(providersPr, provider);
|
|
342
|
+
return fromProviderPullRequest(providersPr, provider, { projection: "point" });
|
|
286
343
|
} catch (ex) {
|
|
287
344
|
scope?.error(ex);
|
|
288
345
|
return;
|
|
@@ -302,7 +359,7 @@ var BitbucketApi = class {
|
|
|
302
359
|
].join(","));
|
|
303
360
|
const pr = (await this.request(provider, token, baseUrl, `repositories/${owner}/${repo}/commit/${rev}/pullrequests?fields=${fieldsParam}`, { method: "GET" }, scope, cancellation))?.values?.reduce((acc, pr) => !acc || pr.updated_on > acc.updated_on ? pr : acc, void 0);
|
|
304
361
|
if (!pr) return void 0;
|
|
305
|
-
return fromBitbucketPullRequest(pr, provider);
|
|
362
|
+
return fromBitbucketPullRequest(pr, provider, { projection: "point" });
|
|
306
363
|
} catch (ex) {
|
|
307
364
|
if (ex.original instanceof ProviderFetchError) {
|
|
308
365
|
if ((await ex.original.response.json())?.error === "Invalid or unknown installation") {
|
|
@@ -477,6 +534,13 @@ __decorate([trace({ args: (provider, token, owner, repo, id, baseUrl) => ({
|
|
|
477
534
|
id,
|
|
478
535
|
baseUrl
|
|
479
536
|
}) })], BitbucketApi.prototype, "getPullRequest", null);
|
|
537
|
+
__decorate([trace({ args: (provider, token, owner, repo, ids) => ({
|
|
538
|
+
provider: provider.name,
|
|
539
|
+
token: `<token:${token.microHash}>`,
|
|
540
|
+
owner,
|
|
541
|
+
repo,
|
|
542
|
+
ids: ids.length
|
|
543
|
+
}) })], BitbucketApi.prototype, "getPullRequestsEtagFields", null);
|
|
480
544
|
__decorate([trace({ args: (provider, token, owner, repo, id, baseUrl) => ({
|
|
481
545
|
provider: provider.name,
|
|
482
546
|
token: `<token:${token.microHash}>`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bitbucket.js","names":["Logger"],"sources":["../../../../../../plus/integrations/src/providers/bitbucket/bitbucket.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport { reportRequestFailure } from '@gitlens/git/errors.js';\nimport type { Account, CommitAuthor, UnidentifiedAuthor } from '@gitlens/git/models/author.js';\nimport type { DefaultBranch } from '@gitlens/git/models/defaultBranch.js';\nimport type { Issue } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequest, IssueOrPullRequestType } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type { PullRequest } from '@gitlens/git/models/pullRequest.js';\nimport type { Provider } from '@gitlens/git/models/remoteProvider.js';\nimport type { RepositoryMetadata } from '@gitlens/git/models/repositoryMetadata.js';\nimport { CancellationError, isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { trace } from '@gitlens/utils/decorators/log.js';\nimport type { Disposable } from '@gitlens/utils/disposable.js';\nimport { Logger } from '@gitlens/utils/logger.js';\nimport type { ScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { maybeStopWatch } from '@gitlens/utils/stopwatch.js';\nimport { equalsIgnoreCase } from '@gitlens/utils/string.js';\nimport type { TokenWithInfo } from '../../authentication/models.js';\nimport type { IntegrationServiceContext } from '../../context.js';\nimport {\n\tAuthenticationError,\n\tAuthenticationErrorReason,\n\tisRateLimitResponse,\n\tProviderFetchError,\n\tRequestClientError,\n\tRequestNotFoundError,\n\ttoRateLimitError,\n} from '../../errors.js';\nimport type { ProviderApiConfig } from '../apiConfig.js';\nimport { baseProviderApiConfig } from '../apiConfig.js';\nimport type { BitbucketServerCommit, BitbucketServerPullRequest } from '../bitbucket-server/models.js';\nimport { normalizeBitbucketServerPullRequest } from '../bitbucket-server/models.js';\nimport { fromProviderPullRequest } from '../models.js';\nimport { selectBranchPullRequests } from '../utils/providerPaging.js';\nimport type { BitbucketCommit, BitbucketIssue, BitbucketPullRequest, BitbucketRepository } from './models.js';\nimport {\n\tbitbucketIssueStateToState,\n\tfromBitbucketIssue,\n\tfromBitbucketPullRequest,\n\tparseRawBitbucketAuthor,\n} from './models.js';\n\n/** `handleRequestError` maps 410 and 422 to the same error as a 404, but only a 404 proves the resource absent. */\nfunction isNotFoundResponse(ex: unknown): boolean {\n\treturn RequestNotFoundError.is(ex) && ex.original instanceof ProviderFetchError && ex.original.status === 404;\n}\n\nexport class BitbucketApi implements Disposable {\n\tprivate readonly _disposable: Disposable | undefined;\n\n\tconstructor(private readonly config: ProviderApiConfig) {\n\t\tthis._disposable = config.onConfigChanged?.(() => this.resetCaches());\n\t}\n\n\tdispose(): void {\n\t\tthis._disposable?.dispose();\n\t}\n\n\tprivate resetCaches(): void {}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getPullRequestForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst response = await this.request<{\n\t\t\tvalues: BitbucketPullRequest[];\n\t\t\tpagelen: number;\n\t\t\tsize: number;\n\t\t\tpage: number;\n\t\t}>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`repositories/${owner}/${repo}/pullrequests?q=source.branch.name=\"${branch}\"&fields=%2Bvalues.reviewers,%2Bvalues.participants`,\n\t\t\t{\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t\tscope,\n\t\t);\n\n\t\tif (!response?.values?.length) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn fromBitbucketPullRequest(response.values[0], provider);\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequestForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst response = await this.request<{\n\t\t\tvalues: BitbucketServerPullRequest[];\n\t\t\tpagelen: number;\n\t\t\tsize: number;\n\t\t\tpage: number;\n\t\t}>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`projects/${owner}/repos/${repo}/pull-requests?at=refs/heads/${branch}&direction=OUTGOING&state=ALL`,\n\t\t\t{\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t\tscope,\n\t\t);\n\n\t\tif (!response?.values?.length) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst providersPr = normalizeBitbucketServerPullRequest(response.values[0]);\n\t\tconst gitlensPr = fromProviderPullRequest(providersPr, provider);\n\t\treturn gitlensPr;\n\t}\n\n\t@trace({\n\t\targs: (provider, token, userUuid, owner, repo, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\tuserUuid: userUuid,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getUsersIssuesForRepo(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\tuserUuid: string,\n\t\towner: string,\n\t\trepo: string,\n\t\tbaseUrl: string,\n\t): Promise<Issue[] | undefined> {\n\t\tconst scope = getScopedLogger();\n\t\tconst query = encodeURIComponent(`assignee.uuid=\"${userUuid}\" OR reporter.uuid=\"${userUuid}\"`);\n\n\t\tconst response = await this.request<{\n\t\t\tvalues: BitbucketIssue[];\n\t\t\tpagelen: number;\n\t\t\tsize: number;\n\t\t\tpage: number;\n\t\t}>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`repositories/${owner}/${repo}/issues?q=${query}`,\n\t\t\t{\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t\tscope,\n\t\t);\n\n\t\tif (!response?.values?.length) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn response.values.map(issue => fromBitbucketIssue(issue, provider));\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getIssue(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t): Promise<Issue | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.request<BitbucketIssue>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/issues/${id}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t);\n\n\t\t\tif (response) {\n\t\t\t\treturn fromBitbucketIssue(response, provider);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getIssueOrPullRequest(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t\toptions?: {\n\t\t\ttype?: IssueOrPullRequestType;\n\t\t},\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif (options?.type === undefined || options?.type === 'pullrequest') {\n\t\t\ttry {\n\t\t\t\tconst pr = await this.getPullRequest(provider, token, owner, repo, id, baseUrl);\n\t\t\t\tif (pr != null) return pr;\n\t\t\t} catch (ex) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\n\t\tif (options?.type === undefined || options?.type === 'issue') {\n\t\t\ttry {\n\t\t\t\tconst issueResponse = await this.request<BitbucketIssue>(\n\t\t\t\t\tprovider,\n\t\t\t\t\ttoken,\n\t\t\t\t\tbaseUrl,\n\t\t\t\t\t`repositories/${owner}/${repo}/issues/${id}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\t},\n\t\t\t\t\tscope,\n\t\t\t\t);\n\n\t\t\t\tif (issueResponse) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: issueResponse.id.toString(),\n\t\t\t\t\t\ttype: 'issue',\n\t\t\t\t\t\tnodeId: issueResponse.id.toString(),\n\t\t\t\t\t\tprovider: provider,\n\t\t\t\t\t\tcreatedDate: new Date(issueResponse.created_on),\n\t\t\t\t\t\tupdatedDate: new Date(issueResponse.updated_on),\n\t\t\t\t\t\tstate: bitbucketIssueStateToState(issueResponse.state),\n\t\t\t\t\t\tclosed: issueResponse.state === 'closed',\n\t\t\t\t\t\ttitle: issueResponse.title,\n\t\t\t\t\t\turl: issueResponse.links.html.href,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} catch (ex) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequestById(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\treturn await this.getServerPullRequest(provider, token, owner, repo, id, baseUrl);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * A Bitbucket Cloud pull request by id. Strict, unlike {@link getIssueOrPullRequest}: `undefined` means a 404,\n\t * and every other failure throws, so the answer can be cached as a proven absence.\n\t */\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getPullRequest(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t\toptions?: { currentAccount?: { id: string; username?: string }; deferFailure?: boolean },\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst pr = await this.request<BitbucketPullRequest>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/pullrequests/${id}?fields=%2Bvalues.reviewers,%2Bvalues.participants`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tundefined,\n\t\t\t\toptions?.deferFailure,\n\t\t\t);\n\t\t\tif (pr == null) throw new Error(`Bitbucket returned no pull request for ${owner}/${repo}#${id}`);\n\n\t\t\treturn fromBitbucketPullRequest(pr, provider, { currentAccount: options?.currentAccount });\n\t\t} catch (ex) {\n\t\t\tif (isNotFoundResponse(ex)) return undefined;\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/**\n\t * A Bitbucket Data Center pull request by id. Strict, unlike {@link getServerPullRequestById}: `undefined` means\n\t * a 404, and every other failure throws, so the answer can be cached as a proven absence.\n\t */\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequest(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t\toptions?: { currentAccount?: { id: string; username?: string }; deferFailure?: boolean },\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst pr = await this.request<BitbucketServerPullRequest>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${owner}/repos/${repo}/pull-requests/${id}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tundefined,\n\t\t\t\toptions?.deferFailure,\n\t\t\t);\n\t\t\tif (pr == null) throw new Error(`Bitbucket returned no pull request for ${owner}/${repo}#${id}`);\n\n\t\t\treturn fromProviderPullRequest(normalizeBitbucketServerPullRequest(pr), provider, {\n\t\t\t\tcurrentAccount: options?.currentAccount,\n\t\t\t});\n\t\t} catch (ex) {\n\t\t\tif (isNotFoundResponse(ex)) return undefined;\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/**\n\t * Every Bitbucket Cloud pull request into `owner/repo` whose source is `branch`, in any state, newest first, at\n\t * most `limit`: from the repository itself when `headOwner` is omitted, otherwise from a fork in the `headOwner`\n\t * workspace. Keyed on the source branch NAME, so a merged pull request whose branch was deleted still matches.\n\t *\n\t * Strict like {@link getPullRequest}: a 404 (a missing repository) is an empty list, and every other failure\n\t * throws.\n\t */\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getPullRequestsForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t\toptions: {\n\t\t\theadOwner?: string;\n\t\t\tlimit: number;\n\t\t\tcurrentAccount?: { id: string; username?: string };\n\t\t\tdeferFailure?: boolean;\n\t\t},\n\t): Promise<{ pullRequests: PullRequest[]; truncated: boolean }> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst escapedBranch = branch.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n\t\tconst params = new URLSearchParams({\n\t\t\t// Every state named: Bitbucket answers only OPEN pull requests unless asked for the others.\n\t\t\tq: `source.branch.name=\"${escapedBranch}\" AND (state=\"OPEN\" OR state=\"MERGED\" OR state=\"DECLINED\" OR state=\"SUPERSEDED\")`,\n\t\t\tsort: '-updated_on',\n\t\t\tpagelen: String(options.limit),\n\t\t\tfields: '+values.reviewers,+values.participants',\n\t\t});\n\n\t\ttry {\n\t\t\tconst response = await this.request<{ values: BitbucketPullRequest[]; next?: string }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pullrequests?${params.toString()}`,\n\t\t\t\t{ method: 'GET' },\n\t\t\t\tscope,\n\t\t\t\tundefined,\n\t\t\t\toptions.deferFailure,\n\t\t\t);\n\t\t\tif (response?.values == null) {\n\t\t\t\tthrow new Error(`Bitbucket returned no pull requests for ${owner}/${repo}:${branch}`);\n\t\t\t}\n\n\t\t\tconst headOwner = options.headOwner;\n\t\t\tconst { values, truncated } = selectBranchPullRequests(response.values, {\n\t\t\t\tmatchesHead: pr => {\n\t\t\t\t\tconst source = pr.source.repository;\n\t\t\t\t\tif (pr.source.branch.name !== branch || source == null) return false;\n\t\t\t\t\tif (headOwner == null) return source.uuid === pr.destination.repository.uuid;\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\tsource.uuid !== pr.destination.repository.uuid &&\n\t\t\t\t\t\tequalsIgnoreCase(source.full_name.split('/')[0], headOwner)\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tupdatedAt: pr => Date.parse(pr.updated_on),\n\t\t\t\tmap: pr => fromBitbucketPullRequest(pr, provider, { currentAccount: options.currentAccount }),\n\t\t\t\tlimit: options.limit,\n\t\t\t\tmore: response.next != null,\n\t\t\t});\n\t\t\treturn { pullRequests: values, truncated: truncated };\n\t\t} catch (ex) {\n\t\t\tif (isNotFoundResponse(ex)) return { pullRequests: [], truncated: false };\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/**\n\t * Every Bitbucket Data Center pull request whose source is `branch` in `owner/repo` and whose target is that same\n\t * repository, in any state, newest first, at most `limit`. Asked of the repository the branch lives in\n\t * (`direction=OUTGOING`), which is why a fork's pull requests can't be found through the repository they target.\n\t *\n\t * Strict like {@link getServerPullRequest}: a 404 (a missing repository) is an empty list, and every other\n\t * failure throws.\n\t */\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequestsForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t\toptions: { limit: number; currentAccount?: { id: string; username?: string }; deferFailure?: boolean },\n\t): Promise<{ pullRequests: PullRequest[]; truncated: boolean }> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst ref = `refs/heads/${branch}`;\n\t\tconst params = new URLSearchParams({\n\t\t\tat: ref,\n\t\t\tdirection: 'OUTGOING',\n\t\t\tstate: 'ALL',\n\t\t\torder: 'NEWEST',\n\t\t\tlimit: String(options.limit),\n\t\t});\n\n\t\ttry {\n\t\t\tconst response = await this.request<{ values: BitbucketServerPullRequest[]; isLastPage?: boolean }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${encodeURIComponent(owner)}/repos/${encodeURIComponent(repo)}/pull-requests?${params.toString()}`,\n\t\t\t\t{ method: 'GET' },\n\t\t\t\tscope,\n\t\t\t\tundefined,\n\t\t\t\toptions.deferFailure,\n\t\t\t);\n\t\t\tif (response?.values == null) {\n\t\t\t\tthrow new Error(`Bitbucket returned no pull requests for ${owner}/${repo}:${branch}`);\n\t\t\t}\n\n\t\t\tconst { values, truncated } = selectBranchPullRequests(response.values, {\n\t\t\t\t// `OUTGOING` also lists this branch's pull requests into other repositories, e.g. the upstream of a\n\t\t\t\t// repository that is itself a fork.\n\t\t\t\tmatchesHead: pr => pr.fromRef.id === ref && pr.fromRef.repository.id === pr.toRef.repository.id,\n\t\t\t\tupdatedAt: pr => pr.updatedDate,\n\t\t\t\tmap: pr =>\n\t\t\t\t\tfromProviderPullRequest(normalizeBitbucketServerPullRequest(pr), provider, {\n\t\t\t\t\t\tcurrentAccount: options.currentAccount,\n\t\t\t\t\t}),\n\t\t\t\tlimit: options.limit,\n\t\t\t\tmore: response.isLastPage !== true,\n\t\t\t});\n\t\t\treturn { pullRequests: values, truncated: truncated };\n\t\t} catch (ex) {\n\t\t\tif (isNotFoundResponse(ex)) return { pullRequests: [], truncated: false };\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, workspace) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\tworkspace: workspace,\n\t\t}),\n\t})\n\tasync getRepositoriesForWorkspace(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\tworkspace: string,\n\t\toptions: {\n\t\t\tbaseUrl: string;\n\t\t},\n\t): Promise<RepositoryMetadata[] | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tinterface BitbucketRepositoriesResponse {\n\t\t\t\tsize: number;\n\t\t\t\tpage: number;\n\t\t\t\tpagelen: number;\n\t\t\t\tnext?: string;\n\t\t\t\tprevious?: string;\n\t\t\t\tvalues: BitbucketRepository[];\n\t\t\t}\n\n\t\t\tconst response = await this.request<BitbucketRepositoriesResponse>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\toptions.baseUrl,\n\t\t\t\t`repositories/${workspace}?role=contributor&fields=%2Bvalues.parent.workspace`, // field=+<field> must be encoded as field=%2B<field>\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t);\n\n\t\t\tif (response) {\n\t\t\t\treturn response.values.map(repo => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tprovider: provider,\n\t\t\t\t\t\towner: repo.workspace.slug,\n\t\t\t\t\t\tname: repo.slug,\n\t\t\t\t\t\tisFork: Boolean(repo.parent),\n\t\t\t\t\t\tparent: repo.parent\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\towner: repo.parent.workspace.slug,\n\t\t\t\t\t\t\t\t\tname: repo.parent.slug,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t}),\n\t})\n\tasync getRepositoryMetadata(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\toptions: {\n\t\t\tbaseUrl: string;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<RepositoryMetadata | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.getRepository(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\towner,\n\t\t\t\trepo,\n\t\t\t\toptions.baseUrl,\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (response == null) return undefined;\n\n\t\t\tlet parent: RepositoryMetadata['parent'];\n\t\t\tif (response.parent != null) {\n\t\t\t\t// Derive the parent from `full_name` (\"owner/repo\") rather than `parent.workspace`, which is a\n\t\t\t\t// requested field expansion Bitbucket doesn't always honor (an unexpanded parent would otherwise\n\t\t\t\t// throw and null out the whole result).\n\t\t\t\t// `full_name` is \"owner/repo\"; only report a parent when both parts are present so a malformed\n\t\t\t\t// value doesn't produce a parent with an undefined owner/name while `isFork` stays true.\n\t\t\t\tconst [parentOwner, parentName] = response.parent.full_name.split('/');\n\t\t\t\tif (parentOwner && parentName) {\n\t\t\t\t\tparent = { owner: parentOwner, name: parentName };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tprovider: provider,\n\t\t\t\towner: response.workspace.slug,\n\t\t\t\tname: response.slug,\n\t\t\t\tisFork: response.parent != null,\n\t\t\t\tparent: parent,\n\t\t\t} satisfies RepositoryMetadata;\n\t\t} catch (ex) {\n\t\t\t// Cancellations and 404s are expected outcomes for a probe; don't log them as errors.\n\t\t\tif (!isCancellationError(ex) && !(ex instanceof RequestNotFoundError)) {\n\t\t\t\tscope?.error(ex);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t}),\n\t})\n\tasync getDefaultBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\toptions: {\n\t\t\tbaseUrl: string;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<DefaultBranch | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.getRepository(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\towner,\n\t\t\t\trepo,\n\t\t\t\toptions.baseUrl,\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst name = response?.mainbranch?.name;\n\t\t\tif (name == null) return undefined;\n\n\t\t\treturn { provider: provider, name: name } satisfies DefaultBranch;\n\t\t} catch (ex) {\n\t\t\t// Cancellations and 404s are expected outcomes for a probe; don't log them as errors.\n\t\t\tif (!isCancellationError(ex) && !(ex instanceof RequestNotFoundError)) {\n\t\t\t\tscope?.error(ex);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate getRepository(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbaseUrl: string,\n\t\tscope: ScopedLogger | undefined,\n\t\tcancellation?: AbortSignal,\n\t): Promise<BitbucketRepository | undefined> {\n\t\treturn this.request<BitbucketRepository>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`repositories/${owner}/${repo}`,\n\t\t\t{ method: 'GET' },\n\t\t\tscope,\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getServerPullRequestForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.request<{ values: BitbucketServerPullRequest[] }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${owner}/repos/${repo}/commits/${rev}/pull-requests`, //?fields=${fieldsParam}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst prResponse = response?.values?.reduce<BitbucketServerPullRequest | undefined>(\n\t\t\t\t(acc, pr) => (!acc || pr.updatedDate > acc.updatedDate ? pr : acc),\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tif (!prResponse) return undefined;\n\n\t\t\tconst providersPr = normalizeBitbucketServerPullRequest(prResponse);\n\t\t\tconst gitlensPr = fromProviderPullRequest(providersPr, provider);\n\t\t\treturn gitlensPr;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getPullRequestForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst fields = [\n\t\t\t\t'+values.*',\n\t\t\t\t'+values.destination.repository',\n\t\t\t\t'+values.destination.branch.*',\n\t\t\t\t'+values.destination.commit.*',\n\t\t\t\t'+values.source.repository.*',\n\t\t\t\t'+values.source.branch.*',\n\t\t\t\t'+values.source.commit.*',\n\t\t\t];\n\t\t\tconst fieldsParam = encodeURIComponent(fields.join(','));\n\t\t\tconst response = await this.request<{ values: BitbucketPullRequest[] }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/commit/${rev}/pullrequests?fields=${fieldsParam}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst pr = response?.values?.reduce<BitbucketPullRequest | undefined>(\n\t\t\t\t(acc, pr) => (!acc || pr.updated_on > acc.updated_on ? pr : acc),\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tif (!pr) return undefined;\n\t\t\treturn fromBitbucketPullRequest(pr, provider);\n\t\t} catch (ex) {\n\t\t\tif (ex.original instanceof ProviderFetchError) {\n\t\t\t\tconst json = await ex.original.response.json();\n\t\t\t\tif (json?.error === 'Invalid or unknown installation') {\n\t\t\t\t\t// TODO: In future get it on to home as an warning on the integration itself \"this integration has issues\"\n\t\t\t\t\t// even user suppresses the message it's still visible with some capacity. It's a broader thing to get other errors.\n\t\t\t\t\tconst commitWebUrl = `https://bitbucket.org/${owner}/${repo}/commits/${rev}`;\n\t\t\t\t\tthis.config.onBitbucketCommitLinksAppMissing?.(commitWebUrl);\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getAccountForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst commit = await this.request<BitbucketCommit>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/commit/${rev}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (!commit) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst { name, email } = parseRawBitbucketAuthor(commit.author.raw);\n\t\t\tconst commitAuthor: CommitAuthor = {\n\t\t\t\tprovider: provider,\n\t\t\t\tid: commit.author.user?.account_id,\n\t\t\t\tusername: commit.author.user?.nickname,\n\t\t\t\tname: commit.author.user?.display_name || name,\n\t\t\t\temail: email,\n\t\t\t\tavatarUrl: commit.author.user?.links?.avatar?.href,\n\t\t\t};\n\t\t\tif (commitAuthor.id != null && commitAuthor.username != null) {\n\t\t\t\treturn {\n\t\t\t\t\t...commitAuthor,\n\t\t\t\t\tid: commitAuthor.id,\n\t\t\t\t} satisfies Account;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...commitAuthor,\n\t\t\t\tid: undefined,\n\t\t\t\tusername: undefined,\n\t\t\t} satisfies UnidentifiedAuthor;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getServerAccountForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst commit = await this.request<BitbucketServerCommit>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${owner}/repos/${repo}/commits/${rev}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (!commit?.author) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (commit.author.id != null) {\n\t\t\t\treturn {\n\t\t\t\t\tprovider: provider,\n\t\t\t\t\tid: commit.author.id.toString(),\n\t\t\t\t\tusername: commit.author.name,\n\t\t\t\t\tname: commit.author.name,\n\t\t\t\t\temail: commit.author.emailAddress,\n\t\t\t\t\tavatarUrl: commit.author?.avatarUrl,\n\t\t\t\t} satisfies Account;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tprovider: provider,\n\t\t\t\tid: undefined,\n\t\t\t\tusername: undefined,\n\t\t\t\tname: commit.author.name,\n\t\t\t\temail: commit.author.emailAddress,\n\t\t\t\tavatarUrl: undefined,\n\t\t\t} satisfies UnidentifiedAuthor;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate async request<T>(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\tbaseUrl: string,\n\t\troute: string,\n\t\toptions?: { method: RequestInit['method'] } & Record<string, unknown>,\n\t\tscope?: ScopedLogger | undefined,\n\t\tcancellation?: AbortSignal | undefined,\n\t\tdeferFailure?: boolean,\n\t): Promise<T | undefined> {\n\t\tconst { accessToken } = token;\n\t\tconst url = `${baseUrl}/${route}`;\n\n\t\tlet rsp: Response;\n\t\ttry {\n\t\t\tconst sw = maybeStopWatch(`[BITBUCKET] ${options?.method ?? 'GET'} ${url}`, { log: { onlyExit: true } });\n\n\t\t\ttry {\n\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\trsp = await this.config.wrapForForcedInsecureSSL(provider.getIgnoreSSLErrors(), () =>\n\t\t\t\t\tthis.config.fetch(url, {\n\t\t\t\t\t\theaders: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' },\n\t\t\t\t\t\tsignal: cancellation,\n\t\t\t\t\t\t...options,\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\tif (rsp.ok) {\n\t\t\t\t\treturn (await rsp.json()) as T;\n\t\t\t\t}\n\n\t\t\t\t// Reads the body so the 403 branch below can tell a throttled request from a permission failure.\n\t\t\t\tthrow await ProviderFetchError.fromResponse('Bitbucket', rsp);\n\t\t\t} finally {\n\t\t\t\tsw?.stop();\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof ProviderFetchError || ex.name === 'AbortError') {\n\t\t\t\tthis.handleRequestError(provider, token, ex, scope, deferFailure);\n\t\t\t} else if (Logger.isDebugging) {\n\t\t\t\tthis.config.onError?.(`Bitbucket request failed: ${ex.message}`);\n\t\t\t}\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\tprivate handleRequestError(\n\t\tprovider: Provider | undefined,\n\t\ttoken: TokenWithInfo,\n\t\tex: ProviderFetchError | (Error & { name: 'AbortError' }),\n\t\tscope: ScopedLogger | undefined,\n\t\tdeferFailure: boolean | undefined,\n\t): void {\n\t\tif (ex.name === 'AbortError' || !(ex instanceof ProviderFetchError)) throw new CancellationError(ex);\n\n\t\tconst { accessToken, ...tokenInfo } = token;\n\t\tswitch (ex.status) {\n\t\t\tcase 404: // Not found\n\t\t\tcase 410: // Gone\n\t\t\tcase 422: // Unprocessable Entity\n\t\t\t\tthrow new RequestNotFoundError(ex);\n\t\t\tcase 401: // Unauthorized\n\t\t\t\tthrow new AuthenticationError(tokenInfo, AuthenticationErrorReason.Unauthorized, ex);\n\t\t\tcase 429: // Too Many Requests\n\t\t\t\tthrow toRateLimitError(ex, accessToken);\n\t\t\tcase 403: // Forbidden\n\t\t\t\t// Bitbucket returns 403 for both a permission failure and a throttled request (\"API rate limit\n\t\t\t\t// exceeded\"), so the message is the discriminant. Reporting a throttle as `auth` would prompt the\n\t\t\t\t// user to re-authenticate a healthy connection instead of retrying (see `isRateLimitResponse`).\n\t\t\t\tif (isRateLimitResponse(ex)) throw toRateLimitError(ex, accessToken);\n\n\t\t\t\tthrow new AuthenticationError(tokenInfo, AuthenticationErrorReason.Forbidden, ex);\n\t\t\tcase 500: // Internal Server Error\n\t\t\t\tscope?.error(ex);\n\t\t\t\tif (ex.response != null) {\n\t\t\t\t\treportRequestFailure(\n\t\t\t\t\t\tprovider,\n\t\t\t\t\t\tex,\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\tthis.config.onRequestFailed?.(\n\t\t\t\t\t\t\t\tprovider == null || provider.id === 'bitbucket'\n\t\t\t\t\t\t\t\t\t? l10n.t(\n\t\t\t\t\t\t\t\t\t\t\t'{0} failed to respond and might be experiencing issues. Please visit the [Bitbucket status page](https://bitbucket.status.atlassian.com/) for more information.',\n\t\t\t\t\t\t\t\t\t\t\tprovider?.name ?? 'Bitbucket',\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t: l10n.t('{0} failed to respond and might be experiencing issues.', provider.name),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\tdeferFailure,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase 502: // Bad Gateway\n\t\t\t\tscope?.error(ex);\n\t\t\t\t// TODO: Learn the Bitbucket API docs and put it in order:\n\t\t\t\t// if (ex.message.includes('timeout')) {\n\t\t\t\t// \tprovider?.trackRequestException();\n\t\t\t\t// \tvoid showIntegrationRequestTimedOutWarningMessage(provider?.name ?? 'Bitbucket');\n\t\t\t\t// \treturn;\n\t\t\t\t// }\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (ex.status >= 400 && ex.status < 500) throw new RequestClientError(ex);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tscope?.error(ex);\n\t\tif (Logger.isDebugging) {\n\t\t\tthis.config.onError?.(\n\t\t\t\t`Bitbucket request failed: ${(ex.response as any)?.errors?.[0]?.message ?? ex.message}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/** Wires a {@link BitbucketApi} from the full runtime context, mapping `ctx` down to the narrow config. */\nexport function createBitbucketApi(ctx: IntegrationServiceContext): BitbucketApi {\n\tconst config: ProviderApiConfig = {\n\t\t...baseProviderApiConfig(ctx),\n\t\tonBitbucketCommitLinksAppMissing: revLink => ctx.hooks?.ui?.onBitbucketCommitLinksAppMissing?.(revLink),\n\t};\n\n\treturn new BitbucketApi(config);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bitbucket.js","names":["Logger"],"sources":["../../../../../../plus/integrations/src/providers/bitbucket/bitbucket.ts"],"sourcesContent":["import * as l10n from '@vscode/l10n';\nimport { reportRequestFailure } from '@gitlens/git/errors.js';\nimport type { Account, CommitAuthor, UnidentifiedAuthor } from '@gitlens/git/models/author.js';\nimport type { DefaultBranch } from '@gitlens/git/models/defaultBranch.js';\nimport type { Issue } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequest, IssueOrPullRequestType } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type { PullRequest, PullRequestProjection } from '@gitlens/git/models/pullRequest.js';\nimport type { Provider } from '@gitlens/git/models/remoteProvider.js';\nimport type { RepositoryMetadata } from '@gitlens/git/models/repositoryMetadata.js';\nimport { CancellationError, isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { trace } from '@gitlens/utils/decorators/log.js';\nimport type { Disposable } from '@gitlens/utils/disposable.js';\nimport { Logger } from '@gitlens/utils/logger.js';\nimport type { ScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport { maybeStopWatch } from '@gitlens/utils/stopwatch.js';\nimport { equalsIgnoreCase } from '@gitlens/utils/string.js';\nimport type { TokenWithInfo } from '../../authentication/models.js';\nimport type { IntegrationServiceContext } from '../../context.js';\nimport {\n\tAuthenticationError,\n\tAuthenticationErrorReason,\n\tisRateLimitResponse,\n\tProviderFetchError,\n\tRequestClientError,\n\tRequestNotFoundError,\n\ttoRateLimitError,\n} from '../../errors.js';\nimport type { PullRequestEtagInclude } from '../../models/integration.js';\nimport type { ProviderApiConfig } from '../apiConfig.js';\nimport { baseProviderApiConfig } from '../apiConfig.js';\nimport type { BitbucketServerCommit, BitbucketServerPullRequest } from '../bitbucket-server/models.js';\nimport { normalizeBitbucketServerPullRequest } from '../bitbucket-server/models.js';\nimport { fromProviderPullRequest } from '../models.js';\nimport { selectBranchPullRequests } from '../utils/providerPaging.js';\nimport type {\n\tBitbucketCommit,\n\tBitbucketIssue,\n\tBitbucketPullRequest,\n\tBitbucketPullRequestEtagNode,\n\tBitbucketPullRequestState,\n\tBitbucketRepository,\n} from './models.js';\nimport {\n\tbitbucketEtagFieldsMaxIds,\n\tbitbucketIssueStateToState,\n\tfromBitbucketIssue,\n\tfromBitbucketPullRequest,\n\tparseRawBitbucketAuthor,\n} from './models.js';\n\n/** `handleRequestError` maps 410 and 422 to the same error as a 404, but only a 404 proves the resource absent. */\nfunction isNotFoundResponse(ex: unknown): boolean {\n\treturn RequestNotFoundError.is(ex) && ex.original instanceof ProviderFetchError && ex.original.status === 404;\n}\n\nexport class BitbucketApi implements Disposable {\n\tprivate readonly _disposable: Disposable | undefined;\n\n\tconstructor(private readonly config: ProviderApiConfig) {\n\t\tthis._disposable = config.onConfigChanged?.(() => this.resetCaches());\n\t}\n\n\tdispose(): void {\n\t\tthis._disposable?.dispose();\n\t}\n\n\tprivate resetCaches(): void {}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getPullRequestForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst response = await this.request<{\n\t\t\tvalues: BitbucketPullRequest[];\n\t\t\tpagelen: number;\n\t\t\tsize: number;\n\t\t\tpage: number;\n\t\t}>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`repositories/${owner}/${repo}/pullrequests?q=source.branch.name=\"${branch}\"&fields=%2Bvalues.reviewers,%2Bvalues.participants`,\n\t\t\t{\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t\tscope,\n\t\t);\n\n\t\tif (!response?.values?.length) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn fromBitbucketPullRequest(response.values[0], provider, { projection: 'point' });\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequestForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst response = await this.request<{\n\t\t\tvalues: BitbucketServerPullRequest[];\n\t\t\tpagelen: number;\n\t\t\tsize: number;\n\t\t\tpage: number;\n\t\t}>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`projects/${owner}/repos/${repo}/pull-requests?at=refs/heads/${branch}&direction=OUTGOING&state=ALL`,\n\t\t\t{\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t\tscope,\n\t\t);\n\n\t\tif (!response?.values?.length) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst providersPr = normalizeBitbucketServerPullRequest(response.values[0]);\n\t\tconst gitlensPr = fromProviderPullRequest(providersPr, provider, { projection: 'point' });\n\t\treturn gitlensPr;\n\t}\n\n\t@trace({\n\t\targs: (provider, token, userUuid, owner, repo, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\tuserUuid: userUuid,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getUsersIssuesForRepo(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\tuserUuid: string,\n\t\towner: string,\n\t\trepo: string,\n\t\tbaseUrl: string,\n\t): Promise<Issue[] | undefined> {\n\t\tconst scope = getScopedLogger();\n\t\tconst query = encodeURIComponent(`assignee.uuid=\"${userUuid}\" OR reporter.uuid=\"${userUuid}\"`);\n\n\t\tconst response = await this.request<{\n\t\t\tvalues: BitbucketIssue[];\n\t\t\tpagelen: number;\n\t\t\tsize: number;\n\t\t\tpage: number;\n\t\t}>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`repositories/${owner}/${repo}/issues?q=${query}`,\n\t\t\t{\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t\tscope,\n\t\t);\n\n\t\tif (!response?.values?.length) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn response.values.map(issue => fromBitbucketIssue(issue, provider, 'account'));\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getIssue(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t): Promise<Issue | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.request<BitbucketIssue>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/issues/${id}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t);\n\n\t\t\tif (response) {\n\t\t\t\treturn fromBitbucketIssue(response, provider, 'point');\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getIssueOrPullRequest(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t\toptions?: {\n\t\t\ttype?: IssueOrPullRequestType;\n\t\t},\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif (options?.type === undefined || options?.type === 'pullrequest') {\n\t\t\ttry {\n\t\t\t\tconst pr = await this.getPullRequest(provider, token, owner, repo, id, baseUrl);\n\t\t\t\tif (pr != null) return pr;\n\t\t\t} catch (ex) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\n\t\tif (options?.type === undefined || options?.type === 'issue') {\n\t\t\ttry {\n\t\t\t\tconst issueResponse = await this.request<BitbucketIssue>(\n\t\t\t\t\tprovider,\n\t\t\t\t\ttoken,\n\t\t\t\t\tbaseUrl,\n\t\t\t\t\t`repositories/${owner}/${repo}/issues/${id}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\t},\n\t\t\t\t\tscope,\n\t\t\t\t);\n\n\t\t\t\tif (issueResponse) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: issueResponse.id.toString(),\n\t\t\t\t\t\ttype: 'issue',\n\t\t\t\t\t\tnodeId: issueResponse.id.toString(),\n\t\t\t\t\t\tprovider: provider,\n\t\t\t\t\t\tcreatedDate: new Date(issueResponse.created_on),\n\t\t\t\t\t\tupdatedDate: new Date(issueResponse.updated_on),\n\t\t\t\t\t\tstate: bitbucketIssueStateToState(issueResponse.state),\n\t\t\t\t\t\tclosed: issueResponse.state === 'closed',\n\t\t\t\t\t\ttitle: issueResponse.title,\n\t\t\t\t\t\turl: issueResponse.links.html.href,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} catch (ex) {\n\t\t\t\tscope?.error(ex);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequestById(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\treturn await this.getServerPullRequest(provider, token, owner, repo, id, baseUrl);\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * A Bitbucket Cloud pull request by id. Strict, unlike {@link getIssueOrPullRequest}: `undefined` means a 404,\n\t * and every other failure throws, so the answer can be cached as a proven absence.\n\t */\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getPullRequest(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t\toptions?: {\n\t\t\tcurrentAccount?: { id: string; username?: string };\n\t\t\tdeferFailure?: boolean;\n\t\t\t/** The calling read, stamped on the row. */\n\t\t\tprojection?: PullRequestProjection;\n\t\t},\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst pr = await this.request<BitbucketPullRequest>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/pullrequests/${id}?fields=%2Bvalues.reviewers,%2Bvalues.participants`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tundefined,\n\t\t\t\toptions?.deferFailure,\n\t\t\t);\n\t\t\tif (pr == null) throw new Error(`Bitbucket returned no pull request for ${owner}/${repo}#${id}`);\n\n\t\t\treturn fromBitbucketPullRequest(pr, provider, {\n\t\t\t\tcurrentAccount: options?.currentAccount,\n\t\t\t\tprojection: options?.projection,\n\t\t\t});\n\t\t} catch (ex) {\n\t\t\tif (isNotFoundResponse(ex)) return undefined;\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/**\n\t * The change state of pull requests `ids` in `owner/repo` — the cheap check behind the batch read's etags — in ONE\n\t * request for up to {@link bitbucketEtagFieldsMaxIds} ids, selecting only what {@link getPullRequest}'s row reads\n\t * into its etag (plus the participants and reviewers for the `reviewDecision` include). One entry per input id, in\n\t * order.\n\t *\n\t * Strict like {@link getPullRequest}: `undefined` is a PROVEN ABSENCE, for an id missing from a complete page, or\n\t * for every id when the repository is a 404, as each id's own read would be. A page with more (`next`) and every\n\t * other failure throw. Every state is asked for, since the list answers only open pull requests by default.\n\t */\n\t@trace({\n\t\targs: (provider, token, owner, repo, ids) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tids: ids.length,\n\t\t}),\n\t})\n\tpublic async getPullRequestsEtagFields(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tids: readonly number[],\n\t\tbaseUrl: string,\n\t\toptions: { etagIncludes: readonly PullRequestEtagInclude[]; deferFailure?: boolean },\n\t\tcancellation?: AbortSignal,\n\t): Promise<(BitbucketPullRequestEtagNode | undefined)[]> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif (!ids.length) return [];\n\t\tif (ids.length > bitbucketEtagFieldsMaxIds) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot read more than ${bitbucketEtagFieldsMaxIds} Bitbucket pull requests in one request`,\n\t\t\t);\n\t\t}\n\n\t\tconst fields = [\n\t\t\t'values.id',\n\t\t\t'values.state',\n\t\t\t'values.draft',\n\t\t\t'values.updated_on',\n\t\t\t'values.source.commit.hash',\n\t\t\t'next',\n\t\t];\n\t\tif (options.etagIncludes.includes('reviewDecision')) {\n\t\t\tfields.push(\n\t\t\t\t'values.participants.approved',\n\t\t\t\t'values.participants.state',\n\t\t\t\t'values.participants.participated_on',\n\t\t\t\t'values.reviewers.uuid',\n\t\t\t);\n\t\t}\n\n\t\tconst params = new URLSearchParams({\n\t\t\tq: `id IN (${ids.join(',')})`,\n\t\t\tfields: fields.join(','),\n\t\t\tpagelen: String(ids.length),\n\t\t});\n\t\tfor (const state of ['OPEN', 'MERGED', 'DECLINED', 'SUPERSEDED'] satisfies BitbucketPullRequestState[]) {\n\t\t\tparams.append('state', state);\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await this.request<{ values?: BitbucketPullRequestEtagNode[]; next?: string }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pullrequests?${params.toString()}`,\n\t\t\t\t{ method: 'GET' },\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t\toptions.deferFailure,\n\t\t\t);\n\t\t\tif (response?.values == null) {\n\t\t\t\tthrow new Error(`Bitbucket returned no pull requests for ${owner}/${repo}`);\n\t\t\t}\n\t\t\tif (response.next != null) throw new Error(`Bitbucket returned a partial page of ${owner}/${repo}`);\n\n\t\t\tconst byId = new Map(response.values.map(pr => [pr.id, pr]));\n\t\t\treturn ids.map(id => byId.get(id));\n\t\t} catch (ex) {\n\t\t\tif (isNotFoundResponse(ex)) return ids.map(() => undefined);\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/**\n\t * A Bitbucket Data Center pull request by id. Strict, unlike {@link getServerPullRequestById}: `undefined` means\n\t * a 404, and every other failure throws, so the answer can be cached as a proven absence.\n\t */\n\t@trace({\n\t\targs: (provider, token, owner, repo, id, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tid: id,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequest(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tid: string,\n\t\tbaseUrl: string,\n\t\toptions?: {\n\t\t\tcurrentAccount?: { id: string; username?: string };\n\t\t\tdeferFailure?: boolean;\n\t\t\t/** The calling read, stamped on the row. */\n\t\t\tprojection?: PullRequestProjection;\n\t\t},\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst pr = await this.request<BitbucketServerPullRequest>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${owner}/repos/${repo}/pull-requests/${id}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tundefined,\n\t\t\t\toptions?.deferFailure,\n\t\t\t);\n\t\t\tif (pr == null) throw new Error(`Bitbucket returned no pull request for ${owner}/${repo}#${id}`);\n\n\t\t\treturn fromProviderPullRequest(normalizeBitbucketServerPullRequest(pr), provider, {\n\t\t\t\tcurrentAccount: options?.currentAccount,\n\t\t\t\tprojection: options?.projection,\n\t\t\t});\n\t\t} catch (ex) {\n\t\t\tif (isNotFoundResponse(ex)) return undefined;\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/**\n\t * Every Bitbucket Cloud pull request into `owner/repo` whose source is `branch`, in any state, newest first, at\n\t * most `limit`: from the repository itself when `headOwner` is omitted, otherwise from a fork in the `headOwner`\n\t * workspace. Keyed on the source branch NAME, so a merged pull request whose branch was deleted still matches.\n\t *\n\t * Strict like {@link getPullRequest}: a 404 (a missing repository) is an empty list, and every other failure\n\t * throws.\n\t */\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getPullRequestsForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t\toptions: {\n\t\t\theadOwner?: string;\n\t\t\tlimit: number;\n\t\t\tcurrentAccount?: { id: string; username?: string };\n\t\t\tdeferFailure?: boolean;\n\t\t},\n\t): Promise<{ pullRequests: PullRequest[]; truncated: boolean }> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst escapedBranch = branch.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n\t\tconst params = new URLSearchParams({\n\t\t\t// Every state named: Bitbucket answers only OPEN pull requests unless asked for the others.\n\t\t\tq: `source.branch.name=\"${escapedBranch}\" AND (state=\"OPEN\" OR state=\"MERGED\" OR state=\"DECLINED\" OR state=\"SUPERSEDED\")`,\n\t\t\tsort: '-updated_on',\n\t\t\tpagelen: String(options.limit),\n\t\t\tfields: '+values.reviewers,+values.participants',\n\t\t});\n\n\t\ttry {\n\t\t\tconst response = await this.request<{ values: BitbucketPullRequest[]; next?: string }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pullrequests?${params.toString()}`,\n\t\t\t\t{ method: 'GET' },\n\t\t\t\tscope,\n\t\t\t\tundefined,\n\t\t\t\toptions.deferFailure,\n\t\t\t);\n\t\t\tif (response?.values == null) {\n\t\t\t\tthrow new Error(`Bitbucket returned no pull requests for ${owner}/${repo}:${branch}`);\n\t\t\t}\n\n\t\t\tconst headOwner = options.headOwner;\n\t\t\tconst { values, truncated } = selectBranchPullRequests(response.values, {\n\t\t\t\tmatchesHead: pr => {\n\t\t\t\t\tconst source = pr.source.repository;\n\t\t\t\t\tif (pr.source.branch.name !== branch || source == null) return false;\n\t\t\t\t\tif (headOwner == null) return source.uuid === pr.destination.repository.uuid;\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\tsource.uuid !== pr.destination.repository.uuid &&\n\t\t\t\t\t\tequalsIgnoreCase(source.full_name.split('/')[0], headOwner)\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tupdatedAt: pr => Date.parse(pr.updated_on),\n\t\t\t\tmap: pr =>\n\t\t\t\t\tfromBitbucketPullRequest(pr, provider, {\n\t\t\t\t\t\tcurrentAccount: options.currentAccount,\n\t\t\t\t\t\tprojection: 'batch',\n\t\t\t\t\t}),\n\t\t\t\tlimit: options.limit,\n\t\t\t\tmore: response.next != null,\n\t\t\t});\n\t\t\treturn { pullRequests: values, truncated: truncated };\n\t\t} catch (ex) {\n\t\t\tif (isNotFoundResponse(ex)) return { pullRequests: [], truncated: false };\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/**\n\t * Every Bitbucket Data Center pull request whose source is `branch` in `owner/repo` and whose target is that same\n\t * repository, in any state, newest first, at most `limit`. Asked of the repository the branch lives in\n\t * (`direction=OUTGOING`), which is why a fork's pull requests can't be found through the repository they target.\n\t *\n\t * Strict like {@link getServerPullRequest}: a 404 (a missing repository) is an empty list, and every other\n\t * failure throws.\n\t */\n\t@trace({\n\t\targs: (provider, token, owner, repo, branch, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\tbranch: branch,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tpublic async getServerPullRequestsForBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbranch: string,\n\t\tbaseUrl: string,\n\t\toptions: { limit: number; currentAccount?: { id: string; username?: string }; deferFailure?: boolean },\n\t): Promise<{ pullRequests: PullRequest[]; truncated: boolean }> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst ref = `refs/heads/${branch}`;\n\t\tconst params = new URLSearchParams({\n\t\t\tat: ref,\n\t\t\tdirection: 'OUTGOING',\n\t\t\tstate: 'ALL',\n\t\t\torder: 'NEWEST',\n\t\t\tlimit: String(options.limit),\n\t\t});\n\n\t\ttry {\n\t\t\tconst response = await this.request<{ values: BitbucketServerPullRequest[]; isLastPage?: boolean }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${encodeURIComponent(owner)}/repos/${encodeURIComponent(repo)}/pull-requests?${params.toString()}`,\n\t\t\t\t{ method: 'GET' },\n\t\t\t\tscope,\n\t\t\t\tundefined,\n\t\t\t\toptions.deferFailure,\n\t\t\t);\n\t\t\tif (response?.values == null) {\n\t\t\t\tthrow new Error(`Bitbucket returned no pull requests for ${owner}/${repo}:${branch}`);\n\t\t\t}\n\n\t\t\tconst { values, truncated } = selectBranchPullRequests(response.values, {\n\t\t\t\t// `OUTGOING` also lists this branch's pull requests into other repositories, e.g. the upstream of a\n\t\t\t\t// repository that is itself a fork.\n\t\t\t\tmatchesHead: pr => pr.fromRef.id === ref && pr.fromRef.repository.id === pr.toRef.repository.id,\n\t\t\t\tupdatedAt: pr => pr.updatedDate,\n\t\t\t\tmap: pr =>\n\t\t\t\t\tfromProviderPullRequest(normalizeBitbucketServerPullRequest(pr), provider, {\n\t\t\t\t\t\tcurrentAccount: options.currentAccount,\n\t\t\t\t\t\tprojection: 'batch',\n\t\t\t\t\t}),\n\t\t\t\tlimit: options.limit,\n\t\t\t\tmore: response.isLastPage !== true,\n\t\t\t});\n\t\t\treturn { pullRequests: values, truncated: truncated };\n\t\t} catch (ex) {\n\t\t\tif (isNotFoundResponse(ex)) return { pullRequests: [], truncated: false };\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, workspace) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\tworkspace: workspace,\n\t\t}),\n\t})\n\tasync getRepositoriesForWorkspace(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\tworkspace: string,\n\t\toptions: {\n\t\t\tbaseUrl: string;\n\t\t},\n\t): Promise<RepositoryMetadata[] | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tinterface BitbucketRepositoriesResponse {\n\t\t\t\tsize: number;\n\t\t\t\tpage: number;\n\t\t\t\tpagelen: number;\n\t\t\t\tnext?: string;\n\t\t\t\tprevious?: string;\n\t\t\t\tvalues: BitbucketRepository[];\n\t\t\t}\n\n\t\t\tconst response = await this.request<BitbucketRepositoriesResponse>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\toptions.baseUrl,\n\t\t\t\t`repositories/${workspace}?role=contributor&fields=%2Bvalues.parent.workspace`, // field=+<field> must be encoded as field=%2B<field>\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t);\n\n\t\t\tif (response) {\n\t\t\t\treturn response.values.map(repo => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tprovider: provider,\n\t\t\t\t\t\towner: repo.workspace.slug,\n\t\t\t\t\t\tname: repo.slug,\n\t\t\t\t\t\tisFork: Boolean(repo.parent),\n\t\t\t\t\t\tparent: repo.parent\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\towner: repo.parent.workspace.slug,\n\t\t\t\t\t\t\t\t\tname: repo.parent.slug,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t}),\n\t})\n\tasync getRepositoryMetadata(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\toptions: {\n\t\t\tbaseUrl: string;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<RepositoryMetadata | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.getRepository(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\towner,\n\t\t\t\trepo,\n\t\t\t\toptions.baseUrl,\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (response == null) return undefined;\n\n\t\t\tlet parent: RepositoryMetadata['parent'];\n\t\t\tif (response.parent != null) {\n\t\t\t\t// Derive the parent from `full_name` (\"owner/repo\") rather than `parent.workspace`, which is a\n\t\t\t\t// requested field expansion Bitbucket doesn't always honor (an unexpanded parent would otherwise\n\t\t\t\t// throw and null out the whole result).\n\t\t\t\t// `full_name` is \"owner/repo\"; only report a parent when both parts are present so a malformed\n\t\t\t\t// value doesn't produce a parent with an undefined owner/name while `isFork` stays true.\n\t\t\t\tconst [parentOwner, parentName] = response.parent.full_name.split('/');\n\t\t\t\tif (parentOwner && parentName) {\n\t\t\t\t\tparent = { owner: parentOwner, name: parentName };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tprovider: provider,\n\t\t\t\towner: response.workspace.slug,\n\t\t\t\tname: response.slug,\n\t\t\t\tisFork: response.parent != null,\n\t\t\t\tparent: parent,\n\t\t\t} satisfies RepositoryMetadata;\n\t\t} catch (ex) {\n\t\t\t// Cancellations and 404s are expected outcomes for a probe; don't log them as errors.\n\t\t\tif (!isCancellationError(ex) && !(ex instanceof RequestNotFoundError)) {\n\t\t\t\tscope?.error(ex);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t}),\n\t})\n\tasync getDefaultBranch(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\toptions: {\n\t\t\tbaseUrl: string;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<DefaultBranch | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.getRepository(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\towner,\n\t\t\t\trepo,\n\t\t\t\toptions.baseUrl,\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst name = response?.mainbranch?.name;\n\t\t\tif (name == null) return undefined;\n\n\t\t\treturn { provider: provider, name: name } satisfies DefaultBranch;\n\t\t} catch (ex) {\n\t\t\t// Cancellations and 404s are expected outcomes for a probe; don't log them as errors.\n\t\t\tif (!isCancellationError(ex) && !(ex instanceof RequestNotFoundError)) {\n\t\t\t\tscope?.error(ex);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate getRepository(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\tbaseUrl: string,\n\t\tscope: ScopedLogger | undefined,\n\t\tcancellation?: AbortSignal,\n\t): Promise<BitbucketRepository | undefined> {\n\t\treturn this.request<BitbucketRepository>(\n\t\t\tprovider,\n\t\t\ttoken,\n\t\t\tbaseUrl,\n\t\t\t`repositories/${owner}/${repo}`,\n\t\t\t{ method: 'GET' },\n\t\t\tscope,\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getServerPullRequestForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst response = await this.request<{ values: BitbucketServerPullRequest[] }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${owner}/repos/${repo}/commits/${rev}/pull-requests`, //?fields=${fieldsParam}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst prResponse = response?.values?.reduce<BitbucketServerPullRequest | undefined>(\n\t\t\t\t(acc, pr) => (!acc || pr.updatedDate > acc.updatedDate ? pr : acc),\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tif (!prResponse) return undefined;\n\n\t\t\tconst providersPr = normalizeBitbucketServerPullRequest(prResponse);\n\t\t\tconst gitlensPr = fromProviderPullRequest(providersPr, provider, { projection: 'point' });\n\t\t\treturn gitlensPr;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getPullRequestForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst fields = [\n\t\t\t\t'+values.*',\n\t\t\t\t'+values.destination.repository',\n\t\t\t\t'+values.destination.branch.*',\n\t\t\t\t'+values.destination.commit.*',\n\t\t\t\t'+values.source.repository.*',\n\t\t\t\t'+values.source.branch.*',\n\t\t\t\t'+values.source.commit.*',\n\t\t\t];\n\t\t\tconst fieldsParam = encodeURIComponent(fields.join(','));\n\t\t\tconst response = await this.request<{ values: BitbucketPullRequest[] }>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/commit/${rev}/pullrequests?fields=${fieldsParam}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst pr = response?.values?.reduce<BitbucketPullRequest | undefined>(\n\t\t\t\t(acc, pr) => (!acc || pr.updated_on > acc.updated_on ? pr : acc),\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tif (!pr) return undefined;\n\t\t\treturn fromBitbucketPullRequest(pr, provider, { projection: 'point' });\n\t\t} catch (ex) {\n\t\t\tif (ex.original instanceof ProviderFetchError) {\n\t\t\t\tconst json = await ex.original.response.json();\n\t\t\t\tif (json?.error === 'Invalid or unknown installation') {\n\t\t\t\t\t// TODO: In future get it on to home as an warning on the integration itself \"this integration has issues\"\n\t\t\t\t\t// even user suppresses the message it's still visible with some capacity. It's a broader thing to get other errors.\n\t\t\t\t\tconst commitWebUrl = `https://bitbucket.org/${owner}/${repo}/commits/${rev}`;\n\t\t\t\t\tthis.config.onBitbucketCommitLinksAppMissing?.(commitWebUrl);\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getAccountForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst commit = await this.request<BitbucketCommit>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`repositories/${owner}/${repo}/commit/${rev}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (!commit) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst { name, email } = parseRawBitbucketAuthor(commit.author.raw);\n\t\t\tconst commitAuthor: CommitAuthor = {\n\t\t\t\tprovider: provider,\n\t\t\t\tid: commit.author.user?.account_id,\n\t\t\t\tusername: commit.author.user?.nickname,\n\t\t\t\tname: commit.author.user?.display_name || name,\n\t\t\t\temail: email,\n\t\t\t\tavatarUrl: commit.author.user?.links?.avatar?.href,\n\t\t\t};\n\t\t\tif (commitAuthor.id != null && commitAuthor.username != null) {\n\t\t\t\treturn {\n\t\t\t\t\t...commitAuthor,\n\t\t\t\t\tid: commitAuthor.id,\n\t\t\t\t} satisfies Account;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...commitAuthor,\n\t\t\t\tid: undefined,\n\t\t\t\tusername: undefined,\n\t\t\t} satisfies UnidentifiedAuthor;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t@trace({\n\t\targs: (provider, token, owner, repo, rev, baseUrl) => ({\n\t\t\tprovider: provider.name,\n\t\t\ttoken: `<token:${token.microHash}>`,\n\t\t\towner: owner,\n\t\t\trepo: repo,\n\t\t\trev: rev,\n\t\t\tbaseUrl: baseUrl,\n\t\t}),\n\t})\n\tasync getServerAccountForCommit(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\towner: string,\n\t\trepo: string,\n\t\trev: string,\n\t\tbaseUrl: string,\n\t\t_options?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\ttry {\n\t\t\tconst commit = await this.request<BitbucketServerCommit>(\n\t\t\t\tprovider,\n\t\t\t\ttoken,\n\t\t\t\tbaseUrl,\n\t\t\t\t`projects/${owner}/repos/${repo}/commits/${rev}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tif (!commit?.author) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (commit.author.id != null) {\n\t\t\t\treturn {\n\t\t\t\t\tprovider: provider,\n\t\t\t\t\tid: commit.author.id.toString(),\n\t\t\t\t\tusername: commit.author.name,\n\t\t\t\t\tname: commit.author.name,\n\t\t\t\t\temail: commit.author.emailAddress,\n\t\t\t\t\tavatarUrl: commit.author?.avatarUrl,\n\t\t\t\t} satisfies Account;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tprovider: provider,\n\t\t\t\tid: undefined,\n\t\t\t\tusername: undefined,\n\t\t\t\tname: commit.author.name,\n\t\t\t\temail: commit.author.emailAddress,\n\t\t\t\tavatarUrl: undefined,\n\t\t\t} satisfies UnidentifiedAuthor;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate async request<T>(\n\t\tprovider: Provider,\n\t\ttoken: TokenWithInfo,\n\t\tbaseUrl: string,\n\t\troute: string,\n\t\toptions?: { method: RequestInit['method'] } & Record<string, unknown>,\n\t\tscope?: ScopedLogger | undefined,\n\t\tcancellation?: AbortSignal | undefined,\n\t\tdeferFailure?: boolean,\n\t): Promise<T | undefined> {\n\t\tconst { accessToken } = token;\n\t\tconst url = `${baseUrl}/${route}`;\n\n\t\tlet rsp: Response;\n\t\ttry {\n\t\t\tconst sw = maybeStopWatch(`[BITBUCKET] ${options?.method ?? 'GET'} ${url}`, { log: { onlyExit: true } });\n\n\t\t\ttry {\n\t\t\t\tif (cancellation?.aborted) throw new CancellationError();\n\n\t\t\t\trsp = await this.config.wrapForForcedInsecureSSL(provider.getIgnoreSSLErrors(), () =>\n\t\t\t\t\tthis.config.fetch(url, {\n\t\t\t\t\t\theaders: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' },\n\t\t\t\t\t\tsignal: cancellation,\n\t\t\t\t\t\t...options,\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\tif (rsp.ok) {\n\t\t\t\t\treturn (await rsp.json()) as T;\n\t\t\t\t}\n\n\t\t\t\t// Reads the body so the 403 branch below can tell a throttled request from a permission failure.\n\t\t\t\tthrow await ProviderFetchError.fromResponse('Bitbucket', rsp);\n\t\t\t} finally {\n\t\t\t\tsw?.stop();\n\t\t\t}\n\t\t} catch (ex) {\n\t\t\tif (ex instanceof ProviderFetchError || ex.name === 'AbortError') {\n\t\t\t\tthis.handleRequestError(provider, token, ex, scope, deferFailure);\n\t\t\t} else if (Logger.isDebugging) {\n\t\t\t\tthis.config.onError?.(`Bitbucket request failed: ${ex.message}`);\n\t\t\t}\n\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\tprivate handleRequestError(\n\t\tprovider: Provider | undefined,\n\t\ttoken: TokenWithInfo,\n\t\tex: ProviderFetchError | (Error & { name: 'AbortError' }),\n\t\tscope: ScopedLogger | undefined,\n\t\tdeferFailure: boolean | undefined,\n\t): void {\n\t\tif (ex.name === 'AbortError' || !(ex instanceof ProviderFetchError)) throw new CancellationError(ex);\n\n\t\tconst { accessToken, ...tokenInfo } = token;\n\t\tswitch (ex.status) {\n\t\t\tcase 404: // Not found\n\t\t\tcase 410: // Gone\n\t\t\tcase 422: // Unprocessable Entity\n\t\t\t\tthrow new RequestNotFoundError(ex);\n\t\t\tcase 401: // Unauthorized\n\t\t\t\tthrow new AuthenticationError(tokenInfo, AuthenticationErrorReason.Unauthorized, ex);\n\t\t\tcase 429: // Too Many Requests\n\t\t\t\tthrow toRateLimitError(ex, accessToken);\n\t\t\tcase 403: // Forbidden\n\t\t\t\t// Bitbucket returns 403 for both a permission failure and a throttled request (\"API rate limit\n\t\t\t\t// exceeded\"), so the message is the discriminant. Reporting a throttle as `auth` would prompt the\n\t\t\t\t// user to re-authenticate a healthy connection instead of retrying (see `isRateLimitResponse`).\n\t\t\t\tif (isRateLimitResponse(ex)) throw toRateLimitError(ex, accessToken);\n\n\t\t\t\tthrow new AuthenticationError(tokenInfo, AuthenticationErrorReason.Forbidden, ex);\n\t\t\tcase 500: // Internal Server Error\n\t\t\t\tscope?.error(ex);\n\t\t\t\tif (ex.response != null) {\n\t\t\t\t\treportRequestFailure(\n\t\t\t\t\t\tprovider,\n\t\t\t\t\t\tex,\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\tthis.config.onRequestFailed?.(\n\t\t\t\t\t\t\t\tprovider == null || provider.id === 'bitbucket'\n\t\t\t\t\t\t\t\t\t? l10n.t(\n\t\t\t\t\t\t\t\t\t\t\t'{0} failed to respond and might be experiencing issues. Please visit the [Bitbucket status page](https://bitbucket.status.atlassian.com/) for more information.',\n\t\t\t\t\t\t\t\t\t\t\tprovider?.name ?? 'Bitbucket',\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t: l10n.t('{0} failed to respond and might be experiencing issues.', provider.name),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\tdeferFailure,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase 502: // Bad Gateway\n\t\t\t\tscope?.error(ex);\n\t\t\t\t// TODO: Learn the Bitbucket API docs and put it in order:\n\t\t\t\t// if (ex.message.includes('timeout')) {\n\t\t\t\t// \tprovider?.trackRequestException();\n\t\t\t\t// \tvoid showIntegrationRequestTimedOutWarningMessage(provider?.name ?? 'Bitbucket');\n\t\t\t\t// \treturn;\n\t\t\t\t// }\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (ex.status >= 400 && ex.status < 500) throw new RequestClientError(ex);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tscope?.error(ex);\n\t\tif (Logger.isDebugging) {\n\t\t\tthis.config.onError?.(\n\t\t\t\t`Bitbucket request failed: ${(ex.response as any)?.errors?.[0]?.message ?? ex.message}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/** Wires a {@link BitbucketApi} from the full runtime context, mapping `ctx` down to the narrow config. */\nexport function createBitbucketApi(ctx: IntegrationServiceContext): BitbucketApi {\n\tconst config: ProviderApiConfig = {\n\t\t...baseProviderApiConfig(ctx),\n\t\tonBitbucketCommitLinksAppMissing: revLink => ctx.hooks?.ui?.onBitbucketCommitLinksAppMissing?.(revLink),\n\t};\n\n\treturn new BitbucketApi(config);\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { ResourceDescriptor } from "../../../../git/models/resourceDescriptor.js";
|
|
2
2
|
import { Provider } from "../../../../git/models/remoteProvider.js";
|
|
3
3
|
import { IssueOrPullRequestState } from "../../../../git/models/issueOrPullRequest.js";
|
|
4
|
-
import { Issue } from "../../../../git/models/issue.js";
|
|
5
|
-
import { PullRequest, PullRequestMember, PullRequestReviewer } from "../../../../git/models/pullRequest.js";
|
|
4
|
+
import { Issue, IssueProjection } from "../../../../git/models/issue.js";
|
|
5
|
+
import { PullRequest, PullRequestMember, PullRequestProjection, PullRequestReviewDecision, PullRequestReviewer } from "../../../../git/models/pullRequest.js";
|
|
6
|
+
import { PullRequestEtagFields, PullRequestEtagInclude } from "../../models/integration.js";
|
|
6
7
|
//#region ../plus/integrations/src/providers/bitbucket/models.d.ts
|
|
7
8
|
export interface BitbucketRepositoryDescriptor extends ResourceDescriptor {
|
|
8
9
|
owner: string;
|
|
@@ -143,6 +144,7 @@ export interface BitbucketPullRequest {
|
|
|
143
144
|
title: string;
|
|
144
145
|
description: string;
|
|
145
146
|
state: BitbucketPullRequestState;
|
|
147
|
+
draft?: boolean;
|
|
146
148
|
merge_commit: null | BitbucketBriefCommit;
|
|
147
149
|
comment_count: number;
|
|
148
150
|
task_count: number;
|
|
@@ -216,12 +218,47 @@ export declare function isClosedBitbucketPullRequestState(state: BitbucketPullRe
|
|
|
216
218
|
export declare function isClosedBitbucketIssueState(state: BitbucketIssueState): boolean;
|
|
217
219
|
export declare function fromBitbucketUser(user: BitbucketUser): PullRequestMember;
|
|
218
220
|
export declare function fromBitbucketParticipantToReviewer(prt: BitbucketPullRequestParticipant, closedBy: BitbucketUser | null, prState: BitbucketPullRequestState): PullRequestReviewer;
|
|
219
|
-
|
|
221
|
+
/**
|
|
222
|
+
* The review decision a Bitbucket Cloud row carries, derived from its participants and reviewers. Reads only the
|
|
223
|
+
* participants' `participated_on`, `approved` and `state` and whether there are reviewers, which is what the cheap etag
|
|
224
|
+
* read selects for it.
|
|
225
|
+
*/
|
|
226
|
+
export declare function getBitbucketReviewDecision(pr: {
|
|
227
|
+
participants?: readonly Pick<BitbucketPullRequestParticipant, 'approved' | 'state' | 'participated_on'>[];
|
|
228
|
+
reviewers?: readonly unknown[];
|
|
229
|
+
}): PullRequestReviewDecision | undefined;
|
|
230
|
+
export declare function fromBitbucketIssue(issue: BitbucketIssue, provider: Provider, projection?: IssueProjection): Issue;
|
|
220
231
|
export declare function fromBitbucketPullRequest(pr: BitbucketPullRequest, provider: Provider, options?: {
|
|
221
232
|
currentAccount?: {
|
|
222
233
|
id: string;
|
|
223
234
|
username?: string;
|
|
224
235
|
};
|
|
236
|
+
projection?: PullRequestProjection;
|
|
225
237
|
}): PullRequest;
|
|
238
|
+
/** The most pull request ids one etag read asks for: Bitbucket Cloud's largest page of pull requests. */
|
|
239
|
+
export declare const bitbucketEtagFieldsMaxIds = 50;
|
|
240
|
+
/**
|
|
241
|
+
* A pull request as the cheap etag read selects it (`BitbucketApi.getPullRequestsEtagFields`): only the fields
|
|
242
|
+
* {@link fromBitbucketPullRequest} maps into a full row's etag inputs. `participants` and `reviewers` are selected
|
|
243
|
+
* only for the `reviewDecision` include.
|
|
244
|
+
*/
|
|
245
|
+
export interface BitbucketPullRequestEtagNode {
|
|
246
|
+
id: number;
|
|
247
|
+
state: BitbucketPullRequestState;
|
|
248
|
+
updated_on: string;
|
|
249
|
+
draft?: boolean;
|
|
250
|
+
source: {
|
|
251
|
+
commit: {
|
|
252
|
+
hash: string;
|
|
253
|
+
};
|
|
254
|
+
};
|
|
255
|
+
participants?: Pick<BitbucketPullRequestParticipant, 'approved' | 'state' | 'participated_on'>[];
|
|
256
|
+
reviewers?: unknown[];
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* A cheap etag read's pull request in the vocabulary {@link fromBitbucketPullRequest}'s row ends in, so both reads
|
|
260
|
+
* compute the same etag. That row reads neither a mergeability nor a check rollup, so neither does this.
|
|
261
|
+
*/
|
|
262
|
+
export declare function toBitbucketPullRequestEtagFields(node: BitbucketPullRequestEtagNode, etagIncludes: readonly PullRequestEtagInclude[]): PullRequestEtagFields;
|
|
226
263
|
//#endregion
|
|
227
264
|
//# sourceMappingURL=models.d.ts.map
|
|
@@ -52,6 +52,11 @@ function fromBitbucketParticipantToReviewer(prt, closedBy, prState) {
|
|
|
52
52
|
state: prt.approved ? "APPROVED" : prt.state === "changes_requested" ? "CHANGES_REQUESTED" : prt.participated_on != null ? "COMMENTED" : prt.user.uuid === closedBy?.uuid && prState === "DECLINED" ? "DISMISSED" : "REVIEW_REQUESTED"
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* The review decision a Bitbucket Cloud row carries, derived from its participants and reviewers. Reads only the
|
|
57
|
+
* participants' `participated_on`, `approved` and `state` and whether there are reviewers, which is what the cheap etag
|
|
58
|
+
* read selects for it.
|
|
59
|
+
*/
|
|
55
60
|
function getBitbucketReviewDecision(pr) {
|
|
56
61
|
if (!pr.participants?.length && pr.reviewers?.length) return "ReviewRequired";
|
|
57
62
|
if (!pr.participants) return;
|
|
@@ -72,21 +77,20 @@ function fromBitbucketRepository(repo) {
|
|
|
72
77
|
return {
|
|
73
78
|
owner: repo.full_name.split("/")[0],
|
|
74
79
|
repo: repo.name,
|
|
75
|
-
id: repo.uuid
|
|
76
|
-
accessLevel: 30
|
|
80
|
+
id: repo.uuid
|
|
77
81
|
};
|
|
78
82
|
}
|
|
79
|
-
function fromBitbucketIssue(issue, provider) {
|
|
83
|
+
function fromBitbucketIssue(issue, provider, projection) {
|
|
80
84
|
return new Issue(provider, issue.id.toString(), issue.id.toString(), issue.title, issue.links.html.href, new Date(issue.created_on), new Date(issue.updated_on), isClosedBitbucketIssueState(issue.state), bitbucketIssueStateToState(issue.state), fromBitbucketUser(issue.reporter), issue.assignee ? [fromBitbucketUser(issue.assignee)] : [], fromBitbucketRepository(issue.repository), void 0, void 0, void 0, issue.votes, issue.content.html, !issue.repository?.project ? void 0 : {
|
|
81
85
|
id: issue.repository.project.uuid,
|
|
82
86
|
name: issue.repository.project.name,
|
|
83
87
|
resourceId: issue.repository.project.uuid,
|
|
84
88
|
resourceName: issue.repository.project.name
|
|
85
|
-
});
|
|
89
|
+
}, void 0, void 0, void 0, void 0, void 0, projection);
|
|
86
90
|
}
|
|
87
91
|
function fromBitbucketPullRequest(pr, provider, options) {
|
|
88
92
|
const author = fromBitbucketUser(pr.author);
|
|
89
|
-
return new PullRequest(provider, author, pr.id.toString(), pr.id.toString(), pr.title, pr.links.html.href, fromBitbucketRepository(pr.destination.repository), bitbucketPullRequestStateToState(pr.state), new Date(pr.created_on), new Date(pr.updated_on), pr.closed_by ? new Date(pr.updated_on) : void 0, pr.state === "MERGED" ? new Date(pr.updated_on) : void 0,
|
|
93
|
+
return new PullRequest(provider, author, pr.id.toString(), pr.id.toString(), pr.title, pr.links.html.href, fromBitbucketRepository(pr.destination.repository), bitbucketPullRequestStateToState(pr.state), new Date(pr.created_on), new Date(pr.updated_on), pr.closed_by ? new Date(pr.updated_on) : void 0, pr.state === "MERGED" ? new Date(pr.updated_on) : void 0, void 0, void 0, {
|
|
90
94
|
base: {
|
|
91
95
|
branch: pr.destination.branch.name,
|
|
92
96
|
sha: pr.destination.commit.hash,
|
|
@@ -104,9 +108,28 @@ function fromBitbucketPullRequest(pr, provider, options) {
|
|
|
104
108
|
url: pr.source.repository.links.html.href
|
|
105
109
|
},
|
|
106
110
|
isCrossRepository: pr.source.repository.uuid !== pr.destination.repository.uuid
|
|
107
|
-
},
|
|
111
|
+
}, pr.draft, void 0, void 0, void 0, void 0, getBitbucketReviewDecision(pr), pr.participants?.filter((prt) => prt.role === "REVIEWER").map((prt) => fromBitbucketParticipantToReviewer(prt, pr.closed_by, pr.state)).filter((rv) => rv.state === "REVIEW_REQUESTED"), pr.participants?.filter((prt) => prt.participated_on != null).map((prt) => fromBitbucketParticipantToReviewer(prt, pr.closed_by, pr.state)), void 0, void 0, void 0, void 0, void 0, void 0, void 0, pr.description ?? void 0, pr.id, options?.currentAccount != null ? author.id === options.currentAccount.id : void 0, options?.projection, options?.currentAccount);
|
|
112
|
+
}
|
|
113
|
+
/** The most pull request ids one etag read asks for: Bitbucket Cloud's largest page of pull requests. */
|
|
114
|
+
const bitbucketEtagFieldsMaxIds = 50;
|
|
115
|
+
/**
|
|
116
|
+
* A cheap etag read's pull request in the vocabulary {@link fromBitbucketPullRequest}'s row ends in, so both reads
|
|
117
|
+
* compute the same etag. That row reads neither a mergeability nor a check rollup, so neither does this.
|
|
118
|
+
*/
|
|
119
|
+
function toBitbucketPullRequestEtagFields(node, etagIncludes) {
|
|
120
|
+
const fields = {
|
|
121
|
+
state: bitbucketPullRequestStateToState(node.state),
|
|
122
|
+
isDraft: node.draft,
|
|
123
|
+
updatedDate: new Date(node.updated_on),
|
|
124
|
+
headSha: node.source.commit.hash
|
|
125
|
+
};
|
|
126
|
+
if (etagIncludes.includes("reviewDecision")) {
|
|
127
|
+
if (node.participants == null || node.reviewers == null) throw new Error(`Bitbucket returned pull request ${node.id} without its participants or reviewers`);
|
|
128
|
+
fields.reviewDecision = getBitbucketReviewDecision(node);
|
|
129
|
+
}
|
|
130
|
+
return fields;
|
|
108
131
|
}
|
|
109
132
|
//#endregion
|
|
110
|
-
export { bitbucketIssueStateToState, bitbucketPullRequestStateToState, fromBitbucketIssue, fromBitbucketParticipantToReviewer, fromBitbucketPullRequest, fromBitbucketUser, isClosedBitbucketIssueState, isClosedBitbucketPullRequestState, parseRawBitbucketAuthor };
|
|
133
|
+
export { bitbucketEtagFieldsMaxIds, bitbucketIssueStateToState, bitbucketPullRequestStateToState, fromBitbucketIssue, fromBitbucketParticipantToReviewer, fromBitbucketPullRequest, fromBitbucketUser, getBitbucketReviewDecision, isClosedBitbucketIssueState, isClosedBitbucketPullRequestState, parseRawBitbucketAuthor, toBitbucketPullRequestEtagFields };
|
|
111
134
|
|
|
112
135
|
//# sourceMappingURL=models.js.map
|