@codraoss/provider-github 0.9.4
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/LICENSE +625 -0
- package/README.md +15 -0
- package/dist/chunk-JIVK2ZFL.js +53 -0
- package/dist/chunk-JIVK2ZFL.js.map +1 -0
- package/dist/chunk-OACX7HPZ.js +83 -0
- package/dist/chunk-OACX7HPZ.js.map +1 -0
- package/dist/index.d.ts +89 -0
- package/dist/index.js +653 -0
- package/dist/index.js.map +1 -0
- package/dist/oauth-mK0KJT6r.d.ts +74 -0
- package/dist/oauth.d.ts +3 -0
- package/dist/oauth.js +13 -0
- package/dist/oauth.js.map +1 -0
- package/dist/webhook.d.ts +8 -0
- package/dist/webhook.js +7 -0
- package/dist/webhook.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// src/webhook.ts
|
|
2
|
+
function normalizeGitHubWebhook(eventName, payload) {
|
|
3
|
+
if (eventName === "pull_request") {
|
|
4
|
+
const prPayload = payload;
|
|
5
|
+
return {
|
|
6
|
+
eventName: "change_request",
|
|
7
|
+
payload: {
|
|
8
|
+
action: prPayload.action,
|
|
9
|
+
installationId: String(prPayload.installation?.id ?? ""),
|
|
10
|
+
repository: {
|
|
11
|
+
owner: prPayload.repository.owner.login,
|
|
12
|
+
name: prPayload.repository.name
|
|
13
|
+
},
|
|
14
|
+
changeRequest: {
|
|
15
|
+
number: prPayload.pull_request.number,
|
|
16
|
+
title: prPayload.pull_request.title,
|
|
17
|
+
author: prPayload.pull_request.user.login,
|
|
18
|
+
head: { sha: prPayload.pull_request.head.sha, ref: prPayload.pull_request.head.ref },
|
|
19
|
+
base: { sha: prPayload.pull_request.base.sha, ref: prPayload.pull_request.base.ref },
|
|
20
|
+
draft: prPayload.pull_request.draft,
|
|
21
|
+
body: prPayload.pull_request.body
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (eventName === "issue_comment") {
|
|
27
|
+
const icPayload = payload;
|
|
28
|
+
return {
|
|
29
|
+
eventName: "comment",
|
|
30
|
+
payload: {
|
|
31
|
+
action: icPayload.action,
|
|
32
|
+
installationId: String(icPayload.installation?.id ?? ""),
|
|
33
|
+
repository: {
|
|
34
|
+
owner: icPayload.repository.owner.login,
|
|
35
|
+
name: icPayload.repository.name
|
|
36
|
+
},
|
|
37
|
+
issue: {
|
|
38
|
+
number: icPayload.issue.number,
|
|
39
|
+
isChangeRequest: !!icPayload.issue.pull_request
|
|
40
|
+
},
|
|
41
|
+
comment: {
|
|
42
|
+
body: icPayload.comment.body
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export {
|
|
51
|
+
normalizeGitHubWebhook
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=chunk-JIVK2ZFL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/webhook.ts"],"sourcesContent":["import type { WebhookPayload, WebhookEventName } from '@codraoss/schema/webhook';\nimport type { PullRequestWebhookPayload, IssueCommentWebhookPayload } from '@codraoss/schema/github';\n\nexport function normalizeGitHubWebhook(\n eventName: string,\n payload: unknown,\n): { eventName: WebhookEventName; payload: WebhookPayload } | null {\n if (eventName === 'pull_request') {\n const prPayload = payload as PullRequestWebhookPayload;\n return {\n eventName: 'change_request',\n payload: {\n action: prPayload.action,\n installationId: String(prPayload.installation?.id ?? ''),\n repository: {\n owner: prPayload.repository.owner.login,\n name: prPayload.repository.name,\n },\n changeRequest: {\n number: prPayload.pull_request.number,\n title: prPayload.pull_request.title,\n author: prPayload.pull_request.user.login,\n head: { sha: prPayload.pull_request.head.sha, ref: prPayload.pull_request.head.ref },\n base: { sha: prPayload.pull_request.base.sha, ref: prPayload.pull_request.base.ref },\n draft: prPayload.pull_request.draft,\n body: prPayload.pull_request.body,\n },\n },\n };\n }\n\n if (eventName === 'issue_comment') {\n const icPayload = payload as IssueCommentWebhookPayload;\n return {\n eventName: 'comment',\n payload: {\n action: icPayload.action,\n installationId: String(icPayload.installation?.id ?? ''),\n repository: {\n owner: icPayload.repository.owner.login,\n name: icPayload.repository.name,\n },\n issue: {\n number: icPayload.issue.number,\n isChangeRequest: !!icPayload.issue.pull_request,\n },\n comment: {\n body: icPayload.comment.body,\n },\n },\n };\n }\n\n return null;\n}\n"],"mappings":";AAGO,SAAS,uBACd,WACA,SACiE;AACjE,MAAI,cAAc,gBAAgB;AAChC,UAAM,YAAY;AAClB,WAAO;AAAA,MACL,WAAW;AAAA,MACX,SAAS;AAAA,QACP,QAAQ,UAAU;AAAA,QAClB,gBAAgB,OAAO,UAAU,cAAc,MAAM,EAAE;AAAA,QACvD,YAAY;AAAA,UACV,OAAO,UAAU,WAAW,MAAM;AAAA,UAClC,MAAM,UAAU,WAAW;AAAA,QAC7B;AAAA,QACA,eAAe;AAAA,UACb,QAAQ,UAAU,aAAa;AAAA,UAC/B,OAAO,UAAU,aAAa;AAAA,UAC9B,QAAQ,UAAU,aAAa,KAAK;AAAA,UACpC,MAAM,EAAE,KAAK,UAAU,aAAa,KAAK,KAAK,KAAK,UAAU,aAAa,KAAK,IAAI;AAAA,UACnF,MAAM,EAAE,KAAK,UAAU,aAAa,KAAK,KAAK,KAAK,UAAU,aAAa,KAAK,IAAI;AAAA,UACnF,OAAO,UAAU,aAAa;AAAA,UAC9B,MAAM,UAAU,aAAa;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,cAAc,iBAAiB;AACjC,UAAM,YAAY;AAClB,WAAO;AAAA,MACL,WAAW;AAAA,MACX,SAAS;AAAA,QACP,QAAQ,UAAU;AAAA,QAClB,gBAAgB,OAAO,UAAU,cAAc,MAAM,EAAE;AAAA,QACvD,YAAY;AAAA,UACV,OAAO,UAAU,WAAW,MAAM;AAAA,UAClC,MAAM,UAAU,WAAW;AAAA,QAC7B;AAAA,QACA,OAAO;AAAA,UACL,QAAQ,UAAU,MAAM;AAAA,UACxB,iBAAiB,CAAC,CAAC,UAAU,MAAM;AAAA,QACrC;AAAA,QACA,SAAS;AAAA,UACP,MAAM,UAAU,QAAQ;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// src/oauth.ts
|
|
2
|
+
function githubHeaders(token) {
|
|
3
|
+
return {
|
|
4
|
+
Accept: "application/vnd.github+json",
|
|
5
|
+
"User-Agent": "codra-app",
|
|
6
|
+
...token ? { Authorization: `Bearer ${token}` } : {}
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
async function exchangeGitHubOAuthCode(env, code) {
|
|
10
|
+
const response = await fetch("https://github.com/login/oauth/access_token", {
|
|
11
|
+
method: "POST",
|
|
12
|
+
headers: {
|
|
13
|
+
Accept: "application/json",
|
|
14
|
+
"content-type": "application/x-www-form-urlencoded"
|
|
15
|
+
},
|
|
16
|
+
body: new URLSearchParams({
|
|
17
|
+
client_id: env.GITHUB_CLIENT_ID ?? "",
|
|
18
|
+
client_secret: env.GITHUB_CLIENT_SECRET ?? "",
|
|
19
|
+
code,
|
|
20
|
+
redirect_uri: env.AUTH_CALLBACK_URL ?? ""
|
|
21
|
+
})
|
|
22
|
+
});
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
throw new Error(`GitHub token exchange failed with ${response.status}`);
|
|
25
|
+
}
|
|
26
|
+
const payload = await response.json();
|
|
27
|
+
if (!payload.access_token) {
|
|
28
|
+
throw new Error(payload.error_description ?? payload.error ?? "GitHub token exchange did not return an access token.");
|
|
29
|
+
}
|
|
30
|
+
return payload.access_token;
|
|
31
|
+
}
|
|
32
|
+
async function fetchGitHubOAuthProfile(token) {
|
|
33
|
+
const response = await fetch("https://api.github.com/user", {
|
|
34
|
+
headers: githubHeaders(token)
|
|
35
|
+
});
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
throw new Error(`GitHub user lookup failed with ${response.status}`);
|
|
38
|
+
}
|
|
39
|
+
return await response.json();
|
|
40
|
+
}
|
|
41
|
+
function toDashboardSessionUser(profile) {
|
|
42
|
+
return {
|
|
43
|
+
provider: "github",
|
|
44
|
+
providerUserId: profile.id.toString(),
|
|
45
|
+
login: profile.login,
|
|
46
|
+
name: profile.name,
|
|
47
|
+
avatarUrl: profile.avatar_url,
|
|
48
|
+
email: profile.email,
|
|
49
|
+
signedInAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
50
|
+
metadata: {
|
|
51
|
+
githubUserId: profile.id,
|
|
52
|
+
githubUsername: profile.login
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
var GitHubIdentityProvider = class {
|
|
57
|
+
async beginAuthorization(redirectUri, state, env) {
|
|
58
|
+
const url = new URL("https://github.com/login/oauth/authorize");
|
|
59
|
+
url.searchParams.set("client_id", env.GITHUB_CLIENT_ID ?? "");
|
|
60
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
61
|
+
url.searchParams.set("scope", "read:user");
|
|
62
|
+
url.searchParams.set("state", state);
|
|
63
|
+
return { url: url.toString() };
|
|
64
|
+
}
|
|
65
|
+
async completeAuthorization(code, state, expectedState, env) {
|
|
66
|
+
if (state !== expectedState) {
|
|
67
|
+
throw new Error("Invalid state");
|
|
68
|
+
}
|
|
69
|
+
const token = await exchangeGitHubOAuthCode(env, code);
|
|
70
|
+
const profile = await fetchGitHubOAuthProfile(token);
|
|
71
|
+
return {
|
|
72
|
+
identity: toDashboardSessionUser(profile)
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export {
|
|
78
|
+
exchangeGitHubOAuthCode,
|
|
79
|
+
fetchGitHubOAuthProfile,
|
|
80
|
+
toDashboardSessionUser,
|
|
81
|
+
GitHubIdentityProvider
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=chunk-OACX7HPZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/oauth.ts"],"sourcesContent":["import type { DashboardSessionUser, IdentityProvider, AuthorizationResult } from '@codraoss/core';\nimport type { AppBindingsConfig } from './service';\n\nexport type GitHubOAuthProfile = {\n id: number;\n login: string;\n name: string | null;\n avatar_url: string | null;\n email: string | null;\n};\n\nfunction githubHeaders(token?: string) {\n return {\n Accept: 'application/vnd.github+json',\n 'User-Agent': 'codra-app',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n };\n}\n\nexport async function exchangeGitHubOAuthCode(\n env: AppBindingsConfig,\n code: string,\n) {\n const response = await fetch('https://github.com/login/oauth/access_token', {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'content-type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n client_id: env.GITHUB_CLIENT_ID ?? '',\n client_secret: env.GITHUB_CLIENT_SECRET ?? '',\n code,\n redirect_uri: env.AUTH_CALLBACK_URL ?? '',\n }),\n });\n\n if (!response.ok) {\n throw new Error(`GitHub token exchange failed with ${response.status}`);\n }\n\n const payload = await response.json() as {\n access_token?: string;\n error?: string;\n error_description?: string;\n };\n\n if (!payload.access_token) {\n throw new Error(payload.error_description ?? payload.error ?? 'GitHub token exchange did not return an access token.');\n }\n\n return payload.access_token;\n}\n\nexport async function fetchGitHubOAuthProfile(token: string) {\n const response = await fetch('https://api.github.com/user', {\n headers: githubHeaders(token),\n });\n\n if (!response.ok) {\n throw new Error(`GitHub user lookup failed with ${response.status}`);\n }\n\n return (await response.json()) as GitHubOAuthProfile;\n}\n\nexport function toDashboardSessionUser(profile: GitHubOAuthProfile): DashboardSessionUser {\n return {\n provider: 'github',\n providerUserId: profile.id.toString(),\n login: profile.login,\n name: profile.name,\n avatarUrl: profile.avatar_url,\n email: profile.email,\n signedInAt: new Date().toISOString(),\n metadata: {\n githubUserId: profile.id,\n githubUsername: profile.login,\n },\n };\n}\n\nexport class GitHubIdentityProvider implements IdentityProvider {\n async beginAuthorization(redirectUri: string, state: string, env: AppBindingsConfig): Promise<{ url: string }> {\n const url = new URL('https://github.com/login/oauth/authorize');\n url.searchParams.set('client_id', env.GITHUB_CLIENT_ID ?? '');\n url.searchParams.set('redirect_uri', redirectUri);\n url.searchParams.set('scope', 'read:user');\n url.searchParams.set('state', state);\n\n return { url: url.toString() };\n }\n\n async completeAuthorization(code: string, state: string, expectedState: string, env: AppBindingsConfig): Promise<AuthorizationResult> {\n if (state !== expectedState) {\n throw new Error('Invalid state');\n }\n\n const token = await exchangeGitHubOAuthCode(env, code);\n const profile = await fetchGitHubOAuthProfile(token);\n\n return {\n identity: toDashboardSessionUser(profile),\n };\n }\n}\n"],"mappings":";AAWA,SAAS,cAAc,OAAgB;AACrC,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,GAAI,QAAQ,EAAE,eAAe,UAAU,KAAK,GAAG,IAAI,CAAC;AAAA,EACtD;AACF;AAEA,eAAsB,wBACpB,KACA,MACA;AACA,QAAM,WAAW,MAAM,MAAM,+CAA+C;AAAA,IAC1E,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,QAAQ;AAAA,MACR,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM,IAAI,gBAAgB;AAAA,MACxB,WAAW,IAAI,oBAAoB;AAAA,MACnC,eAAe,IAAI,wBAAwB;AAAA,MAC3C;AAAA,MACA,cAAc,IAAI,qBAAqB;AAAA,IACzC,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,qCAAqC,SAAS,MAAM,EAAE;AAAA,EACxE;AAEA,QAAM,UAAU,MAAM,SAAS,KAAK;AAMpC,MAAI,CAAC,QAAQ,cAAc;AACzB,UAAM,IAAI,MAAM,QAAQ,qBAAqB,QAAQ,SAAS,uDAAuD;AAAA,EACvH;AAEA,SAAO,QAAQ;AACjB;AAEA,eAAsB,wBAAwB,OAAe;AAC3D,QAAM,WAAW,MAAM,MAAM,+BAA+B;AAAA,IAC1D,SAAS,cAAc,KAAK;AAAA,EAC9B,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,kCAAkC,SAAS,MAAM,EAAE;AAAA,EACrE;AAEA,SAAQ,MAAM,SAAS,KAAK;AAC9B;AAEO,SAAS,uBAAuB,SAAmD;AACxF,SAAO;AAAA,IACL,UAAU;AAAA,IACV,gBAAgB,QAAQ,GAAG,SAAS;AAAA,IACpC,OAAO,QAAQ;AAAA,IACf,MAAM,QAAQ;AAAA,IACd,WAAW,QAAQ;AAAA,IACnB,OAAO,QAAQ;AAAA,IACf,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,IACnC,UAAU;AAAA,MACR,cAAc,QAAQ;AAAA,MACtB,gBAAgB,QAAQ;AAAA,IAC1B;AAAA,EACF;AACF;AAEO,IAAM,yBAAN,MAAyD;AAAA,EAC9D,MAAM,mBAAmB,aAAqB,OAAe,KAAkD;AAC7G,UAAM,MAAM,IAAI,IAAI,0CAA0C;AAC9D,QAAI,aAAa,IAAI,aAAa,IAAI,oBAAoB,EAAE;AAC5D,QAAI,aAAa,IAAI,gBAAgB,WAAW;AAChD,QAAI,aAAa,IAAI,SAAS,WAAW;AACzC,QAAI,aAAa,IAAI,SAAS,KAAK;AAEnC,WAAO,EAAE,KAAK,IAAI,SAAS,EAAE;AAAA,EAC/B;AAAA,EAEA,MAAM,sBAAsB,MAAc,OAAe,eAAuB,KAAsD;AACpI,QAAI,UAAU,eAAe;AAC3B,YAAM,IAAI,MAAM,eAAe;AAAA,IACjC;AAEA,UAAM,QAAQ,MAAM,wBAAwB,KAAK,IAAI;AACrD,UAAM,UAAU,MAAM,wBAAwB,KAAK;AAEnD,WAAO;AAAA,MACL,UAAU,uBAAuB,OAAO;AAAA,IAC1C;AAAA,EACF;AACF;","names":[]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { A as AppBindingsConfig } from './oauth-mK0KJT6r.js';
|
|
2
|
+
export { G as GitHubOAuthProfile, a as GitHubService, e as exchangeGitHubOAuthCode, f as fetchGitHubOAuthProfile, t as toDashboardSessionUser } from './oauth-mK0KJT6r.js';
|
|
3
|
+
import { PullRequestRecord, ReviewComment } from '@codraoss/core/ports';
|
|
4
|
+
export { normalizeGitHubWebhook } from './webhook.js';
|
|
5
|
+
import '@codraoss/core';
|
|
6
|
+
import '@codraoss/schema/webhook';
|
|
7
|
+
|
|
8
|
+
type GitHubInstallation = {
|
|
9
|
+
id: number;
|
|
10
|
+
};
|
|
11
|
+
type GitHubRepository = {
|
|
12
|
+
name: string;
|
|
13
|
+
owner: {
|
|
14
|
+
login: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
type InstallationTokenCacheRecord = {
|
|
18
|
+
token: string;
|
|
19
|
+
expiresAt: string;
|
|
20
|
+
};
|
|
21
|
+
type GitHubAppRecord = {
|
|
22
|
+
html_url?: string;
|
|
23
|
+
slug?: string;
|
|
24
|
+
};
|
|
25
|
+
type GitHubIssueLabel = {
|
|
26
|
+
name?: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
declare class GitHubError extends Error {
|
|
30
|
+
readonly status: number;
|
|
31
|
+
readonly body: string;
|
|
32
|
+
readonly path: string;
|
|
33
|
+
constructor(status: number, body: string, path: string, message: string);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
declare class GitHubClient {
|
|
37
|
+
private env;
|
|
38
|
+
private readonly installationId;
|
|
39
|
+
private readonly tracker?;
|
|
40
|
+
constructor(env: AppBindingsConfig, installationId: string, tracker?: {
|
|
41
|
+
incrementSubrequests(count?: number): void;
|
|
42
|
+
} | undefined);
|
|
43
|
+
private memoToken;
|
|
44
|
+
getInstallationToken(): Promise<string>;
|
|
45
|
+
static listInstallations(env: AppBindingsConfig): Promise<GitHubInstallation[]>;
|
|
46
|
+
static getAppInstallationUrl(env: AppBindingsConfig): Promise<string>;
|
|
47
|
+
listRepositories(): Promise<GitHubRepository[]>;
|
|
48
|
+
private request;
|
|
49
|
+
private requestAndCheck;
|
|
50
|
+
private ctx;
|
|
51
|
+
graphql<T>(query: string, variables: Record<string, unknown>): Promise<T>;
|
|
52
|
+
getPullRequest(owner: string, repo: string, pullNumber: number): Promise<PullRequestRecord>;
|
|
53
|
+
getPullRequestDiff(owner: string, repo: string, pullNumber: number): Promise<string>;
|
|
54
|
+
getCompareDiff(owner: string, repo: string, base: string, head: string): Promise<string>;
|
|
55
|
+
getRepoFileOrNull(owner: string, repo: string, path: string): Promise<string | null>;
|
|
56
|
+
createCheckRun(owner: string, repo: string, input: {
|
|
57
|
+
headSha: string;
|
|
58
|
+
title: string;
|
|
59
|
+
summary: string;
|
|
60
|
+
detailsUrl?: string;
|
|
61
|
+
}): Promise<{
|
|
62
|
+
id: number;
|
|
63
|
+
}>;
|
|
64
|
+
updateCheckRun(owner: string, repo: string, checkRunId: number, input: {
|
|
65
|
+
title: string;
|
|
66
|
+
summary: string;
|
|
67
|
+
status?: 'in_progress' | 'completed';
|
|
68
|
+
conclusion?: 'success' | 'neutral' | 'failure' | 'cancelled';
|
|
69
|
+
}): Promise<void>;
|
|
70
|
+
createReview(owner: string, repo: string, pullNumber: number, input: {
|
|
71
|
+
commitSha: string;
|
|
72
|
+
event: 'APPROVE' | 'COMMENT' | 'REQUEST_CHANGES';
|
|
73
|
+
body: string;
|
|
74
|
+
comments: ReviewComment[];
|
|
75
|
+
}): Promise<{
|
|
76
|
+
id: number;
|
|
77
|
+
postedIndices: number[];
|
|
78
|
+
}>;
|
|
79
|
+
findBotReviewForCommit(owner: string, repo: string, pullNumber: number, commitSha: string, botLogin: string): Promise<{
|
|
80
|
+
id: number;
|
|
81
|
+
} | null>;
|
|
82
|
+
ensureLabel(owner: string, repo: string, name: string, color: string): Promise<void>;
|
|
83
|
+
addIssueLabels(owner: string, repo: string, issueNumber: number, labels: string[]): Promise<void>;
|
|
84
|
+
listIssueLabels(owner: string, repo: string, issueNumber: number): Promise<string[]>;
|
|
85
|
+
removeIssueLabelsIfPresent(owner: string, repo: string, issueNumber: number, labels: string[]): Promise<void>;
|
|
86
|
+
removeIssueLabel(owner: string, repo: string, issueNumber: number, label: string): Promise<void>;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { type GitHubAppRecord, GitHubClient, GitHubError, type GitHubInstallation, type GitHubIssueLabel, type GitHubRepository, type InstallationTokenCacheRecord };
|