@theholocron/github-client 1.57.1-alpha.2 → 1.58.0-alpha.10
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/index.d.mts +336 -2
- package/dist/index.mjs +86 -6
- package/package.json +16 -16
package/dist/index.d.mts
CHANGED
|
@@ -1,16 +1,47 @@
|
|
|
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;
|
|
9
30
|
/** Reports transport failures and unexpected 5xx. Defaults to a no-op. */
|
|
10
31
|
errors?: ErrorSink;
|
|
11
32
|
}
|
|
33
|
+
/** One branch as `GET /branches` returns it: its name and the commit it points at. */
|
|
34
|
+
interface GitHubBranch {
|
|
35
|
+
name: string;
|
|
36
|
+
commit: {
|
|
37
|
+
sha: string;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** The lifecycle state of a check run. */
|
|
12
41
|
type CheckRunStatus = "queued" | "in_progress" | "completed";
|
|
42
|
+
/** The final result of a completed check run. */
|
|
13
43
|
type CheckRunConclusion = "success" | "failure" | "neutral" | "cancelled" | "timed_out" | "action_required" | "skipped";
|
|
44
|
+
/** The severity of a check run annotation. */
|
|
14
45
|
type CheckRunAnnotationLevel = "notice" | "warning" | "failure";
|
|
15
46
|
/**
|
|
16
47
|
* GitHub's cap on `output.annotations` per `createCheckRun()` /
|
|
@@ -19,15 +50,19 @@ type CheckRunAnnotationLevel = "notice" | "warning" | "failure";
|
|
|
19
50
|
* do for you; slice with it rather than hardcoding the number.
|
|
20
51
|
*/
|
|
21
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. */
|
|
22
54
|
interface CheckRunAnnotation {
|
|
23
55
|
/** File path relative to the repo root. */
|
|
24
56
|
path: string;
|
|
25
57
|
/** 1-indexed. */
|
|
26
58
|
start_line: number;
|
|
59
|
+
/** 1-indexed last line of the annotated range. */
|
|
27
60
|
end_line: number;
|
|
28
61
|
/** Only valid when `start_line === end_line`. */
|
|
29
62
|
start_column?: number;
|
|
63
|
+
/** Column of the end of the range; only valid when `start_line === end_line`. */
|
|
30
64
|
end_column?: number;
|
|
65
|
+
/** Severity of the annotation. */
|
|
31
66
|
annotation_level: CheckRunAnnotationLevel;
|
|
32
67
|
/** Max 64KB. */
|
|
33
68
|
message: string;
|
|
@@ -36,9 +71,13 @@ interface CheckRunAnnotation {
|
|
|
36
71
|
/** Max 64KB. */
|
|
37
72
|
raw_details?: string;
|
|
38
73
|
}
|
|
74
|
+
/** The title, summary and optional annotations shown on a check run. */
|
|
39
75
|
interface CheckRunOutput {
|
|
76
|
+
/** The output's title. */
|
|
40
77
|
title: string;
|
|
78
|
+
/** The output's summary, rendered as Markdown. */
|
|
41
79
|
summary: string;
|
|
80
|
+
/** Longer details text, rendered as Markdown. */
|
|
42
81
|
text?: string;
|
|
43
82
|
/**
|
|
44
83
|
* Inline PR annotations — up to {@link MAX_CHECK_RUN_ANNOTATIONS} per
|
|
@@ -47,7 +86,9 @@ interface CheckRunOutput {
|
|
|
47
86
|
*/
|
|
48
87
|
annotations?: CheckRunAnnotation[];
|
|
49
88
|
}
|
|
89
|
+
/** The body of a `createCheckRun()` request. */
|
|
50
90
|
interface CreateCheckRunInput {
|
|
91
|
+
/** The check run's name, as shown in the checks list. */
|
|
51
92
|
name: string;
|
|
52
93
|
/** The commit SHA the check run attaches to. */
|
|
53
94
|
head_sha: string;
|
|
@@ -55,30 +96,46 @@ interface CreateCheckRunInput {
|
|
|
55
96
|
status?: CheckRunStatus;
|
|
56
97
|
/** Required when `status` is `"completed"`. */
|
|
57
98
|
conclusion?: CheckRunConclusion;
|
|
99
|
+
/** The title, summary and annotations to show on the check run. */
|
|
58
100
|
output?: CheckRunOutput;
|
|
59
101
|
/** URL for the "Details" link on the check run. GitHub defaults to the check suite's own summary page when omitted. */
|
|
60
102
|
details_url?: string;
|
|
61
103
|
}
|
|
104
|
+
/** A check run as GitHub returns it, with only the fields this client reads. */
|
|
62
105
|
interface GitHubCheckRun {
|
|
106
|
+
/** The check run's numeric id. */
|
|
63
107
|
id: number;
|
|
108
|
+
/** The check run's name. */
|
|
64
109
|
name: string;
|
|
110
|
+
/** The commit SHA the check run is attached to. */
|
|
65
111
|
head_sha: string;
|
|
112
|
+
/** The check run's current lifecycle state. */
|
|
66
113
|
status: CheckRunStatus;
|
|
114
|
+
/** The check run's result, or `null` until it is completed. */
|
|
67
115
|
conclusion: CheckRunConclusion | null;
|
|
116
|
+
/** The URL of the check run's page on GitHub. */
|
|
68
117
|
html_url: string;
|
|
69
118
|
}
|
|
119
|
+
/** The body of an `updateCheckRun()` request; every field is optional. */
|
|
70
120
|
interface UpdateCheckRunInput {
|
|
121
|
+
/** The lifecycle state to move the check run to. */
|
|
71
122
|
status?: CheckRunStatus;
|
|
72
123
|
/** Required when `status` is `"completed"`. */
|
|
73
124
|
conclusion?: CheckRunConclusion;
|
|
125
|
+
/** The title, summary and annotations to set on the check run. */
|
|
74
126
|
output?: CheckRunOutput;
|
|
75
127
|
/** URL for the "Details" link on the check run. */
|
|
76
128
|
details_url?: string;
|
|
77
129
|
}
|
|
130
|
+
/** A deployment environment of a repository and its protection settings. */
|
|
78
131
|
interface GitHubEnvironment {
|
|
132
|
+
/** The environment's name. */
|
|
79
133
|
name: string;
|
|
134
|
+
/** Minutes to wait before a job that targets the environment may proceed. */
|
|
80
135
|
wait_timer?: number;
|
|
136
|
+
/** Whether the user who triggered a deployment may also approve it. */
|
|
81
137
|
prevent_self_review?: boolean;
|
|
138
|
+
/** The protection rules on the environment; each has a `type` and, for required reviewers, the reviewers. */
|
|
82
139
|
protection_rules?: Array<{
|
|
83
140
|
type: string;
|
|
84
141
|
reviewers?: Array<{
|
|
@@ -89,52 +146,87 @@ interface GitHubEnvironment {
|
|
|
89
146
|
}>;
|
|
90
147
|
}>;
|
|
91
148
|
}
|
|
149
|
+
/** A git reference (such as a branch) and the object it points at. */
|
|
92
150
|
interface GitRef {
|
|
151
|
+
/** The object the reference points at. */
|
|
93
152
|
object: {
|
|
153
|
+
/** The object's SHA. */
|
|
94
154
|
sha: string;
|
|
155
|
+
/** The object's type, e.g. `commit`. */
|
|
95
156
|
type: string;
|
|
157
|
+
/** The API URL of the object. */
|
|
96
158
|
url: string;
|
|
97
159
|
};
|
|
160
|
+
/** The full reference name, e.g. `refs/heads/main`. */
|
|
98
161
|
ref: string;
|
|
162
|
+
/** The API URL of the reference. */
|
|
99
163
|
url: string;
|
|
100
164
|
}
|
|
165
|
+
/** A git commit, with only the fields this client reads. */
|
|
101
166
|
interface GitCommit {
|
|
167
|
+
/** The commit's SHA. */
|
|
102
168
|
sha: string;
|
|
169
|
+
/** The tree the commit points at. */
|
|
103
170
|
tree: {
|
|
171
|
+
/** The tree's SHA. */
|
|
104
172
|
sha: string;
|
|
173
|
+
/** The API URL of the tree. */
|
|
105
174
|
url: string;
|
|
106
175
|
};
|
|
107
176
|
}
|
|
177
|
+
/** One entry of a git tree. */
|
|
108
178
|
interface GitTreeItem {
|
|
179
|
+
/** The entry's path within the tree. */
|
|
109
180
|
path: string;
|
|
181
|
+
/** The entry's object SHA. */
|
|
110
182
|
sha: string;
|
|
183
|
+
/** The kind of object the entry points at, e.g. `blob` or `tree`. */
|
|
111
184
|
type: string;
|
|
185
|
+
/** The entry's file mode, e.g. `100644`. */
|
|
112
186
|
mode?: string;
|
|
187
|
+
/** The blob's size in bytes; absent for trees. */
|
|
113
188
|
size?: number;
|
|
114
189
|
}
|
|
190
|
+
/** A git tree as GitHub returns it. */
|
|
115
191
|
interface GitTree {
|
|
192
|
+
/** The tree's SHA. */
|
|
116
193
|
sha: string;
|
|
194
|
+
/** The entries of the tree. */
|
|
117
195
|
tree: GitTreeItem[];
|
|
196
|
+
/** Whether GitHub cut the entry list short because the tree was too large. */
|
|
118
197
|
truncated: boolean;
|
|
119
198
|
}
|
|
199
|
+
/** A file's contents as the contents API returns them. */
|
|
120
200
|
interface GitContents {
|
|
201
|
+
/** The file content, encoded as named by `encoding`. */
|
|
121
202
|
content: string;
|
|
203
|
+
/** The encoding of `content`, normally `base64`. */
|
|
122
204
|
encoding: string;
|
|
205
|
+
/** The file's blob SHA. */
|
|
123
206
|
sha: string;
|
|
207
|
+
/** The file's name. */
|
|
124
208
|
name: string;
|
|
209
|
+
/** The file's path in the repository. */
|
|
125
210
|
path: string;
|
|
126
211
|
}
|
|
127
212
|
/** What `git.putContents` returns: the file's new blob sha (the `sha` to pass next time) and the commit it made. */
|
|
128
213
|
interface PutContentsResult {
|
|
214
|
+
/** The file written: its path and its new blob SHA. */
|
|
129
215
|
content: {
|
|
216
|
+
/** The file's new blob SHA. */
|
|
130
217
|
sha: string;
|
|
218
|
+
/** The file's path. */
|
|
131
219
|
path: string;
|
|
132
220
|
};
|
|
221
|
+
/** The commit that was made. */
|
|
133
222
|
commit: {
|
|
223
|
+
/** The new commit's SHA. */
|
|
134
224
|
sha: string;
|
|
135
225
|
};
|
|
136
226
|
}
|
|
227
|
+
/** The body of a `putContents()` request. */
|
|
137
228
|
interface PutContentsInput {
|
|
229
|
+
/** The commit message. */
|
|
138
230
|
message: string;
|
|
139
231
|
/** The new file text (UTF-8); the client encodes it. */
|
|
140
232
|
content: string;
|
|
@@ -147,102 +239,179 @@ interface PutContentsInput {
|
|
|
147
239
|
/** Defaults to the repo's default branch. */
|
|
148
240
|
branch?: string;
|
|
149
241
|
}
|
|
242
|
+
/** A git blob created in the repository. */
|
|
150
243
|
interface GitBlob {
|
|
244
|
+
/** The blob's SHA. */
|
|
151
245
|
sha: string;
|
|
246
|
+
/** The API URL of the blob. */
|
|
152
247
|
url: string;
|
|
153
248
|
}
|
|
249
|
+
/** A pull request as returned when one is created, with only the fields this client reads. */
|
|
154
250
|
interface GitPull {
|
|
251
|
+
/** The pull request's number. */
|
|
155
252
|
number: number;
|
|
253
|
+
/** The URL of the pull request's page on GitHub. */
|
|
156
254
|
html_url: string;
|
|
255
|
+
/** The pull request's title. */
|
|
157
256
|
title: string;
|
|
158
257
|
}
|
|
258
|
+
/** The body of a `createPull()` request. */
|
|
159
259
|
interface CreatePullInput {
|
|
260
|
+
/** The pull request's title. */
|
|
160
261
|
title: string;
|
|
262
|
+
/** The branch the changes come from. */
|
|
161
263
|
head: string;
|
|
264
|
+
/** The branch the changes are to be merged into. */
|
|
162
265
|
base: string;
|
|
266
|
+
/** The pull request's description. */
|
|
163
267
|
body?: string;
|
|
164
268
|
}
|
|
269
|
+
/** An issue as GitHub returns it, with only the fields this client reads. */
|
|
165
270
|
interface GitHubIssue {
|
|
271
|
+
/** The issue's numeric id. */
|
|
166
272
|
id: number;
|
|
273
|
+
/** The issue's number within its repository. */
|
|
167
274
|
number: number;
|
|
275
|
+
/** The issue's title. */
|
|
168
276
|
title: string;
|
|
277
|
+
/** The issue's description; `null` or absent when empty. */
|
|
169
278
|
body?: string | null;
|
|
279
|
+
/** Whether the issue is open or closed. */
|
|
170
280
|
state: "open" | "closed";
|
|
281
|
+
/** The labels on the issue. */
|
|
171
282
|
labels: Array<{
|
|
172
283
|
name: string;
|
|
173
284
|
}>;
|
|
285
|
+
/** The user the issue is assigned to, or `null` when unassigned. */
|
|
174
286
|
assignee: {
|
|
175
287
|
login: string;
|
|
176
288
|
name?: string | null;
|
|
177
289
|
email?: string | null;
|
|
178
290
|
} | null;
|
|
291
|
+
/** When the issue was last updated, as an ISO 8601 timestamp. */
|
|
179
292
|
updated_at: string;
|
|
293
|
+
/** The URL of the issue's page on GitHub. */
|
|
180
294
|
html_url: string;
|
|
295
|
+
/** Set when the item is a pull request; GitHub's issues API returns pull requests too. */
|
|
181
296
|
pull_request?: unknown;
|
|
182
297
|
}
|
|
298
|
+
/** A milestone, with only the fields this client reads. */
|
|
183
299
|
interface GitHubMilestone {
|
|
300
|
+
/** The milestone's number. */
|
|
184
301
|
number: number;
|
|
302
|
+
/** The milestone's title. */
|
|
185
303
|
title: string;
|
|
186
304
|
}
|
|
305
|
+
/** Filters for listing issues. */
|
|
187
306
|
interface IssueSearchParams {
|
|
307
|
+
/** Which issues to list by state; GitHub defaults to `open`. */
|
|
188
308
|
state?: "open" | "closed" | "all";
|
|
309
|
+
/** The field to sort by, passed through to GitHub. */
|
|
189
310
|
sort?: string;
|
|
311
|
+
/** The sort direction, passed through to GitHub. */
|
|
190
312
|
direction?: string;
|
|
313
|
+
/** The number of issues per page. */
|
|
191
314
|
per_page?: number;
|
|
315
|
+
/** Which issues to list by relation to the user, passed through to GitHub. */
|
|
192
316
|
filter?: string;
|
|
317
|
+
/** Limit to issues assigned to this login. */
|
|
193
318
|
assignee?: string;
|
|
194
319
|
}
|
|
320
|
+
/** A repository label. */
|
|
195
321
|
interface GitHubLabel {
|
|
322
|
+
/** The label's name. */
|
|
196
323
|
name: string;
|
|
324
|
+
/** The label's color as a hex code without the leading `#`. */
|
|
197
325
|
color: string;
|
|
326
|
+
/** The label's description, or `null` when it has none. */
|
|
198
327
|
description: string | null;
|
|
199
328
|
}
|
|
329
|
+
/** How a Pages site is built: by a workflow or from a branch. */
|
|
200
330
|
type PagesBuildType = "workflow" | "legacy";
|
|
331
|
+
/** The status of a Pages build. */
|
|
201
332
|
type PagesBuildStatus = "built" | "building" | "errored" | "unknown";
|
|
333
|
+
/** A repository's GitHub Pages site configuration. */
|
|
202
334
|
interface GitHubPages {
|
|
335
|
+
/** The latest build's status, or `null` when there is none. */
|
|
203
336
|
status: PagesBuildStatus | null;
|
|
337
|
+
/** How the site is built, or `null` when unknown. */
|
|
204
338
|
build_type: PagesBuildType | null;
|
|
339
|
+
/** The branch and folder the site is published from, for a legacy build. */
|
|
205
340
|
source?: {
|
|
341
|
+
/** The branch the site is published from. */
|
|
206
342
|
branch: string;
|
|
343
|
+
/** The folder on the branch, `/` or `/docs`. */
|
|
207
344
|
path: string;
|
|
208
345
|
};
|
|
346
|
+
/** Whether HTTPS is enforced for the site. */
|
|
209
347
|
https_enforced: boolean;
|
|
348
|
+
/** The site's custom domain, or `null` when it has none. */
|
|
210
349
|
custom_domain: string | null;
|
|
211
350
|
}
|
|
351
|
+
/** The body of a Pages creation request. */
|
|
212
352
|
interface CreatePagesPayload {
|
|
353
|
+
/** How the site is built. */
|
|
213
354
|
build_type: PagesBuildType;
|
|
214
355
|
/** Required when build_type is "legacy". */
|
|
215
356
|
source?: {
|
|
357
|
+
/** The branch the site is published from. */
|
|
216
358
|
branch: string;
|
|
359
|
+
/** The folder on the branch, `/` or `/docs`. */
|
|
217
360
|
path: string;
|
|
218
361
|
};
|
|
219
362
|
}
|
|
363
|
+
/** The body of a Pages update request; every field is optional. */
|
|
220
364
|
interface UpdatePagesPayload {
|
|
365
|
+
/** How the site is built. */
|
|
221
366
|
build_type?: PagesBuildType;
|
|
367
|
+
/** The branch and folder to publish from. */
|
|
222
368
|
source?: {
|
|
369
|
+
/** The branch the site is published from. */
|
|
223
370
|
branch: string;
|
|
371
|
+
/** The folder on the branch, `/` or `/docs`. */
|
|
224
372
|
path: string;
|
|
225
373
|
};
|
|
374
|
+
/** The custom domain, or `null` to remove it. */
|
|
226
375
|
cname?: string | null;
|
|
376
|
+
/** Whether to enforce HTTPS. */
|
|
227
377
|
https_enforced?: boolean;
|
|
228
378
|
}
|
|
229
379
|
/** One custom property of an organization, as its schema defines it. */
|
|
230
380
|
interface OrgProperty {
|
|
381
|
+
/** The property's name. */
|
|
231
382
|
property_name: string;
|
|
232
383
|
/** `string`, `single_select`, `multi_select`, `true_false` or `url`. */
|
|
233
384
|
value_type: string;
|
|
385
|
+
/** Whether a repository must set the property. */
|
|
234
386
|
required?: boolean;
|
|
235
387
|
/** The values a `single_select` or `multi_select` property accepts; `null` for any other type. */
|
|
236
388
|
allowed_values?: string[] | null;
|
|
237
389
|
}
|
|
390
|
+
/** One custom property value set on a repository. */
|
|
391
|
+
interface RepoPropertyValue {
|
|
392
|
+
/** The property's name. */
|
|
393
|
+
property_name: string;
|
|
394
|
+
/** A string, a string array for `multi_select`, or `null` when unset. */
|
|
395
|
+
value: string | string[] | null;
|
|
396
|
+
}
|
|
397
|
+
/** A pull request as GitHub returns it, with only the fields this client reads. */
|
|
238
398
|
interface GitHubPullRequest {
|
|
399
|
+
/** The pull request's number. */
|
|
239
400
|
number: number;
|
|
401
|
+
/** The pull request's title. */
|
|
240
402
|
title: string;
|
|
403
|
+
/** Whether the pull request is open or closed. */
|
|
241
404
|
state: "open" | "closed";
|
|
405
|
+
/** When the pull request was merged as an ISO 8601 timestamp, or `null` if it was not merged. */
|
|
242
406
|
merged_at: string | null;
|
|
407
|
+
/** The URL of the pull request's page on GitHub. */
|
|
243
408
|
html_url: string;
|
|
409
|
+
/** The head branch: its name and the commit it pointed at when the PR was read. */
|
|
244
410
|
head: {
|
|
411
|
+
/** The branch name, e.g. `fix/my-change`. */
|
|
245
412
|
ref: string;
|
|
413
|
+
/** The head commit. */
|
|
414
|
+
sha: string;
|
|
246
415
|
};
|
|
247
416
|
}
|
|
248
417
|
/** A commit's name/email as git itself recorded it — `commit.author`/`commit.committer`, distinct from the GitHub-account `author` below (a commit can carry any email, linked to a GitHub account or not). */
|
|
@@ -252,10 +421,15 @@ interface GitHubCommitIdentity {
|
|
|
252
421
|
}
|
|
253
422
|
/** One commit as returned by `GET /pulls/{pull_number}/commits` — only the fields any known consumer needs. */
|
|
254
423
|
interface GitHubPullRequestCommit {
|
|
424
|
+
/** The commit's SHA. */
|
|
255
425
|
sha: string;
|
|
426
|
+
/** The commit's message and git identities. */
|
|
256
427
|
commit: {
|
|
428
|
+
/** The commit message. */
|
|
257
429
|
message: string;
|
|
430
|
+
/** The commit's author, as git recorded it. */
|
|
258
431
|
author: GitHubCommitIdentity;
|
|
432
|
+
/** The commit's committer, as git recorded it. */
|
|
259
433
|
committer: GitHubCommitIdentity;
|
|
260
434
|
};
|
|
261
435
|
/** 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). */
|
|
@@ -270,7 +444,9 @@ interface GitHubPullRequestCommit {
|
|
|
270
444
|
}
|
|
271
445
|
/** One file as returned by `GET /pulls/{pull_number}/files` — only the fields any known consumer needs. */
|
|
272
446
|
interface GitHubPullRequestFile {
|
|
447
|
+
/** The file's path in the repository. */
|
|
273
448
|
filename: string;
|
|
449
|
+
/** How the pull request changes the file. */
|
|
274
450
|
status: "added" | "removed" | "modified" | "renamed" | "copied" | "changed" | "unchanged";
|
|
275
451
|
/** Set only when `status === "renamed"`. */
|
|
276
452
|
previous_filename?: string;
|
|
@@ -290,8 +466,10 @@ interface CreateReviewComment {
|
|
|
290
466
|
line: number;
|
|
291
467
|
/** Almost always `"RIGHT"` (the PR's own new content) — `"LEFT"` targets the base/pre-PR version instead. */
|
|
292
468
|
side: "LEFT" | "RIGHT";
|
|
469
|
+
/** The comment text. */
|
|
293
470
|
body: string;
|
|
294
471
|
}
|
|
472
|
+
/** The body of a review creation request. */
|
|
295
473
|
interface CreateReviewInput {
|
|
296
474
|
/** The PR's head SHA the review attaches to. */
|
|
297
475
|
commit_id: string;
|
|
@@ -304,11 +482,14 @@ interface CreateReviewInput {
|
|
|
304
482
|
* required-approval counts and dismissal.
|
|
305
483
|
*/
|
|
306
484
|
event: "COMMENT" | "REQUEST_CHANGES" | "APPROVE";
|
|
485
|
+
/** Inline comments to post with the review. */
|
|
307
486
|
comments?: CreateReviewComment[];
|
|
308
487
|
}
|
|
309
488
|
/** `POST /pulls/{pull_number}/reviews`'s response — only the fields any known consumer needs. */
|
|
310
489
|
interface GitHubPullRequestReview {
|
|
490
|
+
/** The review's numeric id. */
|
|
311
491
|
id: number;
|
|
492
|
+
/** The URL of the review on GitHub. */
|
|
312
493
|
html_url: string;
|
|
313
494
|
}
|
|
314
495
|
/**
|
|
@@ -319,7 +500,9 @@ interface GitHubPullRequestReview {
|
|
|
319
500
|
* never compare it against a REST-sourced ID.
|
|
320
501
|
*/
|
|
321
502
|
interface ReviewThread {
|
|
503
|
+
/** The thread's GraphQL node id. */
|
|
322
504
|
id: string;
|
|
505
|
+
/** Whether the thread is resolved. */
|
|
323
506
|
isResolved: boolean;
|
|
324
507
|
/** 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. */
|
|
325
508
|
authorLogin: string | undefined;
|
|
@@ -337,19 +520,70 @@ interface ReviewThread {
|
|
|
337
520
|
*/
|
|
338
521
|
body: string | undefined;
|
|
339
522
|
}
|
|
523
|
+
/** A repository as GitHub returns it, with only the fields this client reads. */
|
|
340
524
|
interface GitHubRepo {
|
|
525
|
+
/** The name of the repository's default branch. */
|
|
341
526
|
default_branch: string;
|
|
527
|
+
/** The repository's `owner/name`. */
|
|
342
528
|
full_name: string;
|
|
343
|
-
|
|
529
|
+
/** The repository description. */
|
|
530
|
+
description?: string | null;
|
|
531
|
+
/** The repository homepage URL. */
|
|
532
|
+
homepage?: string | null;
|
|
533
|
+
/** The topics set on the repository. */
|
|
534
|
+
topics?: string[];
|
|
535
|
+
/** Whether squash merging is allowed. */
|
|
536
|
+
allow_squash_merge?: boolean;
|
|
537
|
+
/** Whether merge commits are allowed. */
|
|
538
|
+
allow_merge_commit?: boolean;
|
|
539
|
+
/** Whether rebase merging is allowed. */
|
|
540
|
+
allow_rebase_merge?: boolean;
|
|
541
|
+
/** Whether auto-merge is allowed. */
|
|
542
|
+
allow_auto_merge?: boolean;
|
|
543
|
+
/** Whether a pull request branch can be updated from its base. */
|
|
544
|
+
allow_update_branch?: boolean;
|
|
545
|
+
/** Whether a merged pull request's branch is deleted. */
|
|
546
|
+
delete_branch_on_merge?: boolean;
|
|
547
|
+
/** Whether issues are enabled. */
|
|
548
|
+
has_issues?: boolean;
|
|
549
|
+
/** Whether discussions are enabled. */
|
|
550
|
+
has_discussions?: boolean;
|
|
551
|
+
/** Whether projects are enabled. */
|
|
552
|
+
has_projects?: boolean;
|
|
553
|
+
/** Whether the wiki is enabled. */
|
|
554
|
+
has_wiki?: boolean;
|
|
555
|
+
/** Each feature's `status` (`enabled` / `disabled`). Only an admin token sees it; absent for the rest. */
|
|
556
|
+
security_and_analysis?: Record<string, {
|
|
557
|
+
status: string;
|
|
558
|
+
} | undefined> | null;
|
|
559
|
+
}
|
|
560
|
+
/** A file's contents as the contents API returns them. */
|
|
344
561
|
interface GitHubContents {
|
|
562
|
+
/** The file content, encoded as named by `encoding`. */
|
|
345
563
|
content: string;
|
|
564
|
+
/** The encoding of `content`, normally `base64`. */
|
|
346
565
|
encoding: string;
|
|
347
566
|
}
|
|
567
|
+
/** A repository ruleset in summary form. */
|
|
348
568
|
interface GitHubRuleset {
|
|
569
|
+
/** The ruleset's numeric id. */
|
|
349
570
|
id: number;
|
|
571
|
+
/** The ruleset's name. */
|
|
350
572
|
name: string;
|
|
573
|
+
/** How the ruleset is enforced, e.g. `active`, `evaluate` or `disabled`. */
|
|
351
574
|
enforcement: string;
|
|
352
575
|
}
|
|
576
|
+
/** One ruleset in full, as `GET /repos/{repo}/rulesets/{id}` returns it. */
|
|
577
|
+
interface GitHubRulesetDetail extends GitHubRuleset {
|
|
578
|
+
/** What the ruleset applies to, e.g. `branch`. */
|
|
579
|
+
target?: string;
|
|
580
|
+
/** Each rule has a `type`; some carry `parameters`. */
|
|
581
|
+
rules?: Array<{
|
|
582
|
+
type: string;
|
|
583
|
+
parameters?: Record<string, unknown>;
|
|
584
|
+
}>;
|
|
585
|
+
}
|
|
586
|
+
/** Where a secret lives: the repository, one of its environments, or an organization. */
|
|
353
587
|
type SecretScope = {
|
|
354
588
|
kind: "repo";
|
|
355
589
|
} | {
|
|
@@ -359,21 +593,39 @@ type SecretScope = {
|
|
|
359
593
|
kind: "organization";
|
|
360
594
|
org: string;
|
|
361
595
|
};
|
|
596
|
+
/** A public key used to encrypt a secret before it is sent. */
|
|
362
597
|
interface GitHubPublicKey {
|
|
598
|
+
/** The key's id, sent back with the encrypted secret. */
|
|
363
599
|
key_id: string;
|
|
600
|
+
/** The Base64-encoded public key. */
|
|
364
601
|
key: string;
|
|
365
602
|
}
|
|
603
|
+
/** The workflow run that a code scanning setup started. */
|
|
366
604
|
interface CodeScanningSetupResult {
|
|
605
|
+
/** The id of the workflow run. */
|
|
367
606
|
run_id: number;
|
|
607
|
+
/** The URL of the workflow run. */
|
|
368
608
|
run_url: string;
|
|
369
609
|
}
|
|
610
|
+
/** A permission level a team can hold on a repository. */
|
|
370
611
|
type TeamPermission = "pull" | "triage" | "push" | "maintain" | "admin";
|
|
612
|
+
/** A team with access to a repository, and the permission it has there. */
|
|
613
|
+
interface RepoTeam {
|
|
614
|
+
/** The team's slug. */
|
|
615
|
+
slug: string;
|
|
616
|
+
/** The team's permission on the repository. */
|
|
617
|
+
permission: TeamPermission;
|
|
618
|
+
}
|
|
371
619
|
/** A member of a team, as GitHub lists it. `id` is the numeric user id, which survives a rename; `login` does not. */
|
|
372
620
|
interface TeamMember {
|
|
621
|
+
/** The member's numeric user id. */
|
|
373
622
|
id: number;
|
|
623
|
+
/** The member's login. */
|
|
374
624
|
login: string;
|
|
625
|
+
/** The kind of account, e.g. `User`. */
|
|
375
626
|
type?: string;
|
|
376
627
|
}
|
|
628
|
+
/** Where a variable lives: the repository, one of its environments, or an organization. */
|
|
377
629
|
type VariableScope = {
|
|
378
630
|
kind: "repo";
|
|
379
631
|
} | {
|
|
@@ -390,40 +642,76 @@ type VariableScope = {
|
|
|
390
642
|
type VariableVisibility = "all" | "private" | "selected";
|
|
391
643
|
/** A GitHub Actions variable. Unlike a secret its value is readable, so a reconcile can tell whether it differs. */
|
|
392
644
|
interface GitHubVariable {
|
|
645
|
+
/** The variable's name. */
|
|
393
646
|
name: string;
|
|
647
|
+
/** The variable's value. */
|
|
394
648
|
value: string;
|
|
395
649
|
/** Present on organization variables only. */
|
|
396
650
|
visibility?: VariableVisibility;
|
|
397
651
|
}
|
|
652
|
+
/** The authenticated user, with only the fields this client reads. */
|
|
398
653
|
interface GitHubUser {
|
|
654
|
+
/** The user's login. */
|
|
399
655
|
login: string;
|
|
656
|
+
/** The user's display name, or `null` when not set. */
|
|
400
657
|
name: string | null;
|
|
658
|
+
/** The user's public email, or `null` when not set. */
|
|
401
659
|
email: string | null;
|
|
402
660
|
}
|
|
661
|
+
/** The authenticated user and, for a token that expires, when. */
|
|
662
|
+
interface GitHubUserWithExpiry {
|
|
663
|
+
/** The authenticated user. */
|
|
664
|
+
user: GitHubUser;
|
|
665
|
+
/** When the token stops working, ISO 8601 in UTC. Absent for a token that never expires. */
|
|
666
|
+
expiresAt?: string;
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* The expiry GitHub reports in the `github-authentication-token-expiration` header (`2026-11-19 03:46:04 UTC`) as
|
|
670
|
+
* ISO 8601, or `undefined` when the header is missing or is not a date.
|
|
671
|
+
*/
|
|
672
|
+
export declare function parseTokenExpiration(header: string | null): string | undefined;
|
|
673
|
+
/** A workflow run as GitHub returns it, with only the fields this client reads. */
|
|
403
674
|
interface GitHubWorkflowRun {
|
|
675
|
+
/** The run's numeric id. */
|
|
404
676
|
id: number;
|
|
677
|
+
/** The workflow's name, or `null` when unnamed. */
|
|
405
678
|
name: string | null;
|
|
679
|
+
/** The run's display title. */
|
|
406
680
|
display_title: string;
|
|
681
|
+
/** The branch the run was triggered on. */
|
|
407
682
|
head_branch: string;
|
|
683
|
+
/** The commit SHA the run was triggered on. */
|
|
408
684
|
head_sha: string;
|
|
685
|
+
/** The run's status, e.g. `queued`, `in_progress` or `completed`. */
|
|
409
686
|
status: string;
|
|
687
|
+
/** The run's result once completed, or `null` before. */
|
|
410
688
|
conclusion: string | null;
|
|
689
|
+
/** The URL of the run's page on GitHub. */
|
|
411
690
|
html_url: string;
|
|
691
|
+
/** When the run was created, as an ISO 8601 timestamp. */
|
|
412
692
|
created_at: string;
|
|
693
|
+
/** When the run was last updated, as an ISO 8601 timestamp. */
|
|
413
694
|
updated_at: string;
|
|
414
695
|
}
|
|
696
|
+
/** Filters for listing workflow runs. */
|
|
415
697
|
interface WorkflowRunFilter {
|
|
698
|
+
/** Only runs on this branch. */
|
|
416
699
|
branch?: string;
|
|
700
|
+
/** The maximum number of runs to return. */
|
|
417
701
|
limit?: number;
|
|
702
|
+
/** Only runs with this status. */
|
|
418
703
|
status?: string;
|
|
419
704
|
}
|
|
705
|
+
/** The credentials identifying a GitHub App: its id and private key. */
|
|
420
706
|
interface GitHubAppCredentials {
|
|
421
707
|
/** The App's numeric id (not the client id). */
|
|
422
708
|
appId: string;
|
|
423
709
|
/** PEM-encoded RSA private key — PKCS#1 (GitHub's default download format) or PKCS#8, either works. */
|
|
424
710
|
privateKey: string;
|
|
425
711
|
}
|
|
712
|
+
/** A short-lived installation access token and when it expires. */
|
|
426
713
|
interface InstallationAccessToken {
|
|
714
|
+
/** The installation access token, used as a bearer token for the REST API. */
|
|
427
715
|
token: string;
|
|
428
716
|
/** ISO 8601 — installation tokens are short-lived, about an hour. */
|
|
429
717
|
expiresAt: string;
|
|
@@ -473,6 +761,7 @@ export declare function verifyGitHubWebhookSignature(input: {
|
|
|
473
761
|
signature: string | undefined;
|
|
474
762
|
secret: string;
|
|
475
763
|
}): boolean;
|
|
764
|
+
/** The three GitHub webhook headers a consumer needs. */
|
|
476
765
|
interface GitHubWebhookHeaders {
|
|
477
766
|
/** `X-GitHub-Event` — the event category, e.g. `"push"`, `"pull_request"`. */
|
|
478
767
|
event: string | undefined;
|
|
@@ -483,34 +772,67 @@ interface GitHubWebhookHeaders {
|
|
|
483
772
|
}
|
|
484
773
|
/** Extracts GitHub's three webhook headers, case-insensitively (Node's raw headers may arrive lower-cased, or as an array when a header repeats). */
|
|
485
774
|
export declare function parseGitHubWebhookHeaders(headers: Record<string, string | string[] | undefined>): GitHubWebhookHeaders;
|
|
775
|
+
/** The payload of an `installation` webhook delivery. */
|
|
486
776
|
interface GitHubInstallationWebhookPayload {
|
|
777
|
+
/** What happened to the installation, e.g. `created` or `deleted`. */
|
|
487
778
|
action: string;
|
|
779
|
+
/** The installation the delivery is about. */
|
|
488
780
|
installation: {
|
|
781
|
+
/** The installation id. */
|
|
489
782
|
id: number;
|
|
490
783
|
};
|
|
491
784
|
}
|
|
785
|
+
/** The payload of a `push` webhook delivery. */
|
|
492
786
|
interface GitHubPushWebhookPayload {
|
|
787
|
+
/** The full name of the pushed ref, e.g. `refs/heads/main`. */
|
|
493
788
|
ref: string;
|
|
789
|
+
/** The installation the delivery is about, when sent. */
|
|
494
790
|
installation?: {
|
|
791
|
+
/** The installation id. */
|
|
495
792
|
id: number;
|
|
496
793
|
};
|
|
794
|
+
/** The repository that was pushed to. */
|
|
497
795
|
repository: {
|
|
796
|
+
/** The repository's owner/name. */
|
|
498
797
|
full_name: string;
|
|
798
|
+
/** The name of the default branch. */
|
|
499
799
|
default_branch: string;
|
|
500
800
|
};
|
|
501
801
|
}
|
|
802
|
+
/** The payload of a `pull_request` webhook delivery. */
|
|
502
803
|
interface GitHubPullRequestWebhookPayload {
|
|
804
|
+
/** What happened to the pull request, e.g. `opened` or `closed`. */
|
|
503
805
|
action: string;
|
|
806
|
+
/** For an `edited` action, the fields that changed (each holds the previous value); absent for other actions. */
|
|
807
|
+
changes?: {
|
|
808
|
+
/** Present when the title was edited. */
|
|
809
|
+
title?: {
|
|
810
|
+
/** The title before the edit. */
|
|
811
|
+
from: string;
|
|
812
|
+
};
|
|
813
|
+
/** Present when the description was edited. */
|
|
814
|
+
body?: {
|
|
815
|
+
/** The description before the edit; `null` when it was empty. */
|
|
816
|
+
from: string | null;
|
|
817
|
+
};
|
|
818
|
+
};
|
|
819
|
+
/** The installation the delivery is about, when sent. */
|
|
504
820
|
installation?: {
|
|
821
|
+
/** The installation id. */
|
|
505
822
|
id: number;
|
|
506
823
|
};
|
|
824
|
+
/** The repository the pull request belongs to. */
|
|
507
825
|
repository: {
|
|
826
|
+
/** The repository's owner/name. */
|
|
508
827
|
full_name: string;
|
|
509
828
|
};
|
|
510
829
|
}
|
|
830
|
+
/** 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. */
|
|
511
831
|
export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
512
832
|
branches: {
|
|
513
833
|
protectBranch: (repo: string, branch: string, payload: Record<string, unknown>) => Promise<void>;
|
|
834
|
+
listBranches: (repo: string) => Promise<GitHubBranch[]>;
|
|
835
|
+
removeBranch: (repo: string, branch: string) => Promise<void>;
|
|
514
836
|
};
|
|
515
837
|
checks: {
|
|
516
838
|
createCheckRun: (repo: string, input: CreateCheckRunInput) => Promise<GitHubCheckRun>;
|
|
@@ -539,6 +861,8 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
539
861
|
updateRef: (repo: string, ref: string, sha: string, force?: boolean) => Promise<GitRef>;
|
|
540
862
|
createPull: (repo: string, input: CreatePullInput) => Promise<GitPull>;
|
|
541
863
|
};
|
|
864
|
+
/** The GraphQL client, for the callers whose API (Projects v2) has no REST form. */
|
|
865
|
+
graphql: GraphQLClient;
|
|
542
866
|
issues: {
|
|
543
867
|
listIssues: (repo: string, params?: IssueSearchParams) => Promise<GitHubIssue[]>;
|
|
544
868
|
getIssue: (repo: string, number: number) => Promise<GitHubIssue>;
|
|
@@ -570,11 +894,13 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
570
894
|
updatePages: (repo: string, payload: UpdatePagesPayload) => Promise<void>;
|
|
571
895
|
};
|
|
572
896
|
properties: {
|
|
897
|
+
getValues: (repo: string) => Promise<RepoPropertyValue[]>;
|
|
573
898
|
orgSchema: (org: string) => Promise<OrgProperty[]>;
|
|
574
899
|
setProperties: (repo: string, values: Record<string, string | string[]>) => Promise<void>;
|
|
575
900
|
};
|
|
576
901
|
pulls: {
|
|
577
902
|
getPullRequest: (repo: string, number: number) => Promise<GitHubPullRequest>;
|
|
903
|
+
listPullRequests: (repo: string, state: "open" | "closed") => Promise<GitHubPullRequest[]>;
|
|
578
904
|
listCommits: (repo: string, number: number) => Promise<GitHubPullRequestCommit[]>;
|
|
579
905
|
listFiles: (repo: string, number: number) => Promise<GitHubPullRequestFile[]>;
|
|
580
906
|
createReview: (repo: string, number: number, input: CreateReviewInput) => Promise<GitHubPullRequestReview>;
|
|
@@ -587,6 +913,7 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
587
913
|
getContents: (repo: string, path: string) => Promise<GitHubContents>;
|
|
588
914
|
};
|
|
589
915
|
rulesets: {
|
|
916
|
+
getRuleset: (repo: string, id: number) => Promise<GitHubRulesetDetail>;
|
|
590
917
|
listRulesets: (repo: string) => Promise<GitHubRuleset[]>;
|
|
591
918
|
createRuleset: (repo: string, payload: Record<string, unknown>) => Promise<GitHubRuleset>;
|
|
592
919
|
updateRuleset: (repo: string, id: number, payload: Record<string, unknown>) => Promise<GitHubRuleset>;
|
|
@@ -598,6 +925,10 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
598
925
|
deleteSecret: (repo: string, scope: SecretScope, name: string) => Promise<void>;
|
|
599
926
|
};
|
|
600
927
|
security: {
|
|
928
|
+
vulnerabilityAlertsEnabled: (repo: string) => Promise<boolean>;
|
|
929
|
+
automatedSecurityFixesEnabled: (repo: string) => Promise<boolean>;
|
|
930
|
+
privateVulnerabilityReportingEnabled: (repo: string) => Promise<boolean>;
|
|
931
|
+
codeScanningDefaultSetupState: (repo: string) => Promise<string>;
|
|
601
932
|
enableVulnerabilityAlerts: (repo: string) => Promise<void>;
|
|
602
933
|
enableAutomatedSecurityFixes: (repo: string) => Promise<void>;
|
|
603
934
|
enableSecretScanning: (repo: string) => Promise<void>;
|
|
@@ -608,6 +939,7 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
608
939
|
};
|
|
609
940
|
teams: {
|
|
610
941
|
members: (org: string, teamSlug: string) => Promise<TeamMember[]>;
|
|
942
|
+
listForRepo: (repo: string) => Promise<RepoTeam[]>;
|
|
611
943
|
addRepo: (org: string, teamSlug: string, owner: string, repo: string, permission: TeamPermission) => Promise<void>;
|
|
612
944
|
};
|
|
613
945
|
topics: {
|
|
@@ -622,6 +954,7 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
622
954
|
};
|
|
623
955
|
user: {
|
|
624
956
|
getCurrentUser: () => Promise<GitHubUser>;
|
|
957
|
+
getCurrentUserWithExpiry(): Promise<GitHubUserWithExpiry>;
|
|
625
958
|
};
|
|
626
959
|
workflows: {
|
|
627
960
|
listRuns: (repo: string, filter?: WorkflowRunFilter) => Promise<GitHubWorkflowRun[]>;
|
|
@@ -629,5 +962,6 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
629
962
|
createWorkflowDispatch: (repo: string, workflowFile: string, ref: string, inputs?: Record<string, string>) => Promise<void>;
|
|
630
963
|
};
|
|
631
964
|
};
|
|
965
|
+
/** The client returned by `createGitHubClient()`: one group of methods per GitHub API area. */
|
|
632
966
|
export type GitHubClient = ReturnType<typeof createGitHubClient>;
|
|
633
|
-
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 };
|
|
967
|
+
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, GitHubRulesetDetail, GitHubUser, GitHubUserWithExpiry, GitHubVariable, GitHubWebhookHeaders, GitHubWorkflowRun, GitPull, GitRef, GitTree, GitTreeItem, GraphQLClient, InstallationAccessToken, IssueSearchParams, OrgProperty, PagesBuildStatus, PagesBuildType, PutContentsInput, PutContentsResult, RepoPropertyValue, RepoTeam, ReviewThread, SecretScope, TeamMember, TeamPermission, UpdateCheckRunInput, UpdatePagesPayload, VariableScope, VariableVisibility, WorkflowRunFilter };
|
package/dist/index.mjs
CHANGED
|
@@ -76,11 +76,28 @@ function toBase64(text) {
|
|
|
76
76
|
return btoa(binary);
|
|
77
77
|
}
|
|
78
78
|
// src/branches/branches.ts
|
|
79
|
+
/** Page size and the most pages {@link branches}`.listBranches` reads: 100 a page (GitHub's maximum) over 100 pages. */
|
|
80
|
+
const BRANCH_PAGE_SIZE = 100;
|
|
81
|
+
const BRANCH_MAX_PAGES = 100;
|
|
79
82
|
function branches(rest) {
|
|
80
|
-
return {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
return {
|
|
84
|
+
protectBranch: (repo, branch, payload) => rest.request(`${repoBase(repo)}/branches/${encodeURIComponent(branch)}/protection`, {
|
|
85
|
+
method: "PUT",
|
|
86
|
+
body: payload
|
|
87
|
+
}),
|
|
88
|
+
/** Every branch, read a page at a time until a page comes back short. */
|
|
89
|
+
listBranches: async (repo) => {
|
|
90
|
+
const all = [];
|
|
91
|
+
for (let page = 1; page <= BRANCH_MAX_PAGES; page++) {
|
|
92
|
+
const batch = await rest.request(`${repoBase(repo)}/branches?per_page=${BRANCH_PAGE_SIZE}&page=${page}`);
|
|
93
|
+
all.push(...batch);
|
|
94
|
+
if (batch.length < BRANCH_PAGE_SIZE) break;
|
|
95
|
+
}
|
|
96
|
+
return all;
|
|
97
|
+
},
|
|
98
|
+
/** Delete one branch's ref. The name keeps its `/`s; each segment is encoded. */
|
|
99
|
+
removeBranch: (repo, branch) => rest.request(`${repoBase(repo)}/git/refs/heads/${branch.split("/").map(encodeURIComponent).join("/")}`, { method: "DELETE" })
|
|
100
|
+
};
|
|
84
101
|
}
|
|
85
102
|
// src/checks/checks.ts
|
|
86
103
|
/**
|
|
@@ -276,6 +293,8 @@ function pages(rest) {
|
|
|
276
293
|
// src/properties/properties.ts
|
|
277
294
|
function properties(rest) {
|
|
278
295
|
return {
|
|
296
|
+
/** The custom property values set on a repository (read-only). */
|
|
297
|
+
getValues: (repo) => rest.request(`${repoBase(repo)}/properties/values`),
|
|
279
298
|
/**
|
|
280
299
|
* The custom properties an organization defines, with their types and allowed values (read-only).
|
|
281
300
|
* The token needs read access to the organization's custom properties.
|
|
@@ -331,10 +350,26 @@ const RESOLVE_REVIEW_THREAD_MUTATION = `
|
|
|
331
350
|
}
|
|
332
351
|
}
|
|
333
352
|
`;
|
|
353
|
+
/** Page size and the most pages {@link pulls}`.listPullRequests` reads: 100 a page (GitHub's maximum) over 100 pages, so 10,000 pull requests. */
|
|
354
|
+
const PULL_REQUEST_PAGE_SIZE = 100;
|
|
355
|
+
const PULL_REQUEST_MAX_PAGES = 100;
|
|
334
356
|
function pulls(rest, graphql) {
|
|
335
357
|
return {
|
|
336
358
|
getPullRequest: (repo, number) => rest.request(`${repoBase(repo)}/pulls/${number}`),
|
|
337
359
|
/**
|
|
360
|
+
* Every pull request in one state, newest first, read a page at a time until a page comes back short.
|
|
361
|
+
* `closed` includes the merged ones; tell them apart by `merged_at`.
|
|
362
|
+
*/
|
|
363
|
+
listPullRequests: async (repo, state) => {
|
|
364
|
+
const all = [];
|
|
365
|
+
for (let page = 1; page <= PULL_REQUEST_MAX_PAGES; page++) {
|
|
366
|
+
const batch = await rest.request(`${repoBase(repo)}/pulls?state=${state}&sort=created&direction=desc&per_page=${PULL_REQUEST_PAGE_SIZE}&page=${page}`);
|
|
367
|
+
all.push(...batch);
|
|
368
|
+
if (batch.length < PULL_REQUEST_PAGE_SIZE) break;
|
|
369
|
+
}
|
|
370
|
+
return all;
|
|
371
|
+
},
|
|
372
|
+
/**
|
|
338
373
|
* A PR's own commits, in commit order. `per_page=100` — GitHub's max —
|
|
339
374
|
* covers every real PR in this org; a PR genuinely exceeding 100
|
|
340
375
|
* commits (GitHub caps this endpoint at 250 regardless of pagination)
|
|
@@ -398,6 +433,7 @@ function repos(rest) {
|
|
|
398
433
|
// src/rulesets/rulesets.ts
|
|
399
434
|
function rulesets(rest) {
|
|
400
435
|
return {
|
|
436
|
+
getRuleset: (repo, id) => rest.request(`${repoBase(repo)}/rulesets/${id}`),
|
|
401
437
|
listRulesets: (repo) => rest.request(`${repoBase(repo)}/rulesets`),
|
|
402
438
|
createRuleset: (repo, payload) => rest.request(`${repoBase(repo)}/rulesets`, {
|
|
403
439
|
method: "POST",
|
|
@@ -435,6 +471,22 @@ function secrets(rest) {
|
|
|
435
471
|
// src/security/security.ts
|
|
436
472
|
function security(rest) {
|
|
437
473
|
return {
|
|
474
|
+
/** Whether vulnerability alerts are on: GitHub answers 204 when they are and 404 when they are not. */
|
|
475
|
+
vulnerabilityAlertsEnabled: async (repo) => {
|
|
476
|
+
try {
|
|
477
|
+
await rest.request(`${repoBase(repo)}/vulnerability-alerts`, { expectNoContent: true });
|
|
478
|
+
return true;
|
|
479
|
+
} catch (err) {
|
|
480
|
+
if (err instanceof ProviderApiError && err.status === 404) return false;
|
|
481
|
+
throw err;
|
|
482
|
+
}
|
|
483
|
+
},
|
|
484
|
+
/** Whether Dependabot security updates are on. */
|
|
485
|
+
automatedSecurityFixesEnabled: async (repo) => (await rest.request(`${repoBase(repo)}/automated-security-fixes`)).enabled,
|
|
486
|
+
/** Whether private vulnerability reporting is on. */
|
|
487
|
+
privateVulnerabilityReportingEnabled: async (repo) => (await rest.request(`${repoBase(repo)}/private-vulnerability-reporting`)).enabled,
|
|
488
|
+
/** The state of CodeQL default setup: `configured` or `not-configured`. */
|
|
489
|
+
codeScanningDefaultSetupState: async (repo) => (await rest.request(`${repoBase(repo)}/code-scanning/default-setup`)).state,
|
|
438
490
|
enableVulnerabilityAlerts: (repo) => rest.request(`${repoBase(repo)}/vulnerability-alerts`, {
|
|
439
491
|
method: "PUT",
|
|
440
492
|
expectNoContent: true
|
|
@@ -502,6 +554,8 @@ function teams(rest) {
|
|
|
502
554
|
if ((await read(51)).length > 0) throw new Error(`team ${org}/${teamSlug} has more than 5000 members; refusing to read them all`);
|
|
503
555
|
return all;
|
|
504
556
|
},
|
|
557
|
+
/** The teams that have access to a repository, with each team's permission there (read-only). */
|
|
558
|
+
listForRepo: (repo) => rest.request(`${repoBase(repo)}/teams`, { query: { per_page: String(PAGE$1) } }),
|
|
505
559
|
addRepo: (org, teamSlug, owner, repo, permission) => rest.request(`/orgs/${org}/teams/${teamSlug}/repos/${owner}/${repo}`, {
|
|
506
560
|
method: "PUT",
|
|
507
561
|
body: { permission }
|
|
@@ -516,8 +570,31 @@ function topics(rest) {
|
|
|
516
570
|
}) };
|
|
517
571
|
}
|
|
518
572
|
// src/user/user.ts
|
|
573
|
+
/**
|
|
574
|
+
* The expiry GitHub reports in the `github-authentication-token-expiration` header (`2026-11-19 03:46:04 UTC`) as
|
|
575
|
+
* ISO 8601, or `undefined` when the header is missing or is not a date.
|
|
576
|
+
*/
|
|
577
|
+
function parseTokenExpiration(header) {
|
|
578
|
+
if (!header) return void 0;
|
|
579
|
+
const time = Date.parse(header.replace(/ UTC$/, "Z").replace(" ", "T"));
|
|
580
|
+
return Number.isNaN(time) ? void 0 : new Date(time).toISOString();
|
|
581
|
+
}
|
|
519
582
|
function user(rest) {
|
|
520
|
-
return {
|
|
583
|
+
return {
|
|
584
|
+
getCurrentUser: () => rest.request("/user"),
|
|
585
|
+
/** The authenticated user plus when the token expires, read from the response header on the same call. */
|
|
586
|
+
async getCurrentUserWithExpiry() {
|
|
587
|
+
let header = null;
|
|
588
|
+
const me = await rest.request("/user", { onResponse: (headers) => {
|
|
589
|
+
header = headers.get("github-authentication-token-expiration");
|
|
590
|
+
} });
|
|
591
|
+
const expiresAt = parseTokenExpiration(header);
|
|
592
|
+
return expiresAt ? {
|
|
593
|
+
user: me,
|
|
594
|
+
expiresAt
|
|
595
|
+
} : { user: me };
|
|
596
|
+
}
|
|
597
|
+
};
|
|
521
598
|
}
|
|
522
599
|
// src/variables/variables.ts
|
|
523
600
|
/** GitHub's maximum page size for this listing is 30, not the usual 100. */
|
|
@@ -814,6 +891,7 @@ function parseGitHubWebhookHeaders(headers) {
|
|
|
814
891
|
};
|
|
815
892
|
}
|
|
816
893
|
// src/index.ts
|
|
894
|
+
/** 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. */
|
|
817
895
|
function createGitHubClient(opts) {
|
|
818
896
|
const rest = createGitHubRestClient(opts);
|
|
819
897
|
const graphql = createGitHubGraphQLApiClient(opts);
|
|
@@ -822,6 +900,8 @@ function createGitHubClient(opts) {
|
|
|
822
900
|
checks: checks(rest),
|
|
823
901
|
environments: environments(rest),
|
|
824
902
|
git: git(rest),
|
|
903
|
+
/** The GraphQL client, for the callers whose API (Projects v2) has no REST form. */
|
|
904
|
+
graphql,
|
|
825
905
|
issues: issues(rest),
|
|
826
906
|
labels: labels(rest),
|
|
827
907
|
pages: pages(rest),
|
|
@@ -838,4 +918,4 @@ function createGitHubClient(opts) {
|
|
|
838
918
|
workflows: workflows(rest)
|
|
839
919
|
};
|
|
840
920
|
}
|
|
841
|
-
export { MAX_CHECK_RUN_ANNOTATIONS, createAppJWT, createGitHubClient, createInstallationClient, getInstallationAccessToken, parseGitHubWebhookHeaders, verifyGitHubWebhookSignature };
|
|
921
|
+
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.
|
|
3
|
+
"version": "1.58.0-alpha.10",
|
|
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/http-client": "^1.
|
|
36
|
-
"@theholocron/observability": "^0.
|
|
35
|
+
"@theholocron/http-client": "^1.58.0-alpha.10",
|
|
36
|
+
"@theholocron/observability": "^0.7.0-alpha.1"
|
|
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/vitest-config": "^8.9.0-alpha.
|
|
48
|
+
"@theholocron/tsconfig": "^8.9.0-alpha.8",
|
|
49
|
+
"@theholocron/tsdown-config": "^8.9.0-alpha.8",
|
|
50
|
+
"@theholocron/eslint-config": "^8.9.0-alpha.8",
|
|
51
|
+
"@theholocron/vitest-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
|
}
|