@reliverse/rse
Version:
@reliverse/rse is your all-in-one companion for bootstrapping and improving any kind of projects (especially web apps built with frameworks like Next.js) — whether you're kicking off something new or upgrading an existing app. It is also a little AI-power
134 lines (133 loc) • 4.09 kB
JavaScript
import { RequestError } from "@octokit/request-error";
import { relinka } from "@reliverse/relinka";
import { selectPrompt } from "@reliverse/rempts";
import { UNKNOWN_VALUE } from "../../../../constants.js";
import { cd } from "../../../../utils/terminalHelpers.js";
import { initGitDir } from "./git.js";
import { setupGitRemote } from "./utils-git-github.js";
export async function checkGithubRepoOwnership(githubInstance, owner, repo) {
try {
const { data: repository } = await githubInstance.rest.repos.get({
owner,
repo
});
return {
exists: true,
isOwner: repository.permissions?.admin ?? false,
defaultBranch: repository.default_branch
};
} catch (error) {
if (error instanceof RequestError) {
if (error.status === 404) {
return { exists: false, isOwner: false };
}
if (error.status === 403) {
throw new Error("GitHub API rate limit exceeded");
}
if (error.status === 401) {
throw new Error("Invalid GitHub token");
}
}
throw error;
}
}
export async function createGithubRepo(githubInstance, repoName, repoOwner, projectPath, isDev, cwd, config, isTemplateDownload) {
if (isTemplateDownload) {
relinka(
"verbose",
"Skipping createGithubRepo since it's a template download"
);
return true;
}
try {
await cd(projectPath);
relinka("verbose", "[C] initGitDir");
await initGitDir({
cwd,
isDev,
projectPath,
projectName: repoName,
allowReInit: true,
createCommit: true,
config,
isTemplateDownload
});
let privacyAction = config.repoPrivacy;
if (privacyAction === UNKNOWN_VALUE) {
const selectedPrivacyAction = await selectPrompt({
title: "Choose repository privacy setting",
defaultValue: "public",
options: [
{
label: "Public repository",
value: "public",
hint: "Anyone can see the repository (recommended for open source)"
},
{
label: "Private repository",
value: "private",
hint: "Only you and collaborators can see the repository"
}
]
});
privacyAction = selectedPrivacyAction;
}
relinka("verbose", "Creating repository...");
try {
await githubInstance.rest.repos.createForAuthenticatedUser({
name: repoName,
private: privacyAction === "private",
auto_init: false
});
} catch (error) {
if (error instanceof Error && error.message.includes("already exists")) {
relinka("error", `Repository '${repoName}' already exists on GitHub`);
return false;
}
throw error;
}
const remoteUrl = `https://github.com/${repoOwner}/${repoName}.git`;
relinka("verbose", "Setting up Git remote and pushing initial commit...");
return await setupGitRemote(
cwd,
isDev,
repoName,
projectPath,
remoteUrl,
"origin"
);
} catch (error) {
if (error instanceof RequestError) {
if (error.status === 401 || error.status === 403) {
relinka(
"error",
"GitHub token is invalid or lacks necessary permissions. Ensure your token has the 'repo' scope."
);
} else if (error.status === 422) {
relinka(
"error",
"Invalid repository name or repository already exists and you don't have access to it."
);
} else if (error.message?.includes("rate limit")) {
relinka(
"error",
"GitHub API rate limit exceeded. Please try again later."
);
} else if (error.message?.includes("network")) {
relinka(
"error",
"Network error occurred. Please check your internet connection."
);
} else {
relinka("error", "GitHub operation failed:", error.message);
}
} else {
relinka(
"error",
"An unexpected error occurred:",
error?.message ?? String(error)
);
}
return false;
}
}