@osdlc/typed-gh 0.5.0 → 0.6.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/async.d.ts CHANGED
@@ -8,13 +8,13 @@
8
8
  * sync client would block the event loop: a fan-out of per-PR queries.
9
9
  */
10
10
  import { type AsyncCommandRunner, type CommandResult } from '@osdlc/command-seam';
11
- import type { IssueRow, Label, OwnerRepo, PullRequest } from './types.ts';
11
+ import type { IssueRow, Label, OwnerRepo, PrSearchHit, PullRequest, Repository } from './types.ts';
12
12
  import * as v from './verbs.ts';
13
- import type { ApiOptions, ApiResponse, AuthStatus, IssueListOptions, PrListOptions } from './verbs.ts';
13
+ import type { ApiOptions, ApiResponse, AuthStatus, GhTarget, IssueListOptions, ListResult, PrListOptions } from './verbs.ts';
14
14
  /**
15
- * Per-call options for {@link AsyncGh}. Eleven methods accept them: `raw`, `rawChecked`,
16
- * `prList`, `prView`, `openPrFor`, `prViewSettled`, `prBody`, `api`, `labelList`,
17
- * `issueList` and `issueView`.
15
+ * Per-call options for {@link AsyncGh}. Sixteen methods accept them: `raw`, `rawChecked`,
16
+ * `prList`, `prView`, `prFind`, `openPrFor`, `prViewSettled`, `prBody`, `api`, `graphql`,
17
+ * `labelList`, `issueList`, `issueView`, `repoList`, `repoView` and `searchPrs`.
18
18
  */
19
19
  export interface AsyncCallOptions {
20
20
  /**
@@ -26,15 +26,25 @@ export interface AsyncCallOptions {
26
26
  /** Aborts the call; the runner stops the child. */
27
27
  signal?: AbortSignal | undefined;
28
28
  }
29
- /** A typed, awaitable gh client bound to one working directory. */
29
+ /** What an {@link AsyncGh} is built with: the runner, and the repository and host it talks to. */
30
+ export interface AsyncGhOptions extends GhTarget {
31
+ runner?: AsyncCommandRunner | undefined;
32
+ }
33
+ /**
34
+ * A typed, awaitable gh client bound to one working directory, and optionally
35
+ * to one repository and host. `repo` and `hostname` work as on `Gh`.
36
+ */
30
37
  export declare class AsyncGh {
31
38
  readonly cwd: string;
39
+ readonly repo: string | undefined;
40
+ readonly hostname: string | undefined;
41
+ private readonly target;
32
42
  private readonly runner;
33
- constructor(cwd: string, opts?: {
34
- runner?: AsyncCommandRunner | undefined;
35
- });
36
- /** The same client rooted at a different directory (same runner). */
43
+ constructor(cwd: string, opts?: AsyncGhOptions);
44
+ /** The same client rooted at a different directory (same runner, repo and host). */
37
45
  at(cwd: string): AsyncGh;
46
+ /** The same client aimed at another repository (same runner, directory and host). */
47
+ withRepo(repo: string): AsyncGh;
38
48
  /** Unchecked passthrough for verbs not yet lifted into the API. */
39
49
  raw(argv: string[], opts?: AsyncCallOptions): Promise<CommandResult>;
40
50
  /** Checked passthrough — rejects with `CommandFailed` on a non-zero exit. */
@@ -42,9 +52,13 @@ export declare class AsyncGh {
42
52
  /** Run one verb from the table, honouring its checked/unchecked contract. */
43
53
  private exec;
44
54
  /** Pull requests matching `opts`, or null when gh failed. */
45
- prList(opts?: PrListOptions & AsyncCallOptions): Promise<PullRequest[] | null>;
46
- /** One PR with the heavy fields, or null when gh failed. */
47
- prView(number: number, opts?: {
55
+ prList(opts?: PrListOptions & AsyncCallOptions): Promise<ListResult<PullRequest> | null>;
56
+ /** One PR by number, branch or URL, with the heavy fields, or null. See `Gh.prView`. */
57
+ prView(ref: number | string, opts?: {
58
+ fields?: readonly string[] | undefined;
59
+ } & AsyncCallOptions): Promise<PullRequest | null>;
60
+ /** The one PR that `input` names, or null. See `Gh.prFind`. */
61
+ prFind(input: string, opts?: {
48
62
  fields?: readonly string[] | undefined;
49
63
  } & AsyncCallOptions): Promise<PullRequest | null>;
50
64
  /** The open PR whose head exactly equals `branch`, or null. See `Gh.openPrFor`. */
@@ -62,14 +76,28 @@ export declare class AsyncGh {
62
76
  prBody(number: number, opts?: AsyncCallOptions): Promise<string | null>;
63
77
  /** A REST GET through `gh api`; failure is `ok: false`, never a rejection. */
64
78
  api(endpoint: string, opts?: ApiOptions & AsyncCallOptions): Promise<ApiResponse>;
79
+ /**
80
+ * A GraphQL query; each page's `data`, or null. See `Gh.graphql`.
81
+ *
82
+ * @experimental
83
+ */
84
+ graphql(query: string, variables?: Record<string, v.GraphqlVariable>, opts?: v.GraphqlOptions & AsyncCallOptions): Promise<unknown[] | null>;
65
85
  /** Every label on the repository (up to `opts.limit`, default 1000), or null when gh failed. */
66
86
  labelList(opts?: {
67
87
  limit?: number | undefined;
68
- } & AsyncCallOptions): Promise<Label[] | null>;
88
+ } & AsyncCallOptions): Promise<ListResult<Label> | null>;
69
89
  /** Issues matching `opts`, or null when gh failed. */
70
- issueList(opts?: IssueListOptions & AsyncCallOptions): Promise<IssueRow[] | null>;
90
+ issueList(opts?: IssueListOptions & AsyncCallOptions): Promise<ListResult<IssueRow> | null>;
71
91
  /** One issue with its labels, or null when gh failed. */
72
92
  issueView(number: number, opts?: AsyncCallOptions): Promise<IssueRow | null>;
93
+ /** An owner's repositories, or null when gh failed. See `Gh.repoList`. */
94
+ repoList(owner: string, opts?: v.RepoListOptions & AsyncCallOptions): Promise<ListResult<Repository> | null>;
95
+ /** One repository, or null when gh failed. See `Gh.repoView`. */
96
+ repoView(repo?: string | undefined, opts?: {
97
+ fields?: readonly string[] | undefined;
98
+ } & AsyncCallOptions): Promise<Repository | null>;
99
+ /** Pull requests across repositories matching a search query, or null. See `Gh.searchPrs`. */
100
+ searchPrs(query: string, opts?: v.SearchPrsOptions & AsyncCallOptions): Promise<ListResult<PrSearchHit> | null>;
73
101
  /** True iff the `gh` binary is on PATH and runs. */
74
102
  installed(): Promise<boolean>;
75
103
  /** True iff `gh` holds credentials. */
@@ -1 +1 @@
1
- {"version":3,"file":"async.d.ts","sourceRoot":"","sources":["../async.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"async.d.ts","sourceRoot":"","sources":["../async.ts"],"names":[],"mappings":"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"}
package/dist/async.js CHANGED
@@ -8,21 +8,35 @@
8
8
  * sync client would block the event loop: a fan-out of per-PR queries.
9
9
  */
10
10
  import { runCheckedAsync, resolveRunnerAsync, } from '@osdlc/command-seam';
11
- import { parseOwnerRepo } from "./repo.js";
11
+ import { ownerRepoSlug, parseOwnerRepo, parsePrRef } from "./repo.js";
12
12
  import * as v from "./verbs.js";
13
13
  /** How long to wait between merge-state retries, in milliseconds. */
14
14
  const MERGE_STATE_RETRY_DELAY_MS = 1_500;
15
- /** A typed, awaitable gh client bound to one working directory. */
15
+ /**
16
+ * A typed, awaitable gh client bound to one working directory, and optionally
17
+ * to one repository and host. `repo` and `hostname` work as on `Gh`.
18
+ */
16
19
  export class AsyncGh {
17
20
  cwd;
21
+ repo;
22
+ hostname;
23
+ target;
18
24
  runner;
19
25
  constructor(cwd, opts = {}) {
26
+ v.checkTarget(opts);
20
27
  this.cwd = cwd;
28
+ this.repo = opts.repo;
29
+ this.hostname = opts.hostname;
30
+ this.target = { repo: opts.repo, hostname: opts.hostname };
21
31
  this.runner = resolveRunnerAsync('gh', opts.runner);
22
32
  }
23
- /** The same client rooted at a different directory (same runner). */
33
+ /** The same client rooted at a different directory (same runner, repo and host). */
24
34
  at(cwd) {
25
- return new AsyncGh(cwd, { runner: this.runner });
35
+ return new AsyncGh(cwd, { runner: this.runner, repo: this.repo, hostname: this.hostname });
36
+ }
37
+ /** The same client aimed at another repository (same runner, directory and host). */
38
+ withRepo(repo) {
39
+ return new AsyncGh(this.cwd, { runner: this.runner, repo, hostname: this.hostname });
26
40
  }
27
41
  // ── escape hatches ────────────────────────────────────────────────────────
28
42
  /** Unchecked passthrough for verbs not yet lifted into the API. */
@@ -38,6 +52,8 @@ export class AsyncGh {
38
52
  const opts = { cwd: this.cwd };
39
53
  if (verb.input !== undefined)
40
54
  opts.input = verb.input;
55
+ if (verb.env !== undefined)
56
+ opts.env = verb.env;
41
57
  if (call.timeoutMs !== undefined)
42
58
  opts.timeoutMs = call.timeoutMs;
43
59
  if (call.signal !== undefined)
@@ -50,11 +66,25 @@ export class AsyncGh {
50
66
  // ── queries ───────────────────────────────────────────────────────────────
51
67
  /** Pull requests matching `opts`, or null when gh failed. */
52
68
  prList(opts = {}) {
53
- return this.exec(v.prList(opts), opts);
54
- }
55
- /** One PR with the heavy fields, or null when gh failed. */
56
- prView(number, opts = {}) {
57
- return this.exec(v.prView(number, opts.fields ?? v.PR_VIEW_FIELDS), opts);
69
+ return this.exec(v.prList(opts, this.target), opts);
70
+ }
71
+ /** One PR by number, branch or URL, with the heavy fields, or null. See `Gh.prView`. */
72
+ prView(ref, opts = {}) {
73
+ return this.exec(v.prView(ref, opts.fields ?? v.PR_VIEW_FIELDS, this.target), opts);
74
+ }
75
+ /** The one PR that `input` names, or null. See `Gh.prFind`. */
76
+ async prFind(input, opts = {}) {
77
+ const ref = parsePrRef(input);
78
+ if (ref === null)
79
+ return null;
80
+ const call = { ...opts, fields: opts.fields ?? v.PR_LIST_FIELDS };
81
+ if (ref.kind === 'url')
82
+ return this.prView(ref.url, call);
83
+ if (ref.kind === 'branch')
84
+ return prForBranchOn(this, ref.name, call);
85
+ const client = ref.repo === null ? this : this.withRepo(ownerRepoSlug(ref.repo));
86
+ const pr = await client.prView(ref.number, call);
87
+ return pr !== null || ref.orBranch === null ? pr : prForBranchOn(this, ref.orBranch, call);
58
88
  }
59
89
  /** The open PR whose head exactly equals `branch`, or null. See `Gh.openPrFor`. */
60
90
  async openPrFor(branch, opts = {}) {
@@ -65,7 +95,7 @@ export class AsyncGh {
65
95
  timeoutMs: opts.timeoutMs,
66
96
  signal: opts.signal,
67
97
  });
68
- return v.pickPrForBranch(rows, branch);
98
+ return v.pickPrForBranch(rows?.rows ?? null, branch);
69
99
  }
70
100
  /** {@link prView}, re-asked until GitHub settles the merge state. See `Gh.prViewSettled`. */
71
101
  async prViewSettled(number, opts = {}) {
@@ -83,23 +113,43 @@ export class AsyncGh {
83
113
  }
84
114
  /** A PR's body text, or null when gh failed. */
85
115
  prBody(number, opts = {}) {
86
- return this.exec(v.prBody(number), opts);
116
+ return this.exec(v.prBody(number, this.target), opts);
87
117
  }
88
118
  /** A REST GET through `gh api`; failure is `ok: false`, never a rejection. */
89
119
  api(endpoint, opts = {}) {
90
- return this.exec(v.api(endpoint, opts), opts);
120
+ return this.exec(v.api(endpoint, opts, this.target), opts);
121
+ }
122
+ /**
123
+ * A GraphQL query; each page's `data`, or null. See `Gh.graphql`.
124
+ *
125
+ * @experimental
126
+ */
127
+ graphql(query, variables = {}, opts = {}) {
128
+ return this.exec(v.graphql(query, variables, opts, this.target), opts);
91
129
  }
92
130
  /** Every label on the repository (up to `opts.limit`, default 1000), or null when gh failed. */
93
131
  labelList(opts = {}) {
94
- return this.exec(v.labelList(opts), opts);
132
+ return this.exec(v.labelList(opts, this.target), opts);
95
133
  }
96
134
  /** Issues matching `opts`, or null when gh failed. */
97
135
  issueList(opts = {}) {
98
- return this.exec(v.issueList(opts), opts);
136
+ return this.exec(v.issueList(opts, this.target), opts);
99
137
  }
100
138
  /** One issue with its labels, or null when gh failed. */
101
139
  issueView(number, opts = {}) {
102
- return this.exec(v.issueView(number), opts);
140
+ return this.exec(v.issueView(number, this.target), opts);
141
+ }
142
+ /** An owner's repositories, or null when gh failed. See `Gh.repoList`. */
143
+ repoList(owner, opts = {}) {
144
+ return this.exec(v.repoList(owner, opts, this.target), opts);
145
+ }
146
+ /** One repository, or null when gh failed. See `Gh.repoView`. */
147
+ repoView(repo, opts = {}) {
148
+ return this.exec(v.repoView(repo, opts.fields ?? v.REPO_FIELDS, this.target), opts);
149
+ }
150
+ /** Pull requests across repositories matching a search query, or null. See `Gh.searchPrs`. */
151
+ searchPrs(query, opts = {}) {
152
+ return this.exec(v.searchPrs(query, opts, this.target), opts);
103
153
  }
104
154
  /** True iff the `gh` binary is on PATH and runs. */
105
155
  installed() {
@@ -111,7 +161,7 @@ export class AsyncGh {
111
161
  }
112
162
  /** Login state and what `gh auth status` printed. */
113
163
  authStatus() {
114
- return this.exec(v.authStatus());
164
+ return this.exec(v.authStatus(this.target));
115
165
  }
116
166
  /** True iff `gh` is installed AND authenticated; short-circuits. */
117
167
  async ready() {
@@ -127,23 +177,23 @@ export class AsyncGh {
127
177
  // ── mutations (checked) ───────────────────────────────────────────────────
128
178
  /** Open a PR and resolve to its URL ('' if gh printed none). */
129
179
  createPr(opts) {
130
- return this.exec(v.createPr(opts));
180
+ return this.exec(v.createPr(opts, this.target));
131
181
  }
132
182
  /** Retitle or rewrite a PR body. */
133
183
  editPr(number, opts) {
134
- return this.exec(v.editPr(number, opts));
184
+ return this.exec(v.editPr(number, opts, this.target));
135
185
  }
136
186
  /** Rewrite just a PR's body. */
137
187
  editPrBody(number, body) {
138
- return this.exec(v.editPrBody(number, body));
188
+ return this.exec(v.editPrBody(number, body, this.target));
139
189
  }
140
190
  /** The PR's unified diff; rejects with `CommandFailed` when gh cannot produce it. */
141
191
  prDiff(number) {
142
- return this.exec(v.prDiff(number));
192
+ return this.exec(v.prDiff(number, this.target));
143
193
  }
144
194
  /** Post one conversation comment on a PR; resolves to its URL ('' if gh printed none). */
145
195
  prComment(number, body) {
146
- return this.exec(v.prComment(number, body));
196
+ return this.exec(v.prComment(number, body, this.target));
147
197
  }
148
198
  /**
149
199
  * Create a `COMMENT` review with inline comments; resolves to the review's URL ('' if none came back).
@@ -151,15 +201,15 @@ export class AsyncGh {
151
201
  * @experimental
152
202
  */
153
203
  createReview(number, opts) {
154
- return this.exec(v.createReview(number, opts));
204
+ return this.exec(v.createReview(number, opts, this.target));
155
205
  }
156
206
  /** Bring a PR's head branch up to date with its base. */
157
207
  prUpdateBranch(number, style = 'merge') {
158
- return this.exec(v.prUpdateBranch(number, style));
208
+ return this.exec(v.prUpdateBranch(number, style, this.target));
159
209
  }
160
210
  /** Mark a PR ready for review (`draft: false`) or convert it to a draft (`draft: true`). */
161
211
  prSetDraft(number, draft) {
162
- return this.exec(v.prSetDraft(number, draft));
212
+ return this.exec(v.prSetDraft(number, draft, this.target));
163
213
  }
164
214
  /**
165
215
  * Rewrite one PR conversation comment's body. `commentId` is the numeric REST id; anything else rejects with `RangeError`.
@@ -168,29 +218,41 @@ export class AsyncGh {
168
218
  */
169
219
  async issueCommentEdit(commentId, body) {
170
220
  // async, so a bad id rejects the Promise instead of throwing at the call.
171
- return this.exec(v.issueCommentEdit(commentId, body));
221
+ return this.exec(v.issueCommentEdit(commentId, body, this.target));
172
222
  }
173
223
  /** Merge a PR; GitHub refuses when its head is no longer `opts.headSha`. */
174
224
  prMerge(number, opts) {
175
- return this.exec(v.prMerge(number, opts));
225
+ return this.exec(v.prMerge(number, opts, this.target));
176
226
  }
177
227
  /** A PR's review threads, or null when they could not be read completely. */
178
228
  prReviewThreads(number) {
179
- return this.exec(v.prReviewThreads(number));
229
+ return this.exec(v.prReviewThreads(number, this.target));
180
230
  }
181
231
  /** Create a label (or force it to `opts`'s color/description if it exists). */
182
232
  createLabel(opts) {
183
- return this.exec(v.createLabel(opts));
233
+ return this.exec(v.createLabel(opts, this.target));
184
234
  }
185
235
  /** Recolor and/or redescribe an existing label. */
186
236
  editLabel(name, opts) {
187
- return this.exec(v.editLabel(name, opts));
237
+ return this.exec(v.editLabel(name, opts, this.target));
188
238
  }
189
239
  /** Swap an issue's label in a single `gh issue edit` call. */
190
240
  setIssueLabel(number, currentLabel, newLabel) {
191
- return this.exec(v.setIssueLabel(number, currentLabel, newLabel));
241
+ return this.exec(v.setIssueLabel(number, currentLabel, newLabel, this.target));
192
242
  }
193
243
  }
244
+ /** The open PR for `branch`, else its newest closed or merged one. */
245
+ async function prForBranchOn(gh, branch, call) {
246
+ const rows = await gh.prList({
247
+ head: branch,
248
+ state: 'all',
249
+ limit: 20,
250
+ fields: v.branchPrFields(call.fields),
251
+ timeoutMs: call.timeoutMs,
252
+ signal: call.signal,
253
+ });
254
+ return v.branchPr(rows);
255
+ }
194
256
  function sleepAsync(ms) {
195
257
  return new Promise((resolve) => setTimeout(resolve, ms));
196
258
  }
package/dist/index.d.ts CHANGED
@@ -16,11 +16,11 @@
16
16
  *
17
17
  * Authentication is `gh`'s. No token is read, stored, or forwarded.
18
18
  */
19
- export { AsyncGh, type AsyncCallOptions } from './async.ts';
20
- export { Gh, defaultRunnerFactory, type RunnerFactory } from './sync.ts';
21
- export { api, authStatus, createPr, editPr, editPrBody, createLabel, createReview, editLabel, installed, issueList, issueView, labelList, openPrsForBranch, pickPrForBranch, prBody, prComment, prSetDraft, issueCommentEdit, prDiff, prList, prMerge, prReviewThreads, prUpdateBranch, prView, setIssueLabel, PR_LIST_FIELDS, PR_REF_FIELDS, PR_VIEW_FIELDS, type ApiOptions, type ApiResponse, type AuthStatus, type CreateLabelOptions, type CreatePrOptions, type CreateReviewOptions, type GhVerb, type IssueListOptions, type PrListOptions, type PrMergeMethod, type ReviewComment, type ReviewThread, } from './verbs.ts';
19
+ export { AsyncGh, type AsyncCallOptions, type AsyncGhOptions } from './async.ts';
20
+ export { Gh, defaultRunnerFactory, type GhOptions, type RunnerFactory } from './sync.ts';
21
+ export { api, authStatus, createPr, editPr, editPrBody, graphql, createLabel, createReview, editLabel, installed, issueList, issueView, labelList, nodesAt, openPrsForBranch, pickPrForBranch, prBody, prComment, prSetDraft, issueCommentEdit, prDiff, prList, prMerge, prReviewThreads, prUpdateBranch, prView, repoList, repoView, searchPrs, setIssueLabel, PR_LIST_FIELDS, PR_REF_FIELDS, PR_VIEW_FIELDS, REPO_FIELDS, SEARCH_PR_FIELDS, type ApiOptions, type ApiResponse, type AuthStatus, type CreateLabelOptions, type CreatePrOptions, type CreateReviewOptions, type GhTarget, type GraphqlOptions, type GraphqlVariable, type GhVerb, type IssueListOptions, type ListResult, type PrListOptions, type PrMergeMethod, type RepoListOptions, type ReviewComment, type ReviewThread, type SearchPrsOptions, } from './verbs.ts';
22
22
  export { anyCheckFailed, normalizeAuthorLogin, parsePullRequest } from './parse.ts';
23
- export { ownerRepoSlug, parseOwnerRepo, parsePrUrl, type PullRequestRef } from './repo.ts';
24
- export type { Actor, CheckConclusion, CheckRun, Comment, IssueRow, Label, MergeableState, MergeStateStatus, OwnerRepo, PullRequest, PullRequestState, Review, ReviewDecision, ReviewState, } from './types.ts';
23
+ export { ownerRepoSlug, parseOwnerRepo, parsePrRef, parsePrUrl, type PrRef, type PullRequestRef, } from './repo.ts';
24
+ export type { Actor, CheckConclusion, CheckRun, Comment, IssueRow, Label, MergeableState, MergeStateStatus, OwnerRepo, PullRequest, PrSearchHit, PullRequestState, Repository, RepositoryVisibility, Review, ReviewDecision, ReviewState, } from './types.ts';
25
25
  export { CommandFailed, type AsyncCommandRunner, type CommandResult, type CommandRunner, type CommandRunOptions, } from '@osdlc/command-seam';
26
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAE3D,OAAO,EAAE,EAAE,EAAE,oBAAoB,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAA;AAExE,OAAO,EACL,GAAG,EACH,UAAU,EACV,QAAQ,EACR,MAAM,EACN,UAAU,EACV,WAAW,EACX,YAAY,EACZ,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,MAAM,EACN,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,MAAM,EACN,MAAM,EACN,OAAO,EACP,eAAe,EACf,cAAc,EACd,MAAM,EACN,aAAa,EACb,cAAc,EACd,aAAa,EACb,cAAc,EACd,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,MAAM,EACX,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAEnF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAA;AAE1F,YAAY,EACV,KAAK,EACL,eAAe,EACf,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,KAAK,EACL,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,MAAM,EACN,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAA;AAKnB,OAAO,EACL,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhF,OAAO,EAAE,EAAE,EAAE,oBAAoB,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAA;AAExF,OAAO,EACL,GAAG,EACH,UAAU,EACV,QAAQ,EACR,MAAM,EACN,UAAU,EACV,OAAO,EACP,WAAW,EACX,YAAY,EACZ,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,OAAO,EACP,gBAAgB,EAChB,eAAe,EACf,MAAM,EACN,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,MAAM,EACN,MAAM,EACN,OAAO,EACP,eAAe,EACf,cAAc,EACd,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,aAAa,EACb,cAAc,EACd,aAAa,EACb,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,MAAM,EACX,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,gBAAgB,GACtB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAEnF,OAAO,EACL,aAAa,EACb,cAAc,EACd,UAAU,EACV,UAAU,EACV,KAAK,KAAK,EACV,KAAK,cAAc,GACpB,MAAM,WAAW,CAAA;AAElB,YAAY,EACV,KAAK,EACL,eAAe,EACf,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,KAAK,EACL,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,UAAU,EACV,oBAAoB,EACpB,MAAM,EACN,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAA;AAKnB,OAAO,EACL,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAA"}
package/dist/index.js CHANGED
@@ -18,9 +18,9 @@
18
18
  */
19
19
  export { AsyncGh } from "./async.js";
20
20
  export { Gh, defaultRunnerFactory } from "./sync.js";
21
- export { api, authStatus, createPr, editPr, editPrBody, createLabel, createReview, editLabel, installed, issueList, issueView, labelList, openPrsForBranch, pickPrForBranch, prBody, prComment, prSetDraft, issueCommentEdit, prDiff, prList, prMerge, prReviewThreads, prUpdateBranch, prView, setIssueLabel, PR_LIST_FIELDS, PR_REF_FIELDS, PR_VIEW_FIELDS, } from "./verbs.js";
21
+ export { api, authStatus, createPr, editPr, editPrBody, graphql, createLabel, createReview, editLabel, installed, issueList, issueView, labelList, nodesAt, openPrsForBranch, pickPrForBranch, prBody, prComment, prSetDraft, issueCommentEdit, prDiff, prList, prMerge, prReviewThreads, prUpdateBranch, prView, repoList, repoView, searchPrs, setIssueLabel, PR_LIST_FIELDS, PR_REF_FIELDS, PR_VIEW_FIELDS, REPO_FIELDS, SEARCH_PR_FIELDS, } from "./verbs.js";
22
22
  export { anyCheckFailed, normalizeAuthorLogin, parsePullRequest } from "./parse.js";
23
- export { ownerRepoSlug, parseOwnerRepo, parsePrUrl } from "./repo.js";
23
+ export { ownerRepoSlug, parseOwnerRepo, parsePrRef, parsePrUrl, } from "./repo.js";
24
24
  // The seam's error and runner types appear in this package's signatures, so
25
25
  // they are re-exported. Its functions are not: import them from
26
26
  // `@osdlc/command-seam`.
package/dist/parse.d.ts CHANGED
@@ -17,7 +17,7 @@
17
17
  * `StatusContext` carries `context`/`state`. They are folded onto one
18
18
  * verdict axis so a caller never has to know which it got.
19
19
  */
20
- import type { Actor, CheckRun, Label, PullRequest } from './types.ts';
20
+ import type { Actor, CheckRun, Label, PrSearchHit, PullRequest, Repository } from './types.ts';
21
21
  /**
22
22
  * Strip a single trailing `[bot]` suffix — REST shape folded to GraphQL shape.
23
23
  *
@@ -43,4 +43,8 @@ export declare function parseLabels(x: unknown): Label[];
43
43
  * any field subset.
44
44
  */
45
45
  export declare function parsePullRequest(raw: unknown): PullRequest | null;
46
+ /** A `gh repo list`/`view --json` row as a {@link Repository}, or null without `nameWithOwner`. */
47
+ export declare function parseRepository(raw: unknown): Repository | null;
48
+ /** A `gh search prs --json` row as a {@link PrSearchHit}, or null without a `number`. */
49
+ export declare function parsePrSearchHit(raw: unknown): PrSearchHit | null;
46
50
  //# sourceMappingURL=parse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,KAAK,EAEL,QAAQ,EAER,KAAK,EAEL,WAAW,EAGZ,MAAM,YAAY,CAAA;AAqCnB;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI,CAUnD;AAiBD,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAuCzD;AAED,+CAA+C;AAC/C,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,GAAG,OAAO,CAEnE;AAID,6OAA6O;AAC7O,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK,EAAE,CAS/C;AA4CD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAkCjE"}
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,KAAK,EAEL,QAAQ,EAER,KAAK,EAEL,WAAW,EACX,WAAW,EACX,UAAU,EAGX,MAAM,YAAY,CAAA;AAqCnB;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI,CAUnD;AAiBD,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAuCzD;AAED,+CAA+C;AAC/C,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,GAAG,OAAO,CAEnE;AAID,6OAA6O;AAC7O,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK,EAAE,CAS/C;AA4CD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAkCjE;AAID,mGAAmG;AACnG,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAgB/D;AAED,yFAAyF;AACzF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAwBjE"}
package/dist/parse.js CHANGED
@@ -223,3 +223,51 @@ export function parsePullRequest(raw) {
223
223
  updatedAt: strOrNull(raw['updatedAt'] ?? raw['updated_at']),
224
224
  };
225
225
  }
226
+ // ── repositories and search ─────────────────────────────────────────────────
227
+ /** A `gh repo list`/`view --json` row as a {@link Repository}, or null without `nameWithOwner`. */
228
+ export function parseRepository(raw) {
229
+ if (!isRecord(raw))
230
+ return null;
231
+ const nameWithOwner = str(raw['nameWithOwner']);
232
+ const slash = nameWithOwner.indexOf('/');
233
+ if (slash <= 0 || slash === nameWithOwner.length - 1)
234
+ return null;
235
+ const branch = raw['defaultBranchRef'];
236
+ return {
237
+ nameWithOwner,
238
+ owner: nameWithOwner.slice(0, slash),
239
+ name: nameWithOwner.slice(slash + 1),
240
+ description: str(raw['description']),
241
+ defaultBranch: isRecord(branch) ? strOrNull(branch['name']) : null,
242
+ visibility: strOrNull(raw['visibility']),
243
+ isArchived: bool(raw['isArchived']),
244
+ url: str(raw['url']),
245
+ };
246
+ }
247
+ /** A `gh search prs --json` row as a {@link PrSearchHit}, or null without a `number`. */
248
+ export function parsePrSearchHit(raw) {
249
+ if (!isRecord(raw))
250
+ return null;
251
+ const number = raw['number'];
252
+ if (typeof number !== 'number')
253
+ return null;
254
+ const repo = raw['repository'];
255
+ const slug = isRecord(repo) ? str(repo['nameWithOwner']) : '';
256
+ const slash = slug.indexOf('/');
257
+ return {
258
+ number,
259
+ title: str(raw['title']),
260
+ // Search answers in lower case; `PullRequest.state` is upper case.
261
+ state: str(raw['state']).toUpperCase(),
262
+ url: str(raw['url']),
263
+ isDraft: bool(raw['isDraft']),
264
+ repository: slash > 0 && slash < slug.length - 1
265
+ ? { owner: slug.slice(0, slash), repo: slug.slice(slash + 1) }
266
+ : null,
267
+ author: parseActor(raw['author']),
268
+ labels: parseLabels(raw['labels']),
269
+ createdAt: strOrNull(raw['createdAt']),
270
+ updatedAt: strOrNull(raw['updatedAt']),
271
+ closedAt: strOrNull(raw['closedAt']),
272
+ };
273
+ }
package/dist/repo.d.ts CHANGED
@@ -15,22 +15,54 @@ import type { OwnerRepo } from './types.ts';
15
15
  export declare function parseOwnerRepo(remoteUrl: string): OwnerRepo | null;
16
16
  /** `owner/repo`, the form `gh api` paths and `--repo` both take. */
17
17
  export declare function ownerRepoSlug(r: OwnerRepo): string;
18
- /** A pull request coordinate: the repository and the PR's number within it. */
18
+ /** A pull request coordinate: the host, the repository and the PR's number within it. */
19
19
  export interface PullRequestRef extends OwnerRepo {
20
+ /** The GitHub host, lower-cased: `github.com`, or an Enterprise host. */
21
+ hostname: string;
20
22
  number: number;
21
23
  }
22
24
  /**
23
- * The `{owner, repo, number}` a GitHub pull-request URL names, or null when
24
- * `url` is not one.
25
+ * The `{hostname, owner, repo, number}` a GitHub pull-request URL names, or
26
+ * null when `url` is not one.
25
27
  *
26
- * Accepts `https://github.com/<owner>/<repo>/pull/<n>` with or without a
27
- * scheme, a `www.` prefix, a trailing slash, a sub-page (`/files`,
28
- * `/commits`), a query string or a fragment — every shape a browser's address
29
- * bar hands over. `parseGitUrl` is the wrong tool here: it reads `/pull/<n>`
28
+ * Accepts `https://<host>/<owner>/<repo>/pull/<n>` with or without a scheme,
29
+ * a trailing slash, a sub-page (`/files`, `/commits`), a query string or a
30
+ * fragment — every shape a browser's address bar hands over. The host is
31
+ * `github.com` (a `www.` prefix is dropped) or a GitHub Enterprise host such
32
+ * as `github.acme.com` or `acme.ghe.com`; without a scheme the host must
33
+ * contain a dot. `parseGitUrl` is the wrong tool here: it reads `/pull/<n>`
30
34
  * as part of the project path.
31
- *
32
- * GitHub.com only. A GitHub Enterprise host is a different coordinate space
33
- * (the `gh` CLI needs `--hostname`), so it is not silently accepted.
34
35
  */
35
36
  export declare function parsePrUrl(url: string): PullRequestRef | null;
37
+ /**
38
+ * What a person typed to name a pull request, read by {@link parsePrRef}.
39
+ *
40
+ * - `number`: `42`, `#42`, or `owner/name#42` (then `repo` is set). For bare
41
+ * digits, `orBranch` holds the same text, since a branch can be named `42`.
42
+ * - `url`: a pull request URL, with what {@link parsePrUrl} read from it.
43
+ * - `branch`: any other text that is a valid branch name.
44
+ */
45
+ export type PrRef = {
46
+ kind: 'number';
47
+ number: number;
48
+ repo: OwnerRepo | null;
49
+ orBranch: string | null;
50
+ } | ({
51
+ kind: 'url';
52
+ url: string;
53
+ } & PullRequestRef) | {
54
+ kind: 'branch';
55
+ name: string;
56
+ };
57
+ /**
58
+ * Read what a person typed to name a pull request: a number, `#42`,
59
+ * `owner/name#42`, a URL, or a branch name. Null when it is none of these.
60
+ *
61
+ * Pure: it starts no process. Digits are read as a number first, the way
62
+ * `gh pr view 42` reads them; `orBranch` keeps the branch reading. The
63
+ * clients' `prFind` tries both.
64
+ */
65
+ export declare function parsePrRef(input: string): PrRef | null;
66
+ /** True for `owner/name` as GitHub spells it. */
67
+ export declare function isRepoSlug(text: string): boolean;
36
68
  //# sourceMappingURL=repo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../repo.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAMlE;AAED,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAElD;AAED,+EAA+E;AAC/E,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAS7D"}
1
+ {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../repo.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAMlE;AAED,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAElD;AAED,yFAAyF;AACzF,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAgB7D;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,KAAK,GACb;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACnF,CAAC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CAAC,GAC/C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpC;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAwBtD;AAED,iDAAiD;AACjD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD"}