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

114 lines (113 loc) 3.88 kB
import { relinka } from "@reliverse/relinka"; import { multiselectPrompt, selectPrompt, confirmPrompt } from "@reliverse/rempts"; import { projectsDeleteProject } from "@vercel/sdk/funcs/projectsDeleteProject"; import { projectsGetProjects } from "@vercel/sdk/funcs/projectsGetProjects"; import { withRateLimit } from "../init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-api.js"; import { getPrimaryVercelTeam } from "../init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-team.js"; import { initVercelSDK } from "../utils/instanceVercel.js"; import { getMaxHeightSize, sleep } from "../utils/microHelpers.js"; export async function openVercelTools(memory) { const result = await initVercelSDK(memory, true); if (!result) { throw new Error( "Failed to initialize Vercel SDK. Please notify the @rseevelopers if the problem persists." ); } const [token, vercel] = result; const choice = await selectPrompt({ title: "Vercel Tools", options: [{ label: "Delete projects", value: "delete-projects" }] }); const maxItems = getMaxHeightSize().toString(); if (choice === "delete-projects") { await deleteVercelProjects(vercel, memory, maxItems, token); } } async function getVercelProjects(vercelInstance, maxItems, team) { const res = await withRateLimit(async () => { return await projectsGetProjects(vercelInstance, { teamId: team?.id, slug: team?.slug, limit: maxItems }); }); if (!res.ok) { throw res.error; } return res.value.projects; } async function deleteVercelProjects(vercelInstance, memory, maxItems, token) { if (!token) { throw new Error("No Vercel token provided"); } const team = await getPrimaryVercelTeam(vercelInstance, memory); const allProjects = await getVercelProjects(vercelInstance, maxItems, team); const protectedNames = [ "relivator", "rse", "relidocs", "versator", "bleverse", "mfpiano", "blefnk" ]; const projects = allProjects.filter( (p) => !protectedNames.includes(p.name.toLowerCase()) ); const projectNames = new Map(projects.map((p) => [p.id, p.name])); const info = `If you do not see some projects, restart the CLI with a higher terminal height (current: ${maxItems})`; const excludedProjectsInfo = protectedNames.length > 0 ? `${info} Intentionally excluded projects: ${protectedNames.join(", ")}` : info; const projectsToDelete = await multiselectPrompt({ title: "Delete Vercel projects (ctrl+c to exit)", content: excludedProjectsInfo, options: projects.map((project, index) => ({ label: `${index + 1}. ${project.name}`, value: project.id })) }); if (projectsToDelete.length === 0) { relinka("info", "No projects selected for deletion."); return; } const selectedNames = projectsToDelete.map((id) => projectNames.get(id) ?? id).join(", "); const confirmed = await confirmPrompt({ title: "Are you sure you want to delete these projects?", content: selectedNames, defaultValue: false }); if (!confirmed) { relinka("info", "Operation cancelled."); return; } for (const projectId of projectsToDelete) { const projectName = projectNames.get(projectId) ?? projectId; try { relinka("verbose", `Deleting project ${projectName}...`); const res = await withRateLimit(async () => { return await projectsDeleteProject(vercelInstance, { idOrName: projectId, teamId: team?.id, slug: team?.slug }); }); if (!res.ok) { throw res.error; } relinka("success", `Successfully deleted project ${projectName}`); await sleep(2e3); } catch (error) { relinka( "error", `Failed to delete project ${projectName}:`, error instanceof Error ? error.message : String(error) ); } } }