@theholocron/github-client 1.58.0-alpha.13 → 1.58.0-alpha.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -799,6 +799,41 @@ export declare function createAppJWT(creds: GitHubAppCredentials, now?: number):
799
799
  export declare function getInstallationAccessToken(creds: GitHubAppCredentials, installationId: number, opts?: Pick<GitHubClientOptions, "baseUrl" | "fetch">): Promise<InstallationAccessToken>;
800
800
  /** The whole flow in one call — an already-authenticated `GitHubClient` scoped to one installation. */
801
801
  export declare function createInstallationClient(creds: GitHubAppCredentials, installationId: number, opts?: Pick<GitHubClientOptions, "baseUrl" | "fetch">): Promise<GitHubClient>;
802
+ /** The account an App or one of its installations belongs to. */
803
+ interface GitHubAppAccount {
804
+ /** The user or organization login. */
805
+ login: string;
806
+ /** `User` or `Organization` (GitHub also reports `Enterprise` for an enterprise-owned App). */
807
+ type: string;
808
+ }
809
+ /** An App as `GET /app` reports it. */
810
+ interface GitHubApp {
811
+ /** The App's URL name, as in `github.com/apps/<slug>`. */
812
+ slug: string;
813
+ /** The App's display name. */
814
+ name: string;
815
+ /** Who owns the App: decides which settings page its permissions live on. */
816
+ owner: GitHubAppAccount | null;
817
+ /** The permissions the App asks for now: name to `read`, `write` or `admin`. */
818
+ permissions: Record<string, string>;
819
+ /** The webhook events the App is subscribed to now. */
820
+ events: string[];
821
+ }
822
+ /** One installation of an App as `GET /app/installations` reports it. */
823
+ interface GitHubAppInstallation {
824
+ /** The installation id. */
825
+ id: number;
826
+ /** The account the App is installed on. */
827
+ account: GitHubAppAccount | null;
828
+ /** What this installation has accepted: it lags the App's own list until an owner accepts a new request. */
829
+ permissions: Record<string, string>;
830
+ /** The events delivered to this installation. */
831
+ events: string[];
832
+ }
833
+ /** The App this JWT identifies: its slug, owner and the permissions and events it asks for now. */
834
+ export declare function getApp(creds: GitHubAppCredentials, opts?: Pick<GitHubClientOptions, "baseUrl" | "fetch">): Promise<GitHubApp>;
835
+ /** Every installation of the App this JWT identifies, with what each has accepted. Reads all pages. */
836
+ export declare function listAppInstallations(creds: GitHubAppCredentials, opts?: Pick<GitHubClientOptions, "baseUrl" | "fetch">): Promise<GitHubAppInstallation[]>;
802
837
  /**
803
838
  * GitHub's own webhook mechanics — signature verification and header/
804
839
  * payload shapes. Pure functions, no REST call, no auth token: these
@@ -1035,4 +1070,4 @@ export declare function createGitHubClient(opts: GitHubClientOptions): {
1035
1070
  };
1036
1071
  /** The client returned by `createGitHubClient()`: one group of methods per GitHub API area. */
1037
1072
  export type GitHubClient = ReturnType<typeof createGitHubClient>;
1038
- export type { CheckRunAnnotation, CheckRunAnnotationLevel, CheckRunConclusion, CheckRunOutput, CheckRunStatus, CodeScanningSetupResult, CreateCheckRunInput, CreatePagesPayload, CreatePullInput, CreateReviewComment, CreateReviewInput, GitBlob, GitCommit, GitContents, GitDirectoryEntry, GitHubAppCredentials, GitHubCheckRun, GitHubClientOptions, GitHubContents, GitHubEnvironment, GitHubInstallationWebhookPayload, GitHubIssue, GitHubLabel, GitHubMilestone, GitHubPages, GitHubPublicKey, GitHubPullRequest, GitHubPullRequestCommit, GitHubPullRequestFile, GitHubPullRequestReview, GitHubPullRequestWebhookPayload, GitHubPushWebhookPayload, GitHubRepo, GitHubRuleset, GitHubRulesetDetail, GitHubUser, GitHubUserWithExpiry, GitHubVariable, GitHubWebhookHeaders, GitHubWorkflowRun, GitPull, GitRef, GitTree, GitTreeItem, GraphQLClient, InstallationAccessToken, IssueSearchParams, ListDirectoryOptions, OrgProperty, PagesBuildStatus, PagesBuildType, PutContentsInput, PutContentsResult, RepoPropertyValue, RepoTeam, ReviewThread, SecretScope, TeamMember, TeamPermission, UpdateCheckRunInput, UpdatePagesPayload, VariableScope, VariableVisibility, WorkflowRunFilter };
1073
+ export type { CheckRunAnnotation, CheckRunAnnotationLevel, CheckRunConclusion, CheckRunOutput, CheckRunStatus, CodeScanningSetupResult, CreateCheckRunInput, CreatePagesPayload, CreatePullInput, CreateReviewComment, CreateReviewInput, GitBlob, GitCommit, GitContents, GitDirectoryEntry, GitHubApp, GitHubAppAccount, GitHubAppCredentials, GitHubAppInstallation, GitHubCheckRun, GitHubClientOptions, GitHubContents, GitHubEnvironment, GitHubInstallationWebhookPayload, GitHubIssue, GitHubLabel, GitHubMilestone, GitHubPages, GitHubPublicKey, GitHubPullRequest, GitHubPullRequestCommit, GitHubPullRequestFile, GitHubPullRequestReview, GitHubPullRequestWebhookPayload, GitHubPushWebhookPayload, GitHubRepo, GitHubRuleset, GitHubRulesetDetail, GitHubUser, GitHubUserWithExpiry, GitHubVariable, GitHubWebhookHeaders, GitHubWorkflowRun, GitPull, GitRef, GitTree, GitTreeItem, GraphQLClient, InstallationAccessToken, IssueSearchParams, ListDirectoryOptions, OrgProperty, PagesBuildStatus, PagesBuildType, PutContentsInput, PutContentsResult, RepoPropertyValue, RepoTeam, ReviewThread, SecretScope, TeamMember, TeamPermission, UpdateCheckRunInput, UpdatePagesPayload, VariableScope, VariableVisibility, WorkflowRunFilter };
package/dist/index.mjs CHANGED
@@ -891,6 +891,62 @@ async function createInstallationClient(creds, installationId, opts = {}) {
891
891
  fetch: opts.fetch
892
892
  });
893
893
  }
894
+ // src/app-info/app-info.ts
895
+ /**
896
+ * What a GitHub App is right now, read with the App's own JWT (`GET /app`, `GET /app/installations`). GitHub has no
897
+ * endpoint that changes an existing App's permissions or event subscriptions, so these reads are how a caller
898
+ * checks the settings page was done by hand.
899
+ *
900
+ * https://docs.github.com/en/rest/apps/apps#get-the-authenticated-app
901
+ * https://docs.github.com/en/rest/apps/apps#list-installations-for-the-authenticated-app
902
+ */
903
+ const PAGE_SIZE = 100;
904
+ const account = (value) => {
905
+ const { login, type } = value ?? {};
906
+ return typeof login === "string" ? {
907
+ login,
908
+ type: typeof type === "string" ? type : ""
909
+ } : null;
910
+ };
911
+ async function appGet(creds, path, opts) {
912
+ const jwt = await createAppJWT(creds);
913
+ const baseUrl = opts.baseUrl ?? "https://api.github.com";
914
+ const res = await (opts.fetch ?? globalThis.fetch)(`${baseUrl}${path}`, { headers: {
915
+ authorization: `Bearer ${jwt}`,
916
+ accept: "application/vnd.github+json",
917
+ "x-github-api-version": "2022-11-28"
918
+ } });
919
+ if (!res.ok) {
920
+ const body = await res.text().catch(() => "");
921
+ throw new ProviderApiError(`GitHub GET ${path} → ${res.status}`, res.status, body);
922
+ }
923
+ return res.json();
924
+ }
925
+ /** The App this JWT identifies: its slug, owner and the permissions and events it asks for now. */
926
+ async function getApp(creds, opts = {}) {
927
+ const raw = await appGet(creds, "/app", opts);
928
+ return {
929
+ slug: String(raw.slug),
930
+ name: String(raw.name),
931
+ owner: account(raw.owner),
932
+ permissions: raw.permissions ?? {},
933
+ events: raw.events ?? []
934
+ };
935
+ }
936
+ /** Every installation of the App this JWT identifies, with what each has accepted. Reads all pages. */
937
+ async function listAppInstallations(creds, opts = {}) {
938
+ const installations = [];
939
+ for (let page = 1;; page++) {
940
+ const raws = await appGet(creds, `/app/installations?per_page=${PAGE_SIZE}&page=${page}`, opts);
941
+ for (const raw of raws) installations.push({
942
+ id: Number(raw.id),
943
+ account: account(raw.account),
944
+ permissions: raw.permissions ?? {},
945
+ events: raw.events ?? []
946
+ });
947
+ if (raws.length < PAGE_SIZE) return installations;
948
+ }
949
+ }
894
950
  // src/webhooks/webhooks.ts
895
951
  /**
896
952
  * GitHub's own webhook mechanics — signature verification and header/
@@ -964,4 +1020,4 @@ function createGitHubClient(opts) {
964
1020
  workflows: workflows(rest)
965
1021
  };
966
1022
  }
967
- export { MAX_CHECK_RUN_ANNOTATIONS, createAppJWT, createGitHubClient, createInstallationClient, getInstallationAccessToken, parseGitHubWebhookHeaders, parseTokenExpiration, verifyGitHubWebhookSignature };
1023
+ export { MAX_CHECK_RUN_ANNOTATIONS, createAppJWT, createGitHubClient, createInstallationClient, getApp, getInstallationAccessToken, listAppInstallations, parseGitHubWebhookHeaders, parseTokenExpiration, verifyGitHubWebhookSignature };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/github-client",
3
- "version": "1.58.0-alpha.13",
3
+ "version": "1.58.0-alpha.14",
4
4
  "description": "A TypeScript client for the GitHub REST API",
5
5
  "keywords": [
6
6
  "github",
@@ -32,8 +32,8 @@
32
32
  "dist"
33
33
  ],
34
34
  "dependencies": {
35
- "@theholocron/observability": "^0.7.0-alpha.1",
36
- "@theholocron/http-client": "^1.58.0-alpha.13"
35
+ "@theholocron/http-client": "^1.58.0-alpha.14",
36
+ "@theholocron/observability": "^0.7.0-alpha.1"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^26",
@@ -47,8 +47,8 @@
47
47
  "vitest": "^5.0.5",
48
48
  "@theholocron/eslint-config": "^8.9.0-alpha.9",
49
49
  "@theholocron/tsdown-config": "^8.9.0-alpha.9",
50
- "@theholocron/vitest-config": "^8.9.0-alpha.9",
51
- "@theholocron/tsconfig": "^8.9.0-alpha.9"
50
+ "@theholocron/tsconfig": "^8.9.0-alpha.9",
51
+ "@theholocron/vitest-config": "^8.9.0-alpha.9"
52
52
  },
53
53
  "engines": {
54
54
  "node": ">=22.0.0"