@theholocron/github-client 1.58.0-alpha.1 → 1.58.0-alpha.11
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 +6 -1
- package/dist/index.d.mts +343 -2
- package/dist/index.mjs +79 -2
- package/package.json +16 -16
package/README.md
CHANGED
|
@@ -32,6 +32,11 @@ await client.topics.setTopics("owner/name", ["cli", "nodejs"]);
|
|
|
32
32
|
// Git plumbing (blobs, trees, commits, refs, PRs)
|
|
33
33
|
const ref = await client.git.getRef("owner/name", "main");
|
|
34
34
|
const blob = await client.git.createBlob("owner/name", "file contents");
|
|
35
|
+
|
|
36
|
+
// List a directory; a 404 is an empty list. `recursive` descends into nested directories
|
|
37
|
+
// (one request each) and returns a flat list of full paths.
|
|
38
|
+
const entries = await client.git.listDirectory("owner/name", ".holocron", { recursive: true });
|
|
39
|
+
// [{ name, path, type: "file" | "dir" | "symlink" | "submodule", size, sha }]
|
|
35
40
|
```
|
|
36
41
|
|
|
37
42
|
## Namespaces
|
|
@@ -50,7 +55,7 @@ const blob = await client.git.createBlob("owner/name", "file contents");
|
|
|
50
55
|
| `labels` | `listLabels`, `createLabel`, `updateLabel`, `deleteLabel` |
|
|
51
56
|
| `topics` | `setTopics` |
|
|
52
57
|
| `properties` | `setProperties` |
|
|
53
|
-
| `git` | `getRef`, `getCommit`, `getTree`, `getContents`, `putContents`, `createBlob`, `createTree`, `createCommit`, `createRef`, `updateRef`, `createPull`
|
|
58
|
+
| `git` | `getRef`, `getCommit`, `getTree`, `getContents`, `listDirectory`, `putContents`, `createBlob`, `createTree`, `createCommit`, `createRef`, `updateRef`, `createPull` |
|
|
54
59
|
| `checks` | `createCheckRun` |
|
|
55
60
|
|
|
56
61
|
GitHub accepts at most 50 annotations per check-run request. Slice with the
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,29 @@
|
|
|
1
1
|
import "@theholocron/http-client";
|
|
2
2
|
import { ErrorSink, Logger } from "@theholocron/observability/core";
|
|
3
|
+
/**
|
|
4
|
+
* GitHub's GraphQL API has exactly one endpoint (`POST /graphql`, always) —
|
|
5
|
+
* unlike REST's per-resource paths, there's nothing here for `createRestClient()`
|
|
6
|
+
* to route on. Reused anyway for the transport it already gets right (auth
|
|
7
|
+
* header, JSON body/parsing, network-failure wrapping into `ProviderApiError`
|
|
8
|
+
* with `status: 0`) — only the response-shape difference needs handling on
|
|
9
|
+
* top: GraphQL always answers `200 OK`, even for a query error, with the
|
|
10
|
+
* error(s) in the response body's own `errors` array rather than the HTTP
|
|
11
|
+
* status. `createRestClient()`'s own `!res.ok` branch never fires for a
|
|
12
|
+
* GraphQL error — this wrapper's the one place that translates a 200 with a
|
|
13
|
+
* populated `errors` array into a thrown `ProviderApiError`, matching the
|
|
14
|
+
* REST client's own error-throwing contract so callers don't need to know
|
|
15
|
+
* which transport they're talking to.
|
|
16
|
+
*/
|
|
17
|
+
interface GraphQLClient {
|
|
18
|
+
query<T>(document: string, variables?: Record<string, unknown>): Promise<T>;
|
|
19
|
+
}
|
|
20
|
+
/** Options for creating a GitHub client. */
|
|
3
21
|
interface GitHubClientOptions {
|
|
22
|
+
/** The token sent as the bearer credential. */
|
|
4
23
|
token: string;
|
|
24
|
+
/** The GitHub API base URL; defaults to `https://api.github.com`. */
|
|
5
25
|
baseUrl?: string;
|
|
26
|
+
/** The `fetch` implementation to use; defaults to the global `fetch`. */
|
|
6
27
|
fetch?: typeof fetch;
|
|
7
28
|
/** Structured logger for request/response diagnostics. Defaults to a no-op. */
|
|
8
29
|
logger?: Logger;
|
|
@@ -16,8 +37,11 @@ interface GitHubBranch {
|
|
|
16
37
|
sha: string;
|
|
17
38
|
};
|
|
18
39
|
}
|
|
40
|
+
/** The lifecycle state of a check run. */
|
|
19
41
|
type CheckRunStatus = "queued" | "in_progress" | "completed";
|
|
42
|
+
/** The final result of a completed check run. */
|
|
20
43
|
type CheckRunConclusion = "success" | "failure" | "neutral" | "cancelled" | "timed_out" | "action_required" | "skipped";
|
|
44
|
+
/** The severity of a check run annotation. */
|
|
21
45
|
type CheckRunAnnotationLevel = "notice" | "warning" | "failure";
|
|
22
46
|
/**
|
|
23
47
|
* GitHub's cap on `output.annotations` per `createCheckRun()` /
|
|
@@ -26,15 +50,19 @@ type CheckRunAnnotationLevel = "notice" | "warning" | "failure";
|
|
|
26
50
|
* do for you; slice with it rather than hardcoding the number.
|
|
27
51
|
*/
|
|
28
52
|
export declare const MAX_CHECK_RUN_ANNOTATIONS = 50;
|
|
53
|
+
/** One inline annotation attached to a check run's output, anchored to a file and line range. */
|
|
29
54
|
interface CheckRunAnnotation {
|
|
30
55
|
/** File path relative to the repo root. */
|
|
31
56
|
path: string;
|
|
32
57
|
/** 1-indexed. */
|
|
33
58
|
start_line: number;
|
|
59
|
+
/** 1-indexed last line of the annotated range. */
|
|
34
60
|
end_line: number;
|
|
35
61
|
/** Only valid when `start_line === end_line`. */
|
|
36
62
|
start_column?: number;
|
|
63
|
+
/** Column of the end of the range; only valid when `start_line === end_line`. */
|
|
37
64
|
end_column?: number;
|
|
65
|
+
/** Severity of the annotation. */
|
|
38
66
|
annotation_level: CheckRunAnnotationLevel;
|
|
39
67
|
/** Max 64KB. */
|
|
40
68
|
message: string;
|
|
@@ -43,9 +71,13 @@ interface CheckRunAnnotation {
|
|
|
43
71
|
/** Max 64KB. */
|
|
44
72
|
raw_details?: string;
|
|
45
73
|
}
|
|
74
|
+
/** The title, summary and optional annotations shown on a check run. */
|
|
46
75
|
interface CheckRunOutput {
|
|
76
|
+
/** The output's title. */
|
|
47
77
|
title: string;
|
|
78
|
+
/** The output's summary, rendered as Markdown. */
|
|
48
79
|
summary: string;
|
|
80
|
+
/** Longer details text, rendered as Markdown. */
|
|
49
81
|
text?: string;
|
|
50
82
|
/**
|
|
51
83
|
* Inline PR annotations — up to {@link MAX_CHECK_RUN_ANNOTATIONS} per
|
|
@@ -54,7 +86,9 @@ interface CheckRunOutput {
|
|
|
54
86
|
*/
|
|
55
87
|
annotations?: CheckRunAnnotation[];
|
|
56
88
|
}
|
|
89
|
+
/** The body of a `createCheckRun()` request. */
|
|
57
90
|
interface CreateCheckRunInput {
|
|
91
|
+
/** The check run's name, as shown in the checks list. */
|
|
58
92
|
name: string;
|
|
59
93
|
/** The commit SHA the check run attaches to. */
|
|
60
94
|
head_sha: string;
|
|
@@ -62,30 +96,46 @@ interface CreateCheckRunInput {
|
|
|
62
96
|
status?: CheckRunStatus;
|
|
63
97
|
/** Required when `status` is `"completed"`. */
|
|
64
98
|
conclusion?: CheckRunConclusion;
|
|
99
|
+
/** The title, summary and annotations to show on the check run. */
|
|
65
100
|
output?: CheckRunOutput;
|
|
66
101
|
/** URL for the "Details" link on the check run. GitHub defaults to the check suite's own summary page when omitted. */
|
|
67
102
|
details_url?: string;
|
|
68
103
|
}
|
|
104
|
+
/** A check run as GitHub returns it, with only the fields this client reads. */
|
|
69
105
|
interface GitHubCheckRun {
|
|
106
|
+
/** The check run's numeric id. */
|
|
70
107
|
id: number;
|
|
108
|
+
/** The check run's name. */
|
|
71
109
|
name: string;
|
|
110
|
+
/** The commit SHA the check run is attached to. */
|
|
72
111
|
head_sha: string;
|
|
112
|
+
/** The check run's current lifecycle state. */
|
|
73
113
|
status: CheckRunStatus;
|
|
114
|
+
/** The check run's result, or `null` until it is completed. */
|
|
74
115
|
conclusion: CheckRunConclusion | null;
|
|
116
|
+
/** The URL of the check run's page on GitHub. */
|
|
75
117
|
html_url: string;
|
|
76
118
|
}
|
|
119
|
+
/** The body of an `updateCheckRun()` request; every field is optional. */
|
|
77
120
|
interface UpdateCheckRunInput {
|
|
121
|
+
/** The lifecycle state to move the check run to. */
|
|
78
122
|
status?: CheckRunStatus;
|
|
79
123
|
/** Required when `status` is `"completed"`. */
|
|
80
124
|
conclusion?: CheckRunConclusion;
|
|
125
|
+
/** The title, summary and annotations to set on the check run. */
|
|
81
126
|
output?: CheckRunOutput;
|
|
82
127
|
/** URL for the "Details" link on the check run. */
|
|
83
128
|
details_url?: string;
|
|
84
129
|
}
|
|
130
|
+
/** A deployment environment of a repository and its protection settings. */
|
|
85
131
|
interface GitHubEnvironment {
|
|
132
|
+
/** The environment's name. */
|
|
86
133
|
name: string;
|
|
134
|
+
/** Minutes to wait before a job that targets the environment may proceed. */
|
|
87
135
|
wait_timer?: number;
|
|
136
|
+
/** Whether the user who triggered a deployment may also approve it. */
|
|
88
137
|
prevent_self_review?: boolean;
|
|
138
|
+
/** The protection rules on the environment; each has a `type` and, for required reviewers, the reviewers. */
|
|
89
139
|
protection_rules?: Array<{
|
|
90
140
|
type: string;
|
|
91
141
|
reviewers?: Array<{
|
|
@@ -96,52 +146,107 @@ interface GitHubEnvironment {
|
|
|
96
146
|
}>;
|
|
97
147
|
}>;
|
|
98
148
|
}
|
|
149
|
+
/** A git reference (such as a branch) and the object it points at. */
|
|
99
150
|
interface GitRef {
|
|
151
|
+
/** The object the reference points at. */
|
|
100
152
|
object: {
|
|
153
|
+
/** The object's SHA. */
|
|
101
154
|
sha: string;
|
|
155
|
+
/** The object's type, e.g. `commit`. */
|
|
102
156
|
type: string;
|
|
157
|
+
/** The API URL of the object. */
|
|
103
158
|
url: string;
|
|
104
159
|
};
|
|
160
|
+
/** The full reference name, e.g. `refs/heads/main`. */
|
|
105
161
|
ref: string;
|
|
162
|
+
/** The API URL of the reference. */
|
|
106
163
|
url: string;
|
|
107
164
|
}
|
|
165
|
+
/** A git commit, with only the fields this client reads. */
|
|
108
166
|
interface GitCommit {
|
|
167
|
+
/** The commit's SHA. */
|
|
109
168
|
sha: string;
|
|
169
|
+
/** The tree the commit points at. */
|
|
110
170
|
tree: {
|
|
171
|
+
/** The tree's SHA. */
|
|
111
172
|
sha: string;
|
|
173
|
+
/** The API URL of the tree. */
|
|
112
174
|
url: string;
|
|
113
175
|
};
|
|
114
176
|
}
|
|
177
|
+
/** One entry of a git tree. */
|
|
115
178
|
interface GitTreeItem {
|
|
179
|
+
/** The entry's path within the tree. */
|
|
116
180
|
path: string;
|
|
181
|
+
/** The entry's object SHA. */
|
|
117
182
|
sha: string;
|
|
183
|
+
/** The kind of object the entry points at, e.g. `blob` or `tree`. */
|
|
118
184
|
type: string;
|
|
185
|
+
/** The entry's file mode, e.g. `100644`. */
|
|
119
186
|
mode?: string;
|
|
187
|
+
/** The blob's size in bytes; absent for trees. */
|
|
120
188
|
size?: number;
|
|
121
189
|
}
|
|
190
|
+
/** A git tree as GitHub returns it. */
|
|
122
191
|
interface GitTree {
|
|
192
|
+
/** The tree's SHA. */
|
|
123
193
|
sha: string;
|
|
194
|
+
/** The entries of the tree. */
|
|
124
195
|
tree: GitTreeItem[];
|
|
196
|
+
/** Whether GitHub cut the entry list short because the tree was too large. */
|
|
125
197
|
truncated: boolean;
|
|
126
198
|
}
|
|
199
|
+
/** A file's contents as the contents API returns them. */
|
|
127
200
|
interface GitContents {
|
|
201
|
+
/** The file content, encoded as named by `encoding`. */
|
|
128
202
|
content: string;
|
|
203
|
+
/** The encoding of `content`, normally `base64`. */
|
|
129
204
|
encoding: string;
|
|
205
|
+
/** The file's blob SHA. */
|
|
130
206
|
sha: string;
|
|
207
|
+
/** The file's name. */
|
|
131
208
|
name: string;
|
|
209
|
+
/** The file's path in the repository. */
|
|
132
210
|
path: string;
|
|
133
211
|
}
|
|
212
|
+
/** One entry of a directory listing from the contents API. */
|
|
213
|
+
interface GitDirectoryEntry {
|
|
214
|
+
/** The entry's name, without its directory. */
|
|
215
|
+
name: string;
|
|
216
|
+
/** The entry's path from the repository root, e.g. `.holocron/notifications.ts`. */
|
|
217
|
+
path: string;
|
|
218
|
+
/** What the entry is; `dir` entries are listed, and descended into only when `recursive` is set. */
|
|
219
|
+
type: "file" | "dir" | "symlink" | "submodule";
|
|
220
|
+
/** The size in bytes; GitHub reports `0` for directories and submodules. */
|
|
221
|
+
size: number;
|
|
222
|
+
/** The entry's object SHA. */
|
|
223
|
+
sha: string;
|
|
224
|
+
}
|
|
225
|
+
/** Options for `listDirectory()`. */
|
|
226
|
+
interface ListDirectoryOptions {
|
|
227
|
+
/** A branch, tag or commit SHA; defaults to the repo's default branch. */
|
|
228
|
+
ref?: string;
|
|
229
|
+
/** Also list the contents of every nested directory, as one flat list of full paths. Defaults to `false`. */
|
|
230
|
+
recursive?: boolean;
|
|
231
|
+
}
|
|
134
232
|
/** What `git.putContents` returns: the file's new blob sha (the `sha` to pass next time) and the commit it made. */
|
|
135
233
|
interface PutContentsResult {
|
|
234
|
+
/** The file written: its path and its new blob SHA. */
|
|
136
235
|
content: {
|
|
236
|
+
/** The file's new blob SHA. */
|
|
137
237
|
sha: string;
|
|
238
|
+
/** The file's path. */
|
|
138
239
|
path: string;
|
|
139
240
|
};
|
|
241
|
+
/** The commit that was made. */
|
|
140
242
|
commit: {
|
|
243
|
+
/** The new commit's SHA. */
|
|
141
244
|
sha: string;
|
|
142
245
|
};
|
|
143
246
|
}
|
|
247
|
+
/** The body of a `putContents()` request. */
|
|
144
248
|
interface PutContentsInput {
|
|
249
|
+
/** The commit message. */
|
|
145
250
|
message: string;
|
|
146
251
|
/** The new file text (UTF-8); the client encodes it. */
|
|
147
252
|
content: string;
|
|
@@ -154,99 +259,172 @@ interface PutContentsInput {
|
|
|
154
259
|
/** Defaults to the repo's default branch. */
|
|
155
260
|
branch?: string;
|
|
156
261
|
}
|
|
262
|
+
/** A git blob created in the repository. */
|
|
157
263
|
interface GitBlob {
|
|
264
|
+
/** The blob's SHA. */
|
|
158
265
|
sha: string;
|
|
266
|
+
/** The API URL of the blob. */
|
|
159
267
|
url: string;
|
|
160
268
|
}
|
|
269
|
+
/** A pull request as returned when one is created, with only the fields this client reads. */
|
|
161
270
|
interface GitPull {
|
|
271
|
+
/** The pull request's number. */
|
|
162
272
|
number: number;
|
|
273
|
+
/** The URL of the pull request's page on GitHub. */
|
|
163
274
|
html_url: string;
|
|
275
|
+
/** The pull request's title. */
|
|
164
276
|
title: string;
|
|
165
277
|
}
|
|
278
|
+
/** The body of a `createPull()` request. */
|
|
166
279
|
interface CreatePullInput {
|
|
280
|
+
/** The pull request's title. */
|
|
167
281
|
title: string;
|
|
282
|
+
/** The branch the changes come from. */
|
|
168
283
|
head: string;
|
|
284
|
+
/** The branch the changes are to be merged into. */
|
|
169
285
|
base: string;
|
|
286
|
+
/** The pull request's description. */
|
|
170
287
|
body?: string;
|
|
171
288
|
}
|
|
289
|
+
/** An issue as GitHub returns it, with only the fields this client reads. */
|
|
172
290
|
interface GitHubIssue {
|
|
291
|
+
/** The issue's numeric id. */
|
|
173
292
|
id: number;
|
|
293
|
+
/** The issue's number within its repository. */
|
|
174
294
|
number: number;
|
|
295
|
+
/** The issue's title. */
|
|
175
296
|
title: string;
|
|
297
|
+
/** The issue's description; `null` or absent when empty. */
|
|
176
298
|
body?: string | null;
|
|
299
|
+
/** Whether the issue is open or closed. */
|
|
177
300
|
state: "open" | "closed";
|
|
301
|
+
/** The labels on the issue. */
|
|
178
302
|
labels: Array<{
|
|
179
303
|
name: string;
|
|
180
304
|
}>;
|
|
305
|
+
/** The user the issue is assigned to, or `null` when unassigned. */
|
|
181
306
|
assignee: {
|
|
182
307
|
login: string;
|
|
183
308
|
name?: string | null;
|
|
184
309
|
email?: string | null;
|
|
185
310
|
} | null;
|
|
311
|
+
/** When the issue was last updated, as an ISO 8601 timestamp. */
|
|
186
312
|
updated_at: string;
|
|
313
|
+
/** The URL of the issue's page on GitHub. */
|
|
187
314
|
html_url: string;
|
|
315
|
+
/** Set when the item is a pull request; GitHub's issues API returns pull requests too. */
|
|
188
316
|
pull_request?: unknown;
|
|
189
317
|
}
|
|
318
|
+
/** A milestone, with only the fields this client reads. */
|
|
190
319
|
interface GitHubMilestone {
|
|
320
|
+
/** The milestone's number. */
|
|
191
321
|
number: number;
|
|
322
|
+
/** The milestone's title. */
|
|
192
323
|
title: string;
|
|
193
324
|
}
|
|
325
|
+
/** Filters for listing issues. */
|
|
194
326
|
interface IssueSearchParams {
|
|
327
|
+
/** Which issues to list by state; GitHub defaults to `open`. */
|
|
195
328
|
state?: "open" | "closed" | "all";
|
|
329
|
+
/** The field to sort by, passed through to GitHub. */
|
|
196
330
|
sort?: string;
|
|
331
|
+
/** The sort direction, passed through to GitHub. */
|
|
197
332
|
direction?: string;
|
|
333
|
+
/** The number of issues per page. */
|
|
198
334
|
per_page?: number;
|
|
335
|
+
/** Which issues to list by relation to the user, passed through to GitHub. */
|
|
199
336
|
filter?: string;
|
|
337
|
+
/** Limit to issues assigned to this login. */
|
|
200
338
|
assignee?: string;
|
|
201
339
|
}
|
|
340
|
+
/** A repository label. */
|
|
202
341
|
interface GitHubLabel {
|
|
342
|
+
/** The label's name. */
|
|
203
343
|
name: string;
|
|
344
|
+
/** The label's color as a hex code without the leading `#`. */
|
|
204
345
|
color: string;
|
|
346
|
+
/** The label's description, or `null` when it has none. */
|
|
205
347
|
description: string | null;
|
|
206
348
|
}
|
|
349
|
+
/** How a Pages site is built: by a workflow or from a branch. */
|
|
207
350
|
type PagesBuildType = "workflow" | "legacy";
|
|
351
|
+
/** The status of a Pages build. */
|
|
208
352
|
type PagesBuildStatus = "built" | "building" | "errored" | "unknown";
|
|
353
|
+
/** A repository's GitHub Pages site configuration. */
|
|
209
354
|
interface GitHubPages {
|
|
355
|
+
/** The latest build's status, or `null` when there is none. */
|
|
210
356
|
status: PagesBuildStatus | null;
|
|
357
|
+
/** How the site is built, or `null` when unknown. */
|
|
211
358
|
build_type: PagesBuildType | null;
|
|
359
|
+
/** The branch and folder the site is published from, for a legacy build. */
|
|
212
360
|
source?: {
|
|
361
|
+
/** The branch the site is published from. */
|
|
213
362
|
branch: string;
|
|
363
|
+
/** The folder on the branch, `/` or `/docs`. */
|
|
214
364
|
path: string;
|
|
215
365
|
};
|
|
366
|
+
/** Whether HTTPS is enforced for the site. */
|
|
216
367
|
https_enforced: boolean;
|
|
368
|
+
/** The site's custom domain, or `null` when it has none. */
|
|
217
369
|
custom_domain: string | null;
|
|
218
370
|
}
|
|
371
|
+
/** The body of a Pages creation request. */
|
|
219
372
|
interface CreatePagesPayload {
|
|
373
|
+
/** How the site is built. */
|
|
220
374
|
build_type: PagesBuildType;
|
|
221
375
|
/** Required when build_type is "legacy". */
|
|
222
376
|
source?: {
|
|
377
|
+
/** The branch the site is published from. */
|
|
223
378
|
branch: string;
|
|
379
|
+
/** The folder on the branch, `/` or `/docs`. */
|
|
224
380
|
path: string;
|
|
225
381
|
};
|
|
226
382
|
}
|
|
383
|
+
/** The body of a Pages update request; every field is optional. */
|
|
227
384
|
interface UpdatePagesPayload {
|
|
385
|
+
/** How the site is built. */
|
|
228
386
|
build_type?: PagesBuildType;
|
|
387
|
+
/** The branch and folder to publish from. */
|
|
229
388
|
source?: {
|
|
389
|
+
/** The branch the site is published from. */
|
|
230
390
|
branch: string;
|
|
391
|
+
/** The folder on the branch, `/` or `/docs`. */
|
|
231
392
|
path: string;
|
|
232
393
|
};
|
|
394
|
+
/** The custom domain, or `null` to remove it. */
|
|
233
395
|
cname?: string | null;
|
|
396
|
+
/** Whether to enforce HTTPS. */
|
|
234
397
|
https_enforced?: boolean;
|
|
235
398
|
}
|
|
236
399
|
/** One custom property of an organization, as its schema defines it. */
|
|
237
400
|
interface OrgProperty {
|
|
401
|
+
/** The property's name. */
|
|
238
402
|
property_name: string;
|
|
239
403
|
/** `string`, `single_select`, `multi_select`, `true_false` or `url`. */
|
|
240
404
|
value_type: string;
|
|
405
|
+
/** Whether a repository must set the property. */
|
|
241
406
|
required?: boolean;
|
|
242
407
|
/** The values a `single_select` or `multi_select` property accepts; `null` for any other type. */
|
|
243
408
|
allowed_values?: string[] | null;
|
|
244
409
|
}
|
|
410
|
+
/** One custom property value set on a repository. */
|
|
411
|
+
interface RepoPropertyValue {
|
|
412
|
+
/** The property's name. */
|
|
413
|
+
property_name: string;
|
|
414
|
+
/** A string, a string array for `multi_select`, or `null` when unset. */
|
|
415
|
+
value: string | string[] | null;
|
|
416
|
+
}
|
|
417
|
+
/** A pull request as GitHub returns it, with only the fields this client reads. */
|
|
245
418
|
interface GitHubPullRequest {
|
|
419
|
+
/** The pull request's number. */
|
|
246
420
|
number: number;
|
|
421
|
+
/** The pull request's title. */
|
|
247
422
|
title: string;
|
|
423
|
+
/** Whether the pull request is open or closed. */
|
|
248
424
|
state: "open" | "closed";
|
|
425
|
+
/** When the pull request was merged as an ISO 8601 timestamp, or `null` if it was not merged. */
|
|
249
426
|
merged_at: string | null;
|
|
427
|
+
/** The URL of the pull request's page on GitHub. */
|
|
250
428
|
html_url: string;
|
|
251
429
|
/** The head branch: its name and the commit it pointed at when the PR was read. */
|
|
252
430
|
head: {
|
|
@@ -263,10 +441,15 @@ interface GitHubCommitIdentity {
|
|
|
263
441
|
}
|
|
264
442
|
/** One commit as returned by `GET /pulls/{pull_number}/commits` — only the fields any known consumer needs. */
|
|
265
443
|
interface GitHubPullRequestCommit {
|
|
444
|
+
/** The commit's SHA. */
|
|
266
445
|
sha: string;
|
|
446
|
+
/** The commit's message and git identities. */
|
|
267
447
|
commit: {
|
|
448
|
+
/** The commit message. */
|
|
268
449
|
message: string;
|
|
450
|
+
/** The commit's author, as git recorded it. */
|
|
269
451
|
author: GitHubCommitIdentity;
|
|
452
|
+
/** The commit's committer, as git recorded it. */
|
|
270
453
|
committer: GitHubCommitIdentity;
|
|
271
454
|
};
|
|
272
455
|
/** The commit's linked GitHub account, when GitHub can associate one — `null` for a commit email with no linked account. `type: "Bot"` identifies an app-authored commit (e.g. Dependabot, a prior Sentinel auto-fix-commit). */
|
|
@@ -281,7 +464,9 @@ interface GitHubPullRequestCommit {
|
|
|
281
464
|
}
|
|
282
465
|
/** One file as returned by `GET /pulls/{pull_number}/files` — only the fields any known consumer needs. */
|
|
283
466
|
interface GitHubPullRequestFile {
|
|
467
|
+
/** The file's path in the repository. */
|
|
284
468
|
filename: string;
|
|
469
|
+
/** How the pull request changes the file. */
|
|
285
470
|
status: "added" | "removed" | "modified" | "renamed" | "copied" | "changed" | "unchanged";
|
|
286
471
|
/** Set only when `status === "renamed"`. */
|
|
287
472
|
previous_filename?: string;
|
|
@@ -301,8 +486,10 @@ interface CreateReviewComment {
|
|
|
301
486
|
line: number;
|
|
302
487
|
/** Almost always `"RIGHT"` (the PR's own new content) — `"LEFT"` targets the base/pre-PR version instead. */
|
|
303
488
|
side: "LEFT" | "RIGHT";
|
|
489
|
+
/** The comment text. */
|
|
304
490
|
body: string;
|
|
305
491
|
}
|
|
492
|
+
/** The body of a review creation request. */
|
|
306
493
|
interface CreateReviewInput {
|
|
307
494
|
/** The PR's head SHA the review attaches to. */
|
|
308
495
|
commit_id: string;
|
|
@@ -315,11 +502,14 @@ interface CreateReviewInput {
|
|
|
315
502
|
* required-approval counts and dismissal.
|
|
316
503
|
*/
|
|
317
504
|
event: "COMMENT" | "REQUEST_CHANGES" | "APPROVE";
|
|
505
|
+
/** Inline comments to post with the review. */
|
|
318
506
|
comments?: CreateReviewComment[];
|
|
319
507
|
}
|
|
320
508
|
/** `POST /pulls/{pull_number}/reviews`'s response — only the fields any known consumer needs. */
|
|
321
509
|
interface GitHubPullRequestReview {
|
|
510
|
+
/** The review's numeric id. */
|
|
322
511
|
id: number;
|
|
512
|
+
/** The URL of the review on GitHub. */
|
|
323
513
|
html_url: string;
|
|
324
514
|
}
|
|
325
515
|
/**
|
|
@@ -330,7 +520,9 @@ interface GitHubPullRequestReview {
|
|
|
330
520
|
* never compare it against a REST-sourced ID.
|
|
331
521
|
*/
|
|
332
522
|
interface ReviewThread {
|
|
523
|
+
/** The thread's GraphQL node id. */
|
|
333
524
|
id: string;
|
|
525
|
+
/** Whether the thread is resolved. */
|
|
334
526
|
isResolved: boolean;
|
|
335
527
|
/** The thread's first comment's author login (e.g. `"the-holocron-sentinel[bot]"`) — `undefined` if GitHub ever returns a thread with no comments, which shouldn't happen in practice. Callers filter on this before resolving anything, so a bot never touches a human reviewer's own thread. */
|
|
336
528
|
authorLogin: string | undefined;
|
|
@@ -348,19 +540,70 @@ interface ReviewThread {
|
|
|
348
540
|
*/
|
|
349
541
|
body: string | undefined;
|
|
350
542
|
}
|
|
543
|
+
/** A repository as GitHub returns it, with only the fields this client reads. */
|
|
351
544
|
interface GitHubRepo {
|
|
545
|
+
/** The name of the repository's default branch. */
|
|
352
546
|
default_branch: string;
|
|
547
|
+
/** The repository's `owner/name`. */
|
|
353
548
|
full_name: string;
|
|
354
|
-
|
|
549
|
+
/** The repository description. */
|
|
550
|
+
description?: string | null;
|
|
551
|
+
/** The repository homepage URL. */
|
|
552
|
+
homepage?: string | null;
|
|
553
|
+
/** The topics set on the repository. */
|
|
554
|
+
topics?: string[];
|
|
555
|
+
/** Whether squash merging is allowed. */
|
|
556
|
+
allow_squash_merge?: boolean;
|
|
557
|
+
/** Whether merge commits are allowed. */
|
|
558
|
+
allow_merge_commit?: boolean;
|
|
559
|
+
/** Whether rebase merging is allowed. */
|
|
560
|
+
allow_rebase_merge?: boolean;
|
|
561
|
+
/** Whether auto-merge is allowed. */
|
|
562
|
+
allow_auto_merge?: boolean;
|
|
563
|
+
/** Whether a pull request branch can be updated from its base. */
|
|
564
|
+
allow_update_branch?: boolean;
|
|
565
|
+
/** Whether a merged pull request's branch is deleted. */
|
|
566
|
+
delete_branch_on_merge?: boolean;
|
|
567
|
+
/** Whether issues are enabled. */
|
|
568
|
+
has_issues?: boolean;
|
|
569
|
+
/** Whether discussions are enabled. */
|
|
570
|
+
has_discussions?: boolean;
|
|
571
|
+
/** Whether projects are enabled. */
|
|
572
|
+
has_projects?: boolean;
|
|
573
|
+
/** Whether the wiki is enabled. */
|
|
574
|
+
has_wiki?: boolean;
|
|
575
|
+
/** Each feature's `status` (`enabled` / `disabled`). Only an admin token sees it; absent for the rest. */
|
|
576
|
+
security_and_analysis?: Record<string, {
|
|
577
|
+
status: string;
|
|
578
|
+
} | undefined> | null;
|
|
579
|
+
}
|
|
580
|
+
/** A file's contents as the contents API returns them. */
|
|
355
581
|
interface GitHubContents {
|
|
582
|
+
/** The file content, encoded as named by `encoding`. */
|
|
356
583
|
content: string;
|
|
584
|
+
/** The encoding of `content`, normally `base64`. */
|
|
357
585
|
encoding: string;
|
|
358
586
|
}
|
|
587
|
+
/** A repository ruleset in summary form. */
|
|
359
588
|
interface GitHubRuleset {
|
|
589
|
+
/** The ruleset's numeric id. */
|
|
360
590
|
id: number;
|
|
591
|
+
/** The ruleset's name. */
|
|
361
592
|
name: string;
|
|
593
|
+
/** How the ruleset is enforced, e.g. `active`, `evaluate` or `disabled`. */
|
|
362
594
|
enforcement: string;
|
|
363
595
|
}
|
|
596
|
+
/** One ruleset in full, as `GET /repos/{repo}/rulesets/{id}` returns it. */
|
|
597
|
+
interface GitHubRulesetDetail extends GitHubRuleset {
|
|
598
|
+
/** What the ruleset applies to, e.g. `branch`. */
|
|
599
|
+
target?: string;
|
|
600
|
+
/** Each rule has a `type`; some carry `parameters`. */
|
|
601
|
+
rules?: Array<{
|
|
602
|
+
type: string;
|
|
603
|
+
parameters?: Record<string, unknown>;
|
|
604
|
+
}>;
|
|
605
|
+
}
|
|
606
|
+
/** Where a secret lives: the repository, one of its environments, or an organization. */
|
|
364
607
|
type SecretScope = {
|
|
365
608
|
kind: "repo";
|
|
366
609
|
} | {
|
|
@@ -370,21 +613,39 @@ type SecretScope = {
|
|
|
370
613
|
kind: "organization";
|
|
371
614
|
org: string;
|
|
372
615
|
};
|
|
616
|
+
/** A public key used to encrypt a secret before it is sent. */
|
|
373
617
|
interface GitHubPublicKey {
|
|
618
|
+
/** The key's id, sent back with the encrypted secret. */
|
|
374
619
|
key_id: string;
|
|
620
|
+
/** The Base64-encoded public key. */
|
|
375
621
|
key: string;
|
|
376
622
|
}
|
|
623
|
+
/** The workflow run that a code scanning setup started. */
|
|
377
624
|
interface CodeScanningSetupResult {
|
|
625
|
+
/** The id of the workflow run. */
|
|
378
626
|
run_id: number;
|
|
627
|
+
/** The URL of the workflow run. */
|
|
379
628
|
run_url: string;
|
|
380
629
|
}
|
|
630
|
+
/** A permission level a team can hold on a repository. */
|
|
381
631
|
type TeamPermission = "pull" | "triage" | "push" | "maintain" | "admin";
|
|
632
|
+
/** A team with access to a repository, and the permission it has there. */
|
|
633
|
+
interface RepoTeam {
|
|
634
|
+
/** The team's slug. */
|
|
635
|
+
slug: string;
|
|
636
|
+
/** The team's permission on the repository. */
|
|
637
|
+
permission: TeamPermission;
|
|
638
|
+
}
|
|
382
639
|
/** A member of a team, as GitHub lists it. `id` is the numeric user id, which survives a rename; `login` does not. */
|
|
383
640
|
interface TeamMember {
|
|
641
|
+
/** The member's numeric user id. */
|
|
384
642
|
id: number;
|
|
643
|
+
/** The member's login. */
|
|
385
644
|
login: string;
|
|
645
|
+
/** The kind of account, e.g. `User`. */
|
|
386
646
|
type?: string;
|
|
387
647
|
}
|
|
648
|
+
/** Where a variable lives: the repository, one of its environments, or an organization. */
|
|
388
649
|
type VariableScope = {
|
|
389
650
|
kind: "repo";
|
|
390
651
|
} | {
|
|
@@ -401,40 +662,76 @@ type VariableScope = {
|
|
|
401
662
|
type VariableVisibility = "all" | "private" | "selected";
|
|
402
663
|
/** A GitHub Actions variable. Unlike a secret its value is readable, so a reconcile can tell whether it differs. */
|
|
403
664
|
interface GitHubVariable {
|
|
665
|
+
/** The variable's name. */
|
|
404
666
|
name: string;
|
|
667
|
+
/** The variable's value. */
|
|
405
668
|
value: string;
|
|
406
669
|
/** Present on organization variables only. */
|
|
407
670
|
visibility?: VariableVisibility;
|
|
408
671
|
}
|
|
672
|
+
/** The authenticated user, with only the fields this client reads. */
|
|
409
673
|
interface GitHubUser {
|
|
674
|
+
/** The user's login. */
|
|
410
675
|
login: string;
|
|
676
|
+
/** The user's display name, or `null` when not set. */
|
|
411
677
|
name: string | null;
|
|
678
|
+
/** The user's public email, or `null` when not set. */
|
|
412
679
|
email: string | null;
|
|
413
680
|
}
|
|
681
|
+
/** The authenticated user and, for a token that expires, when. */
|
|
682
|
+
interface GitHubUserWithExpiry {
|
|
683
|
+
/** The authenticated user. */
|
|
684
|
+
user: GitHubUser;
|
|
685
|
+
/** When the token stops working, ISO 8601 in UTC. Absent for a token that never expires. */
|
|
686
|
+
expiresAt?: string;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* The expiry GitHub reports in the `github-authentication-token-expiration` header (`2026-11-19 03:46:04 UTC`) as
|
|
690
|
+
* ISO 8601, or `undefined` when the header is missing or is not a date.
|
|
691
|
+
*/
|
|
692
|
+
export declare function parseTokenExpiration(header: string | null): string | undefined;
|
|
693
|
+
/** A workflow run as GitHub returns it, with only the fields this client reads. */
|
|
414
694
|
interface GitHubWorkflowRun {
|
|
695
|
+
/** The run's numeric id. */
|
|
415
696
|
id: number;
|
|
697
|
+
/** The workflow's name, or `null` when unnamed. */
|
|
416
698
|
name: string | null;
|
|
699
|
+
/** The run's display title. */
|
|
417
700
|
display_title: string;
|
|
701
|
+
/** The branch the run was triggered on. */
|
|
418
702
|
head_branch: string;
|
|
703
|
+
/** The commit SHA the run was triggered on. */
|
|
419
704
|
head_sha: string;
|
|
705
|
+
/** The run's status, e.g. `queued`, `in_progress` or `completed`. */
|
|
420
706
|
status: string;
|
|
707
|
+
/** The run's result once completed, or `null` before. */
|
|
421
708
|
conclusion: string | null;
|
|
709
|
+
/** The URL of the run's page on GitHub. */
|
|
422
710
|
html_url: string;
|
|
711
|
+
/** When the run was created, as an ISO 8601 timestamp. */
|
|
423
712
|
created_at: string;
|
|
713
|
+
/** When the run was last updated, as an ISO 8601 timestamp. */
|
|
424
714
|
updated_at: string;
|
|
425
715
|
}
|
|
716
|
+
/** Filters for listing workflow runs. */
|
|
426
717
|
interface WorkflowRunFilter {
|
|
718
|
+
/** Only runs on this branch. */
|
|
427
719
|
branch?: string;
|
|
720
|
+
/** The maximum number of runs to return. */
|
|
428
721
|
limit?: number;
|
|
722
|
+
/** Only runs with this status. */
|
|
429
723
|
status?: string;
|
|
430
724
|
}
|
|
725
|
+
/** The credentials identifying a GitHub App: its id and private key. */
|
|
431
726
|
interface GitHubAppCredentials {
|
|
432
727
|
/** The App's numeric id (not the client id). */
|
|
433
728
|
appId: string;
|
|
434
729
|
/** PEM-encoded RSA private key — PKCS#1 (GitHub's default download format) or PKCS#8, either works. */
|
|
435
730
|
privateKey: string;
|
|
436
731
|
}
|
|
732
|
+
/** A short-lived installation access token and when it expires. */
|
|
437
733
|
interface InstallationAccessToken {
|
|
734
|
+
/** The installation access token, used as a bearer token for the REST API. */
|
|
438
735
|
token: string;
|
|
439
736
|
/** ISO 8601 — installation tokens are short-lived, about an hour. */
|
|
440
737
|
expiresAt: string;
|
|
@@ -484,6 +781,7 @@ export declare function verifyGitHubWebhookSignature(input: {
|
|
|
484
781
|
signature: string | undefined;
|
|
485
782
|
secret: string;
|
|
486
783
|
}): boolean;
|
|
784
|
+
/** The three GitHub webhook headers a consumer needs. */
|
|
487
785
|
interface GitHubWebhookHeaders {
|
|
488
786
|
/** `X-GitHub-Event` — the event category, e.g. `"push"`, `"pull_request"`. */
|
|
489
787
|
event: string | undefined;
|
|
@@ -494,31 +792,62 @@ interface GitHubWebhookHeaders {
|
|
|
494
792
|
}
|
|
495
793
|
/** Extracts GitHub's three webhook headers, case-insensitively (Node's raw headers may arrive lower-cased, or as an array when a header repeats). */
|
|
496
794
|
export declare function parseGitHubWebhookHeaders(headers: Record<string, string | string[] | undefined>): GitHubWebhookHeaders;
|
|
795
|
+
/** The payload of an `installation` webhook delivery. */
|
|
497
796
|
interface GitHubInstallationWebhookPayload {
|
|
797
|
+
/** What happened to the installation, e.g. `created` or `deleted`. */
|
|
498
798
|
action: string;
|
|
799
|
+
/** The installation the delivery is about. */
|
|
499
800
|
installation: {
|
|
801
|
+
/** The installation id. */
|
|
500
802
|
id: number;
|
|
501
803
|
};
|
|
502
804
|
}
|
|
805
|
+
/** The payload of a `push` webhook delivery. */
|
|
503
806
|
interface GitHubPushWebhookPayload {
|
|
807
|
+
/** The full name of the pushed ref, e.g. `refs/heads/main`. */
|
|
504
808
|
ref: string;
|
|
809
|
+
/** The installation the delivery is about, when sent. */
|
|
505
810
|
installation?: {
|
|
811
|
+
/** The installation id. */
|
|
506
812
|
id: number;
|
|
507
813
|
};
|
|
814
|
+
/** The repository that was pushed to. */
|
|
508
815
|
repository: {
|
|
816
|
+
/** The repository's owner/name. */
|
|
509
817
|
full_name: string;
|
|
818
|
+
/** The name of the default branch. */
|
|
510
819
|
default_branch: string;
|
|
511
820
|
};
|
|
512
821
|
}
|
|
822
|
+
/** The payload of a `pull_request` webhook delivery. */
|
|
513
823
|
interface GitHubPullRequestWebhookPayload {
|
|
824
|
+
/** What happened to the pull request, e.g. `opened` or `closed`. */
|
|
514
825
|
action: string;
|
|
826
|
+
/** For an `edited` action, the fields that changed (each holds the previous value); absent for other actions. */
|
|
827
|
+
changes?: {
|
|
828
|
+
/** Present when the title was edited. */
|
|
829
|
+
title?: {
|
|
830
|
+
/** The title before the edit. */
|
|
831
|
+
from: string;
|
|
832
|
+
};
|
|
833
|
+
/** Present when the description was edited. */
|
|
834
|
+
body?: {
|
|
835
|
+
/** The description before the edit; `null` when it was empty. */
|
|
836
|
+
from: string | null;
|
|
837
|
+
};
|
|
838
|
+
};
|
|
839
|
+
/** The installation the delivery is about, when sent. */
|
|
515
840
|
installation?: {
|
|
841
|
+
/** The installation id. */
|
|
516
842
|
id: number;
|
|
517
843
|
};
|
|
844
|
+
/** The repository the pull request belongs to. */
|
|
518
845
|
repository: {
|
|
846
|
+
/** The repository's owner/name. */
|
|
519
847
|
full_name: string;
|
|
520
848
|
};
|
|
521
849
|
}
|
|
850
|
+
/** Creates a GitHub client with a group of methods per API area (branches, pulls, issues, secrets and so on), backed by one REST client and one GraphQL client built from the same options. */
|
|
522
851
|
export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
523
852
|
branches: {
|
|
524
853
|
protectBranch: (repo: string, branch: string, payload: Record<string, unknown>) => Promise<void>;
|
|
@@ -539,6 +868,7 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
539
868
|
getCommit: (repo: string, sha: string) => Promise<GitCommit>;
|
|
540
869
|
getTree: (repo: string, sha: string, recursive?: boolean) => Promise<GitTree>;
|
|
541
870
|
getContents: (repo: string, path: string, ref?: string) => Promise<GitContents>;
|
|
871
|
+
listDirectory: (repo: string, path: string, options?: ListDirectoryOptions) => Promise<GitDirectoryEntry[]>;
|
|
542
872
|
putContents: (repo: string, path: string, input: PutContentsInput) => Promise<PutContentsResult>;
|
|
543
873
|
createBlob: (repo: string, content: string, encoding?: string) => Promise<GitBlob>;
|
|
544
874
|
createTree: (repo: string, tree: Array<{
|
|
@@ -552,6 +882,8 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
552
882
|
updateRef: (repo: string, ref: string, sha: string, force?: boolean) => Promise<GitRef>;
|
|
553
883
|
createPull: (repo: string, input: CreatePullInput) => Promise<GitPull>;
|
|
554
884
|
};
|
|
885
|
+
/** The GraphQL client, for the callers whose API (Projects v2) has no REST form. */
|
|
886
|
+
graphql: GraphQLClient;
|
|
555
887
|
issues: {
|
|
556
888
|
listIssues: (repo: string, params?: IssueSearchParams) => Promise<GitHubIssue[]>;
|
|
557
889
|
getIssue: (repo: string, number: number) => Promise<GitHubIssue>;
|
|
@@ -583,6 +915,7 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
583
915
|
updatePages: (repo: string, payload: UpdatePagesPayload) => Promise<void>;
|
|
584
916
|
};
|
|
585
917
|
properties: {
|
|
918
|
+
getValues: (repo: string) => Promise<RepoPropertyValue[]>;
|
|
586
919
|
orgSchema: (org: string) => Promise<OrgProperty[]>;
|
|
587
920
|
setProperties: (repo: string, values: Record<string, string | string[]>) => Promise<void>;
|
|
588
921
|
};
|
|
@@ -601,6 +934,7 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
601
934
|
getContents: (repo: string, path: string) => Promise<GitHubContents>;
|
|
602
935
|
};
|
|
603
936
|
rulesets: {
|
|
937
|
+
getRuleset: (repo: string, id: number) => Promise<GitHubRulesetDetail>;
|
|
604
938
|
listRulesets: (repo: string) => Promise<GitHubRuleset[]>;
|
|
605
939
|
createRuleset: (repo: string, payload: Record<string, unknown>) => Promise<GitHubRuleset>;
|
|
606
940
|
updateRuleset: (repo: string, id: number, payload: Record<string, unknown>) => Promise<GitHubRuleset>;
|
|
@@ -612,6 +946,10 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
612
946
|
deleteSecret: (repo: string, scope: SecretScope, name: string) => Promise<void>;
|
|
613
947
|
};
|
|
614
948
|
security: {
|
|
949
|
+
vulnerabilityAlertsEnabled: (repo: string) => Promise<boolean>;
|
|
950
|
+
automatedSecurityFixesEnabled: (repo: string) => Promise<boolean>;
|
|
951
|
+
privateVulnerabilityReportingEnabled: (repo: string) => Promise<boolean>;
|
|
952
|
+
codeScanningDefaultSetupState: (repo: string) => Promise<string>;
|
|
615
953
|
enableVulnerabilityAlerts: (repo: string) => Promise<void>;
|
|
616
954
|
enableAutomatedSecurityFixes: (repo: string) => Promise<void>;
|
|
617
955
|
enableSecretScanning: (repo: string) => Promise<void>;
|
|
@@ -622,6 +960,7 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
622
960
|
};
|
|
623
961
|
teams: {
|
|
624
962
|
members: (org: string, teamSlug: string) => Promise<TeamMember[]>;
|
|
963
|
+
listForRepo: (repo: string) => Promise<RepoTeam[]>;
|
|
625
964
|
addRepo: (org: string, teamSlug: string, owner: string, repo: string, permission: TeamPermission) => Promise<void>;
|
|
626
965
|
};
|
|
627
966
|
topics: {
|
|
@@ -636,6 +975,7 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
636
975
|
};
|
|
637
976
|
user: {
|
|
638
977
|
getCurrentUser: () => Promise<GitHubUser>;
|
|
978
|
+
getCurrentUserWithExpiry(): Promise<GitHubUserWithExpiry>;
|
|
639
979
|
};
|
|
640
980
|
workflows: {
|
|
641
981
|
listRuns: (repo: string, filter?: WorkflowRunFilter) => Promise<GitHubWorkflowRun[]>;
|
|
@@ -643,5 +983,6 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
643
983
|
createWorkflowDispatch: (repo: string, workflowFile: string, ref: string, inputs?: Record<string, string>) => Promise<void>;
|
|
644
984
|
};
|
|
645
985
|
};
|
|
986
|
+
/** The client returned by `createGitHubClient()`: one group of methods per GitHub API area. */
|
|
646
987
|
export type GitHubClient = ReturnType<typeof createGitHubClient>;
|
|
647
|
-
export type { CheckRunAnnotation, CheckRunAnnotationLevel, CheckRunConclusion, CheckRunOutput, CheckRunStatus, CodeScanningSetupResult, CreateCheckRunInput, CreatePagesPayload, CreatePullInput, CreateReviewComment, CreateReviewInput, GitBlob, GitCommit, GitContents, GitHubAppCredentials, GitHubCheckRun, GitHubClientOptions, GitHubContents, GitHubEnvironment, GitHubInstallationWebhookPayload, GitHubIssue, GitHubLabel, GitHubMilestone, GitHubPages, GitHubPublicKey, GitHubPullRequest, GitHubPullRequestCommit, GitHubPullRequestFile, GitHubPullRequestReview, GitHubPullRequestWebhookPayload, GitHubPushWebhookPayload, GitHubRepo, GitHubRuleset, GitHubUser, GitHubVariable, GitHubWebhookHeaders, GitHubWorkflowRun, GitPull, GitRef, GitTree, GitTreeItem, InstallationAccessToken, IssueSearchParams, OrgProperty, PagesBuildStatus, PagesBuildType, PutContentsInput, PutContentsResult, ReviewThread, SecretScope, TeamMember, TeamPermission, UpdateCheckRunInput, UpdatePagesPayload, VariableScope, VariableVisibility, WorkflowRunFilter };
|
|
988
|
+
export type { CheckRunAnnotation, CheckRunAnnotationLevel, CheckRunConclusion, CheckRunOutput, CheckRunStatus, CodeScanningSetupResult, CreateCheckRunInput, CreatePagesPayload, CreatePullInput, CreateReviewComment, CreateReviewInput, GitBlob, GitCommit, GitContents, GitDirectoryEntry, GitHubAppCredentials, GitHubCheckRun, GitHubClientOptions, GitHubContents, GitHubEnvironment, GitHubInstallationWebhookPayload, GitHubIssue, GitHubLabel, GitHubMilestone, GitHubPages, GitHubPublicKey, GitHubPullRequest, GitHubPullRequestCommit, GitHubPullRequestFile, GitHubPullRequestReview, GitHubPullRequestWebhookPayload, GitHubPushWebhookPayload, GitHubRepo, GitHubRuleset, GitHubRulesetDetail, GitHubUser, GitHubUserWithExpiry, GitHubVariable, GitHubWebhookHeaders, GitHubWorkflowRun, GitPull, GitRef, GitTree, GitTreeItem, GraphQLClient, InstallationAccessToken, IssueSearchParams, ListDirectoryOptions, OrgProperty, PagesBuildStatus, PagesBuildType, PutContentsInput, PutContentsResult, RepoPropertyValue, RepoTeam, ReviewThread, SecretScope, TeamMember, TeamPermission, UpdateCheckRunInput, UpdatePagesPayload, VariableScope, VariableVisibility, WorkflowRunFilter };
|
package/dist/index.mjs
CHANGED
|
@@ -150,6 +150,36 @@ function git(rest) {
|
|
|
150
150
|
*/
|
|
151
151
|
getContents: (repo, path, ref) => rest.request(`${repoBase(repo)}/contents/${path}`, ref ? { query: { ref } } : void 0),
|
|
152
152
|
/**
|
|
153
|
+
* Lists the directory at `path` through the contents API (`GET /repos/:repo/contents/:path`, which
|
|
154
|
+
* answers an array for a directory). A 404 (no such directory) is an empty list, not an error; any
|
|
155
|
+
* other failure is the usual `ProviderApiError`. One request lists one level: with
|
|
156
|
+
* `recursive: true` it makes one more request per nested directory and returns a flat list of
|
|
157
|
+
* full paths (directories included). A `path` that is a file, not a directory, throws.
|
|
158
|
+
*/
|
|
159
|
+
listDirectory: async (repo, path, options = {}) => {
|
|
160
|
+
const list = async (at) => {
|
|
161
|
+
let body;
|
|
162
|
+
try {
|
|
163
|
+
body = await rest.request(`${repoBase(repo)}/contents/${filePath(at)}`, options.ref ? { query: { ref: options.ref } } : void 0);
|
|
164
|
+
} catch (err) {
|
|
165
|
+
if (err instanceof ProviderApiError && err.status === 404) return [];
|
|
166
|
+
throw err;
|
|
167
|
+
}
|
|
168
|
+
if (!Array.isArray(body)) throw new Error(`${repo}:${at} is a file, not a directory`);
|
|
169
|
+
const entries = body.map(({ name, path: p, type, size, sha }) => ({
|
|
170
|
+
name,
|
|
171
|
+
path: p,
|
|
172
|
+
type,
|
|
173
|
+
size,
|
|
174
|
+
sha
|
|
175
|
+
}));
|
|
176
|
+
if (!options.recursive) return entries;
|
|
177
|
+
const nested = await Promise.all(entries.filter((e) => e.type === "dir").map((e) => list(e.path)));
|
|
178
|
+
return [...entries, ...nested.flat()];
|
|
179
|
+
};
|
|
180
|
+
return list(path.replace(/^\/+|\/+$/g, ""));
|
|
181
|
+
},
|
|
182
|
+
/**
|
|
153
183
|
* `PUT /repos/:repo/contents/:path` — creates or updates one file in a single commit. Pass `sha` when
|
|
154
184
|
* updating so a concurrent change is refused (409) and not silently overwritten.
|
|
155
185
|
*/
|
|
@@ -293,6 +323,8 @@ function pages(rest) {
|
|
|
293
323
|
// src/properties/properties.ts
|
|
294
324
|
function properties(rest) {
|
|
295
325
|
return {
|
|
326
|
+
/** The custom property values set on a repository (read-only). */
|
|
327
|
+
getValues: (repo) => rest.request(`${repoBase(repo)}/properties/values`),
|
|
296
328
|
/**
|
|
297
329
|
* The custom properties an organization defines, with their types and allowed values (read-only).
|
|
298
330
|
* The token needs read access to the organization's custom properties.
|
|
@@ -431,6 +463,7 @@ function repos(rest) {
|
|
|
431
463
|
// src/rulesets/rulesets.ts
|
|
432
464
|
function rulesets(rest) {
|
|
433
465
|
return {
|
|
466
|
+
getRuleset: (repo, id) => rest.request(`${repoBase(repo)}/rulesets/${id}`),
|
|
434
467
|
listRulesets: (repo) => rest.request(`${repoBase(repo)}/rulesets`),
|
|
435
468
|
createRuleset: (repo, payload) => rest.request(`${repoBase(repo)}/rulesets`, {
|
|
436
469
|
method: "POST",
|
|
@@ -468,6 +501,22 @@ function secrets(rest) {
|
|
|
468
501
|
// src/security/security.ts
|
|
469
502
|
function security(rest) {
|
|
470
503
|
return {
|
|
504
|
+
/** Whether vulnerability alerts are on: GitHub answers 204 when they are and 404 when they are not. */
|
|
505
|
+
vulnerabilityAlertsEnabled: async (repo) => {
|
|
506
|
+
try {
|
|
507
|
+
await rest.request(`${repoBase(repo)}/vulnerability-alerts`, { expectNoContent: true });
|
|
508
|
+
return true;
|
|
509
|
+
} catch (err) {
|
|
510
|
+
if (err instanceof ProviderApiError && err.status === 404) return false;
|
|
511
|
+
throw err;
|
|
512
|
+
}
|
|
513
|
+
},
|
|
514
|
+
/** Whether Dependabot security updates are on. */
|
|
515
|
+
automatedSecurityFixesEnabled: async (repo) => (await rest.request(`${repoBase(repo)}/automated-security-fixes`)).enabled,
|
|
516
|
+
/** Whether private vulnerability reporting is on. */
|
|
517
|
+
privateVulnerabilityReportingEnabled: async (repo) => (await rest.request(`${repoBase(repo)}/private-vulnerability-reporting`)).enabled,
|
|
518
|
+
/** The state of CodeQL default setup: `configured` or `not-configured`. */
|
|
519
|
+
codeScanningDefaultSetupState: async (repo) => (await rest.request(`${repoBase(repo)}/code-scanning/default-setup`)).state,
|
|
471
520
|
enableVulnerabilityAlerts: (repo) => rest.request(`${repoBase(repo)}/vulnerability-alerts`, {
|
|
472
521
|
method: "PUT",
|
|
473
522
|
expectNoContent: true
|
|
@@ -535,6 +584,8 @@ function teams(rest) {
|
|
|
535
584
|
if ((await read(51)).length > 0) throw new Error(`team ${org}/${teamSlug} has more than 5000 members; refusing to read them all`);
|
|
536
585
|
return all;
|
|
537
586
|
},
|
|
587
|
+
/** The teams that have access to a repository, with each team's permission there (read-only). */
|
|
588
|
+
listForRepo: (repo) => rest.request(`${repoBase(repo)}/teams`, { query: { per_page: String(PAGE$1) } }),
|
|
538
589
|
addRepo: (org, teamSlug, owner, repo, permission) => rest.request(`/orgs/${org}/teams/${teamSlug}/repos/${owner}/${repo}`, {
|
|
539
590
|
method: "PUT",
|
|
540
591
|
body: { permission }
|
|
@@ -549,8 +600,31 @@ function topics(rest) {
|
|
|
549
600
|
}) };
|
|
550
601
|
}
|
|
551
602
|
// src/user/user.ts
|
|
603
|
+
/**
|
|
604
|
+
* The expiry GitHub reports in the `github-authentication-token-expiration` header (`2026-11-19 03:46:04 UTC`) as
|
|
605
|
+
* ISO 8601, or `undefined` when the header is missing or is not a date.
|
|
606
|
+
*/
|
|
607
|
+
function parseTokenExpiration(header) {
|
|
608
|
+
if (!header) return void 0;
|
|
609
|
+
const time = Date.parse(header.replace(/ UTC$/, "Z").replace(" ", "T"));
|
|
610
|
+
return Number.isNaN(time) ? void 0 : new Date(time).toISOString();
|
|
611
|
+
}
|
|
552
612
|
function user(rest) {
|
|
553
|
-
return {
|
|
613
|
+
return {
|
|
614
|
+
getCurrentUser: () => rest.request("/user"),
|
|
615
|
+
/** The authenticated user plus when the token expires, read from the response header on the same call. */
|
|
616
|
+
async getCurrentUserWithExpiry() {
|
|
617
|
+
let header = null;
|
|
618
|
+
const me = await rest.request("/user", { onResponse: (headers) => {
|
|
619
|
+
header = headers.get("github-authentication-token-expiration");
|
|
620
|
+
} });
|
|
621
|
+
const expiresAt = parseTokenExpiration(header);
|
|
622
|
+
return expiresAt ? {
|
|
623
|
+
user: me,
|
|
624
|
+
expiresAt
|
|
625
|
+
} : { user: me };
|
|
626
|
+
}
|
|
627
|
+
};
|
|
554
628
|
}
|
|
555
629
|
// src/variables/variables.ts
|
|
556
630
|
/** GitHub's maximum page size for this listing is 30, not the usual 100. */
|
|
@@ -847,6 +921,7 @@ function parseGitHubWebhookHeaders(headers) {
|
|
|
847
921
|
};
|
|
848
922
|
}
|
|
849
923
|
// src/index.ts
|
|
924
|
+
/** Creates a GitHub client with a group of methods per API area (branches, pulls, issues, secrets and so on), backed by one REST client and one GraphQL client built from the same options. */
|
|
850
925
|
function createGitHubClient(opts) {
|
|
851
926
|
const rest = createGitHubRestClient(opts);
|
|
852
927
|
const graphql = createGitHubGraphQLApiClient(opts);
|
|
@@ -855,6 +930,8 @@ function createGitHubClient(opts) {
|
|
|
855
930
|
checks: checks(rest),
|
|
856
931
|
environments: environments(rest),
|
|
857
932
|
git: git(rest),
|
|
933
|
+
/** The GraphQL client, for the callers whose API (Projects v2) has no REST form. */
|
|
934
|
+
graphql,
|
|
858
935
|
issues: issues(rest),
|
|
859
936
|
labels: labels(rest),
|
|
860
937
|
pages: pages(rest),
|
|
@@ -871,4 +948,4 @@ function createGitHubClient(opts) {
|
|
|
871
948
|
workflows: workflows(rest)
|
|
872
949
|
};
|
|
873
950
|
}
|
|
874
|
-
export { MAX_CHECK_RUN_ANNOTATIONS, createAppJWT, createGitHubClient, createInstallationClient, getInstallationAccessToken, parseGitHubWebhookHeaders, verifyGitHubWebhookSignature };
|
|
951
|
+
export { MAX_CHECK_RUN_ANNOTATIONS, createAppJWT, createGitHubClient, createInstallationClient, getInstallationAccessToken, parseGitHubWebhookHeaders, parseTokenExpiration, verifyGitHubWebhookSignature };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/github-client",
|
|
3
|
-
"version": "1.58.0-alpha.
|
|
3
|
+
"version": "1.58.0-alpha.11",
|
|
4
4
|
"description": "A TypeScript client for the GitHub REST API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"github",
|
|
@@ -32,23 +32,23 @@
|
|
|
32
32
|
"dist"
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@theholocron/
|
|
36
|
-
"@theholocron/
|
|
35
|
+
"@theholocron/observability": "^0.7.0-alpha.1",
|
|
36
|
+
"@theholocron/http-client": "^1.58.0-alpha.11"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/node": "^26",
|
|
40
40
|
"@vitest/coverage-v8": "^5.0.5",
|
|
41
|
-
"@vitest/eslint-plugin": "^1.6.
|
|
42
|
-
"eslint": "^10.
|
|
43
|
-
"eslint-plugin-n": "^18.
|
|
44
|
-
"globals": "^17.
|
|
45
|
-
"tsdown": "^0.23.
|
|
41
|
+
"@vitest/eslint-plugin": "^1.6.28",
|
|
42
|
+
"eslint": "^10.14.0",
|
|
43
|
+
"eslint-plugin-n": "^18.5.0",
|
|
44
|
+
"globals": "^17.14.0",
|
|
45
|
+
"tsdown": "^0.23.4",
|
|
46
46
|
"typescript": "^5.9.3",
|
|
47
47
|
"vitest": "^5.0.5",
|
|
48
|
-
"@theholocron/tsconfig": "^8.9.0-alpha.
|
|
49
|
-
"@theholocron/
|
|
50
|
-
"@theholocron/
|
|
51
|
-
"@theholocron/
|
|
48
|
+
"@theholocron/tsconfig": "^8.9.0-alpha.8",
|
|
49
|
+
"@theholocron/vitest-config": "^8.9.0-alpha.8",
|
|
50
|
+
"@theholocron/eslint-config": "^8.9.0-alpha.8",
|
|
51
|
+
"@theholocron/tsdown-config": "^8.9.0-alpha.8"
|
|
52
52
|
},
|
|
53
53
|
"engines": {
|
|
54
54
|
"node": ">=22.0.0"
|
|
@@ -57,10 +57,10 @@
|
|
|
57
57
|
"access": "public"
|
|
58
58
|
},
|
|
59
59
|
"scripts": {
|
|
60
|
-
"
|
|
61
|
-
"
|
|
60
|
+
"build": "tsdown && node ../scripts/check-bundle-size.mjs",
|
|
61
|
+
"lint:code": "eslint .",
|
|
62
|
+
"test:unit": "vitest run --coverage",
|
|
62
63
|
"test:watch": "vitest",
|
|
63
|
-
"
|
|
64
|
-
"verification.unitTests": "vitest run"
|
|
64
|
+
"typecheck": "tsc --noEmit"
|
|
65
65
|
}
|
|
66
66
|
}
|