@reliverse/rse-sdk
Version:
@reliverse/rse-sdk allows you to create new plugins for @reliverse/rse CLI, interact with reliverse.org, and even extend your own CLI functionality (you may also try @reliverse/dler-sdk for this case).
152 lines (151 loc) • 5.43 kB
JavaScript
import { relinka } from "@reliverse/relinka";
import { confirmPrompt } from "@reliverse/rempts";
import { projectsAddProjectDomain } from "@vercel/sdk/funcs/projectsAddProjectDomain";
import { projectsCreateProject } from "@vercel/sdk/funcs/projectsCreateProject";
import { isSpecialDomain } from "../helpers/domainHelpers.js";
import { updateReliverseMemory } from "../../../../../sdk-mod.js";
import { withRateLimit } from "./vercel-api.js";
import {
configureBranchProtection,
configureResources,
enableAnalytics,
getConfigurationOptions
} from "./vercel-config.js";
import { createInitialVercelDeployment } from "./vercel-deploy.js";
import { addEnvVarsToVercelProject } from "./vercel-env.js";
import { detectFramework, verifyDomain } from "./vercel-utils.js";
export async function createVercelProject(projectName, projectPath, vercelInstance) {
relinka("info", "Creating new Vercel project...");
const framework = await detectFramework(projectPath);
const createProjectRes = await withRateLimit(
async () => projectsCreateProject(vercelInstance, {
requestBody: {
name: projectName,
framework,
gitRepository: {
type: "github",
repo: projectName
}
}
})
);
if (!createProjectRes.ok) {
throw createProjectRes.error;
}
const projectId = createProjectRes.value.id;
relinka("verbose", `Project created with ID: ${projectId}`);
return projectId;
}
export async function prepareVercelProjectCreation(githubInstance, vercelInstance, vercelToken, githubToken, skipPrompts, projectName, projectPath, domain, memory, deployMode, githubUsername) {
if (!vercelToken) {
throw new Error(
"Vercel token not found in rse's memory. Please restart the CLI and try again. Notify the @reliverse/rse developers if the problem persists."
);
}
try {
const selectedOptions = deployMode === "new" || skipPrompts ? { options: ["env"] } : await getConfigurationOptions();
const projectId = await createVercelProject(
projectName,
projectPath,
vercelInstance
);
if (selectedOptions.options.includes("analytics")) {
await enableAnalytics(vercelInstance, projectId);
}
if (selectedOptions.options.includes("protection")) {
await configureBranchProtection(vercelInstance, projectId);
}
if (selectedOptions.options.includes("resources")) {
await configureResources(vercelInstance, projectId);
}
if (!isSpecialDomain(domain) && domain !== `${projectName}.vercel.app`) {
let shouldAddDomain = false;
if (!skipPrompts) {
shouldAddDomain = await confirmPrompt({
title: `Do you want to add ${domain} to your Vercel project?`,
content: `If not, a ${projectName}.vercel.app domain will be created automatically. You can always add a custom domain later in the dashboard.`
});
}
if (!shouldAddDomain) {
relinka("info", "Skipping custom domain configuration");
} else {
relinka("info", "Setting up custom domain...");
try {
const addDomainRes = await projectsAddProjectDomain(vercelInstance, {
idOrName: projectName,
requestBody: { name: domain }
});
if (!addDomainRes.ok) {
throw addDomainRes.error;
}
const verified = await verifyDomain(
vercelInstance,
projectId,
domain
);
if (!verified) {
relinka(
"warn",
"Domain not verified. Complete verification in the dashboard."
);
}
} catch (error) {
relinka(
"warn",
"Failed to set up custom domain. You can add it later:",
error instanceof Error ? error.message : String(error)
);
}
}
}
if (selectedOptions.options.includes("env")) {
await addEnvVarsToVercelProject(
vercelInstance,
projectName,
projectPath,
{
options: selectedOptions.options,
useSharedEnvVars: false
}
);
}
const deployment = await createInitialVercelDeployment(
githubInstance,
vercelInstance,
projectId,
memory,
projectName,
{ framework: await detectFramework(projectPath) },
{
includes: (option) => selectedOptions.options.includes(option)
},
githubUsername,
githubToken
);
relinka("success", `Deployment preview URL: https://${deployment.url}`);
relinka("verbose", "\u2705 Deployment completed successfully!");
return true;
} catch (error) {
if (error instanceof Error) {
if (error.message.includes("rate limit")) {
relinka(
"error",
"Vercel API rate limit exceeded. Please try again later."
);
} else if (error.message.includes("network")) {
relinka("error", "Network error. Please check your connection.");
} else if (error.message.includes("unauthorized")) {
relinka(
"error",
"Invalid/expired Vercel token. Please provide a new token."
);
await updateReliverseMemory({ vercelKey: "" });
} else {
relinka("error", "Error creating Vercel deployment:", error.message);
}
} else {
relinka("error", "Unexpected error during deployment");
}
return false;
}
}