@henryqw/pi-pr 0.3.1 → 0.3.2

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/extensions/pr.ts +16 -22
  2. package/package.json +1 -1
package/extensions/pr.ts CHANGED
@@ -15,15 +15,15 @@ const CREATE_PR_SKILL_COMMAND = "skill:pi-pr-create";
15
15
  const FAILED_CHECK_STATES = new Set(["ACTION_REQUIRED", "CANCELLED", "ERROR", "FAILURE", "STALE", "STARTUP_FAILURE", "TIMED_OUT"]);
16
16
  const SUCCESSFUL_CHECK_STATES = new Set(["NEUTRAL", "SKIPPED", "SUCCESS"]);
17
17
 
18
- type Lifecycle = "D" | "O" | "M" | "C";
19
18
  type CiStatus = "success" | "running" | "failure" | "none";
20
19
  type PullRequest = {
21
20
  id: string;
22
21
  number: number;
23
- url: string;
22
+ url: URL;
24
23
  headRefOid: string;
25
24
  updatedAt: string;
26
- lifecycle: Lifecycle;
25
+ state: "OPEN" | "MERGED" | "CLOSED";
26
+ isDraft: boolean;
27
27
  mergeable: string;
28
28
  reviewDecision: string | null;
29
29
  statusCheckRollup: unknown[];
@@ -33,14 +33,10 @@ function isRecord(value: unknown): value is Record<string, unknown> {
33
33
  return typeof value === "object" && value !== null && !Array.isArray(value);
34
34
  }
35
35
 
36
- function pullRequestUrl(value: unknown): string | undefined {
37
- if (typeof value !== "string") return undefined;
38
- try {
39
- const url = new URL(value);
40
- return url.protocol === "http:" || url.protocol === "https:" ? url.href : undefined;
41
- } catch {
42
- return undefined;
43
- }
36
+ function pullRequestUrl(value: unknown): URL | undefined {
37
+ if (typeof value !== "string" || !URL.canParse(value)) return undefined;
38
+ const url = new URL(value);
39
+ return url.protocol === "http:" || url.protocol === "https:" ? url : undefined;
44
40
  }
45
41
 
46
42
  export function parsePullRequest(value: unknown): PullRequest | undefined {
@@ -60,16 +56,14 @@ export function parsePullRequest(value: unknown): PullRequest | undefined {
60
56
  typeof id !== "string" || !id ||
61
57
  typeof number !== "number" || !Number.isSafeInteger(number) || number <= 0 || !url ||
62
58
  typeof headRefOid !== "string" || !headRefOid ||
63
- typeof updatedAt !== "string" || Number.isNaN(Date.parse(updatedAt)) || typeof state !== "string" ||
59
+ typeof updatedAt !== "string" || Number.isNaN(Date.parse(updatedAt)) ||
60
+ (state !== "MERGED" && state !== "CLOSED" && state !== "OPEN") ||
64
61
  typeof isDraft !== "boolean" || typeof mergeable !== "string" ||
65
62
  (reviewDecision !== null && typeof reviewDecision !== "string") ||
66
63
  (statusCheckRollup !== null && !Array.isArray(statusCheckRollup))
67
64
  ) return undefined;
68
65
 
69
- const lifecycle = state === "MERGED" ? "M" : state === "CLOSED" ? "C" : state === "OPEN" ? isDraft ? "D" : "O" : undefined;
70
- if (!lifecycle) return undefined;
71
-
72
- return { id, number, url, headRefOid, updatedAt, lifecycle, mergeable, reviewDecision, statusCheckRollup: statusCheckRollup ?? [] };
66
+ return { id, number, url, headRefOid, updatedAt, state, isDraft, mergeable, reviewDecision, statusCheckRollup: statusCheckRollup ?? [] };
73
67
  }
74
68
 
75
69
  function parseUnresolvedReviewCount(value: string): number {
@@ -136,19 +130,19 @@ type Status = {
136
130
  };
137
131
 
138
132
  function statusFor(pullRequest: PullRequest, ci: CiStatus): Status {
139
- if (pullRequest.lifecycle === "M") return { text: "merged", color: "success" };
140
- if (pullRequest.lifecycle === "C") return { text: "closed", color: "dim" };
133
+ if (pullRequest.state === "MERGED") return { text: "merged", color: "success" };
134
+ if (pullRequest.state === "CLOSED") return { text: "closed", color: "dim" };
141
135
  if (pullRequest.mergeable === "CONFLICTING") return { text: "merge conflict", color: "error" };
142
136
  if (pullRequest.reviewDecision === "CHANGES_REQUESTED") return { text: "changes requested", color: "error" };
143
137
  if (ci === "failure") return { text: "CI failed", color: "error" };
144
138
  if (ci === "running") return { text: "CI running", color: "warning" };
145
- if (pullRequest.lifecycle === "D") return { text: "draft", color: "warning" };
139
+ if (pullRequest.isDraft) return { text: "draft", color: "warning" };
146
140
  if (pullRequest.reviewDecision === "APPROVED") return { text: "approved", color: "success" };
147
141
  return { text: "open", color: "accent" };
148
142
  }
149
143
 
150
144
  export function formatPullRequest(pullRequest: PullRequest, theme: ExtensionContext["ui"]["theme"], unresolved = 0): string {
151
- const link = hyperlink(theme.fg("text", `PR #${pullRequest.number}`), pullRequest.url);
145
+ const link = hyperlink(theme.fg("text", `PR #${pullRequest.number}`), pullRequest.url.href);
152
146
  const status = unresolved > 0
153
147
  ? { text: `${unresolved} unresolved`, color: "warning" as const }
154
148
  : statusFor(pullRequest, ciStatus(pullRequest.statusCheckRollup));
@@ -203,7 +197,7 @@ export default function pullRequestExtension(pi: ExtensionAPI): void {
203
197
  ctx.ui.setStatus("pi-pr", undefined);
204
198
  return;
205
199
  }
206
- if (pullRequest.lifecycle === "M" || pullRequest.lifecycle === "C") {
200
+ if (pullRequest.state === "MERGED" || pullRequest.state === "CLOSED") {
207
201
  reviewState = undefined;
208
202
  reviewWindow = undefined;
209
203
  ctx.ui.setStatus("pi-pr", formatPullRequest(pullRequest, ctx.ui.theme));
@@ -234,7 +228,7 @@ export default function pullRequestExtension(pi: ExtensionAPI): void {
234
228
  const reviews = await pi.exec(
235
229
  "gh",
236
230
  [
237
- "api", "graphql", "--hostname", new URL(pullRequest.url).hostname, "--paginate",
231
+ "api", "graphql", "--hostname", pullRequest.url.hostname, "--paginate",
238
232
  "-f", `query=${REVIEW_THREADS_QUERY}`, "-F", `id=${pullRequest.id}`,
239
233
  "--jq", "[.data.node.reviewThreads.nodes[] | select(.isResolved == false)] | length",
240
234
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@henryqw/pi-pr",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Show the current branch pull request status in the Pi footer.",
5
5
  "keywords": [
6
6
  "pi-package",