@pilatos/bitbucket-cli 1.8.2 → 1.8.3

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.
Files changed (2) hide show
  1. package/dist/index.js +302 -33
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -21341,6 +21341,288 @@ class CloneCommand extends BaseCommand {
21341
21341
  }
21342
21342
  }
21343
21343
 
21344
+ // src/services/response-parsers.ts
21345
+ function isRecord(value) {
21346
+ return typeof value === "object" && value !== null;
21347
+ }
21348
+ function getString(value) {
21349
+ return typeof value === "string" ? value : undefined;
21350
+ }
21351
+ function getNumber(value) {
21352
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
21353
+ }
21354
+ function getIterable(value) {
21355
+ if (Array.isArray(value)) {
21356
+ return value;
21357
+ }
21358
+ if (typeof value !== "object" || value === null) {
21359
+ return;
21360
+ }
21361
+ const iterableCandidate = value;
21362
+ const iterator2 = iterableCandidate[Symbol.iterator];
21363
+ return typeof iterator2 === "function" ? value : undefined;
21364
+ }
21365
+ function getValuesIterable(data) {
21366
+ if (isRecord(data) && "values" in data) {
21367
+ return getIterable(data.values);
21368
+ }
21369
+ return getIterable(data);
21370
+ }
21371
+ function mapPaginatedValues(data, mapValue) {
21372
+ const iterableValues = getValuesIterable(data);
21373
+ const values = [];
21374
+ if (iterableValues) {
21375
+ for (const value of iterableValues) {
21376
+ const mappedValue = mapValue(value);
21377
+ if (mappedValue !== undefined) {
21378
+ values.push(mappedValue);
21379
+ }
21380
+ }
21381
+ }
21382
+ const next = isRecord(data) ? getString(data.next) : undefined;
21383
+ return {
21384
+ values,
21385
+ next
21386
+ };
21387
+ }
21388
+ function getCommitFilePath(file) {
21389
+ if (!isRecord(file)) {
21390
+ return;
21391
+ }
21392
+ const path = file.path;
21393
+ return typeof path === "string" && path.length > 0 ? path : undefined;
21394
+ }
21395
+ function parseDiffstatFile(value) {
21396
+ if (!isRecord(value)) {
21397
+ return;
21398
+ }
21399
+ return {
21400
+ path: getCommitFilePath(value.new) ?? getCommitFilePath(value.old) ?? "unknown",
21401
+ additions: getNumber(value.lines_added) ?? 0,
21402
+ deletions: getNumber(value.lines_removed) ?? 0
21403
+ };
21404
+ }
21405
+ function parseActivityUser(value) {
21406
+ if (!isRecord(value)) {
21407
+ return;
21408
+ }
21409
+ const displayName = getString(value.display_name);
21410
+ const username = getString(value.username);
21411
+ const nickname = getString(value.nickname);
21412
+ if (!displayName && !username && !nickname) {
21413
+ return;
21414
+ }
21415
+ return {
21416
+ display_name: displayName,
21417
+ username,
21418
+ nickname
21419
+ };
21420
+ }
21421
+ function parseActivityHash(value) {
21422
+ if (!isRecord(value)) {
21423
+ return;
21424
+ }
21425
+ const hash = getString(value.hash);
21426
+ return hash ? { hash } : undefined;
21427
+ }
21428
+ function parseActivityComment(value) {
21429
+ if (!isRecord(value)) {
21430
+ return;
21431
+ }
21432
+ const id = getNumber(value.id);
21433
+ const raw = getRawContent(value.content);
21434
+ const user = parseActivityUser(value.user);
21435
+ const author = parseActivityUser(value.author);
21436
+ const createdOn = getString(value.created_on);
21437
+ if (id === undefined && raw === undefined && !user && !author && !createdOn) {
21438
+ return;
21439
+ }
21440
+ return {
21441
+ id,
21442
+ content: raw === undefined ? undefined : { raw },
21443
+ user,
21444
+ author,
21445
+ created_on: createdOn
21446
+ };
21447
+ }
21448
+ function parseApproval(value) {
21449
+ if (!isRecord(value)) {
21450
+ return;
21451
+ }
21452
+ const user = parseActivityUser(value.user);
21453
+ const date = getString(value.date);
21454
+ if (!user && !date) {
21455
+ return;
21456
+ }
21457
+ return { user, date };
21458
+ }
21459
+ function parseChangesRequested(value) {
21460
+ if (!isRecord(value)) {
21461
+ return;
21462
+ }
21463
+ const user = parseActivityUser(value.user);
21464
+ const reason = getString(value.reason);
21465
+ const date = getString(value.date);
21466
+ if (!user && !reason && !date) {
21467
+ return;
21468
+ }
21469
+ return {
21470
+ user,
21471
+ reason,
21472
+ date
21473
+ };
21474
+ }
21475
+ function parseMerge(value) {
21476
+ if (!isRecord(value)) {
21477
+ return;
21478
+ }
21479
+ const user = parseActivityUser(value.user);
21480
+ const date = getString(value.date);
21481
+ const commit = parseActivityHash(value.commit);
21482
+ if (!user && !date && !commit) {
21483
+ return;
21484
+ }
21485
+ return {
21486
+ user,
21487
+ date,
21488
+ commit
21489
+ };
21490
+ }
21491
+ function parseDecline(value) {
21492
+ if (!isRecord(value)) {
21493
+ return;
21494
+ }
21495
+ const user = parseActivityUser(value.user);
21496
+ const date = getString(value.date);
21497
+ if (!user && !date) {
21498
+ return;
21499
+ }
21500
+ return { user, date };
21501
+ }
21502
+ function parseCommit(value) {
21503
+ if (!isRecord(value)) {
21504
+ return;
21505
+ }
21506
+ const date = getString(value.date);
21507
+ const hash = getString(value.hash);
21508
+ const author = isRecord(value.author) ? {
21509
+ user: parseActivityUser(value.author.user)
21510
+ } : undefined;
21511
+ if (!date && !hash && !author?.user) {
21512
+ return;
21513
+ }
21514
+ return {
21515
+ date,
21516
+ hash,
21517
+ author
21518
+ };
21519
+ }
21520
+ function parseUpdate(value) {
21521
+ if (!isRecord(value)) {
21522
+ return;
21523
+ }
21524
+ const author = parseActivityUser(value.author);
21525
+ const date = getString(value.date);
21526
+ const title = getString(value.title);
21527
+ const description = getString(value.description);
21528
+ const state = getString(value.state);
21529
+ if (!author && !date && !title && !description && !state) {
21530
+ return;
21531
+ }
21532
+ return {
21533
+ author,
21534
+ date,
21535
+ title,
21536
+ description,
21537
+ state
21538
+ };
21539
+ }
21540
+ function parseActivity(value) {
21541
+ if (!isRecord(value)) {
21542
+ return;
21543
+ }
21544
+ return {
21545
+ type: getString(value.type),
21546
+ comment: parseActivityComment(value.comment),
21547
+ approval: parseApproval(value.approval),
21548
+ changes_requested: parseChangesRequested(value.changes_requested),
21549
+ merge: parseMerge(value.merge),
21550
+ decline: parseDecline(value.decline),
21551
+ commit: parseCommit(value.commit),
21552
+ update: parseUpdate(value.update),
21553
+ user: parseActivityUser(value.user)
21554
+ };
21555
+ }
21556
+ function getLinkHref(links, key) {
21557
+ if (!isRecord(links)) {
21558
+ return;
21559
+ }
21560
+ const link = links[key];
21561
+ if (!isRecord(link)) {
21562
+ return;
21563
+ }
21564
+ return getString(link.href);
21565
+ }
21566
+ function getCloneLinks(links) {
21567
+ if (!isRecord(links)) {
21568
+ return [];
21569
+ }
21570
+ const cloneLinks = getIterable(links.clone);
21571
+ if (!cloneLinks) {
21572
+ return [];
21573
+ }
21574
+ const parsedLinks = [];
21575
+ for (const cloneLink of cloneLinks) {
21576
+ if (!isRecord(cloneLink)) {
21577
+ continue;
21578
+ }
21579
+ const name = getString(cloneLink.name);
21580
+ const href = getString(cloneLink.href);
21581
+ if (name && href) {
21582
+ parsedLinks.push({ name, href });
21583
+ }
21584
+ }
21585
+ return parsedLinks;
21586
+ }
21587
+ function getBranchName(endpoint) {
21588
+ if (!isRecord(endpoint)) {
21589
+ return;
21590
+ }
21591
+ const branch = endpoint.branch;
21592
+ if (!isRecord(branch)) {
21593
+ return;
21594
+ }
21595
+ const name = branch.name;
21596
+ return typeof name === "string" && name.length > 0 ? name : undefined;
21597
+ }
21598
+ function getUserDisplayName(user) {
21599
+ if (!isRecord(user)) {
21600
+ return;
21601
+ }
21602
+ const nickname = getString(user.nickname);
21603
+ if (nickname && nickname.length > 0) {
21604
+ return nickname;
21605
+ }
21606
+ const displayName = getString(user.display_name);
21607
+ if (displayName && displayName.length > 0) {
21608
+ return displayName;
21609
+ }
21610
+ const username = getString(user.username);
21611
+ return username && username.length > 0 ? username : undefined;
21612
+ }
21613
+ function getRawContent(content) {
21614
+ if (!isRecord(content)) {
21615
+ return;
21616
+ }
21617
+ return getString(content.raw);
21618
+ }
21619
+ function parseDiffstatFiles(data) {
21620
+ return Array.from(mapPaginatedValues(data, parseDiffstatFile).values ?? []);
21621
+ }
21622
+ function parsePullrequestActivitiesPage(data) {
21623
+ return mapPaginatedValues(data, parseActivity);
21624
+ }
21625
+
21344
21626
  // src/commands/repo/create.command.ts
21345
21627
  class CreateRepoCommand extends BaseCommand {
21346
21628
  repositoriesApi;
@@ -21379,8 +21661,9 @@ class CreateRepoCommand extends BaseCommand {
21379
21661
  return;
21380
21662
  }
21381
21663
  this.output.success(`Created repository ${repo.full_name}`);
21382
- this.output.text(` ${this.output.dim("URL:")} ${repo.links?.html?.href}`);
21383
- const sshClone = Array.from(repo.links?.clone ?? []).find((c) => c.name === "ssh");
21664
+ const repoUrl = getLinkHref(repo.links, "html") ?? "";
21665
+ this.output.text(` ${this.output.dim("URL:")} ${repoUrl}`);
21666
+ const sshClone = getCloneLinks(repo.links).find((cloneLink) => cloneLink.name === "ssh");
21384
21667
  if (sshClone?.href) {
21385
21668
  this.output.text(` ${this.output.dim("Clone:")} git clone ${sshClone.href}`);
21386
21669
  }
@@ -21553,8 +21836,9 @@ class ViewRepoCommand extends BaseCommand {
21553
21836
  this.output.text(` ${this.output.dim("Created:")} ${this.output.formatDate(repo.created_on ?? "")}`);
21554
21837
  this.output.text(` ${this.output.dim("Updated:")} ${this.output.formatDate(repo.updated_on ?? "")}`);
21555
21838
  this.output.text("");
21556
- this.output.text(` ${this.output.dim("URL:")} ${repo.links?.html?.href}`);
21557
- const sshClone = Array.from(repo.links?.clone ?? []).find((c) => c.name === "ssh");
21839
+ const repoUrl = getLinkHref(repo.links, "html") ?? "";
21840
+ this.output.text(` ${this.output.dim("URL:")} ${repoUrl}`);
21841
+ const sshClone = getCloneLinks(repo.links).find((cloneLink) => cloneLink.name === "ssh");
21558
21842
  if (sshClone?.href) {
21559
21843
  this.output.text(` ${this.output.dim("SSH:")} ${sshClone.href}`);
21560
21844
  }
@@ -22143,7 +22427,7 @@ class CheckoutPRCommand extends BaseCommand {
22143
22427
  pullRequestId: prId
22144
22428
  });
22145
22429
  const pr = prResponse.data;
22146
- const branchName = pr.source?.branch?.name;
22430
+ const branchName = getBranchName(pr.source);
22147
22431
  const localBranchName = `pr-${prId}`;
22148
22432
  if (!branchName) {
22149
22433
  throw new BBError({
@@ -22233,8 +22517,7 @@ class DiffPRCommand extends BaseCommand {
22233
22517
  return response.data;
22234
22518
  },
22235
22519
  shouldInclude: (pullRequest) => {
22236
- const source = pullRequest.source;
22237
- return source?.branch?.name === currentBranch;
22520
+ return getBranchName(pullRequest.source) === currentBranch;
22238
22521
  }
22239
22522
  });
22240
22523
  const pr = matches[0];
@@ -22318,8 +22601,7 @@ class DiffPRCommand extends BaseCommand {
22318
22601
  repoSlug,
22319
22602
  pullRequestId: prId
22320
22603
  });
22321
- const links = prResponse.data.links;
22322
- const htmlUrl = links?.html?.href;
22604
+ const htmlUrl = getLinkHref(prResponse.data.links, "html");
22323
22605
  if (htmlUrl) {
22324
22606
  const normalizedHtmlUrl = htmlUrl.replace(/\/$/, "");
22325
22607
  return `${normalizedHtmlUrl}/diff`;
@@ -22332,15 +22614,7 @@ class DiffPRCommand extends BaseCommand {
22332
22614
  repoSlug,
22333
22615
  pullRequestId: prId
22334
22616
  });
22335
- const diffstat = diffstatResponse.data;
22336
- const files = Array.from(diffstat.values ?? []).map((file) => {
22337
- const path = file.new?.path || file.old?.path || "unknown";
22338
- return {
22339
- path,
22340
- additions: file.lines_added ?? 0,
22341
- deletions: file.lines_removed ?? 0
22342
- };
22343
- });
22617
+ const files = parseDiffstatFiles(diffstatResponse.data);
22344
22618
  const totalAdditions = files.reduce((sum, f) => sum + f.additions, 0);
22345
22619
  const totalDeletions = files.reduce((sum, f) => sum + f.deletions, 0);
22346
22620
  const filesChanged = files.length;
@@ -22378,8 +22652,7 @@ class DiffPRCommand extends BaseCommand {
22378
22652
  repoSlug,
22379
22653
  pullRequestId: prId
22380
22654
  });
22381
- const diffstat = diffstatResponse.data;
22382
- const fileNames = Array.from(diffstat.values ?? []).map((file) => file.new?.path || file.old?.path || "unknown");
22655
+ const fileNames = parseDiffstatFiles(diffstatResponse.data).map((file) => file.path);
22383
22656
  if (useJson) {
22384
22657
  return fileNames;
22385
22658
  }
@@ -22459,7 +22732,7 @@ class ActivityPRCommand extends BaseCommand {
22459
22732
  }, {
22460
22733
  params: { page, pagelen }
22461
22734
  });
22462
- return response.data;
22735
+ return parsePullrequestActivitiesPage(response.data);
22463
22736
  },
22464
22737
  shouldInclude: (activity) => {
22465
22738
  if (filterTypes.length === 0) {
@@ -22468,7 +22741,6 @@ class ActivityPRCommand extends BaseCommand {
22468
22741
  return filterTypes.includes(this.getActivityType(activity));
22469
22742
  }
22470
22743
  });
22471
- const typedActivities = activities;
22472
22744
  if (context.globalOptions.json) {
22473
22745
  this.output.json({
22474
22746
  workspace: repoContext.workspace,
@@ -22477,12 +22749,12 @@ class ActivityPRCommand extends BaseCommand {
22477
22749
  filters: {
22478
22750
  types: filterTypes
22479
22751
  },
22480
- count: typedActivities.length,
22481
- activities: typedActivities
22752
+ count: activities.length,
22753
+ activities
22482
22754
  });
22483
22755
  return;
22484
22756
  }
22485
- if (typedActivities.length === 0) {
22757
+ if (activities.length === 0) {
22486
22758
  if (filterTypes.length > 0) {
22487
22759
  this.output.info("No activity entries matched the requested filter");
22488
22760
  } else {
@@ -22490,7 +22762,7 @@ class ActivityPRCommand extends BaseCommand {
22490
22762
  }
22491
22763
  return;
22492
22764
  }
22493
- const rows = typedActivities.map((activity) => {
22765
+ const rows = activities.map((activity) => {
22494
22766
  const activityType = this.getActivityType(activity);
22495
22767
  return [
22496
22768
  activityType.toUpperCase(),
@@ -22533,10 +22805,7 @@ class ActivityPRCommand extends BaseCommand {
22533
22805
  }
22534
22806
  getActorName(activity) {
22535
22807
  const user = activity.comment?.user ?? activity.comment?.author ?? activity.approval?.user ?? activity.update?.author ?? activity.changes_requested?.user ?? activity.merge?.user ?? activity.decline?.user ?? activity.commit?.author?.user ?? activity.user;
22536
- if (!user) {
22537
- return "Unknown";
22538
- }
22539
- return user.display_name || user.username || "Unknown";
22808
+ return getUserDisplayName(user) ?? "Unknown";
22540
22809
  }
22541
22810
  formatActivityDate(activity) {
22542
22811
  const date = activity.comment?.created_on ?? activity.approval?.date ?? activity.update?.date ?? activity.changes_requested?.date ?? activity.merge?.date ?? activity.decline?.date ?? activity.commit?.date;
@@ -22548,7 +22817,7 @@ class ActivityPRCommand extends BaseCommand {
22548
22817
  buildActivityDetails(activity, type) {
22549
22818
  switch (type) {
22550
22819
  case "comment": {
22551
- const content = activity.comment?.content?.raw ?? "";
22820
+ const content = getRawContent(activity.comment?.content) ?? "";
22552
22821
  const id = activity.comment?.id ? `#${activity.comment.id}` : "";
22553
22822
  const snippet = this.truncate(content, 80);
22554
22823
  return [id, snippet].filter(Boolean).join(" ");
@@ -22728,10 +22997,10 @@ class ListCommentsPRCommand extends BaseCommand {
22728
22997
  return;
22729
22998
  }
22730
22999
  const rows = values.map((comment) => {
22731
- const content = comment.content?.raw ?? "";
23000
+ const content = getRawContent(comment.content) ?? "";
22732
23001
  return [
22733
23002
  comment.id?.toString() ?? "",
22734
- comment.user?.nickname ?? comment.user?.display_name ?? "Unknown",
23003
+ getUserDisplayName(comment.user) ?? "Unknown",
22735
23004
  comment.deleted ? "[deleted]" : options.truncate === false ? content : content.slice(0, 60) + (content.length > 60 ? "..." : ""),
22736
23005
  this.output.formatDate(comment.created_on ?? "")
22737
23006
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pilatos/bitbucket-cli",
3
- "version": "1.8.2",
3
+ "version": "1.8.3",
4
4
  "description": "A command-line interface for Bitbucket Cloud",
5
5
  "author": "",
6
6
  "license": "MIT",