export interface GitHubKey {
id: number;
key: string;
title: string;
}
type GitHubRepoVisibility = "public" | "private" | "internal";
export interface GitHubRepo {
id: number;
name: string;
fullName: string;
description: string | null;
cloneUrl: string;
htmlUrl: string;
defaultBranch: string;
visibility?: GitHubRepoVisibility;
private?: boolean;
installationId?: number;
language?: string | null;
stars?: number | null;
issues?: number | null;
forks?: number | null;
updatedAt?: string | null;
// github reports repo size in kb
sizeKb?: number | null;
}
interface GitHubEmail {
address: string;
primary: boolean;
verified: boolean;
}
export interface GitHubAccount {
login: string;
avatarUrl: string;
email: string | null;
bio: string | null;
blog: string | null;
emails?: GitHubEmail[];
keys: GitHubKey[];
repos: GitHubRepo[];
// localinfra stub runs on its own host instead of github.com
publicOrigin: string;
}
export const GITHUB_ERRORS = {
unavailable: "GitHub connections aren't available on this server.",
signed_out: "Sign in to Tangled, then connect your GitHub account.",
sign_in_expired: "The GitHub sign-in expired. Connect your GitHub account again.",
install_expired: "The GitHub app installation expired. Connect your GitHub account again.",
denied: "GitHub access wasn't granted. Connect your GitHub account to continue.",
failed: "Unable to connect to GitHub. Try connecting again.",
return_unexpected:
"Unable to return to the page you started from. Connect your GitHub account again."
} as const;
export type GitHubError = keyof typeof GITHUB_ERRORS;
export const githubErrorMessage = (code: string | null): string | null =>
code === null
? null
: Object.hasOwn(GITHUB_ERRORS, code)
? GITHUB_ERRORS[code as GitHubError]
: GITHUB_ERRORS.failed;