blob: 60d21918ee46826bd3d74cfea4284d95e3e95e13 [file] [log] [blame]
giod0026612025-05-08 13:00:36 +00001import axios from "axios";
2import { z } from "zod";
3
4export const GithubRepositorySchema = z.object({
5 id: z.number(),
6 name: z.string(),
7 full_name: z.string(),
8 html_url: z.string(),
9 ssh_url: z.string(),
10});
11
gio3ed59592025-05-14 16:51:09 +000012const DeployKeysSchema = z.array(
13 z.object({
14 id: z.number(),
15 key: z.string(),
16 }),
17);
18
giod0026612025-05-08 13:00:36 +000019export type GithubRepository = z.infer<typeof GithubRepositorySchema>;
20
21export class GithubClient {
22 private token: string;
23
24 constructor(token: string) {
25 this.token = token;
26 }
27
28 private getHeaders() {
29 return {
30 Authorization: `Bearer ${this.token}`,
31 Accept: "application/vnd.github.v3+json",
32 };
33 }
34
35 async getRepositories(): Promise<GithubRepository[]> {
36 const response = await axios.get("https://api.github.com/user/repos", {
37 headers: this.getHeaders(),
38 });
39 return z.array(GithubRepositorySchema).parse(response.data);
40 }
41
42 async addDeployKey(repoPath: string, key: string) {
43 const sshUrl = repoPath;
44 const repoOwnerAndName = sshUrl.replace("git@github.com:", "").replace(".git", "");
giod0026612025-05-08 13:00:36 +000045 await axios.post(
46 `https://api.github.com/repos/${repoOwnerAndName}/keys`,
47 {
48 title: "dodo",
49 key: key,
50 read_only: true,
51 },
52 {
53 headers: this.getHeaders(),
54 },
55 );
56 }
gio3ed59592025-05-14 16:51:09 +000057
58 async removeDeployKey(repoPath: string, key: string) {
59 const sshUrl = repoPath;
60 const repoOwnerAndName = sshUrl.replace("git@github.com:", "").replace(".git", "");
61 const response = await axios.get(`https://api.github.com/repos/${repoOwnerAndName}/keys`, {
62 headers: this.getHeaders(),
63 });
64 const result = DeployKeysSchema.safeParse(response.data);
65 if (!result.success) {
66 throw new Error("Failed to parse deploy keys response");
67 }
68 const deployKeys = result.data.filter((k) => k.key === key);
69 await Promise.all(
70 deployKeys.map((deployKey) =>
71 axios.delete(`https://api.github.com/repos/${repoOwnerAndName}/keys/${deployKey.id}`, {
72 headers: this.getHeaders(),
73 }),
74 ),
75 );
76 }
giod0026612025-05-08 13:00:36 +000077}