@pilatos/bitbucket-cli 1.15.0 → 1.16.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/README.md +2 -0
- package/dist/index.js +426 -186
- package/dist/index.js.map +229 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -17440,6 +17440,8 @@ var ServiceTokens = {
|
|
|
17440
17440
|
AddDefaultReviewerCommand: "AddDefaultReviewerCommand",
|
|
17441
17441
|
RemoveDefaultReviewerCommand: "RemoveDefaultReviewerCommand",
|
|
17442
17442
|
DefaultReviewerService: "DefaultReviewerService",
|
|
17443
|
+
UrlBuilderService: "UrlBuilderService",
|
|
17444
|
+
BrowseCommand: "BrowseCommand",
|
|
17443
17445
|
CreatePRCommand: "CreatePRCommand",
|
|
17444
17446
|
ListPRsCommand: "ListPRsCommand",
|
|
17445
17447
|
ViewPRCommand: "ViewPRCommand",
|
|
@@ -17631,7 +17633,16 @@ class ConfigService {
|
|
|
17631
17633
|
await this.verifyPermissions(this.configDir, CONFIG_DIR_MODE, "directory");
|
|
17632
17634
|
await this.verifyPermissions(this.configFile, CONFIG_FILE_MODE, "file");
|
|
17633
17635
|
const data = await fs.readFile(this.configFile, "utf-8");
|
|
17634
|
-
|
|
17636
|
+
try {
|
|
17637
|
+
this.configCache = JSON.parse(data);
|
|
17638
|
+
} catch (parseError) {
|
|
17639
|
+
throw new BBError({
|
|
17640
|
+
code: 4001 /* CONFIG_READ_FAILED */,
|
|
17641
|
+
message: `Config file is not valid JSON: ${this.configFile}. Fix the file by hand or remove it and run \`bb auth login\` again.`,
|
|
17642
|
+
cause: parseError instanceof Error ? parseError : undefined,
|
|
17643
|
+
context: { configFile: this.configFile }
|
|
17644
|
+
});
|
|
17645
|
+
}
|
|
17635
17646
|
return this.configCache;
|
|
17636
17647
|
} catch (error) {
|
|
17637
17648
|
if (error.code === "ENOENT") {
|
|
@@ -17769,10 +17780,14 @@ class ConfigService {
|
|
|
17769
17780
|
}
|
|
17770
17781
|
}
|
|
17771
17782
|
// src/services/git.service.ts
|
|
17783
|
+
var DEFAULT_GIT_TIMEOUT_MS = 60000;
|
|
17784
|
+
|
|
17772
17785
|
class GitService {
|
|
17773
17786
|
cwd;
|
|
17774
|
-
|
|
17787
|
+
timeoutMs;
|
|
17788
|
+
constructor(cwd, options = {}) {
|
|
17775
17789
|
this.cwd = cwd ?? process.cwd();
|
|
17790
|
+
this.timeoutMs = options.timeoutMs ?? DEFAULT_GIT_TIMEOUT_MS;
|
|
17776
17791
|
}
|
|
17777
17792
|
async exec(args, cwd) {
|
|
17778
17793
|
const proc = Bun.spawn(["git", ...args], {
|
|
@@ -17780,14 +17795,28 @@ class GitService {
|
|
|
17780
17795
|
stdout: "pipe",
|
|
17781
17796
|
stderr: "pipe"
|
|
17782
17797
|
});
|
|
17783
|
-
|
|
17784
|
-
const
|
|
17785
|
-
|
|
17786
|
-
|
|
17787
|
-
|
|
17788
|
-
|
|
17789
|
-
|
|
17790
|
-
|
|
17798
|
+
let timedOut = false;
|
|
17799
|
+
const timer = setTimeout(() => {
|
|
17800
|
+
timedOut = true;
|
|
17801
|
+
try {
|
|
17802
|
+
proc.kill();
|
|
17803
|
+
} catch {}
|
|
17804
|
+
}, this.timeoutMs);
|
|
17805
|
+
try {
|
|
17806
|
+
const stdout = await new Response(proc.stdout).text();
|
|
17807
|
+
const stderr = await new Response(proc.stderr).text();
|
|
17808
|
+
const exitCode = await proc.exited;
|
|
17809
|
+
if (timedOut) {
|
|
17810
|
+
throw new GitError(`git ${args.join(" ")} timed out after ${this.timeoutMs}ms`, `git ${args.join(" ")}`, exitCode);
|
|
17811
|
+
}
|
|
17812
|
+
return {
|
|
17813
|
+
stdout: stdout.trim(),
|
|
17814
|
+
stderr: stderr.trim(),
|
|
17815
|
+
exitCode
|
|
17816
|
+
};
|
|
17817
|
+
} finally {
|
|
17818
|
+
clearTimeout(timer);
|
|
17819
|
+
}
|
|
17791
17820
|
}
|
|
17792
17821
|
async execOrError(args, cwd) {
|
|
17793
17822
|
const result = await this.exec(args, cwd);
|
|
@@ -17823,6 +17852,9 @@ class GitService {
|
|
|
17823
17852
|
async getCurrentBranch() {
|
|
17824
17853
|
return this.execOrError(["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
17825
17854
|
}
|
|
17855
|
+
async getCurrentCommit() {
|
|
17856
|
+
return this.execOrError(["rev-parse", "HEAD"]);
|
|
17857
|
+
}
|
|
17826
17858
|
async getRemoteUrl(remote = "origin") {
|
|
17827
17859
|
const result = await this.exec(["remote", "get-url", remote]);
|
|
17828
17860
|
if (result.exitCode !== 0) {
|
|
@@ -17835,7 +17867,7 @@ class GitService {
|
|
|
17835
17867
|
return result.stdout;
|
|
17836
17868
|
}
|
|
17837
17869
|
withCwd(cwd) {
|
|
17838
|
-
return new GitService(cwd);
|
|
17870
|
+
return new GitService(cwd, { timeoutMs: this.timeoutMs });
|
|
17839
17871
|
}
|
|
17840
17872
|
}
|
|
17841
17873
|
// src/services/context.service.ts
|
|
@@ -17935,6 +17967,12 @@ class ContextService {
|
|
|
17935
17967
|
}
|
|
17936
17968
|
return result.context;
|
|
17937
17969
|
}
|
|
17970
|
+
async requireRepoContextFor(options, context) {
|
|
17971
|
+
return this.requireRepoContext({
|
|
17972
|
+
...context.globalOptions,
|
|
17973
|
+
...options
|
|
17974
|
+
});
|
|
17975
|
+
}
|
|
17938
17976
|
buildRepoNotFoundMessage(reason, remoteUrl) {
|
|
17939
17977
|
const fallback = "Use --workspace and --repo options, or run this command from within a Bitbucket repository.";
|
|
17940
17978
|
switch (reason) {
|
|
@@ -18566,6 +18604,15 @@ class OutputService {
|
|
|
18566
18604
|
text(message) {
|
|
18567
18605
|
console.log(stripControl(message));
|
|
18568
18606
|
}
|
|
18607
|
+
truncate(text, maxLength, suffix = "...") {
|
|
18608
|
+
if (maxLength <= 0 || text.length <= maxLength) {
|
|
18609
|
+
return text;
|
|
18610
|
+
}
|
|
18611
|
+
if (suffix.length >= maxLength) {
|
|
18612
|
+
return text.slice(0, maxLength);
|
|
18613
|
+
}
|
|
18614
|
+
return text.slice(0, maxLength - suffix.length) + suffix;
|
|
18615
|
+
}
|
|
18569
18616
|
formatDate(date) {
|
|
18570
18617
|
const d = typeof date === "string" ? new Date(date) : date;
|
|
18571
18618
|
return d.toLocaleDateString("en-US", {
|
|
@@ -18635,7 +18682,17 @@ function projectByFieldsRespectingWrapper(data, fields) {
|
|
|
18635
18682
|
return projectFields(data, fields);
|
|
18636
18683
|
}
|
|
18637
18684
|
async function runJq(data, expression) {
|
|
18638
|
-
|
|
18685
|
+
let jq;
|
|
18686
|
+
try {
|
|
18687
|
+
jq = await Promise.resolve().then(() => __toESM(require_dist(), 1));
|
|
18688
|
+
} catch (error) {
|
|
18689
|
+
throw new BBError({
|
|
18690
|
+
code: 8001 /* JQ_FAILED */,
|
|
18691
|
+
message: "Failed to load the embedded jq runtime (jq-wasm). Reinstall the CLI or report this issue.",
|
|
18692
|
+
cause: error instanceof Error ? error : undefined,
|
|
18693
|
+
context: { expression }
|
|
18694
|
+
});
|
|
18695
|
+
}
|
|
18639
18696
|
let result;
|
|
18640
18697
|
try {
|
|
18641
18698
|
result = await jq.raw(data, expression);
|
|
@@ -18807,7 +18864,11 @@ class VersionService {
|
|
|
18807
18864
|
latestVersion,
|
|
18808
18865
|
updateAvailable
|
|
18809
18866
|
};
|
|
18810
|
-
} catch {
|
|
18867
|
+
} catch (error) {
|
|
18868
|
+
if (process.env.DEBUG === "true") {
|
|
18869
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
18870
|
+
console.error(`[version-check] skipped: ${message}`);
|
|
18871
|
+
}
|
|
18811
18872
|
return null;
|
|
18812
18873
|
}
|
|
18813
18874
|
}
|
|
@@ -22941,7 +23002,12 @@ class OAuthService {
|
|
|
22941
23002
|
try {
|
|
22942
23003
|
const open2 = (await Promise.resolve().then(() => (init_open(), exports_open))).default;
|
|
22943
23004
|
await open2(authUrl);
|
|
22944
|
-
} catch {
|
|
23005
|
+
} catch (err) {
|
|
23006
|
+
if (process.env.DEBUG === "true") {
|
|
23007
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23008
|
+
console.error(`[oauth] could not open browser: ${message}`);
|
|
23009
|
+
}
|
|
23010
|
+
}
|
|
22945
23011
|
console.error(`If the browser doesn't open, visit:
|
|
22946
23012
|
${authUrl}
|
|
22947
23013
|
`);
|
|
@@ -23376,6 +23442,67 @@ function accountToEntry(account) {
|
|
|
23376
23442
|
nickname: asUser.nickname
|
|
23377
23443
|
};
|
|
23378
23444
|
}
|
|
23445
|
+
// src/services/url-builder.service.ts
|
|
23446
|
+
var BITBUCKET_WEB_BASE = "https://bitbucket.org";
|
|
23447
|
+
function encodePathSegments(path3) {
|
|
23448
|
+
return path3.split("/").map((segment) => encodeURIComponent(segment)).join("/");
|
|
23449
|
+
}
|
|
23450
|
+
|
|
23451
|
+
class UrlBuilderService {
|
|
23452
|
+
base;
|
|
23453
|
+
constructor(base = BITBUCKET_WEB_BASE) {
|
|
23454
|
+
this.base = base.replace(/\/+$/, "");
|
|
23455
|
+
}
|
|
23456
|
+
repo(ctx) {
|
|
23457
|
+
return this.repoBase(ctx);
|
|
23458
|
+
}
|
|
23459
|
+
src(ctx, branch, path3, line) {
|
|
23460
|
+
const encodedBranch = encodeURIComponent(branch);
|
|
23461
|
+
const trimmedPath = path3?.replace(/^\/+/, "").replace(/\/+$/, "") ?? "";
|
|
23462
|
+
const pathPart = trimmedPath ? `/${encodePathSegments(trimmedPath)}` : "/";
|
|
23463
|
+
const lineFragment = typeof line === "number" && Number.isFinite(line) && line > 0 ? `#lines-${line}` : "";
|
|
23464
|
+
return `${this.repoBase(ctx)}/src/${encodedBranch}${pathPart}${lineFragment}`;
|
|
23465
|
+
}
|
|
23466
|
+
branchList(ctx) {
|
|
23467
|
+
return `${this.repoBase(ctx)}/branches/`;
|
|
23468
|
+
}
|
|
23469
|
+
commit(ctx, sha) {
|
|
23470
|
+
return `${this.repoBase(ctx)}/commits/${encodeURIComponent(sha)}`;
|
|
23471
|
+
}
|
|
23472
|
+
commitList(ctx) {
|
|
23473
|
+
return `${this.repoBase(ctx)}/commits/`;
|
|
23474
|
+
}
|
|
23475
|
+
pullRequest(ctx, id) {
|
|
23476
|
+
return `${this.repoBase(ctx)}/pull-requests/${id}`;
|
|
23477
|
+
}
|
|
23478
|
+
pullRequestList(ctx) {
|
|
23479
|
+
return `${this.repoBase(ctx)}/pull-requests/`;
|
|
23480
|
+
}
|
|
23481
|
+
pipelinesHome(ctx) {
|
|
23482
|
+
return `${this.repoBase(ctx)}/pipelines`;
|
|
23483
|
+
}
|
|
23484
|
+
pipelineRun(ctx, idOrUuid) {
|
|
23485
|
+
return `${this.repoBase(ctx)}/pipelines/results/${encodeURIComponent(idOrUuid)}`;
|
|
23486
|
+
}
|
|
23487
|
+
downloads(ctx) {
|
|
23488
|
+
return `${this.repoBase(ctx)}/downloads/`;
|
|
23489
|
+
}
|
|
23490
|
+
issue(ctx, id) {
|
|
23491
|
+
return `${this.repoBase(ctx)}/issues/${id}`;
|
|
23492
|
+
}
|
|
23493
|
+
issueList(ctx) {
|
|
23494
|
+
return `${this.repoBase(ctx)}/issues`;
|
|
23495
|
+
}
|
|
23496
|
+
wiki(ctx) {
|
|
23497
|
+
return `${this.repoBase(ctx)}/wiki`;
|
|
23498
|
+
}
|
|
23499
|
+
settings(ctx) {
|
|
23500
|
+
return `${this.repoBase(ctx)}/admin`;
|
|
23501
|
+
}
|
|
23502
|
+
repoBase(ctx) {
|
|
23503
|
+
return `${this.base}/${encodeURIComponent(ctx.workspace)}/${encodeURIComponent(ctx.repoSlug)}`;
|
|
23504
|
+
}
|
|
23505
|
+
}
|
|
23379
23506
|
// src/bootstrap.ts
|
|
23380
23507
|
import { createRequire } from "module";
|
|
23381
23508
|
|
|
@@ -27201,6 +27328,18 @@ class BaseCommand {
|
|
|
27201
27328
|
}
|
|
27202
27329
|
return parsed;
|
|
27203
27330
|
}
|
|
27331
|
+
parsePositiveInt(value, name) {
|
|
27332
|
+
const trimmed = value.trim();
|
|
27333
|
+
const parsed = Number.parseInt(trimmed, 10);
|
|
27334
|
+
if (!Number.isFinite(parsed) || parsed < 1 || String(parsed) !== trimmed) {
|
|
27335
|
+
throw new BBError({
|
|
27336
|
+
code: 5002 /* VALIDATION_INVALID */,
|
|
27337
|
+
message: this.appendHelpHint(`--${name} must be a positive integer.`),
|
|
27338
|
+
context: { [name]: value }
|
|
27339
|
+
});
|
|
27340
|
+
}
|
|
27341
|
+
return parsed;
|
|
27342
|
+
}
|
|
27204
27343
|
parseEnumOption(value, name, allowed) {
|
|
27205
27344
|
if (!allowed.includes(value)) {
|
|
27206
27345
|
throw new BBError({
|
|
@@ -28028,10 +28167,7 @@ class ListDefaultReviewersCommand extends BaseCommand {
|
|
|
28028
28167
|
this.contextService = contextService;
|
|
28029
28168
|
}
|
|
28030
28169
|
async execute(options, context) {
|
|
28031
|
-
const repoContext = await this.contextService.
|
|
28032
|
-
...context.globalOptions,
|
|
28033
|
-
...options
|
|
28034
|
-
});
|
|
28170
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
28035
28171
|
const mode = options.repoOnly ? "direct" : "effective";
|
|
28036
28172
|
const reviewers = await this.defaultReviewerService.list(repoContext, mode);
|
|
28037
28173
|
if (context.globalOptions.json) {
|
|
@@ -28074,10 +28210,7 @@ class AddDefaultReviewerCommand extends BaseCommand {
|
|
|
28074
28210
|
this.contextService = contextService;
|
|
28075
28211
|
}
|
|
28076
28212
|
async execute(options, context) {
|
|
28077
|
-
const repoContext = await this.contextService.
|
|
28078
|
-
...context.globalOptions,
|
|
28079
|
-
...options
|
|
28080
|
-
});
|
|
28213
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
28081
28214
|
const userResponse = await this.usersApi.usersSelectedUserGet({
|
|
28082
28215
|
selectedUser: options.username
|
|
28083
28216
|
});
|
|
@@ -28111,10 +28244,7 @@ class RemoveDefaultReviewerCommand extends BaseCommand {
|
|
|
28111
28244
|
this.contextService = contextService;
|
|
28112
28245
|
}
|
|
28113
28246
|
async execute(options, context) {
|
|
28114
|
-
const repoContext = await this.contextService.
|
|
28115
|
-
...context.globalOptions,
|
|
28116
|
-
...options
|
|
28117
|
-
});
|
|
28247
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
28118
28248
|
if (!options.yes) {
|
|
28119
28249
|
throw new BBError({
|
|
28120
28250
|
code: 5001 /* VALIDATION_REQUIRED */,
|
|
@@ -28166,10 +28296,7 @@ class CreatePRCommand extends BaseCommand {
|
|
|
28166
28296
|
message: this.appendHelpHint("Pull request title is required. Use --title option.")
|
|
28167
28297
|
});
|
|
28168
28298
|
}
|
|
28169
|
-
const repoContext = await this.contextService.
|
|
28170
|
-
...context.globalOptions,
|
|
28171
|
-
...options
|
|
28172
|
-
});
|
|
28299
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
28173
28300
|
let sourceBranch = options.source;
|
|
28174
28301
|
if (!sourceBranch) {
|
|
28175
28302
|
sourceBranch = await this.gitService.getCurrentBranch();
|
|
@@ -28294,10 +28421,7 @@ class ListPRsCommand extends BaseCommand {
|
|
|
28294
28421
|
this.contextService = contextService;
|
|
28295
28422
|
}
|
|
28296
28423
|
async execute(options, context) {
|
|
28297
|
-
const repoContext = await this.contextService.
|
|
28298
|
-
...context.globalOptions,
|
|
28299
|
-
...options
|
|
28300
|
-
});
|
|
28424
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
28301
28425
|
const state = options.state ? this.parseEnumOption(options.state, "state", PR_STATES) : "OPEN";
|
|
28302
28426
|
const limit = parseLimit(options.limit);
|
|
28303
28427
|
const reviewerQuery = options.mine ? await this.buildMineFilter() : undefined;
|
|
@@ -28341,19 +28465,13 @@ class ListPRsCommand extends BaseCommand {
|
|
|
28341
28465
|
const destination = pr.destination;
|
|
28342
28466
|
return [
|
|
28343
28467
|
`#${pr.id}`,
|
|
28344
|
-
this.truncate(title ?? "", 50),
|
|
28468
|
+
this.output.truncate(title ?? "", 50),
|
|
28345
28469
|
pr.author?.display_name ?? "Unknown",
|
|
28346
28470
|
`${source?.branch?.name ?? "unknown"} \u2192 ${destination?.branch?.name ?? "unknown"}`
|
|
28347
28471
|
];
|
|
28348
28472
|
});
|
|
28349
28473
|
this.output.table(["ID", "TITLE", "AUTHOR", "BRANCHES"], rows);
|
|
28350
28474
|
}
|
|
28351
|
-
truncate(text, maxLength) {
|
|
28352
|
-
if (text.length <= maxLength) {
|
|
28353
|
-
return text;
|
|
28354
|
-
}
|
|
28355
|
-
return text.substring(0, maxLength - 3) + "...";
|
|
28356
|
-
}
|
|
28357
28475
|
async buildMineFilter() {
|
|
28358
28476
|
const response = await this.usersApi.userGet();
|
|
28359
28477
|
const userUuid = response.data.uuid;
|
|
@@ -28377,11 +28495,8 @@ class ViewPRCommand extends BaseCommand {
|
|
|
28377
28495
|
this.contextService = contextService;
|
|
28378
28496
|
}
|
|
28379
28497
|
async execute(options, context) {
|
|
28380
|
-
const repoContext = await this.contextService.
|
|
28381
|
-
|
|
28382
|
-
...options
|
|
28383
|
-
});
|
|
28384
|
-
const prId = this.parseIntOption(options.id, "id");
|
|
28498
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
28499
|
+
const prId = this.parsePositiveInt(options.id, "id");
|
|
28385
28500
|
const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdGet({
|
|
28386
28501
|
workspace: repoContext.workspace,
|
|
28387
28502
|
repoSlug: repoContext.repoSlug,
|
|
@@ -28506,13 +28621,10 @@ class EditPRCommand extends BaseCommand {
|
|
|
28506
28621
|
this.gitService = gitService;
|
|
28507
28622
|
}
|
|
28508
28623
|
async execute(options, context) {
|
|
28509
|
-
const repoContext = await this.contextService.
|
|
28510
|
-
...context.globalOptions,
|
|
28511
|
-
...options
|
|
28512
|
-
});
|
|
28624
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
28513
28625
|
let prId;
|
|
28514
28626
|
if (options.id) {
|
|
28515
|
-
prId =
|
|
28627
|
+
prId = this.parsePositiveInt(options.id, "id");
|
|
28516
28628
|
} else {
|
|
28517
28629
|
const currentBranch = await this.gitService.getCurrentBranch();
|
|
28518
28630
|
const matches = await collectPages({
|
|
@@ -28587,7 +28699,7 @@ class EditPRCommand extends BaseCommand {
|
|
|
28587
28699
|
this.output.success(`Updated pull request #${pr.id}`);
|
|
28588
28700
|
this.output.text(` ${this.output.dim("Title:")} ${pr.title}`);
|
|
28589
28701
|
if (pr.description) {
|
|
28590
|
-
const truncatedDesc =
|
|
28702
|
+
const truncatedDesc = this.output.truncate(pr.description, 100);
|
|
28591
28703
|
this.output.text(` ${this.output.dim("Description:")} ${truncatedDesc}`);
|
|
28592
28704
|
}
|
|
28593
28705
|
this.output.text(` ${this.output.dim("URL:")} ${links?.html?.href}`);
|
|
@@ -28608,11 +28720,8 @@ class MergePRCommand extends BaseCommand {
|
|
|
28608
28720
|
this.contextService = contextService;
|
|
28609
28721
|
}
|
|
28610
28722
|
async execute(options, context) {
|
|
28611
|
-
const repoContext = await this.contextService.
|
|
28612
|
-
|
|
28613
|
-
...options
|
|
28614
|
-
});
|
|
28615
|
-
const prId = this.parseIntOption(options.id, "id");
|
|
28723
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
28724
|
+
const prId = this.parsePositiveInt(options.id, "id");
|
|
28616
28725
|
const request = {
|
|
28617
28726
|
type: "pullrequest_merge_parameters"
|
|
28618
28727
|
};
|
|
@@ -28656,11 +28765,8 @@ class ApprovePRCommand extends BaseCommand {
|
|
|
28656
28765
|
this.contextService = contextService;
|
|
28657
28766
|
}
|
|
28658
28767
|
async execute(options, context) {
|
|
28659
|
-
const repoContext = await this.contextService.
|
|
28660
|
-
|
|
28661
|
-
...options
|
|
28662
|
-
});
|
|
28663
|
-
const prId = Number.parseInt(options.id, 10);
|
|
28768
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
28769
|
+
const prId = this.parsePositiveInt(options.id, "id");
|
|
28664
28770
|
await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdApprovePost({
|
|
28665
28771
|
workspace: repoContext.workspace,
|
|
28666
28772
|
repoSlug: repoContext.repoSlug,
|
|
@@ -28689,11 +28795,8 @@ class DeclinePRCommand extends BaseCommand {
|
|
|
28689
28795
|
this.contextService = contextService;
|
|
28690
28796
|
}
|
|
28691
28797
|
async execute(options, context) {
|
|
28692
|
-
const repoContext = await this.contextService.
|
|
28693
|
-
|
|
28694
|
-
...options
|
|
28695
|
-
});
|
|
28696
|
-
const prId = Number.parseInt(options.id, 10);
|
|
28798
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
28799
|
+
const prId = this.parsePositiveInt(options.id, "id");
|
|
28697
28800
|
const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdDeclinePost({
|
|
28698
28801
|
workspace: repoContext.workspace,
|
|
28699
28802
|
repoSlug: repoContext.repoSlug,
|
|
@@ -28724,11 +28827,8 @@ class ReadyPRCommand extends BaseCommand {
|
|
|
28724
28827
|
this.contextService = contextService;
|
|
28725
28828
|
}
|
|
28726
28829
|
async execute(options, context) {
|
|
28727
|
-
const repoContext = await this.contextService.
|
|
28728
|
-
|
|
28729
|
-
...options
|
|
28730
|
-
});
|
|
28731
|
-
const prId = Number.parseInt(options.id, 10);
|
|
28830
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
28831
|
+
const prId = this.parsePositiveInt(options.id, "id");
|
|
28732
28832
|
const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdPut({
|
|
28733
28833
|
workspace: repoContext.workspace,
|
|
28734
28834
|
repoSlug: repoContext.repoSlug,
|
|
@@ -28766,11 +28866,8 @@ class CheckoutPRCommand extends BaseCommand {
|
|
|
28766
28866
|
this.gitService = gitService;
|
|
28767
28867
|
}
|
|
28768
28868
|
async execute(options, context) {
|
|
28769
|
-
const repoContext = await this.contextService.
|
|
28770
|
-
|
|
28771
|
-
...options
|
|
28772
|
-
});
|
|
28773
|
-
const prId = Number.parseInt(options.id, 10);
|
|
28869
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
28870
|
+
const prId = this.parsePositiveInt(options.id, "id");
|
|
28774
28871
|
const prResponse = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdGet({
|
|
28775
28872
|
workspace: repoContext.workspace,
|
|
28776
28873
|
repoSlug: repoContext.repoSlug,
|
|
@@ -28833,20 +28930,10 @@ class DiffPRCommand extends BaseCommand {
|
|
|
28833
28930
|
this.gitService = gitService;
|
|
28834
28931
|
}
|
|
28835
28932
|
async execute(options, context) {
|
|
28836
|
-
const repoContext = await this.contextService.
|
|
28837
|
-
...context.globalOptions,
|
|
28838
|
-
...options
|
|
28839
|
-
});
|
|
28933
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
28840
28934
|
let prId;
|
|
28841
28935
|
if (options.id) {
|
|
28842
|
-
prId =
|
|
28843
|
-
if (Number.isNaN(prId)) {
|
|
28844
|
-
throw new BBError({
|
|
28845
|
-
code: 5002 /* VALIDATION_INVALID */,
|
|
28846
|
-
message: "Invalid PR ID",
|
|
28847
|
-
context: { id: options.id }
|
|
28848
|
-
});
|
|
28849
|
-
}
|
|
28936
|
+
prId = this.parsePositiveInt(options.id, "id");
|
|
28850
28937
|
} else {
|
|
28851
28938
|
const currentBranch = await this.gitService.getCurrentBranch();
|
|
28852
28939
|
const matches = await collectPages({
|
|
@@ -29063,11 +29150,8 @@ class ActivityPRCommand extends BaseCommand {
|
|
|
29063
29150
|
this.contextService = contextService;
|
|
29064
29151
|
}
|
|
29065
29152
|
async execute(options, context) {
|
|
29066
|
-
const repoContext = await this.contextService.
|
|
29067
|
-
|
|
29068
|
-
...options
|
|
29069
|
-
});
|
|
29070
|
-
const prId = this.parseIntOption(options.id, "id");
|
|
29153
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
29154
|
+
const prId = this.parsePositiveInt(options.id, "id");
|
|
29071
29155
|
const filterTypes = this.parseTypeFilter(options.type);
|
|
29072
29156
|
const limit = parseLimit(options.limit);
|
|
29073
29157
|
const activities = await collectPages({
|
|
@@ -29176,14 +29260,14 @@ class ActivityPRCommand extends BaseCommand {
|
|
|
29176
29260
|
case "comment": {
|
|
29177
29261
|
const content = getRawContent(activity.comment?.content) ?? "";
|
|
29178
29262
|
const id = activity.comment?.id ? `#${activity.comment.id}` : "";
|
|
29179
|
-
const snippet = this.truncate(content, 80);
|
|
29263
|
+
const snippet = this.output.truncate(content, 80);
|
|
29180
29264
|
return [id, snippet].filter(Boolean).join(" ");
|
|
29181
29265
|
}
|
|
29182
29266
|
case "approval":
|
|
29183
29267
|
return "approved";
|
|
29184
29268
|
case "changes_requested": {
|
|
29185
29269
|
const reason = activity.changes_requested?.reason;
|
|
29186
|
-
return reason ? this.truncate(reason, 80) : "changes requested";
|
|
29270
|
+
return reason ? this.output.truncate(reason, 80) : "changes requested";
|
|
29187
29271
|
}
|
|
29188
29272
|
case "merge":
|
|
29189
29273
|
return this.formatCommitDetail(activity.merge?.commit?.hash, "merged");
|
|
@@ -29196,7 +29280,7 @@ class ActivityPRCommand extends BaseCommand {
|
|
|
29196
29280
|
return `state: ${activity.update.state}`;
|
|
29197
29281
|
}
|
|
29198
29282
|
if (activity.update?.title) {
|
|
29199
|
-
return `title: ${this.truncate(activity.update.title, 60)}`;
|
|
29283
|
+
return `title: ${this.output.truncate(activity.update.title, 60)}`;
|
|
29200
29284
|
}
|
|
29201
29285
|
if (activity.update?.description) {
|
|
29202
29286
|
return "description updated";
|
|
@@ -29214,12 +29298,6 @@ class ActivityPRCommand extends BaseCommand {
|
|
|
29214
29298
|
const shortHash = hash.slice(0, 7);
|
|
29215
29299
|
return label ? `${label} ${shortHash}` : shortHash;
|
|
29216
29300
|
}
|
|
29217
|
-
truncate(text, maxLength) {
|
|
29218
|
-
if (text.length <= maxLength) {
|
|
29219
|
-
return text;
|
|
29220
|
-
}
|
|
29221
|
-
return text.substring(0, maxLength - 3) + "...";
|
|
29222
|
-
}
|
|
29223
29301
|
}
|
|
29224
29302
|
|
|
29225
29303
|
// src/commands/pr/comment.command.ts
|
|
@@ -29253,33 +29331,14 @@ class CommentPRCommand extends BaseCommand {
|
|
|
29253
29331
|
}
|
|
29254
29332
|
});
|
|
29255
29333
|
}
|
|
29256
|
-
|
|
29257
|
-
|
|
29258
|
-
|
|
29259
|
-
|
|
29260
|
-
code: 5002 /* VALIDATION_INVALID */,
|
|
29261
|
-
message: "--line-to must be a positive integer"
|
|
29262
|
-
});
|
|
29263
|
-
}
|
|
29264
|
-
}
|
|
29265
|
-
if (options.lineFrom) {
|
|
29266
|
-
const parsed = Number.parseInt(options.lineFrom, 10);
|
|
29267
|
-
if (Number.isNaN(parsed) || parsed < 1) {
|
|
29268
|
-
throw new BBError({
|
|
29269
|
-
code: 5002 /* VALIDATION_INVALID */,
|
|
29270
|
-
message: "--line-from must be a positive integer"
|
|
29271
|
-
});
|
|
29272
|
-
}
|
|
29273
|
-
}
|
|
29274
|
-
const repoContext = await this.contextService.requireRepoContext({
|
|
29275
|
-
...context.globalOptions,
|
|
29276
|
-
...options
|
|
29277
|
-
});
|
|
29278
|
-
const prId = Number.parseInt(options.id, 10);
|
|
29334
|
+
const lineTo = options.lineTo ? this.parsePositiveInt(options.lineTo, "line-to") : undefined;
|
|
29335
|
+
const lineFrom = options.lineFrom ? this.parsePositiveInt(options.lineFrom, "line-from") : undefined;
|
|
29336
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
29337
|
+
const prId = this.parsePositiveInt(options.id, "id");
|
|
29279
29338
|
const inline = options.file ? {
|
|
29280
29339
|
path: options.file,
|
|
29281
|
-
...
|
|
29282
|
-
...
|
|
29340
|
+
...lineTo !== undefined ? { to: lineTo } : {},
|
|
29341
|
+
...lineFrom !== undefined ? { from: lineFrom } : {}
|
|
29283
29342
|
} : undefined;
|
|
29284
29343
|
const body = {
|
|
29285
29344
|
content: {
|
|
@@ -29329,11 +29388,8 @@ class ListCommentsPRCommand extends BaseCommand {
|
|
|
29329
29388
|
this.contextService = contextService;
|
|
29330
29389
|
}
|
|
29331
29390
|
async execute(options, context) {
|
|
29332
|
-
const repoContext = await this.contextService.
|
|
29333
|
-
|
|
29334
|
-
...options
|
|
29335
|
-
});
|
|
29336
|
-
const prId = this.parseIntOption(options.id, "id");
|
|
29391
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
29392
|
+
const prId = this.parsePositiveInt(options.id, "id");
|
|
29337
29393
|
const limit = parseLimit(options.limit);
|
|
29338
29394
|
const values = await collectPages({
|
|
29339
29395
|
limit,
|
|
@@ -29350,6 +29406,8 @@ class ListCommentsPRCommand extends BaseCommand {
|
|
|
29350
29406
|
});
|
|
29351
29407
|
if (context.globalOptions.json) {
|
|
29352
29408
|
await this.output.json({
|
|
29409
|
+
workspace: repoContext.workspace,
|
|
29410
|
+
repoSlug: repoContext.repoSlug,
|
|
29353
29411
|
pullRequestId: prId,
|
|
29354
29412
|
count: values.length,
|
|
29355
29413
|
comments: values
|
|
@@ -29365,7 +29423,7 @@ class ListCommentsPRCommand extends BaseCommand {
|
|
|
29365
29423
|
return [
|
|
29366
29424
|
comment.id?.toString() ?? "",
|
|
29367
29425
|
getUserDisplayName(comment.user) ?? "Unknown",
|
|
29368
|
-
comment.deleted ? "[deleted]" : options.truncate === false ? content :
|
|
29426
|
+
comment.deleted ? "[deleted]" : options.truncate === false ? content : this.output.truncate(content, 60),
|
|
29369
29427
|
this.output.formatDate(comment.created_on ?? "")
|
|
29370
29428
|
];
|
|
29371
29429
|
});
|
|
@@ -29385,12 +29443,9 @@ class EditCommentPRCommand extends BaseCommand {
|
|
|
29385
29443
|
this.contextService = contextService;
|
|
29386
29444
|
}
|
|
29387
29445
|
async execute(options, context) {
|
|
29388
|
-
const repoContext = await this.contextService.
|
|
29389
|
-
|
|
29390
|
-
|
|
29391
|
-
});
|
|
29392
|
-
const prId = this.parseIntOption(options.prId, "pr-id");
|
|
29393
|
-
const commentId = this.parseIntOption(options.commentId, "comment-id");
|
|
29446
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
29447
|
+
const prId = this.parsePositiveInt(options.prId, "pr-id");
|
|
29448
|
+
const commentId = this.parsePositiveInt(options.commentId, "comment-id");
|
|
29394
29449
|
const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdCommentsCommentIdPut({
|
|
29395
29450
|
workspace: repoContext.workspace,
|
|
29396
29451
|
repoSlug: repoContext.repoSlug,
|
|
@@ -29428,12 +29483,9 @@ class DeleteCommentPRCommand extends BaseCommand {
|
|
|
29428
29483
|
this.contextService = contextService;
|
|
29429
29484
|
}
|
|
29430
29485
|
async execute(options, context) {
|
|
29431
|
-
const repoContext = await this.contextService.
|
|
29432
|
-
|
|
29433
|
-
|
|
29434
|
-
});
|
|
29435
|
-
const prId = this.parseIntOption(options.prId, "pr-id");
|
|
29436
|
-
const commentId = this.parseIntOption(options.commentId, "comment-id");
|
|
29486
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
29487
|
+
const prId = this.parsePositiveInt(options.prId, "pr-id");
|
|
29488
|
+
const commentId = this.parsePositiveInt(options.commentId, "comment-id");
|
|
29437
29489
|
if (!options.yes) {
|
|
29438
29490
|
throw new BBError({
|
|
29439
29491
|
code: 5001 /* VALIDATION_REQUIRED */,
|
|
@@ -29473,11 +29525,8 @@ class AddReviewerPRCommand extends BaseCommand {
|
|
|
29473
29525
|
this.contextService = contextService;
|
|
29474
29526
|
}
|
|
29475
29527
|
async execute(options, context) {
|
|
29476
|
-
const repoContext = await this.contextService.
|
|
29477
|
-
|
|
29478
|
-
...options
|
|
29479
|
-
});
|
|
29480
|
-
const prId = this.parseIntOption(options.id, "id");
|
|
29528
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
29529
|
+
const prId = this.parsePositiveInt(options.id, "id");
|
|
29481
29530
|
const userResponse = await this.usersApi.usersSelectedUserGet({
|
|
29482
29531
|
selectedUser: options.username
|
|
29483
29532
|
});
|
|
@@ -29518,11 +29567,8 @@ class RemoveReviewerPRCommand extends BaseCommand {
|
|
|
29518
29567
|
this.contextService = contextService;
|
|
29519
29568
|
}
|
|
29520
29569
|
async execute(options, context) {
|
|
29521
|
-
const repoContext = await this.contextService.
|
|
29522
|
-
|
|
29523
|
-
...options
|
|
29524
|
-
});
|
|
29525
|
-
const prId = this.parseIntOption(options.id, "id");
|
|
29570
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
29571
|
+
const prId = this.parsePositiveInt(options.id, "id");
|
|
29526
29572
|
const userResponse = await this.usersApi.usersSelectedUserGet({
|
|
29527
29573
|
selectedUser: options.username
|
|
29528
29574
|
});
|
|
@@ -29556,11 +29602,8 @@ class ListReviewersPRCommand extends BaseCommand {
|
|
|
29556
29602
|
this.contextService = contextService;
|
|
29557
29603
|
}
|
|
29558
29604
|
async execute(options, context) {
|
|
29559
|
-
const repoContext = await this.contextService.
|
|
29560
|
-
|
|
29561
|
-
...options
|
|
29562
|
-
});
|
|
29563
|
-
const prId = this.parseIntOption(options.id, "id");
|
|
29605
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
29606
|
+
const prId = this.parsePositiveInt(options.id, "id");
|
|
29564
29607
|
const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdGet({
|
|
29565
29608
|
workspace: repoContext.workspace,
|
|
29566
29609
|
repoSlug: repoContext.repoSlug,
|
|
@@ -29570,6 +29613,8 @@ class ListReviewersPRCommand extends BaseCommand {
|
|
|
29570
29613
|
const reviewers = Array.from(pr.reviewers ?? []);
|
|
29571
29614
|
if (context.globalOptions.json) {
|
|
29572
29615
|
await this.output.json({
|
|
29616
|
+
workspace: repoContext.workspace,
|
|
29617
|
+
repoSlug: repoContext.repoSlug,
|
|
29573
29618
|
pullRequestId: prId,
|
|
29574
29619
|
count: reviewers.length,
|
|
29575
29620
|
reviewers
|
|
@@ -29596,11 +29641,8 @@ class ChecksPRCommand extends BaseCommand {
|
|
|
29596
29641
|
this.contextService = contextService;
|
|
29597
29642
|
}
|
|
29598
29643
|
async execute(options, context) {
|
|
29599
|
-
const repoContext = await this.contextService.
|
|
29600
|
-
|
|
29601
|
-
...options
|
|
29602
|
-
});
|
|
29603
|
-
const prId = this.parseIntOption(options.id, "id");
|
|
29644
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
29645
|
+
const prId = this.parsePositiveInt(options.id, "id");
|
|
29604
29646
|
const response = await this.commitStatusesApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdStatusesGet({
|
|
29605
29647
|
workspace: repoContext.workspace,
|
|
29606
29648
|
repoSlug: repoContext.repoSlug,
|
|
@@ -29654,7 +29696,7 @@ class ChecksPRCommand extends BaseCommand {
|
|
|
29654
29696
|
return [
|
|
29655
29697
|
`${stateIcon} ${stateLabel}`,
|
|
29656
29698
|
this.output.bold(name),
|
|
29657
|
-
this.truncate(description, 40),
|
|
29699
|
+
this.output.truncate(description, 40),
|
|
29658
29700
|
status.updated_on ? this.output.formatDate(status.updated_on) : "-"
|
|
29659
29701
|
];
|
|
29660
29702
|
});
|
|
@@ -29704,12 +29746,6 @@ class ChecksPRCommand extends BaseCommand {
|
|
|
29704
29746
|
return acc;
|
|
29705
29747
|
}, { successful: 0, failed: 0, pending: 0 });
|
|
29706
29748
|
}
|
|
29707
|
-
truncate(text, maxLength) {
|
|
29708
|
-
if (text.length <= maxLength) {
|
|
29709
|
-
return text;
|
|
29710
|
-
}
|
|
29711
|
-
return text.substring(0, maxLength - 3) + "...";
|
|
29712
|
-
}
|
|
29713
29749
|
}
|
|
29714
29750
|
|
|
29715
29751
|
// src/commands/snippet/list.command.ts
|
|
@@ -30122,7 +30158,7 @@ class ListSnippetCommentsCommand extends BaseCommand {
|
|
|
30122
30158
|
String(comment.id ?? ""),
|
|
30123
30159
|
getUserDisplayName(comment.user) ?? "Unknown",
|
|
30124
30160
|
this.output.formatDate(comment.created_on ?? ""),
|
|
30125
|
-
|
|
30161
|
+
this.output.truncate(content, 60)
|
|
30126
30162
|
];
|
|
30127
30163
|
});
|
|
30128
30164
|
this.output.table(["ID", "AUTHOR", "DATE", "CONTENT"], rows);
|
|
@@ -30181,7 +30217,7 @@ class EditSnippetCommentCommand extends BaseCommand {
|
|
|
30181
30217
|
}
|
|
30182
30218
|
async execute(options, context) {
|
|
30183
30219
|
const workspace = await this.contextService.requireWorkspace(options.workspace ?? context.globalOptions.workspace);
|
|
30184
|
-
const commentId = this.
|
|
30220
|
+
const commentId = this.parsePositiveInt(options.commentId, "comment-id");
|
|
30185
30221
|
const body = {
|
|
30186
30222
|
type: "snippet_comment",
|
|
30187
30223
|
content: {
|
|
@@ -30219,7 +30255,7 @@ class DeleteSnippetCommentCommand extends BaseCommand {
|
|
|
30219
30255
|
}
|
|
30220
30256
|
async execute(options, context) {
|
|
30221
30257
|
const workspace = await this.contextService.requireWorkspace(options.workspace ?? context.globalOptions.workspace);
|
|
30222
|
-
const commentId = this.
|
|
30258
|
+
const commentId = this.parsePositiveInt(options.commentId, "comment-id");
|
|
30223
30259
|
if (!options.yes) {
|
|
30224
30260
|
throw new BBError({
|
|
30225
30261
|
code: 5001 /* VALIDATION_REQUIRED */,
|
|
@@ -30451,6 +30487,179 @@ class UninstallCompletionCommand extends BaseCommand {
|
|
|
30451
30487
|
}
|
|
30452
30488
|
}
|
|
30453
30489
|
|
|
30490
|
+
// src/commands/browse.command.ts
|
|
30491
|
+
var SHA_PATTERN = /^[0-9a-f]{7,40}$/i;
|
|
30492
|
+
var PR_NUMBER_PATTERN = /^\d+$/;
|
|
30493
|
+
var PATH_LINE_PATTERN = /^(.+):(\d+)$/;
|
|
30494
|
+
|
|
30495
|
+
class BrowseCommand extends BaseCommand {
|
|
30496
|
+
contextService;
|
|
30497
|
+
gitService;
|
|
30498
|
+
urlBuilder;
|
|
30499
|
+
name = "browse";
|
|
30500
|
+
description = "Open a Bitbucket page (repo, file, PR, commit, etc.) in your browser";
|
|
30501
|
+
constructor(contextService, gitService, urlBuilder, output) {
|
|
30502
|
+
super(output);
|
|
30503
|
+
this.contextService = contextService;
|
|
30504
|
+
this.gitService = gitService;
|
|
30505
|
+
this.urlBuilder = urlBuilder;
|
|
30506
|
+
}
|
|
30507
|
+
async execute(options, context) {
|
|
30508
|
+
const repoContext = await this.contextService.requireRepoContextFor(options, context);
|
|
30509
|
+
this.validateFlagCombination(options);
|
|
30510
|
+
const url2 = await this.resolveUrl(options, repoContext);
|
|
30511
|
+
const useJson = Boolean(context.globalOptions.json);
|
|
30512
|
+
const printOnly = options.browser === false;
|
|
30513
|
+
if (useJson) {
|
|
30514
|
+
await this.output.json({ url: url2 });
|
|
30515
|
+
return { url: url2, opened: false };
|
|
30516
|
+
}
|
|
30517
|
+
if (printOnly) {
|
|
30518
|
+
this.output.text(url2);
|
|
30519
|
+
return { url: url2, opened: false };
|
|
30520
|
+
}
|
|
30521
|
+
await this.openInBrowser(url2);
|
|
30522
|
+
return { url: url2, opened: true };
|
|
30523
|
+
}
|
|
30524
|
+
async resolveUrl(options, ctx) {
|
|
30525
|
+
if (options.pr !== undefined) {
|
|
30526
|
+
return this.urlBuilder.pullRequest(ctx, this.parsePositiveInt(options.pr, "pr"));
|
|
30527
|
+
}
|
|
30528
|
+
if (options.prs || options.pullRequests) {
|
|
30529
|
+
return this.urlBuilder.pullRequestList(ctx);
|
|
30530
|
+
}
|
|
30531
|
+
if (options.branches) {
|
|
30532
|
+
return this.urlBuilder.branchList(ctx);
|
|
30533
|
+
}
|
|
30534
|
+
if (options.commits) {
|
|
30535
|
+
return this.urlBuilder.commitList(ctx);
|
|
30536
|
+
}
|
|
30537
|
+
if (options.commit !== undefined) {
|
|
30538
|
+
const sha = typeof options.commit === "string" && options.commit.length > 0 ? options.commit : await this.gitService.getCurrentCommit();
|
|
30539
|
+
return this.urlBuilder.commit(ctx, sha);
|
|
30540
|
+
}
|
|
30541
|
+
if (options.pipelines) {
|
|
30542
|
+
return this.urlBuilder.pipelinesHome(ctx);
|
|
30543
|
+
}
|
|
30544
|
+
if (options.pipeline !== undefined) {
|
|
30545
|
+
const value = options.pipeline.trim();
|
|
30546
|
+
if (value.length === 0) {
|
|
30547
|
+
throw new BBError({
|
|
30548
|
+
code: 5002 /* VALIDATION_INVALID */,
|
|
30549
|
+
message: this.appendHelpHint("--pipeline requires a run id or uuid.")
|
|
30550
|
+
});
|
|
30551
|
+
}
|
|
30552
|
+
return this.urlBuilder.pipelineRun(ctx, value);
|
|
30553
|
+
}
|
|
30554
|
+
if (options.downloads) {
|
|
30555
|
+
return this.urlBuilder.downloads(ctx);
|
|
30556
|
+
}
|
|
30557
|
+
if (options.issue !== undefined) {
|
|
30558
|
+
return this.urlBuilder.issue(ctx, this.parsePositiveInt(options.issue, "issue"));
|
|
30559
|
+
}
|
|
30560
|
+
if (options.issues) {
|
|
30561
|
+
return this.urlBuilder.issueList(ctx);
|
|
30562
|
+
}
|
|
30563
|
+
if (options.wiki) {
|
|
30564
|
+
return this.urlBuilder.wiki(ctx);
|
|
30565
|
+
}
|
|
30566
|
+
if (options.settings) {
|
|
30567
|
+
return this.urlBuilder.settings(ctx);
|
|
30568
|
+
}
|
|
30569
|
+
const target = options.target?.trim();
|
|
30570
|
+
if (target && target.length > 0) {
|
|
30571
|
+
if (PR_NUMBER_PATTERN.test(target)) {
|
|
30572
|
+
return this.urlBuilder.pullRequest(ctx, this.parsePositiveInt(target, "target"));
|
|
30573
|
+
}
|
|
30574
|
+
if (SHA_PATTERN.test(target)) {
|
|
30575
|
+
return this.urlBuilder.commit(ctx, target);
|
|
30576
|
+
}
|
|
30577
|
+
const { path: path3, line } = this.parsePathWithLine(target);
|
|
30578
|
+
const branch = await this.resolveBranch(options.branch);
|
|
30579
|
+
return this.urlBuilder.src(ctx, branch, path3, line);
|
|
30580
|
+
}
|
|
30581
|
+
if (options.branch) {
|
|
30582
|
+
return this.urlBuilder.src(ctx, options.branch);
|
|
30583
|
+
}
|
|
30584
|
+
return this.urlBuilder.repo(ctx);
|
|
30585
|
+
}
|
|
30586
|
+
validateFlagCombination(options) {
|
|
30587
|
+
const setFlags = [];
|
|
30588
|
+
if (options.pr !== undefined)
|
|
30589
|
+
setFlags.push("--pr");
|
|
30590
|
+
if (options.prs) {
|
|
30591
|
+
setFlags.push("--prs");
|
|
30592
|
+
} else if (options.pullRequests) {
|
|
30593
|
+
setFlags.push("--pull-requests");
|
|
30594
|
+
}
|
|
30595
|
+
if (options.branches)
|
|
30596
|
+
setFlags.push("--branches");
|
|
30597
|
+
if (options.commit !== undefined)
|
|
30598
|
+
setFlags.push("--commit");
|
|
30599
|
+
if (options.commits)
|
|
30600
|
+
setFlags.push("--commits");
|
|
30601
|
+
if (options.pipelines)
|
|
30602
|
+
setFlags.push("--pipelines");
|
|
30603
|
+
if (options.pipeline !== undefined)
|
|
30604
|
+
setFlags.push("--pipeline");
|
|
30605
|
+
if (options.downloads)
|
|
30606
|
+
setFlags.push("--downloads");
|
|
30607
|
+
if (options.issue !== undefined)
|
|
30608
|
+
setFlags.push("--issue");
|
|
30609
|
+
if (options.issues)
|
|
30610
|
+
setFlags.push("--issues");
|
|
30611
|
+
if (options.wiki)
|
|
30612
|
+
setFlags.push("--wiki");
|
|
30613
|
+
if (options.settings)
|
|
30614
|
+
setFlags.push("--settings");
|
|
30615
|
+
if (setFlags.length > 1) {
|
|
30616
|
+
throw new BBError({
|
|
30617
|
+
code: 5002 /* VALIDATION_INVALID */,
|
|
30618
|
+
message: this.appendHelpHint(`Cannot combine ${setFlags.join(" and ")}; pick one resource.`)
|
|
30619
|
+
});
|
|
30620
|
+
}
|
|
30621
|
+
const hasResourceFlag = setFlags.length === 1;
|
|
30622
|
+
const hasTarget = !!options.target?.trim();
|
|
30623
|
+
if (hasResourceFlag && hasTarget) {
|
|
30624
|
+
throw new BBError({
|
|
30625
|
+
code: 5002 /* VALIDATION_INVALID */,
|
|
30626
|
+
message: this.appendHelpHint(`Cannot use a positional target with ${setFlags[0]}.`)
|
|
30627
|
+
});
|
|
30628
|
+
}
|
|
30629
|
+
if (hasResourceFlag && options.branch) {
|
|
30630
|
+
throw new BBError({
|
|
30631
|
+
code: 5002 /* VALIDATION_INVALID */,
|
|
30632
|
+
message: this.appendHelpHint(`Cannot combine --branch with ${setFlags[0]}.`)
|
|
30633
|
+
});
|
|
30634
|
+
}
|
|
30635
|
+
}
|
|
30636
|
+
parsePathWithLine(target) {
|
|
30637
|
+
const match = PATH_LINE_PATTERN.exec(target);
|
|
30638
|
+
if (match) {
|
|
30639
|
+
const line = Number.parseInt(match[2], 10);
|
|
30640
|
+
if (Number.isFinite(line) && line > 0) {
|
|
30641
|
+
return { path: match[1], line };
|
|
30642
|
+
}
|
|
30643
|
+
}
|
|
30644
|
+
return { path: target };
|
|
30645
|
+
}
|
|
30646
|
+
async resolveBranch(explicit) {
|
|
30647
|
+
if (explicit && explicit.length > 0) {
|
|
30648
|
+
return explicit;
|
|
30649
|
+
}
|
|
30650
|
+
try {
|
|
30651
|
+
return await this.gitService.getCurrentBranch();
|
|
30652
|
+
} catch {
|
|
30653
|
+
return "HEAD";
|
|
30654
|
+
}
|
|
30655
|
+
}
|
|
30656
|
+
async openInBrowser(url2) {
|
|
30657
|
+
this.output.info(`Opening ${url2} in your browser...`);
|
|
30658
|
+
const open2 = (await Promise.resolve().then(() => (init_open(), exports_open))).default;
|
|
30659
|
+
await open2(url2);
|
|
30660
|
+
}
|
|
30661
|
+
}
|
|
30662
|
+
|
|
30454
30663
|
// src/bootstrap.ts
|
|
30455
30664
|
var require2 = createRequire(import.meta.url);
|
|
30456
30665
|
var pkg = require2("../package.json");
|
|
@@ -30497,6 +30706,7 @@ function bootstrap(options = {}) {
|
|
|
30497
30706
|
});
|
|
30498
30707
|
registerCommand(container, ServiceTokens.SnippetFilesService, SnippetFilesService, [ServiceTokens.SnippetsAxios]);
|
|
30499
30708
|
registerCommand(container, ServiceTokens.DefaultReviewerService, DefaultReviewerService, [ServiceTokens.PullrequestsApi]);
|
|
30709
|
+
container.register(ServiceTokens.UrlBuilderService, () => new UrlBuilderService);
|
|
30500
30710
|
registerCommand(container, ServiceTokens.LoginCommand, LoginCommand, [
|
|
30501
30711
|
ServiceTokens.CredentialStore,
|
|
30502
30712
|
ServiceTokens.UsersApi,
|
|
@@ -30731,6 +30941,12 @@ function bootstrap(options = {}) {
|
|
|
30731
30941
|
ServiceTokens.OutputService
|
|
30732
30942
|
]);
|
|
30733
30943
|
registerCommand(container, ServiceTokens.ListConfigCommand, ListConfigCommand, [ServiceTokens.ConfigService, ServiceTokens.OutputService]);
|
|
30944
|
+
registerCommand(container, ServiceTokens.BrowseCommand, BrowseCommand, [
|
|
30945
|
+
ServiceTokens.ContextService,
|
|
30946
|
+
ServiceTokens.GitService,
|
|
30947
|
+
ServiceTokens.UrlBuilderService,
|
|
30948
|
+
ServiceTokens.OutputService
|
|
30949
|
+
]);
|
|
30734
30950
|
registerCommand(container, ServiceTokens.InstallCompletionCommand, InstallCompletionCommand, [ServiceTokens.OutputService]);
|
|
30735
30951
|
registerCommand(container, ServiceTokens.UninstallCompletionCommand, UninstallCompletionCommand, [ServiceTokens.OutputService]);
|
|
30736
30952
|
container.register(ServiceTokens.VersionService, () => {
|
|
@@ -30820,6 +31036,7 @@ var ROOT_COMPLETIONS = [
|
|
|
30820
31036
|
"repo",
|
|
30821
31037
|
"pr",
|
|
30822
31038
|
"snippet",
|
|
31039
|
+
"browse",
|
|
30823
31040
|
"config",
|
|
30824
31041
|
"completion",
|
|
30825
31042
|
"--help",
|
|
@@ -31021,7 +31238,7 @@ cli.name("bb").description("A command-line interface for Bitbucket Cloud").versi
|
|
|
31021
31238
|
} catch {}
|
|
31022
31239
|
});
|
|
31023
31240
|
var authCmd = new Command("auth").description("Authenticate with Bitbucket");
|
|
31024
|
-
authCmd.command("login").description("Authenticate with Bitbucket (OAuth or API token)").option("-u, --username <username>", "Bitbucket username (implies API token auth)").option("-p, --password <password>", "Bitbucket API token (implies API token auth)").option("--app-password", "Use API token authentication instead of OAuth").option("--client-id <clientId>", "Custom OAuth consumer client ID").option("--client-secret <clientSecret>", "Custom OAuth consumer client secret").addHelpText("before", `
|
|
31241
|
+
authCmd.command("login").description("Authenticate with Bitbucket (OAuth or API token)").option("-u, --username <username>", "Bitbucket username (implies API token auth)").option("-p, --password <password>", "Bitbucket API token (implies API token auth)").option("--app-password", "Use API token authentication (instead of OAuth). App passwords are deprecated; use API tokens.").option("--client-id <clientId>", "Custom OAuth consumer client ID").option("--client-secret <clientSecret>", "Custom OAuth consumer client secret").addHelpText("before", `
|
|
31025
31242
|
Default: OAuth (browser-based, recommended).
|
|
31026
31243
|
` + `For CI/CD: API token via --app-password or BB_API_TOKEN env var.
|
|
31027
31244
|
` + `Note: Bitbucket app passwords are deprecated; use OAuth or an API token.
|
|
@@ -31164,7 +31381,7 @@ prCmd.command("create").description("Create a pull request").option("-t, --title
|
|
|
31164
31381
|
const context = createContext(cli);
|
|
31165
31382
|
await runCommand(ServiceTokens.CreatePRCommand, withGlobalOptions(options, context), cli, context);
|
|
31166
31383
|
});
|
|
31167
|
-
prCmd.command("list").description("List pull requests").option("-s, --state <state>", `Filter by state (${PR_STATES.join(", ")})`, "OPEN").option("--limit <number>", "Maximum number of PRs to list", "25").option("--mine", "Show only PRs where you are a reviewer").addHelpText("after", buildHelpText({
|
|
31384
|
+
prCmd.command("list").description("List pull requests").option("-s, --state <state>", `Filter by state (${PR_STATES.join(", ")})`, "OPEN").option("--limit <number>", "Maximum number of PRs to list", "25").option("--mine", "Show only PRs where you are a reviewer (not authored by you)").addHelpText("after", buildHelpText({
|
|
31168
31385
|
examples: [
|
|
31169
31386
|
"bb pr list",
|
|
31170
31387
|
"bb pr list -s MERGED --limit 10",
|
|
@@ -31358,23 +31575,23 @@ prReviewersCmd.command("list <id>").description("List reviewers on a pull reques
|
|
|
31358
31575
|
const context = createContext(cli);
|
|
31359
31576
|
await runCommand(ServiceTokens.ListReviewersPRCommand, withGlobalOptions({ id, ...options }, context), cli, context);
|
|
31360
31577
|
});
|
|
31361
|
-
prReviewersCmd.command("add <id> <
|
|
31578
|
+
prReviewersCmd.command("add <id> <user>").description("Add a reviewer to a pull request (user is an account ID or {uuid})").addHelpText("after", buildHelpText({
|
|
31362
31579
|
examples: [
|
|
31363
31580
|
'bb pr reviewers add 42 "712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f"',
|
|
31364
31581
|
'bb pr reviewers add 42 "{c1cb1bb5-2e32-456e-a373-43978dc12aa1}"'
|
|
31365
31582
|
]
|
|
31366
|
-
})).action(async (id,
|
|
31583
|
+
})).action(async (id, user, options) => {
|
|
31367
31584
|
const context = createContext(cli);
|
|
31368
|
-
await runCommand(ServiceTokens.AddReviewerPRCommand, withGlobalOptions({ id, username, ...options }, context), cli, context);
|
|
31585
|
+
await runCommand(ServiceTokens.AddReviewerPRCommand, withGlobalOptions({ id, username: user, ...options }, context), cli, context);
|
|
31369
31586
|
});
|
|
31370
|
-
prReviewersCmd.command("remove <id> <
|
|
31587
|
+
prReviewersCmd.command("remove <id> <user>").description("Remove a reviewer from a pull request (user is an account ID or {uuid})").addHelpText("after", buildHelpText({
|
|
31371
31588
|
examples: [
|
|
31372
31589
|
'bb pr reviewers remove 42 "712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f"',
|
|
31373
31590
|
'bb pr reviewers remove 42 "{c1cb1bb5-2e32-456e-a373-43978dc12aa1}"'
|
|
31374
31591
|
]
|
|
31375
|
-
})).action(async (id,
|
|
31592
|
+
})).action(async (id, user, options) => {
|
|
31376
31593
|
const context = createContext(cli);
|
|
31377
|
-
await runCommand(ServiceTokens.RemoveReviewerPRCommand, withGlobalOptions({ id, username, ...options }, context), cli, context);
|
|
31594
|
+
await runCommand(ServiceTokens.RemoveReviewerPRCommand, withGlobalOptions({ id, username: user, ...options }, context), cli, context);
|
|
31378
31595
|
});
|
|
31379
31596
|
cli.addCommand(prCmd);
|
|
31380
31597
|
prCmd.addCommand(prCommentsCmd);
|
|
@@ -31405,7 +31622,7 @@ snippetCmd.command("view <id>").description("View snippet details").option("-f,
|
|
|
31405
31622
|
const context = createContext(cli);
|
|
31406
31623
|
await runCommand(ServiceTokens.ViewSnippetCommand, withGlobalOptions({ id, ...options }, context), cli, context);
|
|
31407
31624
|
});
|
|
31408
|
-
snippetCmd.command("create").description("Create a new snippet").option("-t, --title <title>", "Snippet title").option("-f, --file <path...>", "File(s) to include").option("--private", "Create a private snippet (default)").option("--public", "Create a public snippet").addHelpText("after", buildHelpText({
|
|
31625
|
+
snippetCmd.command("create").description("Create a new snippet").option("-t, --title <title>", "Snippet title").option("-f, --file <path...>", "File(s) to include (variadic; pass multiple paths or repeat the flag)").option("--private", "Create a private snippet (default)").option("--public", "Create a public snippet").addHelpText("after", buildHelpText({
|
|
31409
31626
|
examples: [
|
|
31410
31627
|
'bb snippet create -t "My snippet" -f file.txt',
|
|
31411
31628
|
'bb snippet create -t "Config files" -f config.yml -f setup.sh --public'
|
|
@@ -31415,7 +31632,7 @@ snippetCmd.command("create").description("Create a new snippet").option("-t, --t
|
|
|
31415
31632
|
const context = createContext(cli);
|
|
31416
31633
|
await runCommand(ServiceTokens.CreateSnippetCommand, withGlobalOptions(options, context), cli, context);
|
|
31417
31634
|
});
|
|
31418
|
-
snippetCmd.command("edit <id>").description("Edit a snippet").option("-t, --title <title>", "New snippet title").option("--private", "Make snippet private").option("--public", "Make snippet public").option("-f, --file <path...>", "Replace/add file(s) (sends multipart update)").addHelpText("after", buildHelpText({
|
|
31635
|
+
snippetCmd.command("edit <id>").description("Edit a snippet").option("-t, --title <title>", "New snippet title").option("--private", "Make snippet private").option("--public", "Make snippet public").option("-f, --file <path...>", "Replace/add file(s) (variadic; pass multiple paths or repeat the flag; sends multipart update)").addHelpText("after", buildHelpText({
|
|
31419
31636
|
examples: [
|
|
31420
31637
|
'bb snippet edit kypj -t "New title"',
|
|
31421
31638
|
"bb snippet edit kypj --public",
|
|
@@ -31488,6 +31705,26 @@ snippetCommentsCmd.command("delete <snippet-id> <comment-id>").description("Dele
|
|
|
31488
31705
|
});
|
|
31489
31706
|
snippetCmd.addCommand(snippetCommentsCmd);
|
|
31490
31707
|
cli.addCommand(snippetCmd);
|
|
31708
|
+
cli.command("browse [target]").description("Open a Bitbucket page (repo home, file, PR, commit, etc.) in your browser").option("--pr <id>", "Open a specific pull request").option("--prs", "Open the pull-requests list").option("--pull-requests", "Alias for --prs").option("--branch <name>", "Open the branch source tree (or, with <target>, that path on the branch)").option("--branches", "Open the branches list").option("--commit [sha]", "Open a specific commit (defaults to HEAD when no SHA is given)").option("--commits", "Open the commits list").option("--pipelines", "Open the pipelines page").option("--pipeline <id>", "Open a specific pipeline run").option("--downloads", "Open the downloads page").option("--issue <id>", "Open a specific issue").option("--issues", "Open the issue tracker").option("--wiki", "Open the wiki").option("--settings", "Open repository settings").option("-n, --no-browser", "Print the URL to stdout instead of opening it").addHelpText("after", buildHelpText({
|
|
31709
|
+
examples: [
|
|
31710
|
+
"bb browse",
|
|
31711
|
+
"bb browse src/cli.ts",
|
|
31712
|
+
"bb browse src/cli.ts:42",
|
|
31713
|
+
"bb browse --branch release/2.0 src/cli.ts",
|
|
31714
|
+
"bb browse 217",
|
|
31715
|
+
"bb browse --pr 217",
|
|
31716
|
+
"bb browse --prs",
|
|
31717
|
+
"bb browse abc1234",
|
|
31718
|
+
"bb browse --commit",
|
|
31719
|
+
"bb browse --pipelines",
|
|
31720
|
+
"bb browse --settings",
|
|
31721
|
+
"bb browse --pr 217 --no-browser",
|
|
31722
|
+
"bb browse --pr 217 --json url"
|
|
31723
|
+
]
|
|
31724
|
+
})).action(async (target, options) => {
|
|
31725
|
+
const context = createContext(cli);
|
|
31726
|
+
await runCommand(ServiceTokens.BrowseCommand, withGlobalOptions({ target, ...options }, context), cli, context);
|
|
31727
|
+
});
|
|
31491
31728
|
var configCmd = new Command("config").description("Manage configuration");
|
|
31492
31729
|
configCmd.command("get <key>").description("Get a configuration value").addHelpText("after", buildHelpText({
|
|
31493
31730
|
examples: ["bb config get defaultWorkspace"],
|
|
@@ -31560,3 +31797,6 @@ if (typeof Bun === "undefined") {
|
|
|
31560
31797
|
process.exit(1);
|
|
31561
31798
|
}
|
|
31562
31799
|
cli.parse(process.argv);
|
|
31800
|
+
|
|
31801
|
+
//# debugId=A7729A51C3738B3664756E2164756E21
|
|
31802
|
+
//# sourceMappingURL=index.js.map
|