azdo-cli 0.5.0-017-pr-comments-threads.242 → 0.5.0-017-pr-comments-threads.244

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 +72 -21
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2406,6 +2406,15 @@ async function readJsonResponse(response) {
2406
2406
  }
2407
2407
  return response.json();
2408
2408
  }
2409
+ async function getPullRequestById(context, repo, pat, prId) {
2410
+ const url = new URL(
2411
+ `https://dev.azure.com/${encodeURIComponent(context.org)}/${encodeURIComponent(context.project)}/_apis/git/repositories/${encodeURIComponent(repo)}/pullRequests/${prId}`
2412
+ );
2413
+ url.searchParams.set("api-version", "7.1");
2414
+ const response = await fetchWithErrors(url.toString(), { headers: authHeaders(pat) });
2415
+ const data = await readJsonResponse(response);
2416
+ return mapPullRequest(repo, data);
2417
+ }
2409
2418
  async function listPullRequests(context, repo, pat, sourceBranch, opts) {
2410
2419
  const response = await fetchWithErrors(
2411
2420
  buildPullRequestsUrl(context, repo, sourceBranch, opts).toString(),
@@ -2475,6 +2484,13 @@ async function getPullRequestThreads(context, repo, pat, prId) {
2475
2484
  }
2476
2485
 
2477
2486
  // src/commands/pr.ts
2487
+ function parsePositivePrNumber(raw) {
2488
+ if (!/^\d+$/.test(raw)) {
2489
+ return null;
2490
+ }
2491
+ const n = Number.parseInt(raw, 10);
2492
+ return Number.isFinite(n) && n > 0 ? n : null;
2493
+ }
2478
2494
  function formatBranchName(refName) {
2479
2495
  return refName.startsWith("refs/heads/") ? refName.slice("refs/heads/".length) : refName;
2480
2496
  }
@@ -2542,10 +2558,20 @@ function formatThreads(prId, title, threads) {
2542
2558
  }
2543
2559
  return lines.join("\n");
2544
2560
  }
2545
- async function resolvePrCommandContext(options) {
2561
+ async function resolvePrCommandContext(options, resolveOpts = {}) {
2562
+ const requireBranch = resolveOpts.requireBranch ?? true;
2546
2563
  const context = resolveContext(options);
2547
2564
  const repo = detectRepoName();
2548
- const branch = getCurrentBranch();
2565
+ let branch;
2566
+ if (requireBranch) {
2567
+ branch = getCurrentBranch();
2568
+ } else {
2569
+ try {
2570
+ branch = getCurrentBranch();
2571
+ } catch {
2572
+ branch = null;
2573
+ }
2574
+ }
2549
2575
  const credential = await requirePat(context.org);
2550
2576
  return {
2551
2577
  context,
@@ -2562,15 +2588,15 @@ function createPrStatusCommand() {
2562
2588
  try {
2563
2589
  const resolved = await resolvePrCommandContext(options);
2564
2590
  context = resolved.context;
2565
- const pullRequests = await listPullRequests(resolved.context, resolved.repo, resolved.pat, resolved.branch);
2591
+ const branch = resolved.branch;
2592
+ const pullRequests = await listPullRequests(resolved.context, resolved.repo, resolved.pat, branch);
2566
2593
  const pullRequestsWithChecks = await Promise.all(
2567
2594
  pullRequests.map(async (pullRequest) => ({
2568
2595
  ...pullRequest,
2569
2596
  checks: await getPullRequestChecks(resolved.context, resolved.repo, resolved.pat, pullRequest.id)
2570
2597
  }))
2571
2598
  );
2572
- const { branch, repo } = resolved;
2573
- const result = { branch, repository: repo, pullRequests: pullRequestsWithChecks };
2599
+ const result = { branch, repository: resolved.repo, pullRequests: pullRequestsWithChecks };
2574
2600
  if (options.json) {
2575
2601
  process.stdout.write(`${JSON.stringify(result, null, 2)}
2576
2602
  `);
@@ -2611,11 +2637,12 @@ function createPrOpenCommand() {
2611
2637
  writeError("Pull request creation requires a source branch other than develop.");
2612
2638
  return;
2613
2639
  }
2640
+ const openBranch = resolved.branch;
2614
2641
  const result = await openPullRequest(
2615
2642
  resolved.context,
2616
2643
  resolved.repo,
2617
2644
  resolved.pat,
2618
- resolved.branch,
2645
+ openBranch,
2619
2646
  title,
2620
2647
  description
2621
2648
  );
@@ -2648,28 +2675,52 @@ ${result.pullRequest.url ?? "\u2014"}
2648
2675
  }
2649
2676
  function createPrCommentsCommand() {
2650
2677
  const command = new Command12("comments");
2651
- command.description("List pull request comment threads for the current branch").option("--org <org>", "Azure DevOps organization").option("--project <project>", "Azure DevOps project").option("--hide-resolved", "hide threads whose status is resolved / won't fix / closed / by design").option("--json", "output JSON").action(async (options) => {
2678
+ command.description("List pull request comment threads for the current branch").option("--org <org>", "Azure DevOps organization").option("--project <project>", "Azure DevOps project").option("--pr-number <N>", "target the pull request with this numeric id, instead of the current branch's PR").option("--hide-resolved", "hide threads whose status is resolved / won't fix / closed / by design").option("--json", "output JSON").action(async (options) => {
2652
2679
  validateOrgProjectPair(options);
2653
2680
  let context;
2654
- try {
2655
- const resolved = await resolvePrCommandContext(options);
2656
- context = resolved.context;
2657
- const pullRequests = await listPullRequests(resolved.context, resolved.repo, resolved.pat, resolved.branch, {
2658
- status: "active"
2659
- });
2660
- if (pullRequests.length === 0) {
2661
- writeError(`No active pull request found for branch ${resolved.branch}.`);
2681
+ let explicitPrId = null;
2682
+ if (options.prNumber !== void 0) {
2683
+ explicitPrId = parsePositivePrNumber(options.prNumber);
2684
+ if (explicitPrId === null) {
2685
+ writeError(`Invalid --pr-number "${options.prNumber}"; expected a positive integer.`);
2662
2686
  return;
2663
2687
  }
2664
- if (pullRequests.length > 1) {
2665
- const ids = pullRequests.map((pullRequest2) => `#${pullRequest2.id}`).join(", ");
2666
- writeError(`Multiple active pull requests found for branch ${resolved.branch}: ${ids}. Use pr status to review them.`);
2667
- return;
2688
+ }
2689
+ try {
2690
+ const resolved = await resolvePrCommandContext(options, { requireBranch: explicitPrId === null });
2691
+ context = resolved.context;
2692
+ let pullRequest;
2693
+ let branchLabel;
2694
+ if (explicitPrId !== null) {
2695
+ try {
2696
+ pullRequest = await getPullRequestById(resolved.context, resolved.repo, resolved.pat, explicitPrId);
2697
+ } catch (err) {
2698
+ if (err instanceof Error && err.message.startsWith("NOT_FOUND")) {
2699
+ writeError(`Pull request #${explicitPrId} not found in ${resolved.context.org}/${resolved.context.project}/${resolved.repo}.`);
2700
+ return;
2701
+ }
2702
+ throw err;
2703
+ }
2704
+ branchLabel = resolved.branch ?? pullRequest.sourceRefName;
2705
+ } else {
2706
+ const pullRequests = await listPullRequests(resolved.context, resolved.repo, resolved.pat, resolved.branch, {
2707
+ status: "active"
2708
+ });
2709
+ if (pullRequests.length === 0) {
2710
+ writeError(`No active pull request found for branch ${resolved.branch}.`);
2711
+ return;
2712
+ }
2713
+ if (pullRequests.length > 1) {
2714
+ const ids = pullRequests.map((pr) => `#${pr.id}`).join(", ");
2715
+ writeError(`Multiple active pull requests found for branch ${resolved.branch}: ${ids}. Use pr status to review them.`);
2716
+ return;
2717
+ }
2718
+ pullRequest = pullRequests[0];
2719
+ branchLabel = resolved.branch;
2668
2720
  }
2669
- const pullRequest = pullRequests[0];
2670
2721
  const allThreads = await getPullRequestThreads(resolved.context, resolved.repo, resolved.pat, pullRequest.id);
2671
2722
  const threads = options.hideResolved ? allThreads.filter((thread) => !isThreadResolved(thread.status)) : allThreads;
2672
- const result = { branch: resolved.branch, pullRequest, threads };
2723
+ const result = { branch: branchLabel, pullRequest, threads };
2673
2724
  if (options.json) {
2674
2725
  process.stdout.write(`${JSON.stringify(result, null, 2)}
2675
2726
  `);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "azdo-cli",
3
- "version": "0.5.0-017-pr-comments-threads.242",
3
+ "version": "0.5.0-017-pr-comments-threads.244",
4
4
  "description": "Azure DevOps CLI tool",
5
5
  "type": "module",
6
6
  "bin": {