gh-api-client 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -4
- package/dist/index.d.mts +66 -3
- package/dist/index.d.ts +66 -3
- package/dist/index.js +50 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +50 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,10 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](LICENSE)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
[GitHub REST API](https://docs.github.com/en/rest).
|
|
8
|
-
|
|
5
|
+
TypeScript client for the [GitHub REST API](https://docs.github.com/en/rest).
|
|
9
6
|
Works in **Node.js** and the **browser** (isomorphic). Fully typed, zero runtime dependencies.
|
|
10
7
|
|
|
11
8
|
---
|
package/dist/index.d.mts
CHANGED
|
@@ -84,6 +84,45 @@ interface GitHubOrganization {
|
|
|
84
84
|
/** Total number of members */
|
|
85
85
|
members_count?: number;
|
|
86
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Request body for creating a repository in an organization.
|
|
89
|
+
*
|
|
90
|
+
* @see {@link https://docs.github.com/en/rest/repos/repos#create-an-organization-repository}
|
|
91
|
+
*/
|
|
92
|
+
interface CreateOrgRepoData {
|
|
93
|
+
/** Repository name (required) */
|
|
94
|
+
name: string;
|
|
95
|
+
/** Repository description */
|
|
96
|
+
description?: string;
|
|
97
|
+
/** Homepage URL */
|
|
98
|
+
homepage?: string;
|
|
99
|
+
/** Whether the repository is private. Defaults to `false`. */
|
|
100
|
+
private?: boolean;
|
|
101
|
+
/** Repository visibility. Overrides `private` when provided. */
|
|
102
|
+
visibility?: 'public' | 'private' | 'internal';
|
|
103
|
+
/** Whether to enable issues. Defaults to `true`. */
|
|
104
|
+
has_issues?: boolean;
|
|
105
|
+
/** Whether to enable projects. Defaults to `true`. */
|
|
106
|
+
has_projects?: boolean;
|
|
107
|
+
/** Whether to enable the wiki. Defaults to `true`. */
|
|
108
|
+
has_wiki?: boolean;
|
|
109
|
+
/** Whether to enable discussions. Defaults to `false`. */
|
|
110
|
+
has_discussions?: boolean;
|
|
111
|
+
/** Whether to initialize the repository with a README. Defaults to `false`. */
|
|
112
|
+
auto_init?: boolean;
|
|
113
|
+
/** `.gitignore` template to apply (e.g., `'Node'`) */
|
|
114
|
+
gitignore_template?: string;
|
|
115
|
+
/** License template to apply (e.g., `'mit'`) */
|
|
116
|
+
license_template?: string;
|
|
117
|
+
/** Whether to allow squash-merging pull requests. Defaults to `true`. */
|
|
118
|
+
allow_squash_merge?: boolean;
|
|
119
|
+
/** Whether to allow merge commits. Defaults to `true`. */
|
|
120
|
+
allow_merge_commit?: boolean;
|
|
121
|
+
/** Whether to allow rebase-merging pull requests. Defaults to `true`. */
|
|
122
|
+
allow_rebase_merge?: boolean;
|
|
123
|
+
/** Whether to automatically delete head branches after pull requests are merged. Defaults to `false`. */
|
|
124
|
+
delete_branch_on_merge?: boolean;
|
|
125
|
+
}
|
|
87
126
|
/**
|
|
88
127
|
* Query parameters for listing organization members.
|
|
89
128
|
*
|
|
@@ -1301,6 +1340,8 @@ type RequestFn = <T>(path: string, params?: Record<string, string | number | boo
|
|
|
1301
1340
|
type RequestListFn = <T>(path: string, params?: Record<string, string | number | boolean>) => Promise<GitHubPagedResponse<T>>;
|
|
1302
1341
|
/** @internal */
|
|
1303
1342
|
type RequestTextFn = (path: string, params?: Record<string, string | number | boolean>) => Promise<string>;
|
|
1343
|
+
/** @internal */
|
|
1344
|
+
type RequestBodyFn = <T>(path: string, body: unknown) => Promise<T>;
|
|
1304
1345
|
/**
|
|
1305
1346
|
* Represents a GitHub organization resource with chainable async methods.
|
|
1306
1347
|
*
|
|
@@ -1326,9 +1367,10 @@ declare class OrganizationResource implements PromiseLike<GitHubOrganization> {
|
|
|
1326
1367
|
private readonly request;
|
|
1327
1368
|
private readonly requestList;
|
|
1328
1369
|
private readonly requestText;
|
|
1370
|
+
private readonly requestBody;
|
|
1329
1371
|
private readonly org;
|
|
1330
1372
|
/** @internal */
|
|
1331
|
-
constructor(request: RequestFn, requestList: RequestListFn, requestText: RequestTextFn, org: string);
|
|
1373
|
+
constructor(request: RequestFn, requestList: RequestListFn, requestText: RequestTextFn, requestBody: RequestBodyFn, org: string);
|
|
1332
1374
|
/**
|
|
1333
1375
|
* Allows the resource to be awaited directly, resolving with the organization info.
|
|
1334
1376
|
* Delegates to {@link OrganizationResource.get}.
|
|
@@ -1377,6 +1419,25 @@ declare class OrganizationResource implements PromiseLike<GitHubOrganization> {
|
|
|
1377
1419
|
* @returns A paged response of users
|
|
1378
1420
|
*/
|
|
1379
1421
|
members(params?: OrgMembersParams): Promise<GitHubPagedResponse<GitHubUser>>;
|
|
1422
|
+
/**
|
|
1423
|
+
* Creates a new repository in this organization.
|
|
1424
|
+
*
|
|
1425
|
+
* `POST /orgs/{org}/repos`
|
|
1426
|
+
*
|
|
1427
|
+
* @param data - Repository creation options. `name` is required.
|
|
1428
|
+
* @returns The newly created repository
|
|
1429
|
+
*
|
|
1430
|
+
* @example
|
|
1431
|
+
* ```typescript
|
|
1432
|
+
* const repo = await gh.org('my-org').createRepo({
|
|
1433
|
+
* name: 'my-new-repo',
|
|
1434
|
+
* description: 'My new repository',
|
|
1435
|
+
* private: true,
|
|
1436
|
+
* auto_init: true,
|
|
1437
|
+
* });
|
|
1438
|
+
* ```
|
|
1439
|
+
*/
|
|
1440
|
+
createRepo(data: CreateOrgRepoData): Promise<GitHubRepository>;
|
|
1380
1441
|
}
|
|
1381
1442
|
|
|
1382
1443
|
/**
|
|
@@ -1472,7 +1533,7 @@ interface RequestEvent {
|
|
|
1472
1533
|
/** Full URL that was requested */
|
|
1473
1534
|
url: string;
|
|
1474
1535
|
/** HTTP method used */
|
|
1475
|
-
method: 'GET';
|
|
1536
|
+
method: 'GET' | 'POST';
|
|
1476
1537
|
/** Timestamp when the request started */
|
|
1477
1538
|
startedAt: Date;
|
|
1478
1539
|
/** Timestamp when the request finished (success or error) */
|
|
@@ -1559,6 +1620,8 @@ declare class GitHubClient {
|
|
|
1559
1620
|
private makeRequestFn;
|
|
1560
1621
|
private makeRequestListFn;
|
|
1561
1622
|
private makeRequestTextFn;
|
|
1623
|
+
private requestPost;
|
|
1624
|
+
private makeRequestBodyFn;
|
|
1562
1625
|
/**
|
|
1563
1626
|
* Fetches the authenticated user's profile.
|
|
1564
1627
|
*
|
|
@@ -1723,4 +1786,4 @@ declare class Security {
|
|
|
1723
1786
|
getRawHeaders(): Record<string, string>;
|
|
1724
1787
|
}
|
|
1725
1788
|
|
|
1726
|
-
export { type BranchesParams, type CheckRunsParams, CommitResource, type CommitStatusesParams, type CommitsParams, type ContentParams, type ForksParams, GitHubApiError, type GitHubBranch, type GitHubCheckRun, GitHubClient, type GitHubClientEvents, type GitHubClientOptions, type GitHubCombinedStatus, type GitHubCommit, type GitHubCommitFile, type GitHubCommitStatus, type GitHubContent, type GitHubLabel, type GitHubMilestone, type GitHubOrganization, type GitHubPagedResponse, type GitHubPullRequest, type GitHubPullRequestFile, type GitHubRef, type GitHubRelease, type GitHubReleaseAsset, type GitHubRepository, type GitHubReview, type GitHubReviewComment, type GitHubTag, type GitHubUser, type GitHubWebhook, type OrgMembersParams, OrganizationResource, type PaginationParams, type PullRequestFilesParams, PullRequestResource, type PullRequestsParams, type ReleasesParams, type ReposParams, RepositoryResource, type RequestEvent, type ReviewCommentsParams, type ReviewsParams, type SearchReposParams, type SearchUsersParams, Security, type TagsParams, UserResource, type UsersParams, type WebhooksParams };
|
|
1789
|
+
export { type BranchesParams, type CheckRunsParams, CommitResource, type CommitStatusesParams, type CommitsParams, type ContentParams, type CreateOrgRepoData, type ForksParams, GitHubApiError, type GitHubBranch, type GitHubCheckRun, GitHubClient, type GitHubClientEvents, type GitHubClientOptions, type GitHubCombinedStatus, type GitHubCommit, type GitHubCommitFile, type GitHubCommitStatus, type GitHubContent, type GitHubLabel, type GitHubMilestone, type GitHubOrganization, type GitHubPagedResponse, type GitHubPullRequest, type GitHubPullRequestFile, type GitHubRef, type GitHubRelease, type GitHubReleaseAsset, type GitHubRepository, type GitHubReview, type GitHubReviewComment, type GitHubTag, type GitHubUser, type GitHubWebhook, type OrgMembersParams, OrganizationResource, type PaginationParams, type PullRequestFilesParams, PullRequestResource, type PullRequestsParams, type ReleasesParams, type ReposParams, RepositoryResource, type RequestEvent, type ReviewCommentsParams, type ReviewsParams, type SearchReposParams, type SearchUsersParams, Security, type TagsParams, UserResource, type UsersParams, type WebhooksParams };
|
package/dist/index.d.ts
CHANGED
|
@@ -84,6 +84,45 @@ interface GitHubOrganization {
|
|
|
84
84
|
/** Total number of members */
|
|
85
85
|
members_count?: number;
|
|
86
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Request body for creating a repository in an organization.
|
|
89
|
+
*
|
|
90
|
+
* @see {@link https://docs.github.com/en/rest/repos/repos#create-an-organization-repository}
|
|
91
|
+
*/
|
|
92
|
+
interface CreateOrgRepoData {
|
|
93
|
+
/** Repository name (required) */
|
|
94
|
+
name: string;
|
|
95
|
+
/** Repository description */
|
|
96
|
+
description?: string;
|
|
97
|
+
/** Homepage URL */
|
|
98
|
+
homepage?: string;
|
|
99
|
+
/** Whether the repository is private. Defaults to `false`. */
|
|
100
|
+
private?: boolean;
|
|
101
|
+
/** Repository visibility. Overrides `private` when provided. */
|
|
102
|
+
visibility?: 'public' | 'private' | 'internal';
|
|
103
|
+
/** Whether to enable issues. Defaults to `true`. */
|
|
104
|
+
has_issues?: boolean;
|
|
105
|
+
/** Whether to enable projects. Defaults to `true`. */
|
|
106
|
+
has_projects?: boolean;
|
|
107
|
+
/** Whether to enable the wiki. Defaults to `true`. */
|
|
108
|
+
has_wiki?: boolean;
|
|
109
|
+
/** Whether to enable discussions. Defaults to `false`. */
|
|
110
|
+
has_discussions?: boolean;
|
|
111
|
+
/** Whether to initialize the repository with a README. Defaults to `false`. */
|
|
112
|
+
auto_init?: boolean;
|
|
113
|
+
/** `.gitignore` template to apply (e.g., `'Node'`) */
|
|
114
|
+
gitignore_template?: string;
|
|
115
|
+
/** License template to apply (e.g., `'mit'`) */
|
|
116
|
+
license_template?: string;
|
|
117
|
+
/** Whether to allow squash-merging pull requests. Defaults to `true`. */
|
|
118
|
+
allow_squash_merge?: boolean;
|
|
119
|
+
/** Whether to allow merge commits. Defaults to `true`. */
|
|
120
|
+
allow_merge_commit?: boolean;
|
|
121
|
+
/** Whether to allow rebase-merging pull requests. Defaults to `true`. */
|
|
122
|
+
allow_rebase_merge?: boolean;
|
|
123
|
+
/** Whether to automatically delete head branches after pull requests are merged. Defaults to `false`. */
|
|
124
|
+
delete_branch_on_merge?: boolean;
|
|
125
|
+
}
|
|
87
126
|
/**
|
|
88
127
|
* Query parameters for listing organization members.
|
|
89
128
|
*
|
|
@@ -1301,6 +1340,8 @@ type RequestFn = <T>(path: string, params?: Record<string, string | number | boo
|
|
|
1301
1340
|
type RequestListFn = <T>(path: string, params?: Record<string, string | number | boolean>) => Promise<GitHubPagedResponse<T>>;
|
|
1302
1341
|
/** @internal */
|
|
1303
1342
|
type RequestTextFn = (path: string, params?: Record<string, string | number | boolean>) => Promise<string>;
|
|
1343
|
+
/** @internal */
|
|
1344
|
+
type RequestBodyFn = <T>(path: string, body: unknown) => Promise<T>;
|
|
1304
1345
|
/**
|
|
1305
1346
|
* Represents a GitHub organization resource with chainable async methods.
|
|
1306
1347
|
*
|
|
@@ -1326,9 +1367,10 @@ declare class OrganizationResource implements PromiseLike<GitHubOrganization> {
|
|
|
1326
1367
|
private readonly request;
|
|
1327
1368
|
private readonly requestList;
|
|
1328
1369
|
private readonly requestText;
|
|
1370
|
+
private readonly requestBody;
|
|
1329
1371
|
private readonly org;
|
|
1330
1372
|
/** @internal */
|
|
1331
|
-
constructor(request: RequestFn, requestList: RequestListFn, requestText: RequestTextFn, org: string);
|
|
1373
|
+
constructor(request: RequestFn, requestList: RequestListFn, requestText: RequestTextFn, requestBody: RequestBodyFn, org: string);
|
|
1332
1374
|
/**
|
|
1333
1375
|
* Allows the resource to be awaited directly, resolving with the organization info.
|
|
1334
1376
|
* Delegates to {@link OrganizationResource.get}.
|
|
@@ -1377,6 +1419,25 @@ declare class OrganizationResource implements PromiseLike<GitHubOrganization> {
|
|
|
1377
1419
|
* @returns A paged response of users
|
|
1378
1420
|
*/
|
|
1379
1421
|
members(params?: OrgMembersParams): Promise<GitHubPagedResponse<GitHubUser>>;
|
|
1422
|
+
/**
|
|
1423
|
+
* Creates a new repository in this organization.
|
|
1424
|
+
*
|
|
1425
|
+
* `POST /orgs/{org}/repos`
|
|
1426
|
+
*
|
|
1427
|
+
* @param data - Repository creation options. `name` is required.
|
|
1428
|
+
* @returns The newly created repository
|
|
1429
|
+
*
|
|
1430
|
+
* @example
|
|
1431
|
+
* ```typescript
|
|
1432
|
+
* const repo = await gh.org('my-org').createRepo({
|
|
1433
|
+
* name: 'my-new-repo',
|
|
1434
|
+
* description: 'My new repository',
|
|
1435
|
+
* private: true,
|
|
1436
|
+
* auto_init: true,
|
|
1437
|
+
* });
|
|
1438
|
+
* ```
|
|
1439
|
+
*/
|
|
1440
|
+
createRepo(data: CreateOrgRepoData): Promise<GitHubRepository>;
|
|
1380
1441
|
}
|
|
1381
1442
|
|
|
1382
1443
|
/**
|
|
@@ -1472,7 +1533,7 @@ interface RequestEvent {
|
|
|
1472
1533
|
/** Full URL that was requested */
|
|
1473
1534
|
url: string;
|
|
1474
1535
|
/** HTTP method used */
|
|
1475
|
-
method: 'GET';
|
|
1536
|
+
method: 'GET' | 'POST';
|
|
1476
1537
|
/** Timestamp when the request started */
|
|
1477
1538
|
startedAt: Date;
|
|
1478
1539
|
/** Timestamp when the request finished (success or error) */
|
|
@@ -1559,6 +1620,8 @@ declare class GitHubClient {
|
|
|
1559
1620
|
private makeRequestFn;
|
|
1560
1621
|
private makeRequestListFn;
|
|
1561
1622
|
private makeRequestTextFn;
|
|
1623
|
+
private requestPost;
|
|
1624
|
+
private makeRequestBodyFn;
|
|
1562
1625
|
/**
|
|
1563
1626
|
* Fetches the authenticated user's profile.
|
|
1564
1627
|
*
|
|
@@ -1723,4 +1786,4 @@ declare class Security {
|
|
|
1723
1786
|
getRawHeaders(): Record<string, string>;
|
|
1724
1787
|
}
|
|
1725
1788
|
|
|
1726
|
-
export { type BranchesParams, type CheckRunsParams, CommitResource, type CommitStatusesParams, type CommitsParams, type ContentParams, type ForksParams, GitHubApiError, type GitHubBranch, type GitHubCheckRun, GitHubClient, type GitHubClientEvents, type GitHubClientOptions, type GitHubCombinedStatus, type GitHubCommit, type GitHubCommitFile, type GitHubCommitStatus, type GitHubContent, type GitHubLabel, type GitHubMilestone, type GitHubOrganization, type GitHubPagedResponse, type GitHubPullRequest, type GitHubPullRequestFile, type GitHubRef, type GitHubRelease, type GitHubReleaseAsset, type GitHubRepository, type GitHubReview, type GitHubReviewComment, type GitHubTag, type GitHubUser, type GitHubWebhook, type OrgMembersParams, OrganizationResource, type PaginationParams, type PullRequestFilesParams, PullRequestResource, type PullRequestsParams, type ReleasesParams, type ReposParams, RepositoryResource, type RequestEvent, type ReviewCommentsParams, type ReviewsParams, type SearchReposParams, type SearchUsersParams, Security, type TagsParams, UserResource, type UsersParams, type WebhooksParams };
|
|
1789
|
+
export { type BranchesParams, type CheckRunsParams, CommitResource, type CommitStatusesParams, type CommitsParams, type ContentParams, type CreateOrgRepoData, type ForksParams, GitHubApiError, type GitHubBranch, type GitHubCheckRun, GitHubClient, type GitHubClientEvents, type GitHubClientOptions, type GitHubCombinedStatus, type GitHubCommit, type GitHubCommitFile, type GitHubCommitStatus, type GitHubContent, type GitHubLabel, type GitHubMilestone, type GitHubOrganization, type GitHubPagedResponse, type GitHubPullRequest, type GitHubPullRequestFile, type GitHubRef, type GitHubRelease, type GitHubReleaseAsset, type GitHubRepository, type GitHubReview, type GitHubReviewComment, type GitHubTag, type GitHubUser, type GitHubWebhook, type OrgMembersParams, OrganizationResource, type PaginationParams, type PullRequestFilesParams, PullRequestResource, type PullRequestsParams, type ReleasesParams, type ReposParams, RepositoryResource, type RequestEvent, type ReviewCommentsParams, type ReviewsParams, type SearchReposParams, type SearchUsersParams, Security, type TagsParams, UserResource, type UsersParams, type WebhooksParams };
|
package/dist/index.js
CHANGED
|
@@ -532,10 +532,11 @@ var RepositoryResource = class {
|
|
|
532
532
|
// src/resources/OrganizationResource.ts
|
|
533
533
|
var OrganizationResource = class {
|
|
534
534
|
/** @internal */
|
|
535
|
-
constructor(request, requestList, requestText, org) {
|
|
535
|
+
constructor(request, requestList, requestText, requestBody, org) {
|
|
536
536
|
this.request = request;
|
|
537
537
|
this.requestList = requestList;
|
|
538
538
|
this.requestText = requestText;
|
|
539
|
+
this.requestBody = requestBody;
|
|
539
540
|
this.org = org;
|
|
540
541
|
}
|
|
541
542
|
/**
|
|
@@ -608,6 +609,27 @@ var OrganizationResource = class {
|
|
|
608
609
|
params
|
|
609
610
|
);
|
|
610
611
|
}
|
|
612
|
+
/**
|
|
613
|
+
* Creates a new repository in this organization.
|
|
614
|
+
*
|
|
615
|
+
* `POST /orgs/{org}/repos`
|
|
616
|
+
*
|
|
617
|
+
* @param data - Repository creation options. `name` is required.
|
|
618
|
+
* @returns The newly created repository
|
|
619
|
+
*
|
|
620
|
+
* @example
|
|
621
|
+
* ```typescript
|
|
622
|
+
* const repo = await gh.org('my-org').createRepo({
|
|
623
|
+
* name: 'my-new-repo',
|
|
624
|
+
* description: 'My new repository',
|
|
625
|
+
* private: true,
|
|
626
|
+
* auto_init: true,
|
|
627
|
+
* });
|
|
628
|
+
* ```
|
|
629
|
+
*/
|
|
630
|
+
async createRepo(data) {
|
|
631
|
+
return this.requestBody(`/orgs/${this.org}/repos`, data);
|
|
632
|
+
}
|
|
611
633
|
};
|
|
612
634
|
|
|
613
635
|
// src/resources/UserResource.ts
|
|
@@ -824,6 +846,32 @@ var GitHubClient = class {
|
|
|
824
846
|
makeRequestTextFn() {
|
|
825
847
|
return (path, params) => this.requestText(path, params);
|
|
826
848
|
}
|
|
849
|
+
async requestPost(path, body) {
|
|
850
|
+
const url = `${this.security.getApiUrl()}${path}`;
|
|
851
|
+
const startedAt = /* @__PURE__ */ new Date();
|
|
852
|
+
let statusCode;
|
|
853
|
+
try {
|
|
854
|
+
const response = await fetch(url, {
|
|
855
|
+
method: "POST",
|
|
856
|
+
headers: this.security.getHeaders(),
|
|
857
|
+
body: JSON.stringify(body)
|
|
858
|
+
});
|
|
859
|
+
statusCode = response.status;
|
|
860
|
+
if (!response.ok) {
|
|
861
|
+
throw new GitHubApiError(response.status, response.statusText);
|
|
862
|
+
}
|
|
863
|
+
const data = await response.json();
|
|
864
|
+
this.emit("request", { url, method: "POST", startedAt, finishedAt: /* @__PURE__ */ new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });
|
|
865
|
+
return data;
|
|
866
|
+
} catch (err) {
|
|
867
|
+
const finishedAt = /* @__PURE__ */ new Date();
|
|
868
|
+
this.emit("request", { url, method: "POST", startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });
|
|
869
|
+
throw err;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
makeRequestBodyFn() {
|
|
873
|
+
return (path, body) => this.requestPost(path, body);
|
|
874
|
+
}
|
|
827
875
|
/**
|
|
828
876
|
* Fetches the authenticated user's profile.
|
|
829
877
|
*
|
|
@@ -887,6 +935,7 @@ var GitHubClient = class {
|
|
|
887
935
|
this.makeRequestFn(),
|
|
888
936
|
this.makeRequestListFn(),
|
|
889
937
|
this.makeRequestTextFn(),
|
|
938
|
+
this.makeRequestBodyFn(),
|
|
890
939
|
name
|
|
891
940
|
);
|
|
892
941
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/security/Security.ts","../src/errors/GitHubApiError.ts","../src/resources/PullRequestResource.ts","../src/resources/CommitResource.ts","../src/resources/RepositoryResource.ts","../src/resources/OrganizationResource.ts","../src/resources/UserResource.ts","../src/GitHubClient.ts"],"sourcesContent":["export { GitHubClient } from './GitHubClient';\nexport { GitHubApiError } from './errors/GitHubApiError';\nexport type { GitHubClientOptions, RequestEvent, GitHubClientEvents } from './GitHubClient';\nexport { Security } from './security/Security';\nexport { OrganizationResource } from './resources/OrganizationResource';\nexport { RepositoryResource } from './resources/RepositoryResource';\nexport { PullRequestResource } from './resources/PullRequestResource';\nexport { CommitResource } from './resources/CommitResource';\nexport { UserResource } from './resources/UserResource';\nexport type { GitHubUser, UsersParams, SearchUsersParams } from './domain/User';\nexport type { GitHubOrganization, OrgMembersParams } from './domain/Organization';\nexport type { GitHubRepository, ReposParams, ForksParams, SearchReposParams } from './domain/Repository';\nexport type { GitHubPullRequest, GitHubRef, GitHubLabel, GitHubMilestone, PullRequestsParams } from './domain/PullRequest';\nexport type { GitHubReview, GitHubReviewComment, ReviewsParams, ReviewCommentsParams } from './domain/Review';\nexport type { GitHubPullRequestFile, PullRequestFilesParams } from './domain/PullRequestFile';\nexport type { GitHubCommit, GitHubCommitFile, CommitsParams } from './domain/Commit';\nexport type { GitHubCommitStatus, GitHubCombinedStatus, GitHubCheckRun, CommitStatusesParams, CheckRunsParams } from './domain/CommitStatus';\nexport type { GitHubBranch, BranchesParams } from './domain/Branch';\nexport type { GitHubTag, TagsParams } from './domain/Tag';\nexport type { GitHubRelease, GitHubReleaseAsset, ReleasesParams } from './domain/Release';\nexport type { GitHubWebhook, WebhooksParams } from './domain/Webhook';\nexport type { GitHubContent, ContentParams } from './domain/Content';\nexport type { PaginationParams, GitHubPagedResponse } from './domain/Pagination';\n","/**\n * Handles Bearer token authentication for GitHub REST API requests.\n *\n * @example\n * ```typescript\n * const security = new Security('ghp_myPersonalAccessToken');\n *\n * const headers = security.getHeaders();\n * // {\n * // Authorization: 'Bearer ghp_myPersonalAccessToken',\n * // Accept: 'application/vnd.github+json',\n * // 'Content-Type': 'application/json',\n * // 'X-GitHub-Api-Version': '2022-11-28',\n * // }\n * ```\n */\nexport class Security {\n private readonly apiUrl: string;\n private readonly token: string;\n\n /**\n * Creates a new Security instance with a GitHub personal access token.\n *\n * @param token - A GitHub personal access token (e.g., `ghp_...`) or OAuth token\n * @param apiUrl - The base URL of the GitHub API. Defaults to `'https://api.github.com'`.\n * Must be a valid URL; throws if it cannot be parsed.\n *\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor(token: string, apiUrl: string = 'https://api.github.com') {\n if (!URL.canParse(apiUrl)) {\n throw new TypeError(`Invalid apiUrl: \"${apiUrl}\" is not a valid URL`);\n }\n this.apiUrl = apiUrl.replace(/\\/$/, '');\n this.token = token;\n }\n\n /**\n * Returns the base URL of the GitHub API, without a trailing slash.\n *\n * @returns The API base URL\n */\n getApiUrl(): string {\n return this.apiUrl;\n }\n\n /**\n * Returns the value of the `Authorization` header for Bearer authentication.\n *\n * @returns The Authorization header value in the format `Bearer <token>`\n */\n getAuthorizationHeader(): string {\n return `Bearer ${this.token}`;\n }\n\n /**\n * Returns the full set of HTTP headers required for authenticated GitHub API requests.\n *\n * @returns An object containing `Authorization`, `Accept`, `Content-Type`, and `X-GitHub-Api-Version` headers\n */\n getHeaders(): Record<string, string> {\n return {\n Authorization: `Bearer ${this.token}`,\n Accept: 'application/vnd.github+json',\n 'Content-Type': 'application/json',\n 'X-GitHub-Api-Version': '2022-11-28',\n };\n }\n\n /**\n * Returns headers for raw file content requests.\n *\n * @returns Headers with `Accept: application/vnd.github.raw+json`\n */\n getRawHeaders(): Record<string, string> {\n return {\n ...this.getHeaders(),\n Accept: 'application/vnd.github.raw+json',\n };\n }\n}\n","/**\n * Thrown when the GitHub REST API returns a non-2xx response.\n *\n * @example\n * ```typescript\n * import { GitHubApiError } from 'github-api-client';\n *\n * try {\n * await gh.user('nonexistent-user-xyz');\n * } catch (err) {\n * if (err instanceof GitHubApiError) {\n * console.log(err.status); // 404\n * console.log(err.statusText); // 'Not Found'\n * console.log(err.message); // 'GitHub API error: 404 Not Found'\n * }\n * }\n * ```\n */\nexport class GitHubApiError extends Error {\n /** HTTP status code (e.g. `404`, `401`, `403`, `422`) */\n readonly status: number;\n /** HTTP status text (e.g. `'Not Found'`, `'Unauthorized'`) */\n readonly statusText: string;\n\n constructor(status: number, statusText: string) {\n super(`GitHub API error: ${status} ${statusText}`);\n this.name = 'GitHubApiError';\n this.status = status;\n this.statusText = statusText;\n }\n}\n","import type { GitHubPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { GitHubReview, GitHubReviewComment, ReviewsParams, ReviewCommentsParams } from '../domain/Review';\nimport type { GitHubPullRequestFile, PullRequestFilesParams } from '../domain/PullRequestFile';\nimport type { GitHubCommit } from '../domain/Commit';\nimport type { GitHubPagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn } from './OrganizationResource';\n\n/**\n * Represents a GitHub pull request resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubPullRequest>` so it can be awaited directly\n * to fetch the pull request info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get pull request info\n * const pr = await gh.org('github').repo('linguist').pullRequest(42);\n *\n * // Get commits in this pull request\n * const commits = await gh.org('github').repo('linguist').pullRequest(42).commits();\n *\n * // Get changed files\n * const files = await gh.org('github').repo('linguist').pullRequest(42).files();\n *\n * // Get reviews\n * const reviews = await gh.org('github').repo('linguist').pullRequest(42).reviews();\n *\n * // Get review comments (inline diff comments)\n * const comments = await gh.org('github').repo('linguist').pullRequest(42).reviewComments();\n * ```\n */\nexport class PullRequestResource implements PromiseLike<GitHubPullRequest> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n owner: string,\n repo: string,\n pullNumber: number,\n ) {\n this.basePath = `/repos/${owner}/${repo}/pulls/${pullNumber}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the pull request info.\n * Delegates to {@link PullRequestResource.get}.\n */\n then<TResult1 = GitHubPullRequest, TResult2 = never>(\n onfulfilled?: ((value: GitHubPullRequest) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the pull request details.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}`\n *\n * @returns The pull request object\n */\n async get(): Promise<GitHubPullRequest> {\n return this.request<GitHubPullRequest>(this.basePath);\n }\n\n /**\n * Fetches the commits included in this pull request.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/commits`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of commits\n */\n async commits(params?: PaginationParams): Promise<GitHubPagedResponse<GitHubCommit>> {\n return this.requestList<GitHubCommit>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the files changed by this pull request.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/files`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of changed files\n */\n async files(params?: PullRequestFilesParams): Promise<GitHubPagedResponse<GitHubPullRequestFile>> {\n return this.requestList<GitHubPullRequestFile>(\n `${this.basePath}/files`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the reviews submitted on this pull request.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of reviews\n */\n async reviews(params?: ReviewsParams): Promise<GitHubPagedResponse<GitHubReview>> {\n return this.requestList<GitHubReview>(\n `${this.basePath}/reviews`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the inline review comments on this pull request's diff.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/comments`\n *\n * @param params - Optional filters: `sort`, `direction`, `since`, `per_page`, `page`\n * @returns A paged response of review comments\n */\n async reviewComments(params?: ReviewCommentsParams): Promise<GitHubPagedResponse<GitHubReviewComment>> {\n return this.requestList<GitHubReviewComment>(\n `${this.basePath}/comments`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Checks whether the pull request has been merged.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/merge`\n *\n * @returns `true` if merged (HTTP 204), `false` if not merged (HTTP 404)\n */\n async isMerged(): Promise<boolean> {\n try {\n await this.request<never>(`${this.basePath}/merge`);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import type { GitHubCommit } from '../domain/Commit';\nimport type { GitHubCommitStatus, GitHubCombinedStatus, GitHubCheckRun, CommitStatusesParams, CheckRunsParams } from '../domain/CommitStatus';\nimport type { GitHubPagedResponse } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn } from './OrganizationResource';\n\n/**\n * Represents a GitHub commit resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubCommit>` so it can be awaited directly\n * to fetch the commit info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get commit info (includes stats and files)\n * const commit = await gh.org('github').repo('linguist').commit('abc123');\n *\n * // Get CI/CD statuses for this commit\n * const statuses = await gh.org('github').repo('linguist').commit('abc123').statuses();\n *\n * // Get the combined (aggregated) status\n * const combined = await gh.org('github').repo('linguist').commit('abc123').combinedStatus();\n *\n * // Get GitHub Actions check runs\n * const checks = await gh.org('github').repo('linguist').commit('abc123').checkRuns();\n * ```\n */\nexport class CommitResource implements PromiseLike<GitHubCommit> {\n private readonly basePath: string;\n private readonly ref: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n owner: string,\n repo: string,\n ref: string,\n ) {\n this.basePath = `/repos/${owner}/${repo}/commits/${ref}`;\n this.ref = ref;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the commit info.\n * Delegates to {@link CommitResource.get}.\n */\n then<TResult1 = GitHubCommit, TResult2 = never>(\n onfulfilled?: ((value: GitHubCommit) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the commit details, including stats and changed files.\n *\n * `GET /repos/{owner}/{repo}/commits/{ref}`\n *\n * @returns The commit object with stats and files\n */\n async get(): Promise<GitHubCommit> {\n return this.request<GitHubCommit>(this.basePath);\n }\n\n /**\n * Fetches the individual commit statuses (from CI/CD systems via the Statuses API).\n *\n * `GET /repos/{owner}/{repo}/statuses/{sha}`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of commit statuses\n */\n async statuses(params?: CommitStatusesParams): Promise<GitHubPagedResponse<GitHubCommitStatus>> {\n const repoPath = this.basePath.replace(`/commits/${this.ref}`, '');\n return this.requestList<GitHubCommitStatus>(\n `${repoPath}/statuses/${this.ref}`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the combined commit status — an aggregation of all statuses for this ref.\n *\n * `GET /repos/{owner}/{repo}/commits/{ref}/status`\n *\n * @returns The combined status object\n */\n async combinedStatus(): Promise<GitHubCombinedStatus> {\n return this.request<GitHubCombinedStatus>(`${this.basePath}/status`);\n }\n\n /**\n * Fetches GitHub Actions check runs for this commit.\n *\n * `GET /repos/{owner}/{repo}/commits/{ref}/check-runs`\n *\n * @param params - Optional filters: `check_name`, `status`, `app_id`, `per_page`, `page`\n * @returns A paged response of check runs\n */\n async checkRuns(params?: CheckRunsParams): Promise<GitHubPagedResponse<GitHubCheckRun>> {\n const raw = await this.request<{ check_runs: GitHubCheckRun[] }>(\n `${this.basePath}/check-runs`,\n params as Record<string, string | number | boolean>,\n );\n return {\n values: raw.check_runs,\n hasNextPage: false,\n };\n }\n}\n","import type { GitHubRepository, ReposParams, ForksParams } from '../domain/Repository';\nimport type { GitHubPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { GitHubCommit, CommitsParams } from '../domain/Commit';\nimport type { GitHubBranch, BranchesParams } from '../domain/Branch';\nimport type { GitHubTag, TagsParams } from '../domain/Tag';\nimport type { GitHubRelease, ReleasesParams } from '../domain/Release';\nimport type { GitHubWebhook, WebhooksParams } from '../domain/Webhook';\nimport type { GitHubContent, ContentParams } from '../domain/Content';\nimport type { GitHubPagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn, RequestTextFn } from './OrganizationResource';\nimport { PullRequestResource } from './PullRequestResource';\nimport { CommitResource } from './CommitResource';\n\n/**\n * Represents a GitHub repository resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubRepository>` so it can be awaited directly\n * to fetch repository info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get repository info\n * const repo = await gh.org('github').repo('linguist');\n *\n * // Get pull requests\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n *\n * // Navigate into a specific pull request\n * const files = await gh.org('github').repo('linguist').pullRequest(42).files();\n *\n * // Get commits\n * const commits = await gh.org('github').repo('linguist').commits({ per_page: 10 });\n *\n * // Get raw file content\n * const content = await gh.org('github').repo('linguist').raw('README.md');\n * ```\n */\nexport class RepositoryResource implements PromiseLike<GitHubRepository> {\n private readonly owner: string;\n private readonly repo: string;\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n private readonly requestText: RequestTextFn,\n owner: string,\n repo: string,\n ) {\n this.owner = owner;\n this.repo = repo;\n this.basePath = `/repos/${owner}/${repo}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the repository info.\n * Delegates to {@link RepositoryResource.get}.\n */\n then<TResult1 = GitHubRepository, TResult2 = never>(\n onfulfilled?: ((value: GitHubRepository) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the repository details.\n *\n * `GET /repos/{owner}/{repo}`\n *\n * @returns The repository object\n */\n async get(): Promise<GitHubRepository> {\n return this.request<GitHubRepository>(this.basePath);\n }\n\n /**\n * Fetches pull requests for this repository.\n *\n * `GET /repos/{owner}/{repo}/pulls`\n *\n * @param params - Optional filters: `state`, `head`, `base`, `sort`, `direction`, `per_page`, `page`\n * @returns A paged response of pull requests\n */\n async pullRequests(params?: PullRequestsParams): Promise<GitHubPagedResponse<GitHubPullRequest>> {\n return this.requestList<GitHubPullRequest>(\n `${this.basePath}/pulls`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link PullRequestResource} for a given pull request number.\n *\n * The returned resource can be awaited directly to fetch pull request info,\n * or chained to access nested resources.\n *\n * @param pullNumber - The pull request number (not the ID)\n * @returns A chainable pull request resource\n *\n * @example\n * ```typescript\n * const pr = await gh.org('github').repo('linguist').pullRequest(42);\n * const files = await gh.org('github').repo('linguist').pullRequest(42).files();\n * const reviews = await gh.org('github').repo('linguist').pullRequest(42).reviews();\n * ```\n */\n pullRequest(pullNumber: number): PullRequestResource {\n return new PullRequestResource(\n this.request,\n this.requestList,\n this.owner,\n this.repo,\n pullNumber,\n );\n }\n\n /**\n * Fetches commits for this repository.\n *\n * `GET /repos/{owner}/{repo}/commits`\n *\n * @param params - Optional filters: `sha`, `path`, `author`, `since`, `until`, `per_page`, `page`\n * @returns A paged response of commits\n */\n async commits(params?: CommitsParams): Promise<GitHubPagedResponse<GitHubCommit>> {\n return this.requestList<GitHubCommit>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link CommitResource} for a given commit ref (SHA, branch, or tag).\n *\n * The returned resource can be awaited directly to fetch commit info,\n * or chained to access nested resources.\n *\n * @param ref - Commit SHA, branch name, or tag name\n * @returns A chainable commit resource\n *\n * @example\n * ```typescript\n * const commit = await gh.org('github').repo('linguist').commit('abc123');\n * const statuses = await gh.org('github').repo('linguist').commit('abc123').statuses();\n * ```\n */\n commit(ref: string): CommitResource {\n return new CommitResource(\n this.request,\n this.requestList,\n this.owner,\n this.repo,\n ref,\n );\n }\n\n /**\n * Fetches branches for this repository.\n *\n * `GET /repos/{owner}/{repo}/branches`\n *\n * @param params - Optional filters: `protected`, `per_page`, `page`\n * @returns A paged response of branches\n */\n async branches(params?: BranchesParams): Promise<GitHubPagedResponse<GitHubBranch>> {\n return this.requestList<GitHubBranch>(\n `${this.basePath}/branches`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches a specific branch by name.\n *\n * `GET /repos/{owner}/{repo}/branches/{branch}`\n *\n * @param name - The branch name (e.g., `'main'`)\n * @returns The branch object\n */\n async branch(name: string): Promise<GitHubBranch> {\n return this.request<GitHubBranch>(`${this.basePath}/branches/${encodeURIComponent(name)}`);\n }\n\n /**\n * Fetches tags for this repository.\n *\n * `GET /repos/{owner}/{repo}/tags`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of tags\n */\n async tags(params?: TagsParams): Promise<GitHubPagedResponse<GitHubTag>> {\n return this.requestList<GitHubTag>(\n `${this.basePath}/tags`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches releases for this repository.\n *\n * `GET /repos/{owner}/{repo}/releases`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of releases\n */\n async releases(params?: ReleasesParams): Promise<GitHubPagedResponse<GitHubRelease>> {\n return this.requestList<GitHubRelease>(\n `${this.basePath}/releases`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the latest published release for this repository.\n *\n * `GET /repos/{owner}/{repo}/releases/latest`\n *\n * @returns The latest release object\n */\n async latestRelease(): Promise<GitHubRelease> {\n return this.request<GitHubRelease>(`${this.basePath}/releases/latest`);\n }\n\n /**\n * Fetches the forks of this repository.\n *\n * `GET /repos/{owner}/{repo}/forks`\n *\n * @param params - Optional filters: `sort`, `per_page`, `page`\n * @returns A paged response of forked repositories\n */\n async forks(params?: ForksParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n return this.requestList<GitHubRepository>(\n `${this.basePath}/forks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches webhooks configured on this repository.\n *\n * `GET /repos/{owner}/{repo}/hooks`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of webhooks\n */\n async webhooks(params?: WebhooksParams): Promise<GitHubPagedResponse<GitHubWebhook>> {\n return this.requestList<GitHubWebhook>(\n `${this.basePath}/hooks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the contents of a file or directory in this repository.\n *\n * `GET /repos/{owner}/{repo}/contents/{path}`\n *\n * Returns a single {@link GitHubContent} for files, or an array for directories.\n *\n * @param path - Path to the file or directory (e.g., `'src/index.ts'` or `'src'`). Omit for root.\n * @param params - Optional: `ref` (branch, tag, or commit SHA)\n * @returns File content object or array of directory entries\n */\n async contents(path?: string, params?: ContentParams): Promise<GitHubContent | GitHubContent[]> {\n const contentPath = path ? `${this.basePath}/contents/${path}` : `${this.basePath}/contents`;\n return this.request<GitHubContent | GitHubContent[]>(\n contentPath,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the raw text content of a file in this repository.\n *\n * Uses `Accept: application/vnd.github.raw+json` to retrieve the file directly\n * without base64 encoding.\n *\n * `GET /repos/{owner}/{repo}/contents/{filePath}`\n *\n * @param filePath - Path to the file (e.g., `'src/index.ts'`)\n * @param params - Optional: `ref` (branch, tag, or commit SHA)\n * @returns The raw file content as a string\n */\n async raw(filePath: string, params?: ContentParams): Promise<string> {\n return this.requestText(\n `${this.basePath}/contents/${filePath}`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the repository topics.\n *\n * `GET /repos/{owner}/{repo}/topics`\n *\n * @returns An array of topic strings\n */\n async topics(): Promise<string[]> {\n const data = await this.request<{ names: string[] }>(`${this.basePath}/topics`);\n return data.names;\n }\n\n /**\n * Fetches contributors to this repository.\n *\n * `GET /repos/{owner}/{repo}/contributors`\n *\n * @param params - Optional filters: `anon` (include anonymous contributors), `per_page`, `page`\n * @returns A paged response of contributors\n */\n async contributors(params?: PaginationParams & { anon?: boolean }): Promise<GitHubPagedResponse<{ login?: string; id?: number; contributions: number; avatar_url?: string; html_url?: string }>> {\n return this.requestList(\n `${this.basePath}/contributors`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","import type { GitHubOrganization, OrgMembersParams } from '../domain/Organization';\nimport type { GitHubRepository, ReposParams } from '../domain/Repository';\nimport type { GitHubUser } from '../domain/User';\nimport type { GitHubPagedResponse } from '../domain/Pagination';\nimport { RepositoryResource } from './RepositoryResource';\n\n/** @internal */\nexport type RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<T>;\n\n/** @internal */\nexport type RequestListFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<GitHubPagedResponse<T>>;\n\n/** @internal */\nexport type RequestTextFn = (\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<string>;\n\n/**\n * Represents a GitHub organization resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubOrganization>` so it can be awaited directly\n * to fetch the organization info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get organization info\n * const org = await gh.org('github');\n *\n * // Get repositories\n * const repos = await gh.org('github').repos({ type: 'public', per_page: 50 });\n *\n * // Navigate into a specific repository\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n *\n * // Get members\n * const members = await gh.org('github').members({ role: 'admin' });\n * ```\n */\nexport class OrganizationResource implements PromiseLike<GitHubOrganization> {\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n private readonly requestText: RequestTextFn,\n private readonly org: string,\n ) {}\n\n /**\n * Allows the resource to be awaited directly, resolving with the organization info.\n * Delegates to {@link OrganizationResource.get}.\n */\n then<TResult1 = GitHubOrganization, TResult2 = never>(\n onfulfilled?: ((value: GitHubOrganization) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the organization details.\n *\n * `GET /orgs/{org}`\n *\n * @returns The organization object\n */\n async get(): Promise<GitHubOrganization> {\n return this.request<GitHubOrganization>(`/orgs/${this.org}`);\n }\n\n /**\n * Fetches repositories belonging to this organization.\n *\n * `GET /orgs/{org}/repos`\n *\n * @param params - Optional filters: `type`, `sort`, `direction`, `per_page`, `page`\n * @returns A paged response of repositories\n */\n async repos(params?: ReposParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n return this.requestList<GitHubRepository>(\n `/orgs/${this.org}/repos`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given repository name within this organization.\n *\n * The returned resource can be awaited directly to fetch repository info,\n * or chained to access nested resources.\n *\n * @param name - The repository name (e.g., `'linguist'`)\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await gh.org('github').repo('linguist');\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n * const commits = await gh.org('github').repo('linguist').commits({ per_page: 10 });\n * ```\n */\n repo(name: string): RepositoryResource {\n return new RepositoryResource(\n this.request,\n this.requestList,\n this.requestText,\n this.org,\n name,\n );\n }\n\n /**\n * Fetches members of this organization.\n *\n * `GET /orgs/{org}/members`\n *\n * @param params - Optional filters: `role`, `filter`, `per_page`, `page`\n * @returns A paged response of users\n */\n async members(params?: OrgMembersParams): Promise<GitHubPagedResponse<GitHubUser>> {\n return this.requestList<GitHubUser>(\n `/orgs/${this.org}/members`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","import type { GitHubUser } from '../domain/User';\nimport type { GitHubRepository, ReposParams } from '../domain/Repository';\nimport type { GitHubPagedResponse } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn, RequestTextFn } from './OrganizationResource';\nimport { RepositoryResource } from './RepositoryResource';\n\n/**\n * Represents a GitHub user resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubUser>` so it can be awaited directly\n * to fetch user info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get user info\n * const user = await gh.user('octocat');\n *\n * // Get the user's public repositories\n * const repos = await gh.user('octocat').repos({ sort: 'updated' });\n *\n * // Navigate into a specific repository\n * const prs = await gh.user('octocat').repo('Hello-World').pullRequests();\n * ```\n */\nexport class UserResource implements PromiseLike<GitHubUser> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n private readonly requestText: RequestTextFn,\n private readonly login: string,\n ) {\n this.basePath = `/users/${login}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the user info.\n * Delegates to {@link UserResource.get}.\n */\n then<TResult1 = GitHubUser, TResult2 = never>(\n onfulfilled?: ((value: GitHubUser) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the user details.\n *\n * `GET /users/{username}`\n *\n * @returns The user object\n */\n async get(): Promise<GitHubUser> {\n return this.request<GitHubUser>(this.basePath);\n }\n\n /**\n * Fetches public repositories for this user.\n *\n * `GET /users/{username}/repos`\n *\n * @param params - Optional filters: `type`, `sort`, `direction`, `per_page`, `page`\n * @returns A paged response of repositories\n */\n async repos(params?: ReposParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n return this.requestList<GitHubRepository>(\n `${this.basePath}/repos`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given repository under this user,\n * providing access to all repository sub-resources.\n *\n * @param name - The repository name\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await gh.user('octocat').repo('Hello-World');\n * const content = await gh.user('octocat').repo('Hello-World').raw('README.md');\n * ```\n */\n repo(name: string): RepositoryResource {\n return new RepositoryResource(\n this.request,\n this.requestList,\n this.requestText,\n this.login,\n name,\n );\n }\n\n /**\n * Fetches the users this user is following.\n *\n * `GET /users/{username}/following`\n *\n * @returns A paged response of users\n */\n async following(params?: { per_page?: number; page?: number }): Promise<GitHubPagedResponse<GitHubUser>> {\n return this.requestList<GitHubUser>(\n `${this.basePath}/following`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the users following this user.\n *\n * `GET /users/{username}/followers`\n *\n * @returns A paged response of users\n */\n async followers(params?: { per_page?: number; page?: number }): Promise<GitHubPagedResponse<GitHubUser>> {\n return this.requestList<GitHubUser>(\n `${this.basePath}/followers`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","import { Security } from './security/Security';\nimport { GitHubApiError } from './errors/GitHubApiError';\nimport { OrganizationResource } from './resources/OrganizationResource';\nimport type { RequestFn, RequestListFn, RequestTextFn } from './resources/OrganizationResource';\nimport { RepositoryResource } from './resources/RepositoryResource';\nimport { UserResource } from './resources/UserResource';\nimport type { GitHubUser } from './domain/User';\nimport type { GitHubRepository, SearchReposParams } from './domain/Repository';\nimport type { GitHubPagedResponse } from './domain/Pagination';\n\n/**\n * Payload emitted on every HTTP request made by {@link GitHubClient}.\n */\nexport interface RequestEvent {\n /** Full URL that was requested */\n url: string;\n /** HTTP method used */\n method: 'GET';\n /** Timestamp when the request started */\n startedAt: Date;\n /** Timestamp when the request finished (success or error) */\n finishedAt: Date;\n /** Total duration in milliseconds */\n durationMs: number;\n /** HTTP status code returned by the server, if a response was received */\n statusCode?: number;\n /** Error thrown, if the request failed */\n error?: Error;\n}\n\n/** Map of supported client events to their callback signatures */\nexport interface GitHubClientEvents {\n request: (event: RequestEvent) => void;\n}\n\n/**\n * Constructor options for {@link GitHubClient}.\n */\nexport interface GitHubClientOptions {\n /** A GitHub personal access token (`ghp_...`), OAuth token, or GitHub App installation token */\n token: string;\n /**\n * The base URL of the GitHub API.\n * Defaults to `'https://api.github.com'`.\n * Override for GitHub Enterprise Server (e.g., `'https://github.mycompany.com/api/v3'`).\n */\n apiUrl?: string;\n}\n\n/**\n * GitHub REST API search result envelope.\n * @internal\n */\ninterface SearchResult<T> {\n total_count: number;\n incomplete_results: boolean;\n items: T[];\n}\n\n/**\n * Main entry point for the GitHub REST API client.\n *\n * @example\n * ```typescript\n * const gh = new GitHubClient({ token: 'ghp_myPersonalAccessToken' });\n *\n * const me = await gh.currentUser();\n * const user = await gh.user('octocat');\n * const repos = await gh.user('octocat').repos({ sort: 'updated' });\n * const org = await gh.org('github');\n * const repo = await gh.repo('octocat', 'Hello-World');\n * const prs = await gh.repo('octocat', 'Hello-World').pullRequests({ state: 'open' });\n * const commits = await gh.repo('octocat', 'Hello-World').commits({ per_page: 10 });\n * const results = await gh.searchRepos({ q: 'language:typescript stars:>1000' });\n * ```\n */\nexport class GitHubClient {\n private readonly security: Security;\n private readonly listeners: Map<keyof GitHubClientEvents, GitHubClientEvents[keyof GitHubClientEvents][]> = new Map();\n\n /**\n * @param options - Authentication and connection options\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor({ token, apiUrl }: GitHubClientOptions) {\n this.security = new Security(token, apiUrl);\n }\n\n /**\n * Subscribes to a client event.\n *\n * @example\n * ```typescript\n * gh.on('request', (event) => {\n * console.log(`${event.method} ${event.url} — ${event.durationMs}ms`);\n * if (event.error) console.error('Request failed:', event.error);\n * });\n * ```\n */\n on<K extends keyof GitHubClientEvents>(event: K, callback: GitHubClientEvents[K]): this {\n const callbacks = this.listeners.get(event) ?? [];\n callbacks.push(callback);\n this.listeners.set(event, callbacks);\n return this;\n }\n\n private emit<K extends keyof GitHubClientEvents>(\n event: K,\n payload: Parameters<GitHubClientEvents[K]>[0],\n ): void {\n const callbacks = this.listeners.get(event) ?? [];\n for (const cb of callbacks) {\n (cb as (p: typeof payload) => void)(payload);\n }\n }\n\n /**\n * Performs an authenticated GET request returning a single JSON object.\n * @internal\n */\n private async request<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n options?: { headers?: Record<string, string> },\n ): Promise<T> {\n const base = `${this.security.getApiUrl()}${path}`;\n const url = buildUrl(base, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const headers = options?.headers ?? this.security.getHeaders();\n const response = await fetch(url, { headers });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as T;\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return data;\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n /**\n * Performs an authenticated GET request returning a paginated list.\n * Parses the `Link` response header to determine if more pages exist.\n * @internal\n */\n private async requestList<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<GitHubPagedResponse<T>> {\n const base = `${this.security.getApiUrl()}${path}`;\n const url = buildUrl(base, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, { headers: this.security.getHeaders() });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as T[];\n const linkHeader = response.headers.get('Link');\n const nextPage = parseNextPage(linkHeader);\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return {\n values: data,\n hasNextPage: nextPage !== undefined,\n nextPage,\n };\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n /**\n * Performs a GET request returning raw text content.\n * Uses `Accept: application/vnd.github.raw+json` to retrieve file content directly.\n * @internal\n */\n private async requestText(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<string> {\n const base = `${this.security.getApiUrl()}${path}`;\n const url = buildUrl(base, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, { headers: this.security.getRawHeaders() });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const text = await response.text();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return text;\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n private makeRequestFn(): RequestFn {\n return <T>(path: string, params?: Record<string, string | number | boolean>) =>\n this.request<T>(path, params);\n }\n\n private makeRequestListFn(): RequestListFn {\n return <T>(path: string, params?: Record<string, string | number | boolean>) =>\n this.requestList<T>(path, params);\n }\n\n private makeRequestTextFn(): RequestTextFn {\n return (path: string, params?: Record<string, string | number | boolean>) =>\n this.requestText(path, params);\n }\n\n /**\n * Fetches the authenticated user's profile.\n *\n * `GET /user`\n *\n * @returns The authenticated user object\n *\n * @example\n * ```typescript\n * const me = await gh.currentUser();\n * console.log(me.login); // 'octocat'\n * ```\n */\n async currentUser(): Promise<GitHubUser> {\n return this.request<GitHubUser>('/user');\n }\n\n /**\n * Returns a {@link UserResource} for a given GitHub login, providing access\n * to user data and their repositories.\n *\n * The returned resource can be awaited directly to fetch user info,\n * or chained to access nested resources.\n *\n * @param login - The user's login name (e.g., `'octocat'`)\n * @returns A chainable user resource\n *\n * @example\n * ```typescript\n * const user = await gh.user('octocat');\n * const repos = await gh.user('octocat').repos({ sort: 'updated' });\n * const pr = await gh.user('octocat').repo('Hello-World').pullRequest(1).files();\n * ```\n */\n user(login: string): UserResource {\n return new UserResource(\n this.makeRequestFn(),\n this.makeRequestListFn(),\n this.makeRequestTextFn(),\n login,\n );\n }\n\n /**\n * Returns an {@link OrganizationResource} for a given GitHub organization, providing\n * access to organization data and its repositories.\n *\n * The returned resource can be awaited directly to fetch organization info,\n * or chained to access nested resources.\n *\n * @param name - The organization's login name (e.g., `'github'`)\n * @returns A chainable organization resource\n *\n * @example\n * ```typescript\n * const org = await gh.org('github');\n * const repos = await gh.org('github').repos({ type: 'public' });\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n * ```\n */\n org(name: string): OrganizationResource {\n return new OrganizationResource(\n this.makeRequestFn(),\n this.makeRequestListFn(),\n this.makeRequestTextFn(),\n name,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given owner and repository name.\n *\n * Shortcut that works for both user repositories and organization repositories.\n *\n * @param owner - The owner login (user or organization)\n * @param name - The repository name\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await gh.repo('octocat', 'Hello-World');\n * const prs = await gh.repo('octocat', 'Hello-World').pullRequests();\n * ```\n */\n repo(owner: string, name: string): RepositoryResource {\n return new RepositoryResource(\n this.makeRequestFn(),\n this.makeRequestListFn(),\n this.makeRequestTextFn(),\n owner,\n name,\n );\n }\n\n /**\n * Searches for repositories using GitHub's search syntax.\n *\n * `GET /search/repositories`\n *\n * @param params - Search query and optional filters. `q` is required.\n * @returns A paged response of repositories with `totalCount`\n *\n * @example\n * ```typescript\n * const results = await gh.searchRepos({ q: 'language:typescript stars:>1000', sort: 'stars' });\n * console.log(`Found ${results.totalCount} repositories`);\n * ```\n */\n async searchRepos(params: SearchReposParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n const base = `${this.security.getApiUrl()}/search/repositories`;\n const url = buildUrl(base, params as unknown as Record<string, string | number | boolean>);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, { headers: this.security.getHeaders() });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as SearchResult<GitHubRepository>;\n const linkHeader = response.headers.get('Link');\n const nextPage = parseNextPage(linkHeader);\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return {\n values: data.items,\n hasNextPage: nextPage !== undefined,\n nextPage,\n totalCount: data.total_count,\n };\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n}\n\n/**\n * Appends query parameters to a URL string, skipping `undefined` values.\n * @internal\n */\nfunction buildUrl(base: string, params?: Record<string, string | number | boolean>): string {\n if (!params) return base;\n const entries = Object.entries(params).filter(([, v]) => v !== undefined);\n if (entries.length === 0) return base;\n const search = new URLSearchParams(entries.map(([k, v]) => [k, String(v)]));\n return `${base}?${search.toString()}`;\n}\n\n/**\n * Parses the `Link` response header to extract the next page number.\n *\n * GitHub Link header format:\n * `<https://api.github.com/...?page=2>; rel=\"next\", <https://api.github.com/...?page=5>; rel=\"last\"`\n *\n * @internal\n */\nfunction parseNextPage(linkHeader: string | null): number | undefined {\n if (!linkHeader) return undefined;\n const match = linkHeader.match(/<[^>]*[?&]page=(\\d+)[^>]*>;\\s*rel=\"next\"/);\n return match ? parseInt(match[1], 10) : undefined;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/security/Security.ts","../src/errors/GitHubApiError.ts","../src/resources/PullRequestResource.ts","../src/resources/CommitResource.ts","../src/resources/RepositoryResource.ts","../src/resources/OrganizationResource.ts","../src/resources/UserResource.ts","../src/GitHubClient.ts"],"sourcesContent":["export { GitHubClient } from './GitHubClient';\nexport { GitHubApiError } from './errors/GitHubApiError';\nexport type { GitHubClientOptions, RequestEvent, GitHubClientEvents } from './GitHubClient';\nexport { Security } from './security/Security';\nexport { OrganizationResource } from './resources/OrganizationResource';\nexport { RepositoryResource } from './resources/RepositoryResource';\nexport { PullRequestResource } from './resources/PullRequestResource';\nexport { CommitResource } from './resources/CommitResource';\nexport { UserResource } from './resources/UserResource';\nexport type { GitHubUser, UsersParams, SearchUsersParams } from './domain/User';\nexport type { GitHubOrganization, OrgMembersParams, CreateOrgRepoData } from './domain/Organization';\nexport type { GitHubRepository, ReposParams, ForksParams, SearchReposParams } from './domain/Repository';\nexport type { GitHubPullRequest, GitHubRef, GitHubLabel, GitHubMilestone, PullRequestsParams } from './domain/PullRequest';\nexport type { GitHubReview, GitHubReviewComment, ReviewsParams, ReviewCommentsParams } from './domain/Review';\nexport type { GitHubPullRequestFile, PullRequestFilesParams } from './domain/PullRequestFile';\nexport type { GitHubCommit, GitHubCommitFile, CommitsParams } from './domain/Commit';\nexport type { GitHubCommitStatus, GitHubCombinedStatus, GitHubCheckRun, CommitStatusesParams, CheckRunsParams } from './domain/CommitStatus';\nexport type { GitHubBranch, BranchesParams } from './domain/Branch';\nexport type { GitHubTag, TagsParams } from './domain/Tag';\nexport type { GitHubRelease, GitHubReleaseAsset, ReleasesParams } from './domain/Release';\nexport type { GitHubWebhook, WebhooksParams } from './domain/Webhook';\nexport type { GitHubContent, ContentParams } from './domain/Content';\nexport type { PaginationParams, GitHubPagedResponse } from './domain/Pagination';\n","/**\n * Handles Bearer token authentication for GitHub REST API requests.\n *\n * @example\n * ```typescript\n * const security = new Security('ghp_myPersonalAccessToken');\n *\n * const headers = security.getHeaders();\n * // {\n * // Authorization: 'Bearer ghp_myPersonalAccessToken',\n * // Accept: 'application/vnd.github+json',\n * // 'Content-Type': 'application/json',\n * // 'X-GitHub-Api-Version': '2022-11-28',\n * // }\n * ```\n */\nexport class Security {\n private readonly apiUrl: string;\n private readonly token: string;\n\n /**\n * Creates a new Security instance with a GitHub personal access token.\n *\n * @param token - A GitHub personal access token (e.g., `ghp_...`) or OAuth token\n * @param apiUrl - The base URL of the GitHub API. Defaults to `'https://api.github.com'`.\n * Must be a valid URL; throws if it cannot be parsed.\n *\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor(token: string, apiUrl: string = 'https://api.github.com') {\n if (!URL.canParse(apiUrl)) {\n throw new TypeError(`Invalid apiUrl: \"${apiUrl}\" is not a valid URL`);\n }\n this.apiUrl = apiUrl.replace(/\\/$/, '');\n this.token = token;\n }\n\n /**\n * Returns the base URL of the GitHub API, without a trailing slash.\n *\n * @returns The API base URL\n */\n getApiUrl(): string {\n return this.apiUrl;\n }\n\n /**\n * Returns the value of the `Authorization` header for Bearer authentication.\n *\n * @returns The Authorization header value in the format `Bearer <token>`\n */\n getAuthorizationHeader(): string {\n return `Bearer ${this.token}`;\n }\n\n /**\n * Returns the full set of HTTP headers required for authenticated GitHub API requests.\n *\n * @returns An object containing `Authorization`, `Accept`, `Content-Type`, and `X-GitHub-Api-Version` headers\n */\n getHeaders(): Record<string, string> {\n return {\n Authorization: `Bearer ${this.token}`,\n Accept: 'application/vnd.github+json',\n 'Content-Type': 'application/json',\n 'X-GitHub-Api-Version': '2022-11-28',\n };\n }\n\n /**\n * Returns headers for raw file content requests.\n *\n * @returns Headers with `Accept: application/vnd.github.raw+json`\n */\n getRawHeaders(): Record<string, string> {\n return {\n ...this.getHeaders(),\n Accept: 'application/vnd.github.raw+json',\n };\n }\n}\n","/**\n * Thrown when the GitHub REST API returns a non-2xx response.\n *\n * @example\n * ```typescript\n * import { GitHubApiError } from 'github-api-client';\n *\n * try {\n * await gh.user('nonexistent-user-xyz');\n * } catch (err) {\n * if (err instanceof GitHubApiError) {\n * console.log(err.status); // 404\n * console.log(err.statusText); // 'Not Found'\n * console.log(err.message); // 'GitHub API error: 404 Not Found'\n * }\n * }\n * ```\n */\nexport class GitHubApiError extends Error {\n /** HTTP status code (e.g. `404`, `401`, `403`, `422`) */\n readonly status: number;\n /** HTTP status text (e.g. `'Not Found'`, `'Unauthorized'`) */\n readonly statusText: string;\n\n constructor(status: number, statusText: string) {\n super(`GitHub API error: ${status} ${statusText}`);\n this.name = 'GitHubApiError';\n this.status = status;\n this.statusText = statusText;\n }\n}\n","import type { GitHubPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { GitHubReview, GitHubReviewComment, ReviewsParams, ReviewCommentsParams } from '../domain/Review';\nimport type { GitHubPullRequestFile, PullRequestFilesParams } from '../domain/PullRequestFile';\nimport type { GitHubCommit } from '../domain/Commit';\nimport type { GitHubPagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn } from './OrganizationResource';\n\n/**\n * Represents a GitHub pull request resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubPullRequest>` so it can be awaited directly\n * to fetch the pull request info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get pull request info\n * const pr = await gh.org('github').repo('linguist').pullRequest(42);\n *\n * // Get commits in this pull request\n * const commits = await gh.org('github').repo('linguist').pullRequest(42).commits();\n *\n * // Get changed files\n * const files = await gh.org('github').repo('linguist').pullRequest(42).files();\n *\n * // Get reviews\n * const reviews = await gh.org('github').repo('linguist').pullRequest(42).reviews();\n *\n * // Get review comments (inline diff comments)\n * const comments = await gh.org('github').repo('linguist').pullRequest(42).reviewComments();\n * ```\n */\nexport class PullRequestResource implements PromiseLike<GitHubPullRequest> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n owner: string,\n repo: string,\n pullNumber: number,\n ) {\n this.basePath = `/repos/${owner}/${repo}/pulls/${pullNumber}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the pull request info.\n * Delegates to {@link PullRequestResource.get}.\n */\n then<TResult1 = GitHubPullRequest, TResult2 = never>(\n onfulfilled?: ((value: GitHubPullRequest) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the pull request details.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}`\n *\n * @returns The pull request object\n */\n async get(): Promise<GitHubPullRequest> {\n return this.request<GitHubPullRequest>(this.basePath);\n }\n\n /**\n * Fetches the commits included in this pull request.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/commits`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of commits\n */\n async commits(params?: PaginationParams): Promise<GitHubPagedResponse<GitHubCommit>> {\n return this.requestList<GitHubCommit>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the files changed by this pull request.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/files`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of changed files\n */\n async files(params?: PullRequestFilesParams): Promise<GitHubPagedResponse<GitHubPullRequestFile>> {\n return this.requestList<GitHubPullRequestFile>(\n `${this.basePath}/files`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the reviews submitted on this pull request.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of reviews\n */\n async reviews(params?: ReviewsParams): Promise<GitHubPagedResponse<GitHubReview>> {\n return this.requestList<GitHubReview>(\n `${this.basePath}/reviews`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the inline review comments on this pull request's diff.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/comments`\n *\n * @param params - Optional filters: `sort`, `direction`, `since`, `per_page`, `page`\n * @returns A paged response of review comments\n */\n async reviewComments(params?: ReviewCommentsParams): Promise<GitHubPagedResponse<GitHubReviewComment>> {\n return this.requestList<GitHubReviewComment>(\n `${this.basePath}/comments`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Checks whether the pull request has been merged.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/merge`\n *\n * @returns `true` if merged (HTTP 204), `false` if not merged (HTTP 404)\n */\n async isMerged(): Promise<boolean> {\n try {\n await this.request<never>(`${this.basePath}/merge`);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import type { GitHubCommit } from '../domain/Commit';\nimport type { GitHubCommitStatus, GitHubCombinedStatus, GitHubCheckRun, CommitStatusesParams, CheckRunsParams } from '../domain/CommitStatus';\nimport type { GitHubPagedResponse } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn } from './OrganizationResource';\n\n/**\n * Represents a GitHub commit resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubCommit>` so it can be awaited directly\n * to fetch the commit info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get commit info (includes stats and files)\n * const commit = await gh.org('github').repo('linguist').commit('abc123');\n *\n * // Get CI/CD statuses for this commit\n * const statuses = await gh.org('github').repo('linguist').commit('abc123').statuses();\n *\n * // Get the combined (aggregated) status\n * const combined = await gh.org('github').repo('linguist').commit('abc123').combinedStatus();\n *\n * // Get GitHub Actions check runs\n * const checks = await gh.org('github').repo('linguist').commit('abc123').checkRuns();\n * ```\n */\nexport class CommitResource implements PromiseLike<GitHubCommit> {\n private readonly basePath: string;\n private readonly ref: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n owner: string,\n repo: string,\n ref: string,\n ) {\n this.basePath = `/repos/${owner}/${repo}/commits/${ref}`;\n this.ref = ref;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the commit info.\n * Delegates to {@link CommitResource.get}.\n */\n then<TResult1 = GitHubCommit, TResult2 = never>(\n onfulfilled?: ((value: GitHubCommit) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the commit details, including stats and changed files.\n *\n * `GET /repos/{owner}/{repo}/commits/{ref}`\n *\n * @returns The commit object with stats and files\n */\n async get(): Promise<GitHubCommit> {\n return this.request<GitHubCommit>(this.basePath);\n }\n\n /**\n * Fetches the individual commit statuses (from CI/CD systems via the Statuses API).\n *\n * `GET /repos/{owner}/{repo}/statuses/{sha}`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of commit statuses\n */\n async statuses(params?: CommitStatusesParams): Promise<GitHubPagedResponse<GitHubCommitStatus>> {\n const repoPath = this.basePath.replace(`/commits/${this.ref}`, '');\n return this.requestList<GitHubCommitStatus>(\n `${repoPath}/statuses/${this.ref}`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the combined commit status — an aggregation of all statuses for this ref.\n *\n * `GET /repos/{owner}/{repo}/commits/{ref}/status`\n *\n * @returns The combined status object\n */\n async combinedStatus(): Promise<GitHubCombinedStatus> {\n return this.request<GitHubCombinedStatus>(`${this.basePath}/status`);\n }\n\n /**\n * Fetches GitHub Actions check runs for this commit.\n *\n * `GET /repos/{owner}/{repo}/commits/{ref}/check-runs`\n *\n * @param params - Optional filters: `check_name`, `status`, `app_id`, `per_page`, `page`\n * @returns A paged response of check runs\n */\n async checkRuns(params?: CheckRunsParams): Promise<GitHubPagedResponse<GitHubCheckRun>> {\n const raw = await this.request<{ check_runs: GitHubCheckRun[] }>(\n `${this.basePath}/check-runs`,\n params as Record<string, string | number | boolean>,\n );\n return {\n values: raw.check_runs,\n hasNextPage: false,\n };\n }\n}\n","import type { GitHubRepository, ReposParams, ForksParams } from '../domain/Repository';\nimport type { GitHubPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { GitHubCommit, CommitsParams } from '../domain/Commit';\nimport type { GitHubBranch, BranchesParams } from '../domain/Branch';\nimport type { GitHubTag, TagsParams } from '../domain/Tag';\nimport type { GitHubRelease, ReleasesParams } from '../domain/Release';\nimport type { GitHubWebhook, WebhooksParams } from '../domain/Webhook';\nimport type { GitHubContent, ContentParams } from '../domain/Content';\nimport type { GitHubPagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn, RequestTextFn } from './OrganizationResource';\nimport { PullRequestResource } from './PullRequestResource';\nimport { CommitResource } from './CommitResource';\n\n/**\n * Represents a GitHub repository resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubRepository>` so it can be awaited directly\n * to fetch repository info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get repository info\n * const repo = await gh.org('github').repo('linguist');\n *\n * // Get pull requests\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n *\n * // Navigate into a specific pull request\n * const files = await gh.org('github').repo('linguist').pullRequest(42).files();\n *\n * // Get commits\n * const commits = await gh.org('github').repo('linguist').commits({ per_page: 10 });\n *\n * // Get raw file content\n * const content = await gh.org('github').repo('linguist').raw('README.md');\n * ```\n */\nexport class RepositoryResource implements PromiseLike<GitHubRepository> {\n private readonly owner: string;\n private readonly repo: string;\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n private readonly requestText: RequestTextFn,\n owner: string,\n repo: string,\n ) {\n this.owner = owner;\n this.repo = repo;\n this.basePath = `/repos/${owner}/${repo}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the repository info.\n * Delegates to {@link RepositoryResource.get}.\n */\n then<TResult1 = GitHubRepository, TResult2 = never>(\n onfulfilled?: ((value: GitHubRepository) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the repository details.\n *\n * `GET /repos/{owner}/{repo}`\n *\n * @returns The repository object\n */\n async get(): Promise<GitHubRepository> {\n return this.request<GitHubRepository>(this.basePath);\n }\n\n /**\n * Fetches pull requests for this repository.\n *\n * `GET /repos/{owner}/{repo}/pulls`\n *\n * @param params - Optional filters: `state`, `head`, `base`, `sort`, `direction`, `per_page`, `page`\n * @returns A paged response of pull requests\n */\n async pullRequests(params?: PullRequestsParams): Promise<GitHubPagedResponse<GitHubPullRequest>> {\n return this.requestList<GitHubPullRequest>(\n `${this.basePath}/pulls`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link PullRequestResource} for a given pull request number.\n *\n * The returned resource can be awaited directly to fetch pull request info,\n * or chained to access nested resources.\n *\n * @param pullNumber - The pull request number (not the ID)\n * @returns A chainable pull request resource\n *\n * @example\n * ```typescript\n * const pr = await gh.org('github').repo('linguist').pullRequest(42);\n * const files = await gh.org('github').repo('linguist').pullRequest(42).files();\n * const reviews = await gh.org('github').repo('linguist').pullRequest(42).reviews();\n * ```\n */\n pullRequest(pullNumber: number): PullRequestResource {\n return new PullRequestResource(\n this.request,\n this.requestList,\n this.owner,\n this.repo,\n pullNumber,\n );\n }\n\n /**\n * Fetches commits for this repository.\n *\n * `GET /repos/{owner}/{repo}/commits`\n *\n * @param params - Optional filters: `sha`, `path`, `author`, `since`, `until`, `per_page`, `page`\n * @returns A paged response of commits\n */\n async commits(params?: CommitsParams): Promise<GitHubPagedResponse<GitHubCommit>> {\n return this.requestList<GitHubCommit>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link CommitResource} for a given commit ref (SHA, branch, or tag).\n *\n * The returned resource can be awaited directly to fetch commit info,\n * or chained to access nested resources.\n *\n * @param ref - Commit SHA, branch name, or tag name\n * @returns A chainable commit resource\n *\n * @example\n * ```typescript\n * const commit = await gh.org('github').repo('linguist').commit('abc123');\n * const statuses = await gh.org('github').repo('linguist').commit('abc123').statuses();\n * ```\n */\n commit(ref: string): CommitResource {\n return new CommitResource(\n this.request,\n this.requestList,\n this.owner,\n this.repo,\n ref,\n );\n }\n\n /**\n * Fetches branches for this repository.\n *\n * `GET /repos/{owner}/{repo}/branches`\n *\n * @param params - Optional filters: `protected`, `per_page`, `page`\n * @returns A paged response of branches\n */\n async branches(params?: BranchesParams): Promise<GitHubPagedResponse<GitHubBranch>> {\n return this.requestList<GitHubBranch>(\n `${this.basePath}/branches`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches a specific branch by name.\n *\n * `GET /repos/{owner}/{repo}/branches/{branch}`\n *\n * @param name - The branch name (e.g., `'main'`)\n * @returns The branch object\n */\n async branch(name: string): Promise<GitHubBranch> {\n return this.request<GitHubBranch>(`${this.basePath}/branches/${encodeURIComponent(name)}`);\n }\n\n /**\n * Fetches tags for this repository.\n *\n * `GET /repos/{owner}/{repo}/tags`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of tags\n */\n async tags(params?: TagsParams): Promise<GitHubPagedResponse<GitHubTag>> {\n return this.requestList<GitHubTag>(\n `${this.basePath}/tags`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches releases for this repository.\n *\n * `GET /repos/{owner}/{repo}/releases`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of releases\n */\n async releases(params?: ReleasesParams): Promise<GitHubPagedResponse<GitHubRelease>> {\n return this.requestList<GitHubRelease>(\n `${this.basePath}/releases`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the latest published release for this repository.\n *\n * `GET /repos/{owner}/{repo}/releases/latest`\n *\n * @returns The latest release object\n */\n async latestRelease(): Promise<GitHubRelease> {\n return this.request<GitHubRelease>(`${this.basePath}/releases/latest`);\n }\n\n /**\n * Fetches the forks of this repository.\n *\n * `GET /repos/{owner}/{repo}/forks`\n *\n * @param params - Optional filters: `sort`, `per_page`, `page`\n * @returns A paged response of forked repositories\n */\n async forks(params?: ForksParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n return this.requestList<GitHubRepository>(\n `${this.basePath}/forks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches webhooks configured on this repository.\n *\n * `GET /repos/{owner}/{repo}/hooks`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of webhooks\n */\n async webhooks(params?: WebhooksParams): Promise<GitHubPagedResponse<GitHubWebhook>> {\n return this.requestList<GitHubWebhook>(\n `${this.basePath}/hooks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the contents of a file or directory in this repository.\n *\n * `GET /repos/{owner}/{repo}/contents/{path}`\n *\n * Returns a single {@link GitHubContent} for files, or an array for directories.\n *\n * @param path - Path to the file or directory (e.g., `'src/index.ts'` or `'src'`). Omit for root.\n * @param params - Optional: `ref` (branch, tag, or commit SHA)\n * @returns File content object or array of directory entries\n */\n async contents(path?: string, params?: ContentParams): Promise<GitHubContent | GitHubContent[]> {\n const contentPath = path ? `${this.basePath}/contents/${path}` : `${this.basePath}/contents`;\n return this.request<GitHubContent | GitHubContent[]>(\n contentPath,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the raw text content of a file in this repository.\n *\n * Uses `Accept: application/vnd.github.raw+json` to retrieve the file directly\n * without base64 encoding.\n *\n * `GET /repos/{owner}/{repo}/contents/{filePath}`\n *\n * @param filePath - Path to the file (e.g., `'src/index.ts'`)\n * @param params - Optional: `ref` (branch, tag, or commit SHA)\n * @returns The raw file content as a string\n */\n async raw(filePath: string, params?: ContentParams): Promise<string> {\n return this.requestText(\n `${this.basePath}/contents/${filePath}`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the repository topics.\n *\n * `GET /repos/{owner}/{repo}/topics`\n *\n * @returns An array of topic strings\n */\n async topics(): Promise<string[]> {\n const data = await this.request<{ names: string[] }>(`${this.basePath}/topics`);\n return data.names;\n }\n\n /**\n * Fetches contributors to this repository.\n *\n * `GET /repos/{owner}/{repo}/contributors`\n *\n * @param params - Optional filters: `anon` (include anonymous contributors), `per_page`, `page`\n * @returns A paged response of contributors\n */\n async contributors(params?: PaginationParams & { anon?: boolean }): Promise<GitHubPagedResponse<{ login?: string; id?: number; contributions: number; avatar_url?: string; html_url?: string }>> {\n return this.requestList(\n `${this.basePath}/contributors`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","import type { GitHubOrganization, OrgMembersParams, CreateOrgRepoData } from '../domain/Organization';\nimport type { GitHubRepository, ReposParams } from '../domain/Repository';\nimport type { GitHubUser } from '../domain/User';\nimport type { GitHubPagedResponse } from '../domain/Pagination';\nimport { RepositoryResource } from './RepositoryResource';\n\n/** @internal */\nexport type RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<T>;\n\n/** @internal */\nexport type RequestListFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<GitHubPagedResponse<T>>;\n\n/** @internal */\nexport type RequestTextFn = (\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<string>;\n\n/** @internal */\nexport type RequestBodyFn = <T>(\n path: string,\n body: unknown,\n) => Promise<T>;\n\n/**\n * Represents a GitHub organization resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubOrganization>` so it can be awaited directly\n * to fetch the organization info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get organization info\n * const org = await gh.org('github');\n *\n * // Get repositories\n * const repos = await gh.org('github').repos({ type: 'public', per_page: 50 });\n *\n * // Navigate into a specific repository\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n *\n * // Get members\n * const members = await gh.org('github').members({ role: 'admin' });\n * ```\n */\nexport class OrganizationResource implements PromiseLike<GitHubOrganization> {\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n private readonly requestText: RequestTextFn,\n private readonly requestBody: RequestBodyFn,\n private readonly org: string,\n ) {}\n\n /**\n * Allows the resource to be awaited directly, resolving with the organization info.\n * Delegates to {@link OrganizationResource.get}.\n */\n then<TResult1 = GitHubOrganization, TResult2 = never>(\n onfulfilled?: ((value: GitHubOrganization) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the organization details.\n *\n * `GET /orgs/{org}`\n *\n * @returns The organization object\n */\n async get(): Promise<GitHubOrganization> {\n return this.request<GitHubOrganization>(`/orgs/${this.org}`);\n }\n\n /**\n * Fetches repositories belonging to this organization.\n *\n * `GET /orgs/{org}/repos`\n *\n * @param params - Optional filters: `type`, `sort`, `direction`, `per_page`, `page`\n * @returns A paged response of repositories\n */\n async repos(params?: ReposParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n return this.requestList<GitHubRepository>(\n `/orgs/${this.org}/repos`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given repository name within this organization.\n *\n * The returned resource can be awaited directly to fetch repository info,\n * or chained to access nested resources.\n *\n * @param name - The repository name (e.g., `'linguist'`)\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await gh.org('github').repo('linguist');\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n * const commits = await gh.org('github').repo('linguist').commits({ per_page: 10 });\n * ```\n */\n repo(name: string): RepositoryResource {\n return new RepositoryResource(\n this.request,\n this.requestList,\n this.requestText,\n this.org,\n name,\n );\n }\n\n /**\n * Fetches members of this organization.\n *\n * `GET /orgs/{org}/members`\n *\n * @param params - Optional filters: `role`, `filter`, `per_page`, `page`\n * @returns A paged response of users\n */\n async members(params?: OrgMembersParams): Promise<GitHubPagedResponse<GitHubUser>> {\n return this.requestList<GitHubUser>(\n `/orgs/${this.org}/members`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Creates a new repository in this organization.\n *\n * `POST /orgs/{org}/repos`\n *\n * @param data - Repository creation options. `name` is required.\n * @returns The newly created repository\n *\n * @example\n * ```typescript\n * const repo = await gh.org('my-org').createRepo({\n * name: 'my-new-repo',\n * description: 'My new repository',\n * private: true,\n * auto_init: true,\n * });\n * ```\n */\n async createRepo(data: CreateOrgRepoData): Promise<GitHubRepository> {\n return this.requestBody<GitHubRepository>(`/orgs/${this.org}/repos`, data);\n }\n}\n","import type { GitHubUser } from '../domain/User';\nimport type { GitHubRepository, ReposParams } from '../domain/Repository';\nimport type { GitHubPagedResponse } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn, RequestTextFn } from './OrganizationResource';\nimport { RepositoryResource } from './RepositoryResource';\n\n/**\n * Represents a GitHub user resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubUser>` so it can be awaited directly\n * to fetch user info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get user info\n * const user = await gh.user('octocat');\n *\n * // Get the user's public repositories\n * const repos = await gh.user('octocat').repos({ sort: 'updated' });\n *\n * // Navigate into a specific repository\n * const prs = await gh.user('octocat').repo('Hello-World').pullRequests();\n * ```\n */\nexport class UserResource implements PromiseLike<GitHubUser> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n private readonly requestText: RequestTextFn,\n private readonly login: string,\n ) {\n this.basePath = `/users/${login}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the user info.\n * Delegates to {@link UserResource.get}.\n */\n then<TResult1 = GitHubUser, TResult2 = never>(\n onfulfilled?: ((value: GitHubUser) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the user details.\n *\n * `GET /users/{username}`\n *\n * @returns The user object\n */\n async get(): Promise<GitHubUser> {\n return this.request<GitHubUser>(this.basePath);\n }\n\n /**\n * Fetches public repositories for this user.\n *\n * `GET /users/{username}/repos`\n *\n * @param params - Optional filters: `type`, `sort`, `direction`, `per_page`, `page`\n * @returns A paged response of repositories\n */\n async repos(params?: ReposParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n return this.requestList<GitHubRepository>(\n `${this.basePath}/repos`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given repository under this user,\n * providing access to all repository sub-resources.\n *\n * @param name - The repository name\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await gh.user('octocat').repo('Hello-World');\n * const content = await gh.user('octocat').repo('Hello-World').raw('README.md');\n * ```\n */\n repo(name: string): RepositoryResource {\n return new RepositoryResource(\n this.request,\n this.requestList,\n this.requestText,\n this.login,\n name,\n );\n }\n\n /**\n * Fetches the users this user is following.\n *\n * `GET /users/{username}/following`\n *\n * @returns A paged response of users\n */\n async following(params?: { per_page?: number; page?: number }): Promise<GitHubPagedResponse<GitHubUser>> {\n return this.requestList<GitHubUser>(\n `${this.basePath}/following`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the users following this user.\n *\n * `GET /users/{username}/followers`\n *\n * @returns A paged response of users\n */\n async followers(params?: { per_page?: number; page?: number }): Promise<GitHubPagedResponse<GitHubUser>> {\n return this.requestList<GitHubUser>(\n `${this.basePath}/followers`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","import { Security } from './security/Security';\nimport { GitHubApiError } from './errors/GitHubApiError';\nimport { OrganizationResource } from './resources/OrganizationResource';\nimport type { RequestFn, RequestListFn, RequestTextFn, RequestBodyFn } from './resources/OrganizationResource';\nimport { RepositoryResource } from './resources/RepositoryResource';\nimport { UserResource } from './resources/UserResource';\nimport type { GitHubUser } from './domain/User';\nimport type { GitHubRepository, SearchReposParams } from './domain/Repository';\nimport type { GitHubPagedResponse } from './domain/Pagination';\n\n/**\n * Payload emitted on every HTTP request made by {@link GitHubClient}.\n */\nexport interface RequestEvent {\n /** Full URL that was requested */\n url: string;\n /** HTTP method used */\n method: 'GET' | 'POST';\n /** Timestamp when the request started */\n startedAt: Date;\n /** Timestamp when the request finished (success or error) */\n finishedAt: Date;\n /** Total duration in milliseconds */\n durationMs: number;\n /** HTTP status code returned by the server, if a response was received */\n statusCode?: number;\n /** Error thrown, if the request failed */\n error?: Error;\n}\n\n/** Map of supported client events to their callback signatures */\nexport interface GitHubClientEvents {\n request: (event: RequestEvent) => void;\n}\n\n/**\n * Constructor options for {@link GitHubClient}.\n */\nexport interface GitHubClientOptions {\n /** A GitHub personal access token (`ghp_...`), OAuth token, or GitHub App installation token */\n token: string;\n /**\n * The base URL of the GitHub API.\n * Defaults to `'https://api.github.com'`.\n * Override for GitHub Enterprise Server (e.g., `'https://github.mycompany.com/api/v3'`).\n */\n apiUrl?: string;\n}\n\n/**\n * GitHub REST API search result envelope.\n * @internal\n */\ninterface SearchResult<T> {\n total_count: number;\n incomplete_results: boolean;\n items: T[];\n}\n\n/**\n * Main entry point for the GitHub REST API client.\n *\n * @example\n * ```typescript\n * const gh = new GitHubClient({ token: 'ghp_myPersonalAccessToken' });\n *\n * const me = await gh.currentUser();\n * const user = await gh.user('octocat');\n * const repos = await gh.user('octocat').repos({ sort: 'updated' });\n * const org = await gh.org('github');\n * const repo = await gh.repo('octocat', 'Hello-World');\n * const prs = await gh.repo('octocat', 'Hello-World').pullRequests({ state: 'open' });\n * const commits = await gh.repo('octocat', 'Hello-World').commits({ per_page: 10 });\n * const results = await gh.searchRepos({ q: 'language:typescript stars:>1000' });\n * ```\n */\nexport class GitHubClient {\n private readonly security: Security;\n private readonly listeners: Map<keyof GitHubClientEvents, GitHubClientEvents[keyof GitHubClientEvents][]> = new Map();\n\n /**\n * @param options - Authentication and connection options\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor({ token, apiUrl }: GitHubClientOptions) {\n this.security = new Security(token, apiUrl);\n }\n\n /**\n * Subscribes to a client event.\n *\n * @example\n * ```typescript\n * gh.on('request', (event) => {\n * console.log(`${event.method} ${event.url} — ${event.durationMs}ms`);\n * if (event.error) console.error('Request failed:', event.error);\n * });\n * ```\n */\n on<K extends keyof GitHubClientEvents>(event: K, callback: GitHubClientEvents[K]): this {\n const callbacks = this.listeners.get(event) ?? [];\n callbacks.push(callback);\n this.listeners.set(event, callbacks);\n return this;\n }\n\n private emit<K extends keyof GitHubClientEvents>(\n event: K,\n payload: Parameters<GitHubClientEvents[K]>[0],\n ): void {\n const callbacks = this.listeners.get(event) ?? [];\n for (const cb of callbacks) {\n (cb as (p: typeof payload) => void)(payload);\n }\n }\n\n /**\n * Performs an authenticated GET request returning a single JSON object.\n * @internal\n */\n private async request<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n options?: { headers?: Record<string, string> },\n ): Promise<T> {\n const base = `${this.security.getApiUrl()}${path}`;\n const url = buildUrl(base, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const headers = options?.headers ?? this.security.getHeaders();\n const response = await fetch(url, { headers });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as T;\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return data;\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n /**\n * Performs an authenticated GET request returning a paginated list.\n * Parses the `Link` response header to determine if more pages exist.\n * @internal\n */\n private async requestList<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<GitHubPagedResponse<T>> {\n const base = `${this.security.getApiUrl()}${path}`;\n const url = buildUrl(base, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, { headers: this.security.getHeaders() });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as T[];\n const linkHeader = response.headers.get('Link');\n const nextPage = parseNextPage(linkHeader);\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return {\n values: data,\n hasNextPage: nextPage !== undefined,\n nextPage,\n };\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n /**\n * Performs a GET request returning raw text content.\n * Uses `Accept: application/vnd.github.raw+json` to retrieve file content directly.\n * @internal\n */\n private async requestText(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<string> {\n const base = `${this.security.getApiUrl()}${path}`;\n const url = buildUrl(base, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, { headers: this.security.getRawHeaders() });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const text = await response.text();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return text;\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n private makeRequestFn(): RequestFn {\n return <T>(path: string, params?: Record<string, string | number | boolean>) =>\n this.request<T>(path, params);\n }\n\n private makeRequestListFn(): RequestListFn {\n return <T>(path: string, params?: Record<string, string | number | boolean>) =>\n this.requestList<T>(path, params);\n }\n\n private makeRequestTextFn(): RequestTextFn {\n return (path: string, params?: Record<string, string | number | boolean>) =>\n this.requestText(path, params);\n }\n\n private async requestPost<T>(path: string, body: unknown): Promise<T> {\n const url = `${this.security.getApiUrl()}${path}`;\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.security.getHeaders(),\n body: JSON.stringify(body),\n });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as T;\n this.emit('request', { url, method: 'POST', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return data;\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'POST', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n private makeRequestBodyFn(): RequestBodyFn {\n return <T>(path: string, body: unknown) =>\n this.requestPost<T>(path, body);\n }\n\n /**\n * Fetches the authenticated user's profile.\n *\n * `GET /user`\n *\n * @returns The authenticated user object\n *\n * @example\n * ```typescript\n * const me = await gh.currentUser();\n * console.log(me.login); // 'octocat'\n * ```\n */\n async currentUser(): Promise<GitHubUser> {\n return this.request<GitHubUser>('/user');\n }\n\n /**\n * Returns a {@link UserResource} for a given GitHub login, providing access\n * to user data and their repositories.\n *\n * The returned resource can be awaited directly to fetch user info,\n * or chained to access nested resources.\n *\n * @param login - The user's login name (e.g., `'octocat'`)\n * @returns A chainable user resource\n *\n * @example\n * ```typescript\n * const user = await gh.user('octocat');\n * const repos = await gh.user('octocat').repos({ sort: 'updated' });\n * const pr = await gh.user('octocat').repo('Hello-World').pullRequest(1).files();\n * ```\n */\n user(login: string): UserResource {\n return new UserResource(\n this.makeRequestFn(),\n this.makeRequestListFn(),\n this.makeRequestTextFn(),\n login,\n );\n }\n\n /**\n * Returns an {@link OrganizationResource} for a given GitHub organization, providing\n * access to organization data and its repositories.\n *\n * The returned resource can be awaited directly to fetch organization info,\n * or chained to access nested resources.\n *\n * @param name - The organization's login name (e.g., `'github'`)\n * @returns A chainable organization resource\n *\n * @example\n * ```typescript\n * const org = await gh.org('github');\n * const repos = await gh.org('github').repos({ type: 'public' });\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n * ```\n */\n org(name: string): OrganizationResource {\n return new OrganizationResource(\n this.makeRequestFn(),\n this.makeRequestListFn(),\n this.makeRequestTextFn(),\n this.makeRequestBodyFn(),\n name,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given owner and repository name.\n *\n * Shortcut that works for both user repositories and organization repositories.\n *\n * @param owner - The owner login (user or organization)\n * @param name - The repository name\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await gh.repo('octocat', 'Hello-World');\n * const prs = await gh.repo('octocat', 'Hello-World').pullRequests();\n * ```\n */\n repo(owner: string, name: string): RepositoryResource {\n return new RepositoryResource(\n this.makeRequestFn(),\n this.makeRequestListFn(),\n this.makeRequestTextFn(),\n owner,\n name,\n );\n }\n\n /**\n * Searches for repositories using GitHub's search syntax.\n *\n * `GET /search/repositories`\n *\n * @param params - Search query and optional filters. `q` is required.\n * @returns A paged response of repositories with `totalCount`\n *\n * @example\n * ```typescript\n * const results = await gh.searchRepos({ q: 'language:typescript stars:>1000', sort: 'stars' });\n * console.log(`Found ${results.totalCount} repositories`);\n * ```\n */\n async searchRepos(params: SearchReposParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n const base = `${this.security.getApiUrl()}/search/repositories`;\n const url = buildUrl(base, params as unknown as Record<string, string | number | boolean>);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, { headers: this.security.getHeaders() });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as SearchResult<GitHubRepository>;\n const linkHeader = response.headers.get('Link');\n const nextPage = parseNextPage(linkHeader);\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return {\n values: data.items,\n hasNextPage: nextPage !== undefined,\n nextPage,\n totalCount: data.total_count,\n };\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n}\n\n/**\n * Appends query parameters to a URL string, skipping `undefined` values.\n * @internal\n */\nfunction buildUrl(base: string, params?: Record<string, string | number | boolean>): string {\n if (!params) return base;\n const entries = Object.entries(params).filter(([, v]) => v !== undefined);\n if (entries.length === 0) return base;\n const search = new URLSearchParams(entries.map(([k, v]) => [k, String(v)]));\n return `${base}?${search.toString()}`;\n}\n\n/**\n * Parses the `Link` response header to extract the next page number.\n *\n * GitHub Link header format:\n * `<https://api.github.com/...?page=2>; rel=\"next\", <https://api.github.com/...?page=5>; rel=\"last\"`\n *\n * @internal\n */\nfunction parseNextPage(linkHeader: string | null): number | undefined {\n if (!linkHeader) return undefined;\n const match = linkHeader.match(/<[^>]*[?&]page=(\\d+)[^>]*>;\\s*rel=\"next\"/);\n return match ? parseInt(match[1], 10) : undefined;\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -499,10 +499,11 @@ var RepositoryResource = class {
|
|
|
499
499
|
// src/resources/OrganizationResource.ts
|
|
500
500
|
var OrganizationResource = class {
|
|
501
501
|
/** @internal */
|
|
502
|
-
constructor(request, requestList, requestText, org) {
|
|
502
|
+
constructor(request, requestList, requestText, requestBody, org) {
|
|
503
503
|
this.request = request;
|
|
504
504
|
this.requestList = requestList;
|
|
505
505
|
this.requestText = requestText;
|
|
506
|
+
this.requestBody = requestBody;
|
|
506
507
|
this.org = org;
|
|
507
508
|
}
|
|
508
509
|
/**
|
|
@@ -575,6 +576,27 @@ var OrganizationResource = class {
|
|
|
575
576
|
params
|
|
576
577
|
);
|
|
577
578
|
}
|
|
579
|
+
/**
|
|
580
|
+
* Creates a new repository in this organization.
|
|
581
|
+
*
|
|
582
|
+
* `POST /orgs/{org}/repos`
|
|
583
|
+
*
|
|
584
|
+
* @param data - Repository creation options. `name` is required.
|
|
585
|
+
* @returns The newly created repository
|
|
586
|
+
*
|
|
587
|
+
* @example
|
|
588
|
+
* ```typescript
|
|
589
|
+
* const repo = await gh.org('my-org').createRepo({
|
|
590
|
+
* name: 'my-new-repo',
|
|
591
|
+
* description: 'My new repository',
|
|
592
|
+
* private: true,
|
|
593
|
+
* auto_init: true,
|
|
594
|
+
* });
|
|
595
|
+
* ```
|
|
596
|
+
*/
|
|
597
|
+
async createRepo(data) {
|
|
598
|
+
return this.requestBody(`/orgs/${this.org}/repos`, data);
|
|
599
|
+
}
|
|
578
600
|
};
|
|
579
601
|
|
|
580
602
|
// src/resources/UserResource.ts
|
|
@@ -791,6 +813,32 @@ var GitHubClient = class {
|
|
|
791
813
|
makeRequestTextFn() {
|
|
792
814
|
return (path, params) => this.requestText(path, params);
|
|
793
815
|
}
|
|
816
|
+
async requestPost(path, body) {
|
|
817
|
+
const url = `${this.security.getApiUrl()}${path}`;
|
|
818
|
+
const startedAt = /* @__PURE__ */ new Date();
|
|
819
|
+
let statusCode;
|
|
820
|
+
try {
|
|
821
|
+
const response = await fetch(url, {
|
|
822
|
+
method: "POST",
|
|
823
|
+
headers: this.security.getHeaders(),
|
|
824
|
+
body: JSON.stringify(body)
|
|
825
|
+
});
|
|
826
|
+
statusCode = response.status;
|
|
827
|
+
if (!response.ok) {
|
|
828
|
+
throw new GitHubApiError(response.status, response.statusText);
|
|
829
|
+
}
|
|
830
|
+
const data = await response.json();
|
|
831
|
+
this.emit("request", { url, method: "POST", startedAt, finishedAt: /* @__PURE__ */ new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });
|
|
832
|
+
return data;
|
|
833
|
+
} catch (err) {
|
|
834
|
+
const finishedAt = /* @__PURE__ */ new Date();
|
|
835
|
+
this.emit("request", { url, method: "POST", startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });
|
|
836
|
+
throw err;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
makeRequestBodyFn() {
|
|
840
|
+
return (path, body) => this.requestPost(path, body);
|
|
841
|
+
}
|
|
794
842
|
/**
|
|
795
843
|
* Fetches the authenticated user's profile.
|
|
796
844
|
*
|
|
@@ -854,6 +902,7 @@ var GitHubClient = class {
|
|
|
854
902
|
this.makeRequestFn(),
|
|
855
903
|
this.makeRequestListFn(),
|
|
856
904
|
this.makeRequestTextFn(),
|
|
905
|
+
this.makeRequestBodyFn(),
|
|
857
906
|
name
|
|
858
907
|
);
|
|
859
908
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/security/Security.ts","../src/errors/GitHubApiError.ts","../src/resources/PullRequestResource.ts","../src/resources/CommitResource.ts","../src/resources/RepositoryResource.ts","../src/resources/OrganizationResource.ts","../src/resources/UserResource.ts","../src/GitHubClient.ts"],"sourcesContent":["/**\n * Handles Bearer token authentication for GitHub REST API requests.\n *\n * @example\n * ```typescript\n * const security = new Security('ghp_myPersonalAccessToken');\n *\n * const headers = security.getHeaders();\n * // {\n * // Authorization: 'Bearer ghp_myPersonalAccessToken',\n * // Accept: 'application/vnd.github+json',\n * // 'Content-Type': 'application/json',\n * // 'X-GitHub-Api-Version': '2022-11-28',\n * // }\n * ```\n */\nexport class Security {\n private readonly apiUrl: string;\n private readonly token: string;\n\n /**\n * Creates a new Security instance with a GitHub personal access token.\n *\n * @param token - A GitHub personal access token (e.g., `ghp_...`) or OAuth token\n * @param apiUrl - The base URL of the GitHub API. Defaults to `'https://api.github.com'`.\n * Must be a valid URL; throws if it cannot be parsed.\n *\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor(token: string, apiUrl: string = 'https://api.github.com') {\n if (!URL.canParse(apiUrl)) {\n throw new TypeError(`Invalid apiUrl: \"${apiUrl}\" is not a valid URL`);\n }\n this.apiUrl = apiUrl.replace(/\\/$/, '');\n this.token = token;\n }\n\n /**\n * Returns the base URL of the GitHub API, without a trailing slash.\n *\n * @returns The API base URL\n */\n getApiUrl(): string {\n return this.apiUrl;\n }\n\n /**\n * Returns the value of the `Authorization` header for Bearer authentication.\n *\n * @returns The Authorization header value in the format `Bearer <token>`\n */\n getAuthorizationHeader(): string {\n return `Bearer ${this.token}`;\n }\n\n /**\n * Returns the full set of HTTP headers required for authenticated GitHub API requests.\n *\n * @returns An object containing `Authorization`, `Accept`, `Content-Type`, and `X-GitHub-Api-Version` headers\n */\n getHeaders(): Record<string, string> {\n return {\n Authorization: `Bearer ${this.token}`,\n Accept: 'application/vnd.github+json',\n 'Content-Type': 'application/json',\n 'X-GitHub-Api-Version': '2022-11-28',\n };\n }\n\n /**\n * Returns headers for raw file content requests.\n *\n * @returns Headers with `Accept: application/vnd.github.raw+json`\n */\n getRawHeaders(): Record<string, string> {\n return {\n ...this.getHeaders(),\n Accept: 'application/vnd.github.raw+json',\n };\n }\n}\n","/**\n * Thrown when the GitHub REST API returns a non-2xx response.\n *\n * @example\n * ```typescript\n * import { GitHubApiError } from 'github-api-client';\n *\n * try {\n * await gh.user('nonexistent-user-xyz');\n * } catch (err) {\n * if (err instanceof GitHubApiError) {\n * console.log(err.status); // 404\n * console.log(err.statusText); // 'Not Found'\n * console.log(err.message); // 'GitHub API error: 404 Not Found'\n * }\n * }\n * ```\n */\nexport class GitHubApiError extends Error {\n /** HTTP status code (e.g. `404`, `401`, `403`, `422`) */\n readonly status: number;\n /** HTTP status text (e.g. `'Not Found'`, `'Unauthorized'`) */\n readonly statusText: string;\n\n constructor(status: number, statusText: string) {\n super(`GitHub API error: ${status} ${statusText}`);\n this.name = 'GitHubApiError';\n this.status = status;\n this.statusText = statusText;\n }\n}\n","import type { GitHubPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { GitHubReview, GitHubReviewComment, ReviewsParams, ReviewCommentsParams } from '../domain/Review';\nimport type { GitHubPullRequestFile, PullRequestFilesParams } from '../domain/PullRequestFile';\nimport type { GitHubCommit } from '../domain/Commit';\nimport type { GitHubPagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn } from './OrganizationResource';\n\n/**\n * Represents a GitHub pull request resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubPullRequest>` so it can be awaited directly\n * to fetch the pull request info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get pull request info\n * const pr = await gh.org('github').repo('linguist').pullRequest(42);\n *\n * // Get commits in this pull request\n * const commits = await gh.org('github').repo('linguist').pullRequest(42).commits();\n *\n * // Get changed files\n * const files = await gh.org('github').repo('linguist').pullRequest(42).files();\n *\n * // Get reviews\n * const reviews = await gh.org('github').repo('linguist').pullRequest(42).reviews();\n *\n * // Get review comments (inline diff comments)\n * const comments = await gh.org('github').repo('linguist').pullRequest(42).reviewComments();\n * ```\n */\nexport class PullRequestResource implements PromiseLike<GitHubPullRequest> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n owner: string,\n repo: string,\n pullNumber: number,\n ) {\n this.basePath = `/repos/${owner}/${repo}/pulls/${pullNumber}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the pull request info.\n * Delegates to {@link PullRequestResource.get}.\n */\n then<TResult1 = GitHubPullRequest, TResult2 = never>(\n onfulfilled?: ((value: GitHubPullRequest) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the pull request details.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}`\n *\n * @returns The pull request object\n */\n async get(): Promise<GitHubPullRequest> {\n return this.request<GitHubPullRequest>(this.basePath);\n }\n\n /**\n * Fetches the commits included in this pull request.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/commits`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of commits\n */\n async commits(params?: PaginationParams): Promise<GitHubPagedResponse<GitHubCommit>> {\n return this.requestList<GitHubCommit>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the files changed by this pull request.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/files`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of changed files\n */\n async files(params?: PullRequestFilesParams): Promise<GitHubPagedResponse<GitHubPullRequestFile>> {\n return this.requestList<GitHubPullRequestFile>(\n `${this.basePath}/files`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the reviews submitted on this pull request.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of reviews\n */\n async reviews(params?: ReviewsParams): Promise<GitHubPagedResponse<GitHubReview>> {\n return this.requestList<GitHubReview>(\n `${this.basePath}/reviews`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the inline review comments on this pull request's diff.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/comments`\n *\n * @param params - Optional filters: `sort`, `direction`, `since`, `per_page`, `page`\n * @returns A paged response of review comments\n */\n async reviewComments(params?: ReviewCommentsParams): Promise<GitHubPagedResponse<GitHubReviewComment>> {\n return this.requestList<GitHubReviewComment>(\n `${this.basePath}/comments`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Checks whether the pull request has been merged.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/merge`\n *\n * @returns `true` if merged (HTTP 204), `false` if not merged (HTTP 404)\n */\n async isMerged(): Promise<boolean> {\n try {\n await this.request<never>(`${this.basePath}/merge`);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import type { GitHubCommit } from '../domain/Commit';\nimport type { GitHubCommitStatus, GitHubCombinedStatus, GitHubCheckRun, CommitStatusesParams, CheckRunsParams } from '../domain/CommitStatus';\nimport type { GitHubPagedResponse } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn } from './OrganizationResource';\n\n/**\n * Represents a GitHub commit resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubCommit>` so it can be awaited directly\n * to fetch the commit info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get commit info (includes stats and files)\n * const commit = await gh.org('github').repo('linguist').commit('abc123');\n *\n * // Get CI/CD statuses for this commit\n * const statuses = await gh.org('github').repo('linguist').commit('abc123').statuses();\n *\n * // Get the combined (aggregated) status\n * const combined = await gh.org('github').repo('linguist').commit('abc123').combinedStatus();\n *\n * // Get GitHub Actions check runs\n * const checks = await gh.org('github').repo('linguist').commit('abc123').checkRuns();\n * ```\n */\nexport class CommitResource implements PromiseLike<GitHubCommit> {\n private readonly basePath: string;\n private readonly ref: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n owner: string,\n repo: string,\n ref: string,\n ) {\n this.basePath = `/repos/${owner}/${repo}/commits/${ref}`;\n this.ref = ref;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the commit info.\n * Delegates to {@link CommitResource.get}.\n */\n then<TResult1 = GitHubCommit, TResult2 = never>(\n onfulfilled?: ((value: GitHubCommit) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the commit details, including stats and changed files.\n *\n * `GET /repos/{owner}/{repo}/commits/{ref}`\n *\n * @returns The commit object with stats and files\n */\n async get(): Promise<GitHubCommit> {\n return this.request<GitHubCommit>(this.basePath);\n }\n\n /**\n * Fetches the individual commit statuses (from CI/CD systems via the Statuses API).\n *\n * `GET /repos/{owner}/{repo}/statuses/{sha}`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of commit statuses\n */\n async statuses(params?: CommitStatusesParams): Promise<GitHubPagedResponse<GitHubCommitStatus>> {\n const repoPath = this.basePath.replace(`/commits/${this.ref}`, '');\n return this.requestList<GitHubCommitStatus>(\n `${repoPath}/statuses/${this.ref}`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the combined commit status — an aggregation of all statuses for this ref.\n *\n * `GET /repos/{owner}/{repo}/commits/{ref}/status`\n *\n * @returns The combined status object\n */\n async combinedStatus(): Promise<GitHubCombinedStatus> {\n return this.request<GitHubCombinedStatus>(`${this.basePath}/status`);\n }\n\n /**\n * Fetches GitHub Actions check runs for this commit.\n *\n * `GET /repos/{owner}/{repo}/commits/{ref}/check-runs`\n *\n * @param params - Optional filters: `check_name`, `status`, `app_id`, `per_page`, `page`\n * @returns A paged response of check runs\n */\n async checkRuns(params?: CheckRunsParams): Promise<GitHubPagedResponse<GitHubCheckRun>> {\n const raw = await this.request<{ check_runs: GitHubCheckRun[] }>(\n `${this.basePath}/check-runs`,\n params as Record<string, string | number | boolean>,\n );\n return {\n values: raw.check_runs,\n hasNextPage: false,\n };\n }\n}\n","import type { GitHubRepository, ReposParams, ForksParams } from '../domain/Repository';\nimport type { GitHubPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { GitHubCommit, CommitsParams } from '../domain/Commit';\nimport type { GitHubBranch, BranchesParams } from '../domain/Branch';\nimport type { GitHubTag, TagsParams } from '../domain/Tag';\nimport type { GitHubRelease, ReleasesParams } from '../domain/Release';\nimport type { GitHubWebhook, WebhooksParams } from '../domain/Webhook';\nimport type { GitHubContent, ContentParams } from '../domain/Content';\nimport type { GitHubPagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn, RequestTextFn } from './OrganizationResource';\nimport { PullRequestResource } from './PullRequestResource';\nimport { CommitResource } from './CommitResource';\n\n/**\n * Represents a GitHub repository resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubRepository>` so it can be awaited directly\n * to fetch repository info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get repository info\n * const repo = await gh.org('github').repo('linguist');\n *\n * // Get pull requests\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n *\n * // Navigate into a specific pull request\n * const files = await gh.org('github').repo('linguist').pullRequest(42).files();\n *\n * // Get commits\n * const commits = await gh.org('github').repo('linguist').commits({ per_page: 10 });\n *\n * // Get raw file content\n * const content = await gh.org('github').repo('linguist').raw('README.md');\n * ```\n */\nexport class RepositoryResource implements PromiseLike<GitHubRepository> {\n private readonly owner: string;\n private readonly repo: string;\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n private readonly requestText: RequestTextFn,\n owner: string,\n repo: string,\n ) {\n this.owner = owner;\n this.repo = repo;\n this.basePath = `/repos/${owner}/${repo}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the repository info.\n * Delegates to {@link RepositoryResource.get}.\n */\n then<TResult1 = GitHubRepository, TResult2 = never>(\n onfulfilled?: ((value: GitHubRepository) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the repository details.\n *\n * `GET /repos/{owner}/{repo}`\n *\n * @returns The repository object\n */\n async get(): Promise<GitHubRepository> {\n return this.request<GitHubRepository>(this.basePath);\n }\n\n /**\n * Fetches pull requests for this repository.\n *\n * `GET /repos/{owner}/{repo}/pulls`\n *\n * @param params - Optional filters: `state`, `head`, `base`, `sort`, `direction`, `per_page`, `page`\n * @returns A paged response of pull requests\n */\n async pullRequests(params?: PullRequestsParams): Promise<GitHubPagedResponse<GitHubPullRequest>> {\n return this.requestList<GitHubPullRequest>(\n `${this.basePath}/pulls`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link PullRequestResource} for a given pull request number.\n *\n * The returned resource can be awaited directly to fetch pull request info,\n * or chained to access nested resources.\n *\n * @param pullNumber - The pull request number (not the ID)\n * @returns A chainable pull request resource\n *\n * @example\n * ```typescript\n * const pr = await gh.org('github').repo('linguist').pullRequest(42);\n * const files = await gh.org('github').repo('linguist').pullRequest(42).files();\n * const reviews = await gh.org('github').repo('linguist').pullRequest(42).reviews();\n * ```\n */\n pullRequest(pullNumber: number): PullRequestResource {\n return new PullRequestResource(\n this.request,\n this.requestList,\n this.owner,\n this.repo,\n pullNumber,\n );\n }\n\n /**\n * Fetches commits for this repository.\n *\n * `GET /repos/{owner}/{repo}/commits`\n *\n * @param params - Optional filters: `sha`, `path`, `author`, `since`, `until`, `per_page`, `page`\n * @returns A paged response of commits\n */\n async commits(params?: CommitsParams): Promise<GitHubPagedResponse<GitHubCommit>> {\n return this.requestList<GitHubCommit>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link CommitResource} for a given commit ref (SHA, branch, or tag).\n *\n * The returned resource can be awaited directly to fetch commit info,\n * or chained to access nested resources.\n *\n * @param ref - Commit SHA, branch name, or tag name\n * @returns A chainable commit resource\n *\n * @example\n * ```typescript\n * const commit = await gh.org('github').repo('linguist').commit('abc123');\n * const statuses = await gh.org('github').repo('linguist').commit('abc123').statuses();\n * ```\n */\n commit(ref: string): CommitResource {\n return new CommitResource(\n this.request,\n this.requestList,\n this.owner,\n this.repo,\n ref,\n );\n }\n\n /**\n * Fetches branches for this repository.\n *\n * `GET /repos/{owner}/{repo}/branches`\n *\n * @param params - Optional filters: `protected`, `per_page`, `page`\n * @returns A paged response of branches\n */\n async branches(params?: BranchesParams): Promise<GitHubPagedResponse<GitHubBranch>> {\n return this.requestList<GitHubBranch>(\n `${this.basePath}/branches`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches a specific branch by name.\n *\n * `GET /repos/{owner}/{repo}/branches/{branch}`\n *\n * @param name - The branch name (e.g., `'main'`)\n * @returns The branch object\n */\n async branch(name: string): Promise<GitHubBranch> {\n return this.request<GitHubBranch>(`${this.basePath}/branches/${encodeURIComponent(name)}`);\n }\n\n /**\n * Fetches tags for this repository.\n *\n * `GET /repos/{owner}/{repo}/tags`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of tags\n */\n async tags(params?: TagsParams): Promise<GitHubPagedResponse<GitHubTag>> {\n return this.requestList<GitHubTag>(\n `${this.basePath}/tags`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches releases for this repository.\n *\n * `GET /repos/{owner}/{repo}/releases`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of releases\n */\n async releases(params?: ReleasesParams): Promise<GitHubPagedResponse<GitHubRelease>> {\n return this.requestList<GitHubRelease>(\n `${this.basePath}/releases`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the latest published release for this repository.\n *\n * `GET /repos/{owner}/{repo}/releases/latest`\n *\n * @returns The latest release object\n */\n async latestRelease(): Promise<GitHubRelease> {\n return this.request<GitHubRelease>(`${this.basePath}/releases/latest`);\n }\n\n /**\n * Fetches the forks of this repository.\n *\n * `GET /repos/{owner}/{repo}/forks`\n *\n * @param params - Optional filters: `sort`, `per_page`, `page`\n * @returns A paged response of forked repositories\n */\n async forks(params?: ForksParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n return this.requestList<GitHubRepository>(\n `${this.basePath}/forks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches webhooks configured on this repository.\n *\n * `GET /repos/{owner}/{repo}/hooks`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of webhooks\n */\n async webhooks(params?: WebhooksParams): Promise<GitHubPagedResponse<GitHubWebhook>> {\n return this.requestList<GitHubWebhook>(\n `${this.basePath}/hooks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the contents of a file or directory in this repository.\n *\n * `GET /repos/{owner}/{repo}/contents/{path}`\n *\n * Returns a single {@link GitHubContent} for files, or an array for directories.\n *\n * @param path - Path to the file or directory (e.g., `'src/index.ts'` or `'src'`). Omit for root.\n * @param params - Optional: `ref` (branch, tag, or commit SHA)\n * @returns File content object or array of directory entries\n */\n async contents(path?: string, params?: ContentParams): Promise<GitHubContent | GitHubContent[]> {\n const contentPath = path ? `${this.basePath}/contents/${path}` : `${this.basePath}/contents`;\n return this.request<GitHubContent | GitHubContent[]>(\n contentPath,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the raw text content of a file in this repository.\n *\n * Uses `Accept: application/vnd.github.raw+json` to retrieve the file directly\n * without base64 encoding.\n *\n * `GET /repos/{owner}/{repo}/contents/{filePath}`\n *\n * @param filePath - Path to the file (e.g., `'src/index.ts'`)\n * @param params - Optional: `ref` (branch, tag, or commit SHA)\n * @returns The raw file content as a string\n */\n async raw(filePath: string, params?: ContentParams): Promise<string> {\n return this.requestText(\n `${this.basePath}/contents/${filePath}`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the repository topics.\n *\n * `GET /repos/{owner}/{repo}/topics`\n *\n * @returns An array of topic strings\n */\n async topics(): Promise<string[]> {\n const data = await this.request<{ names: string[] }>(`${this.basePath}/topics`);\n return data.names;\n }\n\n /**\n * Fetches contributors to this repository.\n *\n * `GET /repos/{owner}/{repo}/contributors`\n *\n * @param params - Optional filters: `anon` (include anonymous contributors), `per_page`, `page`\n * @returns A paged response of contributors\n */\n async contributors(params?: PaginationParams & { anon?: boolean }): Promise<GitHubPagedResponse<{ login?: string; id?: number; contributions: number; avatar_url?: string; html_url?: string }>> {\n return this.requestList(\n `${this.basePath}/contributors`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","import type { GitHubOrganization, OrgMembersParams } from '../domain/Organization';\nimport type { GitHubRepository, ReposParams } from '../domain/Repository';\nimport type { GitHubUser } from '../domain/User';\nimport type { GitHubPagedResponse } from '../domain/Pagination';\nimport { RepositoryResource } from './RepositoryResource';\n\n/** @internal */\nexport type RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<T>;\n\n/** @internal */\nexport type RequestListFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<GitHubPagedResponse<T>>;\n\n/** @internal */\nexport type RequestTextFn = (\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<string>;\n\n/**\n * Represents a GitHub organization resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubOrganization>` so it can be awaited directly\n * to fetch the organization info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get organization info\n * const org = await gh.org('github');\n *\n * // Get repositories\n * const repos = await gh.org('github').repos({ type: 'public', per_page: 50 });\n *\n * // Navigate into a specific repository\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n *\n * // Get members\n * const members = await gh.org('github').members({ role: 'admin' });\n * ```\n */\nexport class OrganizationResource implements PromiseLike<GitHubOrganization> {\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n private readonly requestText: RequestTextFn,\n private readonly org: string,\n ) {}\n\n /**\n * Allows the resource to be awaited directly, resolving with the organization info.\n * Delegates to {@link OrganizationResource.get}.\n */\n then<TResult1 = GitHubOrganization, TResult2 = never>(\n onfulfilled?: ((value: GitHubOrganization) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the organization details.\n *\n * `GET /orgs/{org}`\n *\n * @returns The organization object\n */\n async get(): Promise<GitHubOrganization> {\n return this.request<GitHubOrganization>(`/orgs/${this.org}`);\n }\n\n /**\n * Fetches repositories belonging to this organization.\n *\n * `GET /orgs/{org}/repos`\n *\n * @param params - Optional filters: `type`, `sort`, `direction`, `per_page`, `page`\n * @returns A paged response of repositories\n */\n async repos(params?: ReposParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n return this.requestList<GitHubRepository>(\n `/orgs/${this.org}/repos`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given repository name within this organization.\n *\n * The returned resource can be awaited directly to fetch repository info,\n * or chained to access nested resources.\n *\n * @param name - The repository name (e.g., `'linguist'`)\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await gh.org('github').repo('linguist');\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n * const commits = await gh.org('github').repo('linguist').commits({ per_page: 10 });\n * ```\n */\n repo(name: string): RepositoryResource {\n return new RepositoryResource(\n this.request,\n this.requestList,\n this.requestText,\n this.org,\n name,\n );\n }\n\n /**\n * Fetches members of this organization.\n *\n * `GET /orgs/{org}/members`\n *\n * @param params - Optional filters: `role`, `filter`, `per_page`, `page`\n * @returns A paged response of users\n */\n async members(params?: OrgMembersParams): Promise<GitHubPagedResponse<GitHubUser>> {\n return this.requestList<GitHubUser>(\n `/orgs/${this.org}/members`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","import type { GitHubUser } from '../domain/User';\nimport type { GitHubRepository, ReposParams } from '../domain/Repository';\nimport type { GitHubPagedResponse } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn, RequestTextFn } from './OrganizationResource';\nimport { RepositoryResource } from './RepositoryResource';\n\n/**\n * Represents a GitHub user resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubUser>` so it can be awaited directly\n * to fetch user info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get user info\n * const user = await gh.user('octocat');\n *\n * // Get the user's public repositories\n * const repos = await gh.user('octocat').repos({ sort: 'updated' });\n *\n * // Navigate into a specific repository\n * const prs = await gh.user('octocat').repo('Hello-World').pullRequests();\n * ```\n */\nexport class UserResource implements PromiseLike<GitHubUser> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n private readonly requestText: RequestTextFn,\n private readonly login: string,\n ) {\n this.basePath = `/users/${login}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the user info.\n * Delegates to {@link UserResource.get}.\n */\n then<TResult1 = GitHubUser, TResult2 = never>(\n onfulfilled?: ((value: GitHubUser) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the user details.\n *\n * `GET /users/{username}`\n *\n * @returns The user object\n */\n async get(): Promise<GitHubUser> {\n return this.request<GitHubUser>(this.basePath);\n }\n\n /**\n * Fetches public repositories for this user.\n *\n * `GET /users/{username}/repos`\n *\n * @param params - Optional filters: `type`, `sort`, `direction`, `per_page`, `page`\n * @returns A paged response of repositories\n */\n async repos(params?: ReposParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n return this.requestList<GitHubRepository>(\n `${this.basePath}/repos`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given repository under this user,\n * providing access to all repository sub-resources.\n *\n * @param name - The repository name\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await gh.user('octocat').repo('Hello-World');\n * const content = await gh.user('octocat').repo('Hello-World').raw('README.md');\n * ```\n */\n repo(name: string): RepositoryResource {\n return new RepositoryResource(\n this.request,\n this.requestList,\n this.requestText,\n this.login,\n name,\n );\n }\n\n /**\n * Fetches the users this user is following.\n *\n * `GET /users/{username}/following`\n *\n * @returns A paged response of users\n */\n async following(params?: { per_page?: number; page?: number }): Promise<GitHubPagedResponse<GitHubUser>> {\n return this.requestList<GitHubUser>(\n `${this.basePath}/following`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the users following this user.\n *\n * `GET /users/{username}/followers`\n *\n * @returns A paged response of users\n */\n async followers(params?: { per_page?: number; page?: number }): Promise<GitHubPagedResponse<GitHubUser>> {\n return this.requestList<GitHubUser>(\n `${this.basePath}/followers`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","import { Security } from './security/Security';\nimport { GitHubApiError } from './errors/GitHubApiError';\nimport { OrganizationResource } from './resources/OrganizationResource';\nimport type { RequestFn, RequestListFn, RequestTextFn } from './resources/OrganizationResource';\nimport { RepositoryResource } from './resources/RepositoryResource';\nimport { UserResource } from './resources/UserResource';\nimport type { GitHubUser } from './domain/User';\nimport type { GitHubRepository, SearchReposParams } from './domain/Repository';\nimport type { GitHubPagedResponse } from './domain/Pagination';\n\n/**\n * Payload emitted on every HTTP request made by {@link GitHubClient}.\n */\nexport interface RequestEvent {\n /** Full URL that was requested */\n url: string;\n /** HTTP method used */\n method: 'GET';\n /** Timestamp when the request started */\n startedAt: Date;\n /** Timestamp when the request finished (success or error) */\n finishedAt: Date;\n /** Total duration in milliseconds */\n durationMs: number;\n /** HTTP status code returned by the server, if a response was received */\n statusCode?: number;\n /** Error thrown, if the request failed */\n error?: Error;\n}\n\n/** Map of supported client events to their callback signatures */\nexport interface GitHubClientEvents {\n request: (event: RequestEvent) => void;\n}\n\n/**\n * Constructor options for {@link GitHubClient}.\n */\nexport interface GitHubClientOptions {\n /** A GitHub personal access token (`ghp_...`), OAuth token, or GitHub App installation token */\n token: string;\n /**\n * The base URL of the GitHub API.\n * Defaults to `'https://api.github.com'`.\n * Override for GitHub Enterprise Server (e.g., `'https://github.mycompany.com/api/v3'`).\n */\n apiUrl?: string;\n}\n\n/**\n * GitHub REST API search result envelope.\n * @internal\n */\ninterface SearchResult<T> {\n total_count: number;\n incomplete_results: boolean;\n items: T[];\n}\n\n/**\n * Main entry point for the GitHub REST API client.\n *\n * @example\n * ```typescript\n * const gh = new GitHubClient({ token: 'ghp_myPersonalAccessToken' });\n *\n * const me = await gh.currentUser();\n * const user = await gh.user('octocat');\n * const repos = await gh.user('octocat').repos({ sort: 'updated' });\n * const org = await gh.org('github');\n * const repo = await gh.repo('octocat', 'Hello-World');\n * const prs = await gh.repo('octocat', 'Hello-World').pullRequests({ state: 'open' });\n * const commits = await gh.repo('octocat', 'Hello-World').commits({ per_page: 10 });\n * const results = await gh.searchRepos({ q: 'language:typescript stars:>1000' });\n * ```\n */\nexport class GitHubClient {\n private readonly security: Security;\n private readonly listeners: Map<keyof GitHubClientEvents, GitHubClientEvents[keyof GitHubClientEvents][]> = new Map();\n\n /**\n * @param options - Authentication and connection options\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor({ token, apiUrl }: GitHubClientOptions) {\n this.security = new Security(token, apiUrl);\n }\n\n /**\n * Subscribes to a client event.\n *\n * @example\n * ```typescript\n * gh.on('request', (event) => {\n * console.log(`${event.method} ${event.url} — ${event.durationMs}ms`);\n * if (event.error) console.error('Request failed:', event.error);\n * });\n * ```\n */\n on<K extends keyof GitHubClientEvents>(event: K, callback: GitHubClientEvents[K]): this {\n const callbacks = this.listeners.get(event) ?? [];\n callbacks.push(callback);\n this.listeners.set(event, callbacks);\n return this;\n }\n\n private emit<K extends keyof GitHubClientEvents>(\n event: K,\n payload: Parameters<GitHubClientEvents[K]>[0],\n ): void {\n const callbacks = this.listeners.get(event) ?? [];\n for (const cb of callbacks) {\n (cb as (p: typeof payload) => void)(payload);\n }\n }\n\n /**\n * Performs an authenticated GET request returning a single JSON object.\n * @internal\n */\n private async request<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n options?: { headers?: Record<string, string> },\n ): Promise<T> {\n const base = `${this.security.getApiUrl()}${path}`;\n const url = buildUrl(base, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const headers = options?.headers ?? this.security.getHeaders();\n const response = await fetch(url, { headers });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as T;\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return data;\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n /**\n * Performs an authenticated GET request returning a paginated list.\n * Parses the `Link` response header to determine if more pages exist.\n * @internal\n */\n private async requestList<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<GitHubPagedResponse<T>> {\n const base = `${this.security.getApiUrl()}${path}`;\n const url = buildUrl(base, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, { headers: this.security.getHeaders() });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as T[];\n const linkHeader = response.headers.get('Link');\n const nextPage = parseNextPage(linkHeader);\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return {\n values: data,\n hasNextPage: nextPage !== undefined,\n nextPage,\n };\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n /**\n * Performs a GET request returning raw text content.\n * Uses `Accept: application/vnd.github.raw+json` to retrieve file content directly.\n * @internal\n */\n private async requestText(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<string> {\n const base = `${this.security.getApiUrl()}${path}`;\n const url = buildUrl(base, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, { headers: this.security.getRawHeaders() });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const text = await response.text();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return text;\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n private makeRequestFn(): RequestFn {\n return <T>(path: string, params?: Record<string, string | number | boolean>) =>\n this.request<T>(path, params);\n }\n\n private makeRequestListFn(): RequestListFn {\n return <T>(path: string, params?: Record<string, string | number | boolean>) =>\n this.requestList<T>(path, params);\n }\n\n private makeRequestTextFn(): RequestTextFn {\n return (path: string, params?: Record<string, string | number | boolean>) =>\n this.requestText(path, params);\n }\n\n /**\n * Fetches the authenticated user's profile.\n *\n * `GET /user`\n *\n * @returns The authenticated user object\n *\n * @example\n * ```typescript\n * const me = await gh.currentUser();\n * console.log(me.login); // 'octocat'\n * ```\n */\n async currentUser(): Promise<GitHubUser> {\n return this.request<GitHubUser>('/user');\n }\n\n /**\n * Returns a {@link UserResource} for a given GitHub login, providing access\n * to user data and their repositories.\n *\n * The returned resource can be awaited directly to fetch user info,\n * or chained to access nested resources.\n *\n * @param login - The user's login name (e.g., `'octocat'`)\n * @returns A chainable user resource\n *\n * @example\n * ```typescript\n * const user = await gh.user('octocat');\n * const repos = await gh.user('octocat').repos({ sort: 'updated' });\n * const pr = await gh.user('octocat').repo('Hello-World').pullRequest(1).files();\n * ```\n */\n user(login: string): UserResource {\n return new UserResource(\n this.makeRequestFn(),\n this.makeRequestListFn(),\n this.makeRequestTextFn(),\n login,\n );\n }\n\n /**\n * Returns an {@link OrganizationResource} for a given GitHub organization, providing\n * access to organization data and its repositories.\n *\n * The returned resource can be awaited directly to fetch organization info,\n * or chained to access nested resources.\n *\n * @param name - The organization's login name (e.g., `'github'`)\n * @returns A chainable organization resource\n *\n * @example\n * ```typescript\n * const org = await gh.org('github');\n * const repos = await gh.org('github').repos({ type: 'public' });\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n * ```\n */\n org(name: string): OrganizationResource {\n return new OrganizationResource(\n this.makeRequestFn(),\n this.makeRequestListFn(),\n this.makeRequestTextFn(),\n name,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given owner and repository name.\n *\n * Shortcut that works for both user repositories and organization repositories.\n *\n * @param owner - The owner login (user or organization)\n * @param name - The repository name\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await gh.repo('octocat', 'Hello-World');\n * const prs = await gh.repo('octocat', 'Hello-World').pullRequests();\n * ```\n */\n repo(owner: string, name: string): RepositoryResource {\n return new RepositoryResource(\n this.makeRequestFn(),\n this.makeRequestListFn(),\n this.makeRequestTextFn(),\n owner,\n name,\n );\n }\n\n /**\n * Searches for repositories using GitHub's search syntax.\n *\n * `GET /search/repositories`\n *\n * @param params - Search query and optional filters. `q` is required.\n * @returns A paged response of repositories with `totalCount`\n *\n * @example\n * ```typescript\n * const results = await gh.searchRepos({ q: 'language:typescript stars:>1000', sort: 'stars' });\n * console.log(`Found ${results.totalCount} repositories`);\n * ```\n */\n async searchRepos(params: SearchReposParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n const base = `${this.security.getApiUrl()}/search/repositories`;\n const url = buildUrl(base, params as unknown as Record<string, string | number | boolean>);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, { headers: this.security.getHeaders() });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as SearchResult<GitHubRepository>;\n const linkHeader = response.headers.get('Link');\n const nextPage = parseNextPage(linkHeader);\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return {\n values: data.items,\n hasNextPage: nextPage !== undefined,\n nextPage,\n totalCount: data.total_count,\n };\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n}\n\n/**\n * Appends query parameters to a URL string, skipping `undefined` values.\n * @internal\n */\nfunction buildUrl(base: string, params?: Record<string, string | number | boolean>): string {\n if (!params) return base;\n const entries = Object.entries(params).filter(([, v]) => v !== undefined);\n if (entries.length === 0) return base;\n const search = new URLSearchParams(entries.map(([k, v]) => [k, String(v)]));\n return `${base}?${search.toString()}`;\n}\n\n/**\n * Parses the `Link` response header to extract the next page number.\n *\n * GitHub Link header format:\n * `<https://api.github.com/...?page=2>; rel=\"next\", <https://api.github.com/...?page=5>; rel=\"last\"`\n *\n * @internal\n */\nfunction parseNextPage(linkHeader: string | null): number | undefined {\n if (!linkHeader) return undefined;\n const match = linkHeader.match(/<[^>]*[?&]page=(\\d+)[^>]*>;\\s*rel=\"next\"/);\n return match ? parseInt(match[1], 10) : undefined;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/security/Security.ts","../src/errors/GitHubApiError.ts","../src/resources/PullRequestResource.ts","../src/resources/CommitResource.ts","../src/resources/RepositoryResource.ts","../src/resources/OrganizationResource.ts","../src/resources/UserResource.ts","../src/GitHubClient.ts"],"sourcesContent":["/**\n * Handles Bearer token authentication for GitHub REST API requests.\n *\n * @example\n * ```typescript\n * const security = new Security('ghp_myPersonalAccessToken');\n *\n * const headers = security.getHeaders();\n * // {\n * // Authorization: 'Bearer ghp_myPersonalAccessToken',\n * // Accept: 'application/vnd.github+json',\n * // 'Content-Type': 'application/json',\n * // 'X-GitHub-Api-Version': '2022-11-28',\n * // }\n * ```\n */\nexport class Security {\n private readonly apiUrl: string;\n private readonly token: string;\n\n /**\n * Creates a new Security instance with a GitHub personal access token.\n *\n * @param token - A GitHub personal access token (e.g., `ghp_...`) or OAuth token\n * @param apiUrl - The base URL of the GitHub API. Defaults to `'https://api.github.com'`.\n * Must be a valid URL; throws if it cannot be parsed.\n *\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor(token: string, apiUrl: string = 'https://api.github.com') {\n if (!URL.canParse(apiUrl)) {\n throw new TypeError(`Invalid apiUrl: \"${apiUrl}\" is not a valid URL`);\n }\n this.apiUrl = apiUrl.replace(/\\/$/, '');\n this.token = token;\n }\n\n /**\n * Returns the base URL of the GitHub API, without a trailing slash.\n *\n * @returns The API base URL\n */\n getApiUrl(): string {\n return this.apiUrl;\n }\n\n /**\n * Returns the value of the `Authorization` header for Bearer authentication.\n *\n * @returns The Authorization header value in the format `Bearer <token>`\n */\n getAuthorizationHeader(): string {\n return `Bearer ${this.token}`;\n }\n\n /**\n * Returns the full set of HTTP headers required for authenticated GitHub API requests.\n *\n * @returns An object containing `Authorization`, `Accept`, `Content-Type`, and `X-GitHub-Api-Version` headers\n */\n getHeaders(): Record<string, string> {\n return {\n Authorization: `Bearer ${this.token}`,\n Accept: 'application/vnd.github+json',\n 'Content-Type': 'application/json',\n 'X-GitHub-Api-Version': '2022-11-28',\n };\n }\n\n /**\n * Returns headers for raw file content requests.\n *\n * @returns Headers with `Accept: application/vnd.github.raw+json`\n */\n getRawHeaders(): Record<string, string> {\n return {\n ...this.getHeaders(),\n Accept: 'application/vnd.github.raw+json',\n };\n }\n}\n","/**\n * Thrown when the GitHub REST API returns a non-2xx response.\n *\n * @example\n * ```typescript\n * import { GitHubApiError } from 'github-api-client';\n *\n * try {\n * await gh.user('nonexistent-user-xyz');\n * } catch (err) {\n * if (err instanceof GitHubApiError) {\n * console.log(err.status); // 404\n * console.log(err.statusText); // 'Not Found'\n * console.log(err.message); // 'GitHub API error: 404 Not Found'\n * }\n * }\n * ```\n */\nexport class GitHubApiError extends Error {\n /** HTTP status code (e.g. `404`, `401`, `403`, `422`) */\n readonly status: number;\n /** HTTP status text (e.g. `'Not Found'`, `'Unauthorized'`) */\n readonly statusText: string;\n\n constructor(status: number, statusText: string) {\n super(`GitHub API error: ${status} ${statusText}`);\n this.name = 'GitHubApiError';\n this.status = status;\n this.statusText = statusText;\n }\n}\n","import type { GitHubPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { GitHubReview, GitHubReviewComment, ReviewsParams, ReviewCommentsParams } from '../domain/Review';\nimport type { GitHubPullRequestFile, PullRequestFilesParams } from '../domain/PullRequestFile';\nimport type { GitHubCommit } from '../domain/Commit';\nimport type { GitHubPagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn } from './OrganizationResource';\n\n/**\n * Represents a GitHub pull request resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubPullRequest>` so it can be awaited directly\n * to fetch the pull request info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get pull request info\n * const pr = await gh.org('github').repo('linguist').pullRequest(42);\n *\n * // Get commits in this pull request\n * const commits = await gh.org('github').repo('linguist').pullRequest(42).commits();\n *\n * // Get changed files\n * const files = await gh.org('github').repo('linguist').pullRequest(42).files();\n *\n * // Get reviews\n * const reviews = await gh.org('github').repo('linguist').pullRequest(42).reviews();\n *\n * // Get review comments (inline diff comments)\n * const comments = await gh.org('github').repo('linguist').pullRequest(42).reviewComments();\n * ```\n */\nexport class PullRequestResource implements PromiseLike<GitHubPullRequest> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n owner: string,\n repo: string,\n pullNumber: number,\n ) {\n this.basePath = `/repos/${owner}/${repo}/pulls/${pullNumber}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the pull request info.\n * Delegates to {@link PullRequestResource.get}.\n */\n then<TResult1 = GitHubPullRequest, TResult2 = never>(\n onfulfilled?: ((value: GitHubPullRequest) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the pull request details.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}`\n *\n * @returns The pull request object\n */\n async get(): Promise<GitHubPullRequest> {\n return this.request<GitHubPullRequest>(this.basePath);\n }\n\n /**\n * Fetches the commits included in this pull request.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/commits`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of commits\n */\n async commits(params?: PaginationParams): Promise<GitHubPagedResponse<GitHubCommit>> {\n return this.requestList<GitHubCommit>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the files changed by this pull request.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/files`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of changed files\n */\n async files(params?: PullRequestFilesParams): Promise<GitHubPagedResponse<GitHubPullRequestFile>> {\n return this.requestList<GitHubPullRequestFile>(\n `${this.basePath}/files`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the reviews submitted on this pull request.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of reviews\n */\n async reviews(params?: ReviewsParams): Promise<GitHubPagedResponse<GitHubReview>> {\n return this.requestList<GitHubReview>(\n `${this.basePath}/reviews`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the inline review comments on this pull request's diff.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/comments`\n *\n * @param params - Optional filters: `sort`, `direction`, `since`, `per_page`, `page`\n * @returns A paged response of review comments\n */\n async reviewComments(params?: ReviewCommentsParams): Promise<GitHubPagedResponse<GitHubReviewComment>> {\n return this.requestList<GitHubReviewComment>(\n `${this.basePath}/comments`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Checks whether the pull request has been merged.\n *\n * `GET /repos/{owner}/{repo}/pulls/{pull_number}/merge`\n *\n * @returns `true` if merged (HTTP 204), `false` if not merged (HTTP 404)\n */\n async isMerged(): Promise<boolean> {\n try {\n await this.request<never>(`${this.basePath}/merge`);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import type { GitHubCommit } from '../domain/Commit';\nimport type { GitHubCommitStatus, GitHubCombinedStatus, GitHubCheckRun, CommitStatusesParams, CheckRunsParams } from '../domain/CommitStatus';\nimport type { GitHubPagedResponse } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn } from './OrganizationResource';\n\n/**\n * Represents a GitHub commit resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubCommit>` so it can be awaited directly\n * to fetch the commit info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get commit info (includes stats and files)\n * const commit = await gh.org('github').repo('linguist').commit('abc123');\n *\n * // Get CI/CD statuses for this commit\n * const statuses = await gh.org('github').repo('linguist').commit('abc123').statuses();\n *\n * // Get the combined (aggregated) status\n * const combined = await gh.org('github').repo('linguist').commit('abc123').combinedStatus();\n *\n * // Get GitHub Actions check runs\n * const checks = await gh.org('github').repo('linguist').commit('abc123').checkRuns();\n * ```\n */\nexport class CommitResource implements PromiseLike<GitHubCommit> {\n private readonly basePath: string;\n private readonly ref: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n owner: string,\n repo: string,\n ref: string,\n ) {\n this.basePath = `/repos/${owner}/${repo}/commits/${ref}`;\n this.ref = ref;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the commit info.\n * Delegates to {@link CommitResource.get}.\n */\n then<TResult1 = GitHubCommit, TResult2 = never>(\n onfulfilled?: ((value: GitHubCommit) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the commit details, including stats and changed files.\n *\n * `GET /repos/{owner}/{repo}/commits/{ref}`\n *\n * @returns The commit object with stats and files\n */\n async get(): Promise<GitHubCommit> {\n return this.request<GitHubCommit>(this.basePath);\n }\n\n /**\n * Fetches the individual commit statuses (from CI/CD systems via the Statuses API).\n *\n * `GET /repos/{owner}/{repo}/statuses/{sha}`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of commit statuses\n */\n async statuses(params?: CommitStatusesParams): Promise<GitHubPagedResponse<GitHubCommitStatus>> {\n const repoPath = this.basePath.replace(`/commits/${this.ref}`, '');\n return this.requestList<GitHubCommitStatus>(\n `${repoPath}/statuses/${this.ref}`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the combined commit status — an aggregation of all statuses for this ref.\n *\n * `GET /repos/{owner}/{repo}/commits/{ref}/status`\n *\n * @returns The combined status object\n */\n async combinedStatus(): Promise<GitHubCombinedStatus> {\n return this.request<GitHubCombinedStatus>(`${this.basePath}/status`);\n }\n\n /**\n * Fetches GitHub Actions check runs for this commit.\n *\n * `GET /repos/{owner}/{repo}/commits/{ref}/check-runs`\n *\n * @param params - Optional filters: `check_name`, `status`, `app_id`, `per_page`, `page`\n * @returns A paged response of check runs\n */\n async checkRuns(params?: CheckRunsParams): Promise<GitHubPagedResponse<GitHubCheckRun>> {\n const raw = await this.request<{ check_runs: GitHubCheckRun[] }>(\n `${this.basePath}/check-runs`,\n params as Record<string, string | number | boolean>,\n );\n return {\n values: raw.check_runs,\n hasNextPage: false,\n };\n }\n}\n","import type { GitHubRepository, ReposParams, ForksParams } from '../domain/Repository';\nimport type { GitHubPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { GitHubCommit, CommitsParams } from '../domain/Commit';\nimport type { GitHubBranch, BranchesParams } from '../domain/Branch';\nimport type { GitHubTag, TagsParams } from '../domain/Tag';\nimport type { GitHubRelease, ReleasesParams } from '../domain/Release';\nimport type { GitHubWebhook, WebhooksParams } from '../domain/Webhook';\nimport type { GitHubContent, ContentParams } from '../domain/Content';\nimport type { GitHubPagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn, RequestTextFn } from './OrganizationResource';\nimport { PullRequestResource } from './PullRequestResource';\nimport { CommitResource } from './CommitResource';\n\n/**\n * Represents a GitHub repository resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubRepository>` so it can be awaited directly\n * to fetch repository info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get repository info\n * const repo = await gh.org('github').repo('linguist');\n *\n * // Get pull requests\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n *\n * // Navigate into a specific pull request\n * const files = await gh.org('github').repo('linguist').pullRequest(42).files();\n *\n * // Get commits\n * const commits = await gh.org('github').repo('linguist').commits({ per_page: 10 });\n *\n * // Get raw file content\n * const content = await gh.org('github').repo('linguist').raw('README.md');\n * ```\n */\nexport class RepositoryResource implements PromiseLike<GitHubRepository> {\n private readonly owner: string;\n private readonly repo: string;\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n private readonly requestText: RequestTextFn,\n owner: string,\n repo: string,\n ) {\n this.owner = owner;\n this.repo = repo;\n this.basePath = `/repos/${owner}/${repo}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the repository info.\n * Delegates to {@link RepositoryResource.get}.\n */\n then<TResult1 = GitHubRepository, TResult2 = never>(\n onfulfilled?: ((value: GitHubRepository) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the repository details.\n *\n * `GET /repos/{owner}/{repo}`\n *\n * @returns The repository object\n */\n async get(): Promise<GitHubRepository> {\n return this.request<GitHubRepository>(this.basePath);\n }\n\n /**\n * Fetches pull requests for this repository.\n *\n * `GET /repos/{owner}/{repo}/pulls`\n *\n * @param params - Optional filters: `state`, `head`, `base`, `sort`, `direction`, `per_page`, `page`\n * @returns A paged response of pull requests\n */\n async pullRequests(params?: PullRequestsParams): Promise<GitHubPagedResponse<GitHubPullRequest>> {\n return this.requestList<GitHubPullRequest>(\n `${this.basePath}/pulls`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link PullRequestResource} for a given pull request number.\n *\n * The returned resource can be awaited directly to fetch pull request info,\n * or chained to access nested resources.\n *\n * @param pullNumber - The pull request number (not the ID)\n * @returns A chainable pull request resource\n *\n * @example\n * ```typescript\n * const pr = await gh.org('github').repo('linguist').pullRequest(42);\n * const files = await gh.org('github').repo('linguist').pullRequest(42).files();\n * const reviews = await gh.org('github').repo('linguist').pullRequest(42).reviews();\n * ```\n */\n pullRequest(pullNumber: number): PullRequestResource {\n return new PullRequestResource(\n this.request,\n this.requestList,\n this.owner,\n this.repo,\n pullNumber,\n );\n }\n\n /**\n * Fetches commits for this repository.\n *\n * `GET /repos/{owner}/{repo}/commits`\n *\n * @param params - Optional filters: `sha`, `path`, `author`, `since`, `until`, `per_page`, `page`\n * @returns A paged response of commits\n */\n async commits(params?: CommitsParams): Promise<GitHubPagedResponse<GitHubCommit>> {\n return this.requestList<GitHubCommit>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link CommitResource} for a given commit ref (SHA, branch, or tag).\n *\n * The returned resource can be awaited directly to fetch commit info,\n * or chained to access nested resources.\n *\n * @param ref - Commit SHA, branch name, or tag name\n * @returns A chainable commit resource\n *\n * @example\n * ```typescript\n * const commit = await gh.org('github').repo('linguist').commit('abc123');\n * const statuses = await gh.org('github').repo('linguist').commit('abc123').statuses();\n * ```\n */\n commit(ref: string): CommitResource {\n return new CommitResource(\n this.request,\n this.requestList,\n this.owner,\n this.repo,\n ref,\n );\n }\n\n /**\n * Fetches branches for this repository.\n *\n * `GET /repos/{owner}/{repo}/branches`\n *\n * @param params - Optional filters: `protected`, `per_page`, `page`\n * @returns A paged response of branches\n */\n async branches(params?: BranchesParams): Promise<GitHubPagedResponse<GitHubBranch>> {\n return this.requestList<GitHubBranch>(\n `${this.basePath}/branches`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches a specific branch by name.\n *\n * `GET /repos/{owner}/{repo}/branches/{branch}`\n *\n * @param name - The branch name (e.g., `'main'`)\n * @returns The branch object\n */\n async branch(name: string): Promise<GitHubBranch> {\n return this.request<GitHubBranch>(`${this.basePath}/branches/${encodeURIComponent(name)}`);\n }\n\n /**\n * Fetches tags for this repository.\n *\n * `GET /repos/{owner}/{repo}/tags`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of tags\n */\n async tags(params?: TagsParams): Promise<GitHubPagedResponse<GitHubTag>> {\n return this.requestList<GitHubTag>(\n `${this.basePath}/tags`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches releases for this repository.\n *\n * `GET /repos/{owner}/{repo}/releases`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of releases\n */\n async releases(params?: ReleasesParams): Promise<GitHubPagedResponse<GitHubRelease>> {\n return this.requestList<GitHubRelease>(\n `${this.basePath}/releases`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the latest published release for this repository.\n *\n * `GET /repos/{owner}/{repo}/releases/latest`\n *\n * @returns The latest release object\n */\n async latestRelease(): Promise<GitHubRelease> {\n return this.request<GitHubRelease>(`${this.basePath}/releases/latest`);\n }\n\n /**\n * Fetches the forks of this repository.\n *\n * `GET /repos/{owner}/{repo}/forks`\n *\n * @param params - Optional filters: `sort`, `per_page`, `page`\n * @returns A paged response of forked repositories\n */\n async forks(params?: ForksParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n return this.requestList<GitHubRepository>(\n `${this.basePath}/forks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches webhooks configured on this repository.\n *\n * `GET /repos/{owner}/{repo}/hooks`\n *\n * @param params - Optional pagination: `per_page`, `page`\n * @returns A paged response of webhooks\n */\n async webhooks(params?: WebhooksParams): Promise<GitHubPagedResponse<GitHubWebhook>> {\n return this.requestList<GitHubWebhook>(\n `${this.basePath}/hooks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the contents of a file or directory in this repository.\n *\n * `GET /repos/{owner}/{repo}/contents/{path}`\n *\n * Returns a single {@link GitHubContent} for files, or an array for directories.\n *\n * @param path - Path to the file or directory (e.g., `'src/index.ts'` or `'src'`). Omit for root.\n * @param params - Optional: `ref` (branch, tag, or commit SHA)\n * @returns File content object or array of directory entries\n */\n async contents(path?: string, params?: ContentParams): Promise<GitHubContent | GitHubContent[]> {\n const contentPath = path ? `${this.basePath}/contents/${path}` : `${this.basePath}/contents`;\n return this.request<GitHubContent | GitHubContent[]>(\n contentPath,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the raw text content of a file in this repository.\n *\n * Uses `Accept: application/vnd.github.raw+json` to retrieve the file directly\n * without base64 encoding.\n *\n * `GET /repos/{owner}/{repo}/contents/{filePath}`\n *\n * @param filePath - Path to the file (e.g., `'src/index.ts'`)\n * @param params - Optional: `ref` (branch, tag, or commit SHA)\n * @returns The raw file content as a string\n */\n async raw(filePath: string, params?: ContentParams): Promise<string> {\n return this.requestText(\n `${this.basePath}/contents/${filePath}`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the repository topics.\n *\n * `GET /repos/{owner}/{repo}/topics`\n *\n * @returns An array of topic strings\n */\n async topics(): Promise<string[]> {\n const data = await this.request<{ names: string[] }>(`${this.basePath}/topics`);\n return data.names;\n }\n\n /**\n * Fetches contributors to this repository.\n *\n * `GET /repos/{owner}/{repo}/contributors`\n *\n * @param params - Optional filters: `anon` (include anonymous contributors), `per_page`, `page`\n * @returns A paged response of contributors\n */\n async contributors(params?: PaginationParams & { anon?: boolean }): Promise<GitHubPagedResponse<{ login?: string; id?: number; contributions: number; avatar_url?: string; html_url?: string }>> {\n return this.requestList(\n `${this.basePath}/contributors`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","import type { GitHubOrganization, OrgMembersParams, CreateOrgRepoData } from '../domain/Organization';\nimport type { GitHubRepository, ReposParams } from '../domain/Repository';\nimport type { GitHubUser } from '../domain/User';\nimport type { GitHubPagedResponse } from '../domain/Pagination';\nimport { RepositoryResource } from './RepositoryResource';\n\n/** @internal */\nexport type RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<T>;\n\n/** @internal */\nexport type RequestListFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<GitHubPagedResponse<T>>;\n\n/** @internal */\nexport type RequestTextFn = (\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<string>;\n\n/** @internal */\nexport type RequestBodyFn = <T>(\n path: string,\n body: unknown,\n) => Promise<T>;\n\n/**\n * Represents a GitHub organization resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubOrganization>` so it can be awaited directly\n * to fetch the organization info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get organization info\n * const org = await gh.org('github');\n *\n * // Get repositories\n * const repos = await gh.org('github').repos({ type: 'public', per_page: 50 });\n *\n * // Navigate into a specific repository\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n *\n * // Get members\n * const members = await gh.org('github').members({ role: 'admin' });\n * ```\n */\nexport class OrganizationResource implements PromiseLike<GitHubOrganization> {\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n private readonly requestText: RequestTextFn,\n private readonly requestBody: RequestBodyFn,\n private readonly org: string,\n ) {}\n\n /**\n * Allows the resource to be awaited directly, resolving with the organization info.\n * Delegates to {@link OrganizationResource.get}.\n */\n then<TResult1 = GitHubOrganization, TResult2 = never>(\n onfulfilled?: ((value: GitHubOrganization) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the organization details.\n *\n * `GET /orgs/{org}`\n *\n * @returns The organization object\n */\n async get(): Promise<GitHubOrganization> {\n return this.request<GitHubOrganization>(`/orgs/${this.org}`);\n }\n\n /**\n * Fetches repositories belonging to this organization.\n *\n * `GET /orgs/{org}/repos`\n *\n * @param params - Optional filters: `type`, `sort`, `direction`, `per_page`, `page`\n * @returns A paged response of repositories\n */\n async repos(params?: ReposParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n return this.requestList<GitHubRepository>(\n `/orgs/${this.org}/repos`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given repository name within this organization.\n *\n * The returned resource can be awaited directly to fetch repository info,\n * or chained to access nested resources.\n *\n * @param name - The repository name (e.g., `'linguist'`)\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await gh.org('github').repo('linguist');\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n * const commits = await gh.org('github').repo('linguist').commits({ per_page: 10 });\n * ```\n */\n repo(name: string): RepositoryResource {\n return new RepositoryResource(\n this.request,\n this.requestList,\n this.requestText,\n this.org,\n name,\n );\n }\n\n /**\n * Fetches members of this organization.\n *\n * `GET /orgs/{org}/members`\n *\n * @param params - Optional filters: `role`, `filter`, `per_page`, `page`\n * @returns A paged response of users\n */\n async members(params?: OrgMembersParams): Promise<GitHubPagedResponse<GitHubUser>> {\n return this.requestList<GitHubUser>(\n `/orgs/${this.org}/members`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Creates a new repository in this organization.\n *\n * `POST /orgs/{org}/repos`\n *\n * @param data - Repository creation options. `name` is required.\n * @returns The newly created repository\n *\n * @example\n * ```typescript\n * const repo = await gh.org('my-org').createRepo({\n * name: 'my-new-repo',\n * description: 'My new repository',\n * private: true,\n * auto_init: true,\n * });\n * ```\n */\n async createRepo(data: CreateOrgRepoData): Promise<GitHubRepository> {\n return this.requestBody<GitHubRepository>(`/orgs/${this.org}/repos`, data);\n }\n}\n","import type { GitHubUser } from '../domain/User';\nimport type { GitHubRepository, ReposParams } from '../domain/Repository';\nimport type { GitHubPagedResponse } from '../domain/Pagination';\nimport type { RequestFn, RequestListFn, RequestTextFn } from './OrganizationResource';\nimport { RepositoryResource } from './RepositoryResource';\n\n/**\n * Represents a GitHub user resource with chainable async methods.\n *\n * Implements `PromiseLike<GitHubUser>` so it can be awaited directly\n * to fetch user info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get user info\n * const user = await gh.user('octocat');\n *\n * // Get the user's public repositories\n * const repos = await gh.user('octocat').repos({ sort: 'updated' });\n *\n * // Navigate into a specific repository\n * const prs = await gh.user('octocat').repo('Hello-World').pullRequests();\n * ```\n */\nexport class UserResource implements PromiseLike<GitHubUser> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestList: RequestListFn,\n private readonly requestText: RequestTextFn,\n private readonly login: string,\n ) {\n this.basePath = `/users/${login}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the user info.\n * Delegates to {@link UserResource.get}.\n */\n then<TResult1 = GitHubUser, TResult2 = never>(\n onfulfilled?: ((value: GitHubUser) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the user details.\n *\n * `GET /users/{username}`\n *\n * @returns The user object\n */\n async get(): Promise<GitHubUser> {\n return this.request<GitHubUser>(this.basePath);\n }\n\n /**\n * Fetches public repositories for this user.\n *\n * `GET /users/{username}/repos`\n *\n * @param params - Optional filters: `type`, `sort`, `direction`, `per_page`, `page`\n * @returns A paged response of repositories\n */\n async repos(params?: ReposParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n return this.requestList<GitHubRepository>(\n `${this.basePath}/repos`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given repository under this user,\n * providing access to all repository sub-resources.\n *\n * @param name - The repository name\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await gh.user('octocat').repo('Hello-World');\n * const content = await gh.user('octocat').repo('Hello-World').raw('README.md');\n * ```\n */\n repo(name: string): RepositoryResource {\n return new RepositoryResource(\n this.request,\n this.requestList,\n this.requestText,\n this.login,\n name,\n );\n }\n\n /**\n * Fetches the users this user is following.\n *\n * `GET /users/{username}/following`\n *\n * @returns A paged response of users\n */\n async following(params?: { per_page?: number; page?: number }): Promise<GitHubPagedResponse<GitHubUser>> {\n return this.requestList<GitHubUser>(\n `${this.basePath}/following`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the users following this user.\n *\n * `GET /users/{username}/followers`\n *\n * @returns A paged response of users\n */\n async followers(params?: { per_page?: number; page?: number }): Promise<GitHubPagedResponse<GitHubUser>> {\n return this.requestList<GitHubUser>(\n `${this.basePath}/followers`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","import { Security } from './security/Security';\nimport { GitHubApiError } from './errors/GitHubApiError';\nimport { OrganizationResource } from './resources/OrganizationResource';\nimport type { RequestFn, RequestListFn, RequestTextFn, RequestBodyFn } from './resources/OrganizationResource';\nimport { RepositoryResource } from './resources/RepositoryResource';\nimport { UserResource } from './resources/UserResource';\nimport type { GitHubUser } from './domain/User';\nimport type { GitHubRepository, SearchReposParams } from './domain/Repository';\nimport type { GitHubPagedResponse } from './domain/Pagination';\n\n/**\n * Payload emitted on every HTTP request made by {@link GitHubClient}.\n */\nexport interface RequestEvent {\n /** Full URL that was requested */\n url: string;\n /** HTTP method used */\n method: 'GET' | 'POST';\n /** Timestamp when the request started */\n startedAt: Date;\n /** Timestamp when the request finished (success or error) */\n finishedAt: Date;\n /** Total duration in milliseconds */\n durationMs: number;\n /** HTTP status code returned by the server, if a response was received */\n statusCode?: number;\n /** Error thrown, if the request failed */\n error?: Error;\n}\n\n/** Map of supported client events to their callback signatures */\nexport interface GitHubClientEvents {\n request: (event: RequestEvent) => void;\n}\n\n/**\n * Constructor options for {@link GitHubClient}.\n */\nexport interface GitHubClientOptions {\n /** A GitHub personal access token (`ghp_...`), OAuth token, or GitHub App installation token */\n token: string;\n /**\n * The base URL of the GitHub API.\n * Defaults to `'https://api.github.com'`.\n * Override for GitHub Enterprise Server (e.g., `'https://github.mycompany.com/api/v3'`).\n */\n apiUrl?: string;\n}\n\n/**\n * GitHub REST API search result envelope.\n * @internal\n */\ninterface SearchResult<T> {\n total_count: number;\n incomplete_results: boolean;\n items: T[];\n}\n\n/**\n * Main entry point for the GitHub REST API client.\n *\n * @example\n * ```typescript\n * const gh = new GitHubClient({ token: 'ghp_myPersonalAccessToken' });\n *\n * const me = await gh.currentUser();\n * const user = await gh.user('octocat');\n * const repos = await gh.user('octocat').repos({ sort: 'updated' });\n * const org = await gh.org('github');\n * const repo = await gh.repo('octocat', 'Hello-World');\n * const prs = await gh.repo('octocat', 'Hello-World').pullRequests({ state: 'open' });\n * const commits = await gh.repo('octocat', 'Hello-World').commits({ per_page: 10 });\n * const results = await gh.searchRepos({ q: 'language:typescript stars:>1000' });\n * ```\n */\nexport class GitHubClient {\n private readonly security: Security;\n private readonly listeners: Map<keyof GitHubClientEvents, GitHubClientEvents[keyof GitHubClientEvents][]> = new Map();\n\n /**\n * @param options - Authentication and connection options\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor({ token, apiUrl }: GitHubClientOptions) {\n this.security = new Security(token, apiUrl);\n }\n\n /**\n * Subscribes to a client event.\n *\n * @example\n * ```typescript\n * gh.on('request', (event) => {\n * console.log(`${event.method} ${event.url} — ${event.durationMs}ms`);\n * if (event.error) console.error('Request failed:', event.error);\n * });\n * ```\n */\n on<K extends keyof GitHubClientEvents>(event: K, callback: GitHubClientEvents[K]): this {\n const callbacks = this.listeners.get(event) ?? [];\n callbacks.push(callback);\n this.listeners.set(event, callbacks);\n return this;\n }\n\n private emit<K extends keyof GitHubClientEvents>(\n event: K,\n payload: Parameters<GitHubClientEvents[K]>[0],\n ): void {\n const callbacks = this.listeners.get(event) ?? [];\n for (const cb of callbacks) {\n (cb as (p: typeof payload) => void)(payload);\n }\n }\n\n /**\n * Performs an authenticated GET request returning a single JSON object.\n * @internal\n */\n private async request<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n options?: { headers?: Record<string, string> },\n ): Promise<T> {\n const base = `${this.security.getApiUrl()}${path}`;\n const url = buildUrl(base, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const headers = options?.headers ?? this.security.getHeaders();\n const response = await fetch(url, { headers });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as T;\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return data;\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n /**\n * Performs an authenticated GET request returning a paginated list.\n * Parses the `Link` response header to determine if more pages exist.\n * @internal\n */\n private async requestList<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<GitHubPagedResponse<T>> {\n const base = `${this.security.getApiUrl()}${path}`;\n const url = buildUrl(base, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, { headers: this.security.getHeaders() });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as T[];\n const linkHeader = response.headers.get('Link');\n const nextPage = parseNextPage(linkHeader);\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return {\n values: data,\n hasNextPage: nextPage !== undefined,\n nextPage,\n };\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n /**\n * Performs a GET request returning raw text content.\n * Uses `Accept: application/vnd.github.raw+json` to retrieve file content directly.\n * @internal\n */\n private async requestText(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<string> {\n const base = `${this.security.getApiUrl()}${path}`;\n const url = buildUrl(base, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, { headers: this.security.getRawHeaders() });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const text = await response.text();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return text;\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n private makeRequestFn(): RequestFn {\n return <T>(path: string, params?: Record<string, string | number | boolean>) =>\n this.request<T>(path, params);\n }\n\n private makeRequestListFn(): RequestListFn {\n return <T>(path: string, params?: Record<string, string | number | boolean>) =>\n this.requestList<T>(path, params);\n }\n\n private makeRequestTextFn(): RequestTextFn {\n return (path: string, params?: Record<string, string | number | boolean>) =>\n this.requestText(path, params);\n }\n\n private async requestPost<T>(path: string, body: unknown): Promise<T> {\n const url = `${this.security.getApiUrl()}${path}`;\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.security.getHeaders(),\n body: JSON.stringify(body),\n });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as T;\n this.emit('request', { url, method: 'POST', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return data;\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'POST', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n\n private makeRequestBodyFn(): RequestBodyFn {\n return <T>(path: string, body: unknown) =>\n this.requestPost<T>(path, body);\n }\n\n /**\n * Fetches the authenticated user's profile.\n *\n * `GET /user`\n *\n * @returns The authenticated user object\n *\n * @example\n * ```typescript\n * const me = await gh.currentUser();\n * console.log(me.login); // 'octocat'\n * ```\n */\n async currentUser(): Promise<GitHubUser> {\n return this.request<GitHubUser>('/user');\n }\n\n /**\n * Returns a {@link UserResource} for a given GitHub login, providing access\n * to user data and their repositories.\n *\n * The returned resource can be awaited directly to fetch user info,\n * or chained to access nested resources.\n *\n * @param login - The user's login name (e.g., `'octocat'`)\n * @returns A chainable user resource\n *\n * @example\n * ```typescript\n * const user = await gh.user('octocat');\n * const repos = await gh.user('octocat').repos({ sort: 'updated' });\n * const pr = await gh.user('octocat').repo('Hello-World').pullRequest(1).files();\n * ```\n */\n user(login: string): UserResource {\n return new UserResource(\n this.makeRequestFn(),\n this.makeRequestListFn(),\n this.makeRequestTextFn(),\n login,\n );\n }\n\n /**\n * Returns an {@link OrganizationResource} for a given GitHub organization, providing\n * access to organization data and its repositories.\n *\n * The returned resource can be awaited directly to fetch organization info,\n * or chained to access nested resources.\n *\n * @param name - The organization's login name (e.g., `'github'`)\n * @returns A chainable organization resource\n *\n * @example\n * ```typescript\n * const org = await gh.org('github');\n * const repos = await gh.org('github').repos({ type: 'public' });\n * const prs = await gh.org('github').repo('linguist').pullRequests({ state: 'open' });\n * ```\n */\n org(name: string): OrganizationResource {\n return new OrganizationResource(\n this.makeRequestFn(),\n this.makeRequestListFn(),\n this.makeRequestTextFn(),\n this.makeRequestBodyFn(),\n name,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given owner and repository name.\n *\n * Shortcut that works for both user repositories and organization repositories.\n *\n * @param owner - The owner login (user or organization)\n * @param name - The repository name\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await gh.repo('octocat', 'Hello-World');\n * const prs = await gh.repo('octocat', 'Hello-World').pullRequests();\n * ```\n */\n repo(owner: string, name: string): RepositoryResource {\n return new RepositoryResource(\n this.makeRequestFn(),\n this.makeRequestListFn(),\n this.makeRequestTextFn(),\n owner,\n name,\n );\n }\n\n /**\n * Searches for repositories using GitHub's search syntax.\n *\n * `GET /search/repositories`\n *\n * @param params - Search query and optional filters. `q` is required.\n * @returns A paged response of repositories with `totalCount`\n *\n * @example\n * ```typescript\n * const results = await gh.searchRepos({ q: 'language:typescript stars:>1000', sort: 'stars' });\n * console.log(`Found ${results.totalCount} repositories`);\n * ```\n */\n async searchRepos(params: SearchReposParams): Promise<GitHubPagedResponse<GitHubRepository>> {\n const base = `${this.security.getApiUrl()}/search/repositories`;\n const url = buildUrl(base, params as unknown as Record<string, string | number | boolean>);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, { headers: this.security.getHeaders() });\n statusCode = response.status;\n if (!response.ok) {\n throw new GitHubApiError(response.status, response.statusText);\n }\n const data = await response.json() as SearchResult<GitHubRepository>;\n const linkHeader = response.headers.get('Link');\n const nextPage = parseNextPage(linkHeader);\n this.emit('request', { url, method: 'GET', startedAt, finishedAt: new Date(), durationMs: Date.now() - startedAt.getTime(), statusCode });\n return {\n values: data.items,\n hasNextPage: nextPage !== undefined,\n nextPage,\n totalCount: data.total_count,\n };\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', { url, method: 'GET', startedAt, finishedAt, durationMs: finishedAt.getTime() - startedAt.getTime(), statusCode, error: err instanceof Error ? err : new Error(String(err)) });\n throw err;\n }\n }\n}\n\n/**\n * Appends query parameters to a URL string, skipping `undefined` values.\n * @internal\n */\nfunction buildUrl(base: string, params?: Record<string, string | number | boolean>): string {\n if (!params) return base;\n const entries = Object.entries(params).filter(([, v]) => v !== undefined);\n if (entries.length === 0) return base;\n const search = new URLSearchParams(entries.map(([k, v]) => [k, String(v)]));\n return `${base}?${search.toString()}`;\n}\n\n/**\n * Parses the `Link` response header to extract the next page number.\n *\n * GitHub Link header format:\n * `<https://api.github.com/...?page=2>; rel=\"next\", <https://api.github.com/...?page=5>; rel=\"last\"`\n *\n * @internal\n */\nfunction parseNextPage(linkHeader: string | null): number | undefined {\n if (!linkHeader) return undefined;\n const match = linkHeader.match(/<[^>]*[?&]page=(\\d+)[^>]*>;\\s*rel=\"next\"/);\n return match ? parseInt(match[1], 10) : undefined;\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gh-api-client",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A lightweight Java client for the GitHub API that simplifies common operations such as listing repositories, branches, commits, collaborators, and files, with built-in support for token-based authentication.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|