@pilatos/bitbucket-cli 1.9.1 → 1.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +89 -41
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -18187,6 +18187,24 @@ var axios_default = axios;
|
|
|
18187
18187
|
|
|
18188
18188
|
// src/services/api-client.service.ts
|
|
18189
18189
|
var BASE_URL = "https://api.bitbucket.org/2.0";
|
|
18190
|
+
var MAX_RETRIES = 3;
|
|
18191
|
+
var BASE_DELAY_MS = 1000;
|
|
18192
|
+
var RETRYABLE_STATUS_CODES = new Set([429, 502, 503, 504]);
|
|
18193
|
+
function getRetryDelay(error, attempt) {
|
|
18194
|
+
if (error.response?.status === 429) {
|
|
18195
|
+
const retryAfter = error.response.headers["retry-after"];
|
|
18196
|
+
if (retryAfter) {
|
|
18197
|
+
const seconds = Number.parseInt(retryAfter, 10);
|
|
18198
|
+
if (!Number.isNaN(seconds)) {
|
|
18199
|
+
return seconds * 1000;
|
|
18200
|
+
}
|
|
18201
|
+
}
|
|
18202
|
+
}
|
|
18203
|
+
return BASE_DELAY_MS * Math.pow(2, attempt - 1);
|
|
18204
|
+
}
|
|
18205
|
+
function sleep(ms) {
|
|
18206
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
18207
|
+
}
|
|
18190
18208
|
function createApiClient(configService) {
|
|
18191
18209
|
const instance = axios_default.create({
|
|
18192
18210
|
baseURL: BASE_URL,
|
|
@@ -18210,13 +18228,28 @@ function createApiClient(configService) {
|
|
|
18210
18228
|
console.debug(`[HTTP] Response Body:`, JSON.stringify(response.data, null, 2));
|
|
18211
18229
|
}
|
|
18212
18230
|
return response;
|
|
18213
|
-
}, (error) => {
|
|
18231
|
+
}, async (error) => {
|
|
18214
18232
|
if (process.env.DEBUG === "true") {
|
|
18215
18233
|
console.debug(`[HTTP] Error:`, error.message);
|
|
18216
18234
|
if (error.response) {
|
|
18217
18235
|
console.debug(`[HTTP] Error Response Body:`, JSON.stringify(error.response.data, null, 2));
|
|
18218
18236
|
}
|
|
18219
18237
|
}
|
|
18238
|
+
if (error.response && RETRYABLE_STATUS_CODES.has(error.response.status)) {
|
|
18239
|
+
const config = error.config;
|
|
18240
|
+
if (config) {
|
|
18241
|
+
const retryCount = config.__retryCount ?? 0;
|
|
18242
|
+
if (retryCount < MAX_RETRIES) {
|
|
18243
|
+
config.__retryCount = retryCount + 1;
|
|
18244
|
+
const delay = getRetryDelay(error, config.__retryCount);
|
|
18245
|
+
const status = error.response.status;
|
|
18246
|
+
const label = status === 429 ? "Rate limited" : `Server error (${status})`;
|
|
18247
|
+
console.error(`${label}, retrying in ${(delay / 1000).toFixed(1)}s (attempt ${config.__retryCount}/${MAX_RETRIES})...`);
|
|
18248
|
+
await sleep(delay);
|
|
18249
|
+
return instance(config);
|
|
18250
|
+
}
|
|
18251
|
+
}
|
|
18252
|
+
}
|
|
18220
18253
|
if (error.response) {
|
|
18221
18254
|
const { status, data } = error.response;
|
|
18222
18255
|
const message = extractErrorMessage(data) || error.message;
|
|
@@ -18252,6 +18285,45 @@ function extractErrorMessage(data) {
|
|
|
18252
18285
|
}
|
|
18253
18286
|
return;
|
|
18254
18287
|
}
|
|
18288
|
+
// src/services/reviewer.service.ts
|
|
18289
|
+
function extractReviewerUuids(reviewers) {
|
|
18290
|
+
if (!reviewers) {
|
|
18291
|
+
return [];
|
|
18292
|
+
}
|
|
18293
|
+
const list = Array.from(reviewers);
|
|
18294
|
+
const uuids = [];
|
|
18295
|
+
for (const reviewer of list) {
|
|
18296
|
+
if (reviewer.uuid) {
|
|
18297
|
+
uuids.push(reviewer.uuid);
|
|
18298
|
+
}
|
|
18299
|
+
}
|
|
18300
|
+
return uuids;
|
|
18301
|
+
}
|
|
18302
|
+
function buildReviewersUpdateBody(uuids) {
|
|
18303
|
+
const body = {
|
|
18304
|
+
type: "pullrequest",
|
|
18305
|
+
reviewers: uuids.map((uuid) => ({ type: "user", uuid }))
|
|
18306
|
+
};
|
|
18307
|
+
return body;
|
|
18308
|
+
}
|
|
18309
|
+
async function updatePullRequestReviewers(pullrequestsApi, repoContext, prId, transformUuids) {
|
|
18310
|
+
const prResponse = await pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdGet({
|
|
18311
|
+
workspace: repoContext.workspace,
|
|
18312
|
+
repoSlug: repoContext.repoSlug,
|
|
18313
|
+
pullRequestId: prId
|
|
18314
|
+
});
|
|
18315
|
+
const pr = prResponse.data;
|
|
18316
|
+
const currentUuids = extractReviewerUuids(pr.reviewers);
|
|
18317
|
+
const updatedUuids = transformUuids(currentUuids);
|
|
18318
|
+
const body = buildReviewersUpdateBody(updatedUuids);
|
|
18319
|
+
const response = await pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdPut({
|
|
18320
|
+
workspace: repoContext.workspace,
|
|
18321
|
+
repoSlug: repoContext.repoSlug,
|
|
18322
|
+
pullRequestId: prId,
|
|
18323
|
+
body
|
|
18324
|
+
});
|
|
18325
|
+
return response.data;
|
|
18326
|
+
}
|
|
18255
18327
|
// src/bootstrap.ts
|
|
18256
18328
|
import { createRequire } from "module";
|
|
18257
18329
|
|
|
@@ -23164,25 +23236,11 @@ class AddReviewerPRCommand extends BaseCommand {
|
|
|
23164
23236
|
selectedUser: options.username
|
|
23165
23237
|
});
|
|
23166
23238
|
const user = userResponse.data;
|
|
23167
|
-
const
|
|
23168
|
-
|
|
23169
|
-
|
|
23170
|
-
pullRequestId: prId
|
|
23171
|
-
});
|
|
23172
|
-
const pr = prResponse.data;
|
|
23173
|
-
const existingReviewers = pr.reviewers ? Array.from(pr.reviewers) : [];
|
|
23174
|
-
const reviewerUuids = existingReviewers.map((r) => r.uuid).filter(Boolean);
|
|
23175
|
-
if (!reviewerUuids.includes(user.uuid)) {
|
|
23176
|
-
reviewerUuids.push(user.uuid);
|
|
23177
|
-
}
|
|
23178
|
-
const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdPut({
|
|
23179
|
-
workspace: repoContext.workspace,
|
|
23180
|
-
repoSlug: repoContext.repoSlug,
|
|
23181
|
-
pullRequestId: prId,
|
|
23182
|
-
body: {
|
|
23183
|
-
type: "pullrequest",
|
|
23184
|
-
reviewers: reviewerUuids.map((uuid) => ({ uuid }))
|
|
23239
|
+
const updatedPr = await updatePullRequestReviewers(this.pullrequestsApi, repoContext, prId, (uuids) => {
|
|
23240
|
+
if (!uuids.includes(user.uuid)) {
|
|
23241
|
+
return [...uuids, user.uuid];
|
|
23185
23242
|
}
|
|
23243
|
+
return uuids;
|
|
23186
23244
|
});
|
|
23187
23245
|
if (context.globalOptions.json) {
|
|
23188
23246
|
this.output.json({
|
|
@@ -23192,7 +23250,7 @@ class AddReviewerPRCommand extends BaseCommand {
|
|
|
23192
23250
|
username: options.username,
|
|
23193
23251
|
uuid: user.uuid
|
|
23194
23252
|
},
|
|
23195
|
-
pullRequest:
|
|
23253
|
+
pullRequest: updatedPr
|
|
23196
23254
|
});
|
|
23197
23255
|
return;
|
|
23198
23256
|
}
|
|
@@ -23223,23 +23281,7 @@ class RemoveReviewerPRCommand extends BaseCommand {
|
|
|
23223
23281
|
selectedUser: options.username
|
|
23224
23282
|
});
|
|
23225
23283
|
const user = userResponse.data;
|
|
23226
|
-
const
|
|
23227
|
-
workspace: repoContext.workspace,
|
|
23228
|
-
repoSlug: repoContext.repoSlug,
|
|
23229
|
-
pullRequestId: prId
|
|
23230
|
-
});
|
|
23231
|
-
const pr = prResponse.data;
|
|
23232
|
-
const existingReviewers = pr.reviewers ? Array.from(pr.reviewers) : [];
|
|
23233
|
-
const reviewerUuids = existingReviewers.map((r) => r.uuid).filter((uuid) => uuid && uuid !== user.uuid);
|
|
23234
|
-
const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdPut({
|
|
23235
|
-
workspace: repoContext.workspace,
|
|
23236
|
-
repoSlug: repoContext.repoSlug,
|
|
23237
|
-
pullRequestId: prId,
|
|
23238
|
-
body: {
|
|
23239
|
-
type: "pullrequest",
|
|
23240
|
-
reviewers: reviewerUuids.map((uuid) => ({ uuid }))
|
|
23241
|
-
}
|
|
23242
|
-
});
|
|
23284
|
+
const updatedPr = await updatePullRequestReviewers(this.pullrequestsApi, repoContext, prId, (uuids) => uuids.filter((uuid) => uuid !== user.uuid));
|
|
23243
23285
|
if (context.globalOptions.json) {
|
|
23244
23286
|
this.output.json({
|
|
23245
23287
|
success: true,
|
|
@@ -23248,7 +23290,7 @@ class RemoveReviewerPRCommand extends BaseCommand {
|
|
|
23248
23290
|
username: options.username,
|
|
23249
23291
|
uuid: user.uuid
|
|
23250
23292
|
},
|
|
23251
|
-
pullRequest:
|
|
23293
|
+
pullRequest: updatedPr
|
|
23252
23294
|
});
|
|
23253
23295
|
return;
|
|
23254
23296
|
}
|
|
@@ -23975,11 +24017,17 @@ function createContext(program2) {
|
|
|
23975
24017
|
};
|
|
23976
24018
|
}
|
|
23977
24019
|
async function runCommand(token, options, program2, context) {
|
|
23978
|
-
const cmd = container.resolve(token);
|
|
23979
|
-
const resolvedContext = context ?? createContext(program2);
|
|
23980
24020
|
try {
|
|
24021
|
+
const cmd = container.resolve(token);
|
|
24022
|
+
const resolvedContext = context ?? createContext(program2);
|
|
23981
24023
|
return await cmd.run(options, resolvedContext);
|
|
23982
|
-
} catch {
|
|
24024
|
+
} catch (error) {
|
|
24025
|
+
if (error instanceof Error && error.message.startsWith("Service not registered")) {
|
|
24026
|
+
console.error(`Internal error: ${error.message}`);
|
|
24027
|
+
}
|
|
24028
|
+
if (!process.exitCode) {
|
|
24029
|
+
process.exitCode = 1;
|
|
24030
|
+
}
|
|
23983
24031
|
return;
|
|
23984
24032
|
}
|
|
23985
24033
|
}
|