@pilatos/bitbucket-cli 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +81 -14
- 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;
|
|
@@ -21124,6 +21157,27 @@ class BaseCommand {
|
|
|
21124
21157
|
}
|
|
21125
21158
|
return value;
|
|
21126
21159
|
}
|
|
21160
|
+
parseIntOption(value, name) {
|
|
21161
|
+
const parsed = Number.parseInt(value, 10);
|
|
21162
|
+
if (Number.isNaN(parsed)) {
|
|
21163
|
+
throw new BBError({
|
|
21164
|
+
code: 5002 /* VALIDATION_INVALID */,
|
|
21165
|
+
message: `--${name} must be a valid integer`,
|
|
21166
|
+
context: { [name]: value }
|
|
21167
|
+
});
|
|
21168
|
+
}
|
|
21169
|
+
return parsed;
|
|
21170
|
+
}
|
|
21171
|
+
parseEnumOption(value, name, allowed) {
|
|
21172
|
+
if (!allowed.includes(value)) {
|
|
21173
|
+
throw new BBError({
|
|
21174
|
+
code: 5002 /* VALIDATION_INVALID */,
|
|
21175
|
+
message: `--${name} must be one of: ${allowed.join(", ")}`,
|
|
21176
|
+
context: { [name]: value }
|
|
21177
|
+
});
|
|
21178
|
+
}
|
|
21179
|
+
return value;
|
|
21180
|
+
}
|
|
21127
21181
|
}
|
|
21128
21182
|
|
|
21129
21183
|
// src/commands/auth/login.command.ts
|
|
@@ -21641,7 +21695,8 @@ class CreateRepoCommand extends BaseCommand {
|
|
|
21641
21695
|
this.configService = configService;
|
|
21642
21696
|
}
|
|
21643
21697
|
async execute(options, context) {
|
|
21644
|
-
const {
|
|
21698
|
+
const { description, project } = options;
|
|
21699
|
+
const name = this.requireOption(options.name, "name");
|
|
21645
21700
|
const isPublic = options.public === true;
|
|
21646
21701
|
const workspace = await this.resolveWorkspace(options.workspace);
|
|
21647
21702
|
const request = {
|
|
@@ -21979,7 +22034,13 @@ class ListPRsCommand extends BaseCommand {
|
|
|
21979
22034
|
...context.globalOptions,
|
|
21980
22035
|
...options
|
|
21981
22036
|
});
|
|
21982
|
-
const
|
|
22037
|
+
const ALLOWED_STATES = [
|
|
22038
|
+
"OPEN",
|
|
22039
|
+
"MERGED",
|
|
22040
|
+
"DECLINED",
|
|
22041
|
+
"SUPERSEDED"
|
|
22042
|
+
];
|
|
22043
|
+
const state = options.state ? this.parseEnumOption(options.state, "state", ALLOWED_STATES) : "OPEN";
|
|
21983
22044
|
const limit = parseLimit(options.limit);
|
|
21984
22045
|
const reviewerQuery = options.mine ? await this.buildMineFilter() : undefined;
|
|
21985
22046
|
const values = await collectPages({
|
|
@@ -22994,7 +23055,7 @@ class ListCommentsPRCommand extends BaseCommand {
|
|
|
22994
23055
|
...context.globalOptions,
|
|
22995
23056
|
...options
|
|
22996
23057
|
});
|
|
22997
|
-
const prId =
|
|
23058
|
+
const prId = this.parseIntOption(options.id, "id");
|
|
22998
23059
|
const limit = parseLimit(options.limit);
|
|
22999
23060
|
const values = await collectPages({
|
|
23000
23061
|
limit,
|
|
@@ -23050,8 +23111,8 @@ class EditCommentPRCommand extends BaseCommand {
|
|
|
23050
23111
|
...context.globalOptions,
|
|
23051
23112
|
...options
|
|
23052
23113
|
});
|
|
23053
|
-
const prId =
|
|
23054
|
-
const commentId =
|
|
23114
|
+
const prId = this.parseIntOption(options.prId, "pr-id");
|
|
23115
|
+
const commentId = this.parseIntOption(options.commentId, "comment-id");
|
|
23055
23116
|
const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdCommentsCommentIdPut({
|
|
23056
23117
|
workspace: repoContext.workspace,
|
|
23057
23118
|
repoSlug: repoContext.repoSlug,
|
|
@@ -23093,8 +23154,8 @@ class DeleteCommentPRCommand extends BaseCommand {
|
|
|
23093
23154
|
...context.globalOptions,
|
|
23094
23155
|
...options
|
|
23095
23156
|
});
|
|
23096
|
-
const prId =
|
|
23097
|
-
const commentId =
|
|
23157
|
+
const prId = this.parseIntOption(options.prId, "pr-id");
|
|
23158
|
+
const commentId = this.parseIntOption(options.commentId, "comment-id");
|
|
23098
23159
|
await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdCommentsCommentIdDelete({
|
|
23099
23160
|
workspace: repoContext.workspace,
|
|
23100
23161
|
repoSlug: repoContext.repoSlug,
|
|
@@ -23131,7 +23192,7 @@ class AddReviewerPRCommand extends BaseCommand {
|
|
|
23131
23192
|
...context.globalOptions,
|
|
23132
23193
|
...options
|
|
23133
23194
|
});
|
|
23134
|
-
const prId =
|
|
23195
|
+
const prId = this.parseIntOption(options.id, "id");
|
|
23135
23196
|
const userResponse = await this.usersApi.usersSelectedUserGet({
|
|
23136
23197
|
selectedUser: options.username
|
|
23137
23198
|
});
|
|
@@ -23190,7 +23251,7 @@ class RemoveReviewerPRCommand extends BaseCommand {
|
|
|
23190
23251
|
...context.globalOptions,
|
|
23191
23252
|
...options
|
|
23192
23253
|
});
|
|
23193
|
-
const prId =
|
|
23254
|
+
const prId = this.parseIntOption(options.id, "id");
|
|
23194
23255
|
const userResponse = await this.usersApi.usersSelectedUserGet({
|
|
23195
23256
|
selectedUser: options.username
|
|
23196
23257
|
});
|
|
@@ -23244,7 +23305,7 @@ class ListReviewersPRCommand extends BaseCommand {
|
|
|
23244
23305
|
...context.globalOptions,
|
|
23245
23306
|
...options
|
|
23246
23307
|
});
|
|
23247
|
-
const prId =
|
|
23308
|
+
const prId = this.parseIntOption(options.id, "id");
|
|
23248
23309
|
const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdGet({
|
|
23249
23310
|
workspace: repoContext.workspace,
|
|
23250
23311
|
repoSlug: repoContext.repoSlug,
|
|
@@ -23947,11 +24008,17 @@ function createContext(program2) {
|
|
|
23947
24008
|
};
|
|
23948
24009
|
}
|
|
23949
24010
|
async function runCommand(token, options, program2, context) {
|
|
23950
|
-
const cmd = container.resolve(token);
|
|
23951
|
-
const resolvedContext = context ?? createContext(program2);
|
|
23952
24011
|
try {
|
|
24012
|
+
const cmd = container.resolve(token);
|
|
24013
|
+
const resolvedContext = context ?? createContext(program2);
|
|
23953
24014
|
return await cmd.run(options, resolvedContext);
|
|
23954
|
-
} catch {
|
|
24015
|
+
} catch (error) {
|
|
24016
|
+
if (error instanceof Error && error.message.startsWith("Service not registered")) {
|
|
24017
|
+
console.error(`Internal error: ${error.message}`);
|
|
24018
|
+
}
|
|
24019
|
+
if (!process.exitCode) {
|
|
24020
|
+
process.exitCode = 1;
|
|
24021
|
+
}
|
|
23955
24022
|
return;
|
|
23956
24023
|
}
|
|
23957
24024
|
}
|