@theholocron/github-client 1.57.1-alpha.2 → 1.58.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +28 -1
- package/dist/index.mjs +62 -6
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -9,6 +9,13 @@ interface GitHubClientOptions {
|
|
|
9
9
|
/** Reports transport failures and unexpected 5xx. Defaults to a no-op. */
|
|
10
10
|
errors?: ErrorSink;
|
|
11
11
|
}
|
|
12
|
+
/** One branch as `GET /branches` returns it: its name and the commit it points at. */
|
|
13
|
+
interface GitHubBranch {
|
|
14
|
+
name: string;
|
|
15
|
+
commit: {
|
|
16
|
+
sha: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
12
19
|
type CheckRunStatus = "queued" | "in_progress" | "completed";
|
|
13
20
|
type CheckRunConclusion = "success" | "failure" | "neutral" | "cancelled" | "timed_out" | "action_required" | "skipped";
|
|
14
21
|
type CheckRunAnnotationLevel = "notice" | "warning" | "failure";
|
|
@@ -241,8 +248,12 @@ interface GitHubPullRequest {
|
|
|
241
248
|
state: "open" | "closed";
|
|
242
249
|
merged_at: string | null;
|
|
243
250
|
html_url: string;
|
|
251
|
+
/** The head branch: its name and the commit it pointed at when the PR was read. */
|
|
244
252
|
head: {
|
|
253
|
+
/** The branch name, e.g. `fix/my-change`. */
|
|
245
254
|
ref: string;
|
|
255
|
+
/** The head commit. */
|
|
256
|
+
sha: string;
|
|
246
257
|
};
|
|
247
258
|
}
|
|
248
259
|
/** 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). */
|
|
@@ -400,6 +411,18 @@ interface GitHubUser {
|
|
|
400
411
|
name: string | null;
|
|
401
412
|
email: string | null;
|
|
402
413
|
}
|
|
414
|
+
/** The authenticated user and, for a token that expires, when. */
|
|
415
|
+
interface GitHubUserWithExpiry {
|
|
416
|
+
/** The authenticated user. */
|
|
417
|
+
user: GitHubUser;
|
|
418
|
+
/** When the token stops working, ISO 8601 in UTC. Absent for a token that never expires. */
|
|
419
|
+
expiresAt?: string;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* The expiry GitHub reports in the `github-authentication-token-expiration` header (`2026-11-19 03:46:04 UTC`) as
|
|
423
|
+
* ISO 8601, or `undefined` when the header is missing or is not a date.
|
|
424
|
+
*/
|
|
425
|
+
export declare function parseTokenExpiration(header: string | null): string | undefined;
|
|
403
426
|
interface GitHubWorkflowRun {
|
|
404
427
|
id: number;
|
|
405
428
|
name: string | null;
|
|
@@ -511,6 +534,8 @@ interface GitHubPullRequestWebhookPayload {
|
|
|
511
534
|
export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
512
535
|
branches: {
|
|
513
536
|
protectBranch: (repo: string, branch: string, payload: Record<string, unknown>) => Promise<void>;
|
|
537
|
+
listBranches: (repo: string) => Promise<GitHubBranch[]>;
|
|
538
|
+
removeBranch: (repo: string, branch: string) => Promise<void>;
|
|
514
539
|
};
|
|
515
540
|
checks: {
|
|
516
541
|
createCheckRun: (repo: string, input: CreateCheckRunInput) => Promise<GitHubCheckRun>;
|
|
@@ -575,6 +600,7 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
575
600
|
};
|
|
576
601
|
pulls: {
|
|
577
602
|
getPullRequest: (repo: string, number: number) => Promise<GitHubPullRequest>;
|
|
603
|
+
listPullRequests: (repo: string, state: "open" | "closed") => Promise<GitHubPullRequest[]>;
|
|
578
604
|
listCommits: (repo: string, number: number) => Promise<GitHubPullRequestCommit[]>;
|
|
579
605
|
listFiles: (repo: string, number: number) => Promise<GitHubPullRequestFile[]>;
|
|
580
606
|
createReview: (repo: string, number: number, input: CreateReviewInput) => Promise<GitHubPullRequestReview>;
|
|
@@ -622,6 +648,7 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
622
648
|
};
|
|
623
649
|
user: {
|
|
624
650
|
getCurrentUser: () => Promise<GitHubUser>;
|
|
651
|
+
getCurrentUserWithExpiry(): Promise<GitHubUserWithExpiry>;
|
|
625
652
|
};
|
|
626
653
|
workflows: {
|
|
627
654
|
listRuns: (repo: string, filter?: WorkflowRunFilter) => Promise<GitHubWorkflowRun[]>;
|
|
@@ -630,4 +657,4 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
|
|
|
630
657
|
};
|
|
631
658
|
};
|
|
632
659
|
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 };
|
|
660
|
+
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, GitHubUserWithExpiry, GitHubVariable, GitHubWebhookHeaders, GitHubWorkflowRun, GitPull, GitRef, GitTree, GitTreeItem, InstallationAccessToken, IssueSearchParams, OrgProperty, PagesBuildStatus, PagesBuildType, PutContentsInput, PutContentsResult, 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
|
/**
|
|
@@ -331,10 +348,26 @@ const RESOLVE_REVIEW_THREAD_MUTATION = `
|
|
|
331
348
|
}
|
|
332
349
|
}
|
|
333
350
|
`;
|
|
351
|
+
/** Page size and the most pages {@link pulls}`.listPullRequests` reads: 100 a page (GitHub's maximum) over 100 pages, so 10,000 pull requests. */
|
|
352
|
+
const PULL_REQUEST_PAGE_SIZE = 100;
|
|
353
|
+
const PULL_REQUEST_MAX_PAGES = 100;
|
|
334
354
|
function pulls(rest, graphql) {
|
|
335
355
|
return {
|
|
336
356
|
getPullRequest: (repo, number) => rest.request(`${repoBase(repo)}/pulls/${number}`),
|
|
337
357
|
/**
|
|
358
|
+
* Every pull request in one state, newest first, read a page at a time until a page comes back short.
|
|
359
|
+
* `closed` includes the merged ones; tell them apart by `merged_at`.
|
|
360
|
+
*/
|
|
361
|
+
listPullRequests: async (repo, state) => {
|
|
362
|
+
const all = [];
|
|
363
|
+
for (let page = 1; page <= PULL_REQUEST_MAX_PAGES; page++) {
|
|
364
|
+
const batch = await rest.request(`${repoBase(repo)}/pulls?state=${state}&sort=created&direction=desc&per_page=${PULL_REQUEST_PAGE_SIZE}&page=${page}`);
|
|
365
|
+
all.push(...batch);
|
|
366
|
+
if (batch.length < PULL_REQUEST_PAGE_SIZE) break;
|
|
367
|
+
}
|
|
368
|
+
return all;
|
|
369
|
+
},
|
|
370
|
+
/**
|
|
338
371
|
* A PR's own commits, in commit order. `per_page=100` — GitHub's max —
|
|
339
372
|
* covers every real PR in this org; a PR genuinely exceeding 100
|
|
340
373
|
* commits (GitHub caps this endpoint at 250 regardless of pagination)
|
|
@@ -516,8 +549,31 @@ function topics(rest) {
|
|
|
516
549
|
}) };
|
|
517
550
|
}
|
|
518
551
|
// src/user/user.ts
|
|
552
|
+
/**
|
|
553
|
+
* The expiry GitHub reports in the `github-authentication-token-expiration` header (`2026-11-19 03:46:04 UTC`) as
|
|
554
|
+
* ISO 8601, or `undefined` when the header is missing or is not a date.
|
|
555
|
+
*/
|
|
556
|
+
function parseTokenExpiration(header) {
|
|
557
|
+
if (!header) return void 0;
|
|
558
|
+
const time = Date.parse(header.replace(/ UTC$/, "Z").replace(" ", "T"));
|
|
559
|
+
return Number.isNaN(time) ? void 0 : new Date(time).toISOString();
|
|
560
|
+
}
|
|
519
561
|
function user(rest) {
|
|
520
|
-
return {
|
|
562
|
+
return {
|
|
563
|
+
getCurrentUser: () => rest.request("/user"),
|
|
564
|
+
/** The authenticated user plus when the token expires, read from the response header on the same call. */
|
|
565
|
+
async getCurrentUserWithExpiry() {
|
|
566
|
+
let header = null;
|
|
567
|
+
const me = await rest.request("/user", { onResponse: (headers) => {
|
|
568
|
+
header = headers.get("github-authentication-token-expiration");
|
|
569
|
+
} });
|
|
570
|
+
const expiresAt = parseTokenExpiration(header);
|
|
571
|
+
return expiresAt ? {
|
|
572
|
+
user: me,
|
|
573
|
+
expiresAt
|
|
574
|
+
} : { user: me };
|
|
575
|
+
}
|
|
576
|
+
};
|
|
521
577
|
}
|
|
522
578
|
// src/variables/variables.ts
|
|
523
579
|
/** GitHub's maximum page size for this listing is 30, not the usual 100. */
|
|
@@ -838,4 +894,4 @@ function createGitHubClient(opts) {
|
|
|
838
894
|
workflows: workflows(rest)
|
|
839
895
|
};
|
|
840
896
|
}
|
|
841
|
-
export { MAX_CHECK_RUN_ANNOTATIONS, createAppJWT, createGitHubClient, createInstallationClient, getInstallationAccessToken, parseGitHubWebhookHeaders, verifyGitHubWebhookSignature };
|
|
897
|
+
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.2",
|
|
4
4
|
"description": "A TypeScript client for the GitHub REST API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"github",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"dist"
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@theholocron/http-client": "^1.
|
|
35
|
+
"@theholocron/http-client": "^1.58.0-alpha.2",
|
|
36
36
|
"@theholocron/observability": "^0.6.1-alpha.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"tsdown": "^0.23.3",
|
|
46
46
|
"typescript": "^5.9.3",
|
|
47
47
|
"vitest": "^5.0.5",
|
|
48
|
-
"@theholocron/tsconfig": "^8.9.0-alpha.3",
|
|
49
48
|
"@theholocron/eslint-config": "^8.9.0-alpha.3",
|
|
49
|
+
"@theholocron/tsconfig": "^8.9.0-alpha.3",
|
|
50
50
|
"@theholocron/tsdown-config": "^8.9.0-alpha.3",
|
|
51
51
|
"@theholocron/vitest-config": "^8.9.0-alpha.3"
|
|
52
52
|
},
|