UNPKG

@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
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; } }